• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef FOUNDATION_ACE_NAPI_MODULE_MANAGER_NATIVE_MODULE_MANAGER_H
17 #define FOUNDATION_ACE_NAPI_MODULE_MANAGER_NATIVE_MODULE_MANAGER_H
18 
19 #include <cstdint>
20 #include <map>
21 #include <mutex>
22 #include <unordered_map>
23 #include <unordered_set>
24 #include <vector>
25 #include <string>
26 #include <pthread.h>
27 
28 #include "module_load_checker.h"
29 #include "utils/macros.h"
30 #include "interfaces/inner_api/napi/native_node_api.h"
31 
32 #ifdef WINDOWS_PLATFORM
33 #include <winsock2.h>
34 #include <windows.h>
35 using LIBHANDLE = HMODULE;
36 #define LIBFREE FreeLibrary
37 #define LIBSYM GetProcAddress
38 #else
39 #include <dlfcn.h>
40 using LIBHANDLE = void*;
41 #define LIBFREE dlclose
42 #define LIBSYM dlsym
43 #endif
44 
45 #define NAPI_PATH_MAX 4096
46 
47 class NativeValue;
48 
49 class NativeEngine;
50 
51 typedef napi_value (*RegisterCallback)(napi_env, napi_value);
52 
53 typedef void (*GetJSCodeCallback)(const char** buf, int* bufLen);
54 
55 typedef void (*NapiOnLoadCallback)();
56 
57 struct NativeModule {
58     const char* name = nullptr;       /* .nm_modname from native c++ register info */
59     const char* moduleName = nullptr; /* moduleName required or imported */
60     const char* fileName = nullptr;
61     const char* systemFilePath = nullptr;
62     RegisterCallback registerCallback = nullptr;
63     GetJSCodeCallback getABCCode = nullptr;
64     GetJSCodeCallback getJSCode = nullptr;
65     int32_t version = 0;
66     uint32_t flags = 0;
67     uint32_t refCount = 0;
68     NativeModule* next = nullptr;
69     const char* jsCode = nullptr;
70     const uint8_t* jsABCCode = nullptr;
71     int32_t jsCodeLen = 0;
72     bool moduleLoaded = false;
73     bool isAppModule = false;
74     std::unique_ptr<ApiAllowListChecker> apiAllowListChecker = nullptr;
75 };
76 
77 struct NativeModuleHeadTailStruct {
78     NativeModule* headNativeModule = nullptr;
79     NativeModule* tailNativeModule = nullptr;
80 };
81 class NAPI_EXPORT NativeModuleManager {
82 public:
83     static NativeModuleManager* GetInstance();
84     static uint64_t Release();
85 
86     void Register(NativeModule* nativeModule);
87     void SetAppLibPath(const std::string& moduleName, const std::vector<std::string>& appLibPath,
88                        const bool& isSystemApp = false);
89     bool GetLdNamespaceName(const std::string &moduleName, std::string &nsName);
90     NativeModule* LoadNativeModule(const char* moduleName, const char* path, bool isAppModule,
91         std::string& errInfo, bool internal = false, const char* relativePath = "");
92     void SetNativeEngine(std::string moduleName, NativeEngine* nativeEngine);
93     bool UnloadNativeModule(const std::string& moduleKey);
94     std::string GetModuleFileName(const char* moduleName, bool isAppModule);
95 
96     /**
97      * @brief Set the path for searching napi dynamic libraries, only for the previewer.
98      *
99      * @param previewSearchPath the path for searching napi dynamic libraries
100      */
101     void SetPreviewSearchPath(const std::string& previewSearchPath);
102 
103     /**
104      * @brief Set the Module Load Checker delegate
105      *
106      * @param moduleCheckerDelegate The Module Load Checker delegate
107      */
108     void SetModuleLoadChecker(const std::shared_ptr<ModuleCheckerDelegate>& moduleCheckerDelegate);
109 
CheckModuleRestricted(const std::string & moduleName)110     inline bool CheckModuleRestricted(const std::string& moduleName)
111     {
112         const std::string whiteList[] = {
113             "worker",
114             "arkui.uicontext",
115             "arkui.node",
116             "arkui.modifier",
117             "measure",
118         };
119 
120         size_t listLen = sizeof(whiteList) / sizeof(whiteList[0]);
121         for (size_t i = 0; i < listLen; ++i) {
122             if (moduleName == whiteList[i]) {
123                 return true;
124             }
125         }
126 
127         return false;
128     }
129 
130 private:
131     NativeModuleManager();
132     virtual ~NativeModuleManager();
133 
134     bool GetNativeModulePath(const char* moduleName, const char* path, const char* relativePath,
135         bool isAppModule, char nativeModulePath[][NAPI_PATH_MAX], int32_t pathLength);
136     NativeModule* FindNativeModuleByDisk(const char* moduleName, const char* path, const char* relativePath,
137         bool internal, const bool isAppModule, std::string& errInfo, char nativeModulePath[][NAPI_PATH_MAX],
138         NativeModule* cacheNativeModule);
139     NativeModule* FindNativeModuleByCache(const char* moduleName,
140                                           char nativeModulePath[][NAPI_PATH_MAX],
141                                           NativeModule*& cacheNativeModule,
142                                           NativeModuleHeadTailStruct& cacheHeadTailStruct);
143     bool CheckModuleExist(const char* modulePath);
144     LIBHANDLE LoadModuleLibrary(std::string& moduleKey, const char* path, const char* pathKey,
145         const bool isAppModule, std::string& errInfo, uint32_t& errReason);
146     const uint8_t* GetFileBuffer(const std::string& filePath, const std::string& moduleKey, size_t &len);
147     bool UnloadModuleLibrary(LIBHANDLE handle);
148     bool CloseModuleLibrary(LIBHANDLE handle);
149     void CreateLdNamespace(const std::string moduleName, const char* lib_ld_path, const bool& isSystemApp);
150     bool IsExistedPath(const char* pathKey) const;
151     void EmplaceModuleLib(const std::string moduleKey, LIBHANDLE lib);
152     bool RemoveModuleLib(const std::string moduleKey);
153     void EmplaceModuleBuffer(const std::string moduleKey, const uint8_t* lib);
154     bool RemoveModuleBuffer(const std::string moduleKey);
155     const uint8_t* GetBufferHandle(const std::string& moduleKey) const;
156     void RegisterByBuffer(const std::string& moduleKey, const uint8_t* abcBuffer, size_t len);
157     bool CreateTailNativeModule();
158     bool CreateHeadNativeModule();
159     LIBHANDLE GetNativeModuleHandle(const std::string& moduleKey) const;
160     bool RemoveNativeModuleByCache(const std::string& moduleKey);
161     bool RemoveNativeModule(const std::string& moduleKey);
162     bool CheckNativeListChanged(const NativeModule* cacheHeadNativeModule, const NativeModule* cacheTailNativeModule);
163     void MoveApiAllowListCheckerPtr(
164         std::unique_ptr<ApiAllowListChecker>& apiAllowListChecker, NativeModule* nativeModule);
165     void Napi_onLoadCallback(LIBHANDLE lib, const char* moduleName);
166 #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) && !defined(__BIONIC__) && !defined(IOS_PLATFORM) && \
167     !defined(LINUX_PLATFORM)
168     void CreateSharedLibsSonames();
169 
170     char* sharedLibsSonames_ = nullptr;
171     std::map<std::string, Dl_namespace> nsMap_;
172 #endif
173 
174     std::mutex nativeModuleListMutex_;
175     NativeModule* headNativeModule_ = nullptr;
176     NativeModule* tailNativeModule_ = nullptr;
177 
178     static NativeModuleManager *instance_;
179     pthread_mutex_t mutex_;
180     std::string prefix_;
181     bool isAppModule_ = false;
182     std::string loadingModuleName_;
183 
184     std::mutex nativeEngineListMutex_;
185     std::map<std::string, NativeEngine*> nativeEngineList_;
186 
187     mutable std::mutex moduleLibMutex_;
188     std::map<std::string, const LIBHANDLE> moduleLibMap_;
189 
190     mutable std::mutex moduleBufMutex_;
191     std::map<std::string, const uint8_t*> moduleBufMap_;
192 
193     mutable std::mutex appLibPathMapMutex_;
194     std::map<std::string, char*> appLibPathMap_;
195     std::string previewSearchPath_;
196     std::unique_ptr<ModuleLoadChecker> moduleLoadChecker_ = nullptr;
197 };
198 
199 #endif /* FOUNDATION_ACE_NAPI_MODULE_MANAGER_NATIVE_MODULE_MANAGER_H */
200