/* * Copyright (c) 2020-2021 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef OHOS_ACELITE_MODULE_MANAGER_H #define OHOS_ACELITE_MODULE_MANAGER_H #include "jsi.h" #include "non_copyable.h" #include "product_adapter.h" namespace OHOS { namespace ACELite { /** * Function pointer type used for getting current bundle name. */ typedef const char *(*BundleNameGetter)(); /** * @brief module manager for module load. */ class ModuleManager final : public MemoryHeap { public: ACE_DISALLOW_COPY_AND_MOVE(ModuleManager); /** * @brief Get the single instance of ModuleManager * * @returns the instance. */ static ModuleManager* GetInstance() { static ModuleManager instance; return &instance; } /** * @brief require javascript module object with given module name. * * @param moduleName name of the module required * @returns javascript module object */ JSIValue RequireModule(const char * const moduleName); /** * @brief Release module object created by RequireModule. * This Method should be called when current js page is * going to destroy */ void CleanUpModule(); /** * @brief Call OnTerminate callbacks of required modules. * This Method should be called when current application is * going to terminate */ void OnTerminate(); /** * @brief Set product modules getter hook. * * @param the hook */ void SetProductModulesGetter(ProductModulesGetter getter); /** * @brief Set private modules getter hook. * * @param the hook */ void SetPrivateModulesGetter(PrivateModulesGetter getter); /** * @brief Set bundle name getter hook. * * @param the hook */ void SetBundleNameGetter(BundleNameGetter getter); private: struct CallbackNode : public MemoryHeap { ACE_DISALLOW_COPY_AND_MOVE(CallbackNode); CallbackNode() : moduleName(nullptr), callback(nullptr), callbackHandler(nullptr), next(nullptr) {} ~CallbackNode() { if (moduleName != nullptr) { ace_free(moduleName); moduleName = nullptr; } } char *moduleName; NativeCallback callback; JsiCallback callbackHandler; struct CallbackNode *next; }; ModuleManager() : onDestroyHead_(nullptr), onTerminateHead_(nullptr), productModulesGetter_(nullptr), privateModulesGetter_(nullptr), bundleNameGetter_(nullptr) { } virtual ~ModuleManager() {} /** * @brief get category and name with given moduleName. * * @param [in] moduleName module name passed from JS, e.g. system.vibrator * @param [out] category pointer to category which this module belongs to * Content should be freed with free() when it is not used anymore * @param [out] name pointer to module name parsed from moduleName, e.g. vibrator * Content should be freed with free() when it is not used anymore * @return whether operation succeed */ bool ParseModuleName(const char * const moduleName, char** category, char** name) const; /** * @brief obtains the module object with the given module name. * * @param [in] moduleName module name * @param [in] modules array of module infos * @param [in] modulesCount length of modules * @param [inout] categoryObj pointer to static object, e.g. requiredSystemModules * @param [in] bundleName bundle name of specific private module * @return javascript required module object */ JSIValue GetModuleObject(const char * const moduleName, const Module* modules, uint16_t modulesCount, JSIValue& categoryObj, const char * const bundleName = nullptr); JSIValue InitModuleObject(const char * const name, Module module, JSIValue& categoryObj); // *resPtr should be freed by caller when it's not nullptr and won't be used any more bool CreateString(const char * const srcStr, char** resPtr) const; void InsertCallback(CallbackNode *&head, NativeCallback callback, JsiCallback callbackHandler, const char * const moduleName = nullptr) const; void InsertTerminateCallback(const char * const name, const JSIValue& moduleObj); void InvokeCallbacks(CallbackNode *&head) const; void* GetObjectPointer(JSIValue object) const; void* GetObjectNamedPointer(JSIValue object, const char * const name) const; void DeleteObjectProperty(JSIValue object, const char * const name) const; NativeCallback GetNativeCallback(JSIValue object, const char * const name) const; JsiCallback GetJsiCallback(JSIValue object, const char * const name) const; // For different native module type const char* CATEGORY_SYSTEM = "system"; const char* CATEGORY_OHOS = "ohos"; // JS object for caching modules static JSIValue requiredSystemModules; CallbackNode *onDestroyHead_; CallbackNode *onTerminateHead_; ProductModulesGetter productModulesGetter_; PrivateModulesGetter privateModulesGetter_; BundleNameGetter bundleNameGetter_; }; } // namespace ACELite } // namespace OHOS #endif // OHOS_ACELITE_MODULE_MANAGER_H