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 #include "native_module_manager.h"
17
18 #include <cstring>
19 #include <dirent.h>
20 #include <fstream>
21 #include <iostream>
22 #include <mutex>
23 #include <sstream>
24 #include <unistd.h>
25
26 #ifdef ENABLE_HITRACE
27 #include "hitrace_meter.h"
28 #endif
29 #include "module_load_checker.h"
30 #include "native_engine/native_engine.h"
31 #include "securec.h"
32 #include "utils/log.h"
33
34 #define NDK "ndk"
35 #define ALLOW_ALL_SHARED_LIBS "allow_all_shared_libs"
36
37 namespace {
38 constexpr static int32_t NATIVE_PATH_NUMBER = 3;
39 constexpr static int32_t IS_APP_MODULE_FLAGS = 100;
40 thread_local bool g_isLoadingModule = false;
41 enum ModuleLoadFailedReason : uint32_t {
42 MODULE_LOAD_SUCCESS = 0,
43 MODULE_NOT_EXIST = 1,
44 };
45 } // namespace
46
47 NativeModuleManager* NativeModuleManager::instance_ = NULL;
48 std::mutex g_instanceMutex;
49
NativeModuleManager()50 NativeModuleManager::NativeModuleManager()
51 {
52 HILOG_DEBUG("enter");
53 pthread_mutex_init(&mutex_, nullptr);
54 moduleLoadChecker_ = std::make_unique<ModuleLoadChecker>();
55 }
56
~NativeModuleManager()57 NativeModuleManager::~NativeModuleManager()
58 {
59 HILOG_INFO("enter");
60 {
61 std::lock_guard<std::mutex> lock(nativeModuleListMutex_);
62 NativeModule* nativeModule = headNativeModule_;
63 while (nativeModule != nullptr) {
64 nativeModule = nativeModule->next;
65 if (headNativeModule_->name) {
66 delete[] headNativeModule_->name;
67 }
68 if (headNativeModule_->moduleName) {
69 delete[] headNativeModule_->moduleName;
70 }
71 if (headNativeModule_->jsABCCode) {
72 delete[] headNativeModule_->jsABCCode;
73 }
74 delete headNativeModule_;
75 headNativeModule_ = nativeModule;
76 }
77 headNativeModule_ = nullptr;
78 tailNativeModule_ = nullptr;
79 }
80
81 #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) && !defined(__BIONIC__) && !defined(IOS_PLATFORM) && \
82 !defined(LINUX_PLATFORM)
83 if (sharedLibsSonames_) {
84 delete[] sharedLibsSonames_;
85 }
86 #endif
87 appLibPathMapMutex_.lock();
88 for (const auto& item : appLibPathMap_) {
89 delete[] item.second;
90 }
91 std::map<std::string, char*>().swap(appLibPathMap_);
92 appLibPathMapMutex_.unlock();
93
94 while (nativeEngineList_.size() > 0) {
95 NativeEngine* wraper = nativeEngineList_.begin()->second;
96 if (wraper != nullptr) {
97 delete wraper;
98 wraper = nullptr;
99 }
100 nativeEngineList_.erase(nativeEngineList_.begin());
101 }
102 pthread_mutex_destroy(&mutex_);
103 }
104
GetInstance()105 NativeModuleManager* NativeModuleManager::GetInstance()
106 {
107 if (instance_ == NULL) {
108 std::lock_guard<std::mutex> lock(g_instanceMutex);
109 if (instance_ == NULL) {
110 instance_ = new NativeModuleManager();
111 HILOG_DEBUG("create native module manager instance");
112 }
113 }
114 return instance_;
115 }
116
SetNativeEngine(std::string moduleKey,NativeEngine * nativeEngine)117 void NativeModuleManager::SetNativeEngine(std::string moduleKey, NativeEngine* nativeEngine)
118 {
119 HILOG_DEBUG("modulekey is '%{public}s'", moduleKey.c_str());
120 if (nativeEngine != nullptr) {
121 nativeEngine->SetModuleName(moduleKey);
122 }
123 std::lock_guard<std::mutex> lock(nativeEngineListMutex_);
124 nativeEngineList_.emplace(moduleKey, nativeEngine);
125 }
126
EmplaceModuleLib(std::string moduleKey,const LIBHANDLE lib)127 void NativeModuleManager::EmplaceModuleLib(std::string moduleKey, const LIBHANDLE lib)
128 {
129 HILOG_DEBUG("modulekey is '%{public}s'", moduleKey.c_str());
130 std::lock_guard<std::mutex> lock(moduleLibMutex_);
131 if (lib != nullptr) {
132 moduleLibMap_.emplace(moduleKey, lib);
133 }
134 }
135
RemoveModuleLib(const std::string moduleKey)136 bool NativeModuleManager::RemoveModuleLib(const std::string moduleKey)
137 {
138 HILOG_DEBUG("moduleKey is '%{public}s'", moduleKey.c_str());
139 bool deleted = false;
140 std::lock_guard<std::mutex> lock(moduleLibMutex_);
141 auto it = moduleLibMap_.find(moduleKey);
142 if (it != moduleLibMap_.end()) {
143 moduleLibMap_.erase(it);
144 HILOG_DEBUG("module '%{public}s' erased", moduleKey.c_str());
145 deleted = true;
146 }
147 return deleted;
148 }
149
GetNativeModuleHandle(const std::string & moduleKey) const150 LIBHANDLE NativeModuleManager::GetNativeModuleHandle(const std::string& moduleKey) const
151 {
152 HILOG_DEBUG("moduleKey is '%{public}s'", moduleKey.c_str());
153 std::lock_guard<std::mutex> lock(moduleLibMutex_);
154 auto it = moduleLibMap_.find(moduleKey);
155 if (it == moduleLibMap_.end()) {
156 return nullptr;
157 }
158 return it->second;
159 }
160
EmplaceModuleBuffer(const std::string moduleKey,const uint8_t * lib)161 void NativeModuleManager::EmplaceModuleBuffer(const std::string moduleKey, const uint8_t* lib)
162 {
163 HILOG_DEBUG("modulekey is '%{public}s'", moduleKey.c_str());
164 std::lock_guard<std::mutex> lock(moduleBufMutex_);
165 if (lib != nullptr) {
166 moduleBufMap_.emplace(moduleKey, lib);
167 }
168 }
169
RemoveModuleBuffer(const std::string moduleKey)170 bool NativeModuleManager::RemoveModuleBuffer(const std::string moduleKey)
171 {
172 HILOG_DEBUG("moduleKey is '%{public}s'", moduleKey.c_str());
173 bool deleted = false;
174 std::lock_guard<std::mutex> lock(moduleBufMutex_);
175 auto it = moduleBufMap_.find(moduleKey);
176 if (it != moduleBufMap_.end()) {
177 moduleBufMap_.erase(it);
178 HILOG_DEBUG("module '%{public}s' erased", moduleKey.c_str());
179 deleted = true;
180 }
181 return deleted;
182 }
183
GetBufferHandle(const std::string & moduleKey) const184 const uint8_t* NativeModuleManager::GetBufferHandle(const std::string& moduleKey) const
185 {
186 HILOG_DEBUG("moduleKey is '%{public}s'", moduleKey.c_str());
187 std::lock_guard<std::mutex> lock(moduleBufMutex_);
188 auto it = moduleBufMap_.find(moduleKey);
189 if (it == moduleBufMap_.end()) {
190 return nullptr;
191 }
192 return it->second;
193 }
194
RemoveNativeModule(const std::string & moduleKey)195 bool NativeModuleManager::RemoveNativeModule(const std::string& moduleKey)
196 {
197 bool handleAbcRemoved = RemoveModuleBuffer(moduleKey);
198 bool handleRemoved = RemoveModuleLib(moduleKey);
199 bool moduleRemoved = RemoveNativeModuleByCache(moduleKey);
200
201 HILOG_DEBUG("handleAbcRemoved is %{public}d, handleRemoved is %{public}d, moduleRemoved is %{public}d",
202 handleAbcRemoved, handleRemoved, moduleRemoved);
203 return ((handleRemoved || handleAbcRemoved) && moduleRemoved);
204 }
205
UnloadNativeModule(const std::string & moduleKey)206 bool NativeModuleManager::UnloadNativeModule(const std::string& moduleKey)
207 {
208 HILOG_DEBUG("moduleKey is '%{public}s'", moduleKey.c_str());
209 LIBHANDLE handle = GetNativeModuleHandle(moduleKey);
210 if (handle == nullptr) {
211 HILOG_ERROR("failed to get native module handle.");
212 return false;
213 }
214
215 if (RemoveNativeModule(moduleKey) == false) {
216 HILOG_ERROR("remove native module failed.");
217 return false;
218 }
219
220 return UnloadModuleLibrary(handle);
221 }
222
GetModuleFileName(const char * moduleName,bool isAppModule)223 std::string NativeModuleManager::GetModuleFileName(const char* moduleName, bool isAppModule)
224 {
225 if (moduleName == nullptr) {
226 HILOG_ERROR("invalid param. moduleName is nullptr");
227 return "";
228 }
229 HILOG_INFO("moduleName is '%{public}s', isAppModule is %{public}d", moduleName, isAppModule);
230
231 std::string loadPath;
232 std::string name = isAppModule ? (prefix_ + "/" + moduleName) : moduleName;
233 char nativeModulePath[NATIVE_PATH_NUMBER][NAPI_PATH_MAX];
234 const char* pathKey = "default";
235 if (!GetNativeModulePath(moduleName, pathKey, "", isAppModule, nativeModulePath, NAPI_PATH_MAX)) {
236 HILOG_ERROR("get native module path failed");
237 return loadPath;
238 }
239 NativeModule* cacheNativeModule = nullptr;
240 NativeModuleHeadTailStruct cacheHeadTailNativeModule;
241 NativeModule* module =
242 FindNativeModuleByCache(name.c_str(), nativeModulePath, cacheNativeModule, cacheHeadTailNativeModule);
243 if (module == nullptr) {
244 HILOG_ERROR("get module file name failed");
245 return loadPath;
246 }
247 loadPath = nativeModulePath[0];
248 if (isAppModule && IsExistedPath(pathKey)) {
249 std::lock_guard<std::mutex> guard(appLibPathMapMutex_);
250 loadPath = std::string(appLibPathMap_[pathKey]) + "/" + nativeModulePath[0];
251 }
252 HILOG_ERROR("get module file name failed, moduleName is %{public}s", moduleName);
253 return loadPath;
254 }
255
Register(NativeModule * nativeModule)256 void NativeModuleManager::Register(NativeModule* nativeModule)
257 {
258 if (nativeModule == nullptr) {
259 HILOG_ERROR("nativeModule value is null");
260 return;
261 }
262
263 HILOG_DEBUG("native module name is '%{public}s'", nativeModule->name);
264 std::lock_guard<std::mutex> lock(nativeModuleListMutex_);
265 const char *nativeModuleName = nativeModule->name == nullptr ? "" : nativeModule->name;
266 std::string appName = prefix_ + "/" + nativeModuleName;
267 std::string tmpName = isAppModule_ ? appName : nativeModuleName;
268 if (nativeModule->flags == IS_APP_MODULE_FLAGS) {
269 std::string prefix = "default/";
270 tmpName = prefix + nativeModuleName;
271 }
272 char *moduleName = strdup(tmpName.c_str());
273 if (moduleName == nullptr) {
274 HILOG_ERROR("strdup failed. tmpName is %{public}s", tmpName.c_str());
275 return;
276 }
277
278 if (g_isLoadingModule || !strcmp(loadingModuleName_.c_str(), moduleName)) {
279 if (!CreateTailNativeModule()) {
280 HILOG_ERROR("create tail nativeModule failed");
281 delete moduleName;
282 return;
283 }
284 tailNativeModule_->version = nativeModule->version;
285 tailNativeModule_->fileName = nativeModule->fileName;
286 tailNativeModule_->isAppModule = isAppModule_;
287 tailNativeModule_->name = moduleName;
288 tailNativeModule_->moduleName = nullptr; /* we update moduleName latter */
289 tailNativeModule_->refCount = nativeModule->refCount;
290 tailNativeModule_->registerCallback = nativeModule->registerCallback;
291 tailNativeModule_->getJSCode = nativeModule->getJSCode;
292 tailNativeModule_->getABCCode = nativeModule->getABCCode;
293 tailNativeModule_->next = nullptr;
294 tailNativeModule_->moduleLoaded = true;
295 tailNativeModule_->systemFilePath = "";
296 HILOG_INFO("At tail register module name is '%{public}s', isAppModule is %{public}d",
297 tailNativeModule_->name, isAppModule_);
298 } else {
299 if (!CreateHeadNativeModule()) {
300 HILOG_ERROR("create head nativeModule failed");
301 return;
302 }
303 headNativeModule_->version = nativeModule->version;
304 headNativeModule_->fileName = nativeModule->fileName;
305 headNativeModule_->isAppModule = isAppModule_;
306 headNativeModule_->name = moduleName;
307 headNativeModule_->refCount = nativeModule->refCount;
308 headNativeModule_->registerCallback = nativeModule->registerCallback;
309 headNativeModule_->getJSCode = nativeModule->getJSCode;
310 headNativeModule_->getABCCode = nativeModule->getABCCode;
311 headNativeModule_->moduleLoaded = true;
312 headNativeModule_->systemFilePath = "";
313 HILOG_INFO("At head register module name is '%{public}s', isAppModule is %{public}d",
314 headNativeModule_->name, isAppModule_);
315 }
316 }
317
CreateHeadNativeModule()318 bool NativeModuleManager::CreateHeadNativeModule()
319 {
320 if (headNativeModule_ == tailNativeModule_ && tailNativeModule_ == nullptr) {
321 headNativeModule_ = new NativeModule();
322 if (headNativeModule_ == nullptr) {
323 HILOG_ERROR("first NativeModule create failed");
324 return false;
325 }
326 tailNativeModule_ = headNativeModule_;
327 } else {
328 auto head = new NativeModule();
329 if (head == nullptr) {
330 HILOG_ERROR("head NativeModule create failed");
331 return false;
332 }
333 if (headNativeModule_) {
334 head->next = headNativeModule_;
335 headNativeModule_ = head;
336 }
337 }
338 return true;
339 }
340
CreateTailNativeModule()341 bool NativeModuleManager::CreateTailNativeModule()
342 {
343 if (headNativeModule_ == tailNativeModule_ && tailNativeModule_ == nullptr) {
344 headNativeModule_ = new NativeModule();
345 if (headNativeModule_ == nullptr) {
346 HILOG_ERROR("first NativeModule create failed");
347 return false;
348 }
349 tailNativeModule_ = headNativeModule_;
350 } else {
351 auto tail = new NativeModule();
352 if (tail == nullptr) {
353 HILOG_ERROR("tail NativeModule create failed");
354 return false;
355 }
356 if (tailNativeModule_) {
357 tailNativeModule_->next = tail;
358 tailNativeModule_ = tailNativeModule_->next;
359 }
360 }
361 return true;
362 }
363
364 #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) && !defined(__BIONIC__) && !defined(IOS_PLATFORM) && \
365 !defined(LINUX_PLATFORM)
CreateSharedLibsSonames()366 void NativeModuleManager::CreateSharedLibsSonames()
367 {
368 HILOG_DEBUG("enter");
369 const char* allowList[] = {
370 // bionic library
371 "libc.so",
372 "libdl.so",
373 "libm.so",
374 "libz.so",
375 "libclang_rt.asan.so",
376 "libclang_rt.tsan.so",
377 "libclang_rt.ubsan_standalone.so",
378 "libclang_rt.ubsan_minimal.so",
379 "libclang_rt.hwasan.so",
380 // z library
381 "libace_napi.z.so",
382 "libace_ndk.z.so",
383 "libcj_environment.z.so",
384 "libbundle_ndk.z.so",
385 "libdeviceinfo_ndk.z.so",
386 "libEGL.so",
387 "libGLESv3.so",
388 "libhiappevent_ndk.z.so",
389 "libhuks_ndk.z.so",
390 "libhukssdk.z.so",
391 "libnative_drawing.so",
392 "libnative_window.so",
393 "libnative_buffer.so",
394 "libnative_vsync.so",
395 "libOpenSLES.so",
396 "libpixelmap_ndk.z.so",
397 "libimage_ndk.z.so",
398 "libimage_receiver_ndk.z.so",
399 "libimage_source_ndk.z.so",
400 "librawfile.z.so",
401 "libuv.so",
402 "libhilog.so",
403 "libnative_image.so",
404 "libnative_media_adec.so",
405 "libnative_media_aenc.so",
406 "libnative_media_codecbase.so",
407 "libnative_media_core.so",
408 "libnative_media_vdec.so",
409 "libnative_media_venc.so",
410 "libnative_media_avmuxer.so",
411 "libnative_media_avdemuxer.so",
412 "libnative_media_avsource.so",
413 "libnative_avscreen_capture.so",
414 "libavplayer.so",
415 // adaptor library
416 "libohosadaptor.so",
417 "libusb_ndk.z.so",
418 "libvulkan.so",
419 };
420
421 size_t allowListLength = sizeof(allowList) / sizeof(char*);
422 int32_t sharedLibsSonamesLength = 1;
423 for (size_t i = 0; i < allowListLength; i++) {
424 sharedLibsSonamesLength += strlen(allowList[i]) + 1;
425 }
426 sharedLibsSonames_ = new char[sharedLibsSonamesLength];
427 int32_t cursor = 0;
428 for (size_t i = 0; i < allowListLength; i++) {
429 if (sprintf_s(sharedLibsSonames_ + cursor, sharedLibsSonamesLength - cursor, "%s:", allowList[i]) == -1) {
430 delete[] sharedLibsSonames_;
431 sharedLibsSonames_ = nullptr;
432 return;
433 }
434 cursor += strlen(allowList[i]) + 1;
435 }
436 sharedLibsSonames_[cursor] = '\0';
437 }
438 #endif
439
440 void NativeModuleManager::CreateLdNamespace(const std::string moduleName, const char* lib_ld_path,
441 [[maybe_unused]] const bool& isSystemApp)
442 {
443 #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) && !defined(__BIONIC__) && !defined(IOS_PLATFORM) && \
444 !defined(LINUX_PLATFORM)
445 Dl_namespace current_ns;
446 Dl_namespace ns;
447
448 // Create module ns.
449 std::string nsName = "moduleNs_" + moduleName;
450 dlns_init(&ns, nsName.c_str());
451 dlns_get(nullptr, ¤t_ns);
452
453 Dl_namespace ndk_ns;
454 dlns_get(NDK, &ndk_ns);
455
456 if (isSystemApp) {
457 /*
458 * The app's so may have the same name as the system library, LOCAL_NS_PREFERED means linker will check
459 * and use the app's so first.
460 */
461 dlns_create2(&ns, lib_ld_path, LOCAL_NS_PREFERED);
462 // Performs a namespace check on the full path passed directly or the full path converted after setting rpath.
463 dlns_set_namespace_separated(nsName.c_str(), true);
464 // Allows access to subdirectories of this directory for shared objects (so).
465 dlns_set_namespace_permitted_paths(nsName.c_str(), lib_ld_path);
466 // System app can visit all ndk and default ns libs.
467 if (strlen(ndk_ns.name) > 0) {
468 dlns_inherit(&ns, &ndk_ns, ALLOW_ALL_SHARED_LIBS);
469 dlns_inherit(&ndk_ns, ¤t_ns, ALLOW_ALL_SHARED_LIBS);
470 dlns_inherit(¤t_ns, &ndk_ns, ALLOW_ALL_SHARED_LIBS);
471 dlns_inherit(&ns, ¤t_ns, ALLOW_ALL_SHARED_LIBS);
472 }
473 } else {
474 dlns_create2(&ns, lib_ld_path, 0);
475 // Performs a namespace check on the full path passed directly or the full path converted after setting rpath.
476 dlns_set_namespace_separated(nsName.c_str(), true);
477 // Allows access to subdirectories of this directory for shared objects (so).
478 dlns_set_namespace_permitted_paths(nsName.c_str(), lib_ld_path);
479 // Non-system app can visit all ndk ns libs and default ns shared libs.
480 if (!sharedLibsSonames_) {
481 CreateSharedLibsSonames();
482 }
483 dlns_inherit(&ns, ¤t_ns, sharedLibsSonames_);
484 if (strlen(ndk_ns.name) > 0) {
485 dlns_inherit(&ns, &ndk_ns, ALLOW_ALL_SHARED_LIBS);
486 dlns_inherit(&ndk_ns, ¤t_ns, ALLOW_ALL_SHARED_LIBS);
487 dlns_inherit(¤t_ns, &ndk_ns, ALLOW_ALL_SHARED_LIBS);
488 }
489 }
490
491 nsMap_[moduleName] = ns;
492
493 HILOG_DEBUG("end. moduleName: %{public}s, path: %{public}s", moduleName.c_str(), lib_ld_path);
494 #endif
495 }
496
SetAppLibPath(const std::string & moduleName,const std::vector<std::string> & appLibPath,const bool & isSystemApp)497 void NativeModuleManager::SetAppLibPath(const std::string& moduleName, const std::vector<std::string>& appLibPath,
498 const bool& isSystemApp)
499 {
500 HILOG_DEBUG("moduleName is %{public}s, isisSystemApp is %{public}d", moduleName.c_str(), isSystemApp);
501
502 std::string tmpPath = "";
503 for (size_t i = 0; i < appLibPath.size(); i++) {
504 if (appLibPath[i].empty()) {
505 continue;
506 }
507 tmpPath += appLibPath[i];
508 tmpPath += ":";
509 }
510 if (tmpPath.back() == ':') {
511 tmpPath.pop_back();
512 }
513
514 char *tmp = strdup(tmpPath.c_str());
515 if (tmp == nullptr) {
516 HILOG_ERROR("strdup failed. tmpPath is %{public}s", tmpPath.c_str());
517 return;
518 }
519
520 std::lock_guard<std::mutex> guard(appLibPathMapMutex_);
521 if (appLibPathMap_[moduleName] != nullptr) {
522 delete[] appLibPathMap_[moduleName];
523 }
524 appLibPathMap_[moduleName] = tmp;
525 CreateLdNamespace(moduleName, tmp, isSystemApp);
526 HILOG_DEBUG("path: %{public}s", appLibPathMap_[moduleName]);
527 }
528
MoveApiAllowListCheckerPtr(std::unique_ptr<ApiAllowListChecker> & apiAllowListChecker,NativeModule * nativeModule)529 void NativeModuleManager::MoveApiAllowListCheckerPtr(
530 std::unique_ptr<ApiAllowListChecker>& apiAllowListChecker, NativeModule* nativeModule)
531 {
532 if (apiAllowListChecker != nullptr) {
533 nativeModule->apiAllowListChecker.reset(apiAllowListChecker.release());
534 }
535 }
536
LoadNativeModule(const char * moduleName,const char * path,bool isAppModule,std::string & errInfo,bool internal,const char * relativePath)537 NativeModule* NativeModuleManager::LoadNativeModule(const char* moduleName, const char* path, bool isAppModule,
538 std::string& errInfo, bool internal, const char* relativePath)
539 {
540 if (moduleName == nullptr) {
541 errInfo = "load native module failed. moduleName is nullptr";
542 HILOG_ERROR("%{public}s", errInfo.c_str());
543 return nullptr;
544 }
545
546 if (relativePath == nullptr) {
547 errInfo = "load native module failed. relativePath is nullptr";
548 HILOG_ERROR("%{public}s", errInfo.c_str());
549 return nullptr;
550 }
551
552 HILOG_DEBUG("moduleName is %{public}s, path is %{public}s, relativePath is %{public}s",
553 moduleName, path, relativePath);
554
555 std::unique_ptr<ApiAllowListChecker> apiAllowListChecker = nullptr;
556 if (moduleLoadChecker_ && !moduleLoadChecker_->DiskCheckOnly() &&
557 !moduleLoadChecker_->CheckModuleLoadable(moduleName, apiAllowListChecker)) {
558 errInfo = "module " + std::string(moduleName) + " is in blocklist, loading prohibited";
559 HILOG_ERROR("%{public}s", errInfo.c_str());
560 return nullptr;
561 }
562 std::string prefixTmp;
563 #ifdef ANDROID_PLATFORM
564 std::string strModule(moduleName);
565 std::string strCutName = strModule;
566 if (path != nullptr) {
567 if (IsExistedPath(path)) {
568 strModule = path;
569 }
570 prefixTmp = "default";
571 strModule = prefixTmp + '/' + moduleName;
572 } else {
573 path = "default";
574 if (strModule.find(".") != std::string::npos) {
575 char* temp = const_cast<char*>(strCutName.c_str());
576 for (char* p = strchr(temp, '.'); p != nullptr; p = strchr(p + 1, '.')) {
577 *p = '_';
578 }
579 }
580 }
581 #endif
582
583 char nativeModulePath[NATIVE_PATH_NUMBER][NAPI_PATH_MAX];
584 nativeModulePath[0][0] = 0;
585 nativeModulePath[1][0] = 0;
586 nativeModulePath[2][0] = 0; // 2 : Element index value
587 NativeModule* cacheNativeModule = nullptr;
588 NativeModuleHeadTailStruct cacheHeadTailNativeModule;
589 #ifdef ANDROID_PLATFORM
590 if (!GetNativeModulePath(strCutName.c_str(), path, relativePath, isAppModule, nativeModulePath, NAPI_PATH_MAX)) {
591 errInfo = "failed to get native file path of module " + std::string(moduleName);
592 HILOG_WARN("%{public}s", errInfo.c_str());
593 return nullptr;
594 }
595 NativeModule* nativeModule =
596 FindNativeModuleByCache(strModule.c_str(), nativeModulePath, cacheNativeModule, cacheHeadTailNativeModule);
597 #else
598 std::string key(moduleName);
599 if (isAppModule) {
600 prefixTmp = "default";
601 if (path && IsExistedPath(path)) {
602 prefixTmp = path;
603 }
604 key = prefixTmp + '/' + moduleName;
605 HILOG_INFO("key is %{public}s", key.c_str());
606 }
607 if (!GetNativeModulePath(moduleName, prefixTmp.c_str(), relativePath, isAppModule, nativeModulePath,
608 NAPI_PATH_MAX)) {
609 errInfo = "failed to get native file path of module " + std::string(moduleName);
610 HILOG_WARN("%{public}s", errInfo.c_str());
611 return nullptr;
612 }
613 #ifdef ENABLE_HITRACE
614 StartTrace(HITRACE_TAG_ACE, moduleName);
615 #endif
616 NativeModule* nativeModule =
617 FindNativeModuleByCache(key.c_str(), nativeModulePath, cacheNativeModule, cacheHeadTailNativeModule);
618 #endif
619 if (nativeModule == nullptr) {
620 (void)pthread_mutex_lock(&mutex_);
621 #ifndef IOS_PLATFORM
622 if (CheckNativeListChanged(cacheHeadTailNativeModule.headNativeModule,
623 cacheHeadTailNativeModule.tailNativeModule)) {
624 #ifdef ANDROID_PLATFORM
625 nativeModule = FindNativeModuleByCache(strModule.c_str(), nativeModulePath, cacheNativeModule,
626 cacheHeadTailNativeModule);
627 #else
628 nativeModule =
629 FindNativeModuleByCache(key.c_str(), nativeModulePath, cacheNativeModule, cacheHeadTailNativeModule);
630 #endif
631 }
632 #else
633 #endif
634 if (nativeModule == nullptr) {
635 prefix_ = prefixTmp;
636 isAppModule_ = isAppModule;
637 g_isLoadingModule = true;
638 #ifndef IOS_PLATFORM
639
640 #ifdef ANDROID_PLATFORM
641 HILOG_DEBUG("module '%{public}s' does not in cache", strCutName.c_str());
642 nativeModule = FindNativeModuleByDisk(strCutName.c_str(), path, relativePath, internal, isAppModule,
643 errInfo, nativeModulePath, cacheNativeModule);
644 #else
645 HILOG_DEBUG("module '%{public}s' does not in cache", moduleName);
646 nativeModule = FindNativeModuleByDisk(moduleName, prefix_.c_str(), relativePath, internal, isAppModule,
647 errInfo, nativeModulePath, cacheNativeModule);
648 #endif
649
650 #else
651 nativeModule =
652 FindNativeModuleByCache(moduleName, nativeModulePath, cacheNativeModule, cacheHeadTailNativeModule);
653 #endif
654 g_isLoadingModule = false;
655 }
656
657 (void)pthread_mutex_unlock(&mutex_);
658 }
659 MoveApiAllowListCheckerPtr(apiAllowListChecker, nativeModule);
660 #ifdef ENABLE_HITRACE
661 FinishTrace(HITRACE_TAG_ACE);
662 #endif
663 HILOG_DEBUG("load native module %{public}s", (nativeModule == nullptr) ? "failed" : "success");
664 return nativeModule;
665 }
666
CheckNativeListChanged(const NativeModule * cacheHeadNativeModule,const NativeModule * cacheTailNativeModule)667 bool NativeModuleManager::CheckNativeListChanged(
668 const NativeModule* cacheHeadNativeModule, const NativeModule* cacheTailNativeModule)
669 {
670 std::lock_guard<std::mutex> lock(nativeModuleListMutex_);
671 if (!cacheHeadNativeModule || !cacheTailNativeModule || !headNativeModule_ || !tailNativeModule_) {
672 return true;
673 }
674 if (strcmp(cacheHeadNativeModule->name, headNativeModule_->name) != 0 ||
675 strcmp(cacheTailNativeModule->name, tailNativeModule_->name) != 0) {
676 return true;
677 }
678
679 return false;
680 }
GetNativeModulePath(const char * moduleName,const char * path,const char * relativePath,bool isAppModule,char nativeModulePath[][NAPI_PATH_MAX],int32_t pathLength)681 bool NativeModuleManager::GetNativeModulePath(const char* moduleName, const char* path,
682 const char* relativePath, bool isAppModule, char nativeModulePath[][NAPI_PATH_MAX], int32_t pathLength)
683 {
684 #ifdef WINDOWS_PLATFORM
685 const char* soPostfix = ".dll";
686 const char* zfix = "";
687 std::string sysPrefix("./module");
688 const char* abcfix = ".abc";
689 std::string sysAbcPrefix("./module");
690 #elif defined(MAC_PLATFORM)
691 const char* soPostfix = ".dylib";
692 const char* zfix = "";
693 std::string sysPrefix("./module");
694 const char* abcfix = ".abc";
695 std::string sysAbcPrefix("./module");
696 #elif defined(_ARM64_) || defined(SIMULATOR)
697 const char* soPostfix = ".so";
698 const char* zfix = ".z";
699 std::string sysPrefix("/system/lib64/module");
700 const char* abcfix = ".abc";
701 std::string sysAbcPrefix("/system/etc/abc");
702 #elif defined(LINUX_PLATFORM)
703 const char* soPostfix = ".so";
704 const char* zfix = "";
705 std::string sysPrefix("./module");
706 const char* abcfix = ".abc";
707 std::string sysAbcPrefix("./module");
708 #else
709 const char* soPostfix = ".so";
710 const char* zfix = ".z";
711 std::string sysPrefix("/system/lib/module");
712 const char* abcfix = ".abc";
713 std::string sysAbcPrefix("/system/etc/abc");
714 #endif
715
716 #ifdef ANDROID_PLATFORM
717 isAppModule = true;
718 #endif
719 int32_t lengthOfModuleName = strlen(moduleName);
720 char dupModuleName[NAPI_PATH_MAX] = { 0 };
721 if (strcpy_s(dupModuleName, NAPI_PATH_MAX, moduleName) != 0) {
722 HILOG_ERROR("strcpy_s moduleName '%{public}s' failed", moduleName);
723 return false;
724 }
725
726 const char* prefix = nullptr;
727 if (isAppModule && IsExistedPath(path)) {
728 appLibPathMapMutex_.lock();
729 prefix = appLibPathMap_[path];
730 appLibPathMapMutex_.unlock();
731 #ifdef ANDROID_PLATFORM
732 for (int32_t i = 0; i < lengthOfModuleName; i++) {
733 dupModuleName[i] = tolower(dupModuleName[i]);
734 }
735 #endif
736 } else {
737 if (relativePath[0]) {
738 if (previewSearchPath_.empty()) {
739 sysPrefix = sysPrefix + "/" + relativePath;
740 } else {
741 sysPrefix = previewSearchPath_ + "/module";
742 }
743 }
744 prefix = sysPrefix.c_str();
745 for (int32_t i = 0; i < lengthOfModuleName; i++) {
746 dupModuleName[i] = tolower(dupModuleName[i]);
747 }
748 }
749
750 int32_t lengthOfPostfix = strlen(soPostfix);
751 if ((lengthOfModuleName > lengthOfPostfix) &&
752 (strcmp(dupModuleName + lengthOfModuleName - lengthOfPostfix, soPostfix) == 0)) {
753 if (sprintf_s(nativeModulePath[0], pathLength, "%s/%s", prefix, dupModuleName) == -1) {
754 return false;
755 }
756 return true;
757 }
758
759 char* lastDot = strrchr(dupModuleName, '.');
760 if (lastDot == nullptr) {
761 if (!isAppModule || !IsExistedPath(path)) {
762 #ifdef ANDROID_PLATFORM
763 if (sprintf_s(nativeModulePath[0], pathLength, "lib%s%s", dupModuleName, soPostfix) == -1) {
764 return false;
765 }
766 #else
767 if (sprintf_s(nativeModulePath[0], pathLength, "%s/lib%s%s%s",
768 prefix, dupModuleName, zfix, soPostfix) == -1) {
769 return false;
770 }
771 #endif
772 if (sprintf_s(nativeModulePath[1], pathLength, "%s/lib%s_napi%s%s",
773 prefix, dupModuleName, zfix, soPostfix) == -1) {
774 return false;
775 }
776
777 if (sprintf_s(nativeModulePath[2], pathLength, "%s/%s%s", // 2 : Element index value
778 sysAbcPrefix.c_str(), dupModuleName, abcfix) == -1) {
779 return false;
780 }
781 } else {
782 #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) && !defined(__BIONIC__) && !defined(IOS_PLATFORM) && \
783 !defined(LINUX_PLATFORM)
784 if (sprintf_s(nativeModulePath[0], pathLength, "lib%s%s", dupModuleName, soPostfix) == -1) {
785 return false;
786 }
787 #elif defined(ANDROID_PLATFORM)
788 std::string libPath;
789 int sprintfResult = 0;
790 std::string prefixStr = std::string(prefix);
791 std::size_t pos = prefixStr.find(':');
792 if (pos != std::string::npos) {
793 sprintfResult = sprintf_s(nativeModulePath[1], pathLength, "%s/lib%s%s",
794 prefixStr.substr(0, pos).c_str(), dupModuleName, soPostfix);
795 libPath = prefixStr.substr(pos + 1);
796 } else {
797 sprintfResult = sprintf_s(nativeModulePath[1], pathLength, "lib%s%s", dupModuleName, soPostfix);
798 libPath = prefixStr;
799 }
800 if (sprintfResult == -1) {
801 return false;
802 }
803 #else
804 if (sprintf_s(nativeModulePath[0], pathLength, "%s/lib%s%s", prefix, dupModuleName, soPostfix) == -1) {
805 return false;
806 }
807 #endif
808 #ifdef ANDROID_PLATFORM
809 if (sprintf_s(nativeModulePath[0], pathLength, "%s/lib%s%s", libPath.c_str(),
810 dupModuleName, soPostfix) == -1) {
811 return false;
812 }
813 #endif
814 }
815 } else {
816 char* afterDot = lastDot + 1;
817 if (*afterDot == '\0') {
818 return false;
819 }
820 *lastDot = '\0';
821 lengthOfModuleName = strlen(dupModuleName);
822 for (int32_t i = 0; i < lengthOfModuleName; i++) {
823 if (*(dupModuleName + i) == '.') {
824 *(dupModuleName + i) = '/';
825 }
826 }
827 if (!isAppModule || !IsExistedPath(path)) {
828 if (sprintf_s(nativeModulePath[0], pathLength, "%s/%s/lib%s%s%s",
829 prefix, dupModuleName, afterDot, zfix, soPostfix) == -1) {
830 return false;
831 }
832 if (sprintf_s(nativeModulePath[1], pathLength, "%s/%s/lib%s_napi%s%s",
833 prefix, dupModuleName, afterDot, zfix, soPostfix) == -1) {
834 return false;
835 }
836 if (sprintf_s(nativeModulePath[2], pathLength, "%s/%s/%s%s", // 2 : Element index value
837 sysAbcPrefix.c_str(), dupModuleName, afterDot, abcfix) == -1) {
838 return false;
839 }
840 } else {
841 #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) && !defined(__BIONIC__) && !defined(IOS_PLATFORM) && \
842 !defined(LINUX_PLATFORM)
843 if (sprintf_s(nativeModulePath[0], pathLength, "lib%s%s", afterDot, soPostfix) == -1) {
844 return false;
845 }
846 #else
847 if (sprintf_s(nativeModulePath[0], pathLength, "%s/%s/lib%s%s",
848 prefix, dupModuleName, afterDot, soPostfix) == -1) {
849 return false;
850 }
851 #endif
852 #ifdef ANDROID_PLATFORM
853 if (sprintf_s(nativeModulePath[1], pathLength, "%s/%s/lib%s%s",
854 prefix, moduleName, afterDot, soPostfix) == -1) {
855 return false;
856 }
857 #endif
858 }
859 }
860 return true;
861 }
862
LoadModuleLibrary(std::string & moduleKey,const char * path,const char * pathKey,const bool isAppModule,std::string & errInfo,uint32_t & errReason)863 LIBHANDLE NativeModuleManager::LoadModuleLibrary(std::string& moduleKey, const char* path,
864 const char* pathKey, const bool isAppModule, std::string& errInfo, uint32_t& errReason)
865 {
866 if (strlen(path) == 0) {
867 errInfo += "load module " + moduleKey + " failed. module path is empty";
868 HILOG_ERROR("%{public}s", errInfo.c_str());
869 return nullptr;
870 }
871
872 LIBHANDLE lib = nullptr;
873
874 HILOG_DEBUG("path: %{public}s, pathKey: %{public}s, isAppModule: %{public}d", path, pathKey, isAppModule);
875 #ifdef ENABLE_HITRACE
876 StartTrace(HITRACE_TAG_ACE, path);
877 #endif
878 #if defined(WINDOWS_PLATFORM)
879 if (CheckModuleExist(path) == false) {
880 errReason = MODULE_NOT_EXIST;
881 return nullptr;
882 }
883 lib = LoadLibrary(path);
884 if (lib == nullptr) {
885 errInfo += "load module failed. " + std::to_string(GetLastError());
886 HILOG_WARN("%{public}s", errInfo.c_str());
887 }
888 #elif defined(MAC_PLATFORM) || defined(__BIONIC__) || defined(LINUX_PLATFORM)
889 #ifndef ANDROID_PLATFORM
890 if (CheckModuleExist(path) == false) {
891 errReason = MODULE_NOT_EXIST;
892 return nullptr;
893 }
894 #endif
895 lib = dlopen(path, RTLD_LAZY);
896 if (lib == nullptr) {
897 char* dlerr = dlerror();
898 auto dlerrMsg = dlerr != nullptr ? dlerr : "dlerror msg is empty";
899 errInfo += "load module failed. " + std::string(dlerrMsg);
900 }
901
902 #elif defined(IOS_PLATFORM)
903 lib = nullptr;
904 #else
905 if (isAppModule && IsExistedPath(pathKey)) {
906 Dl_namespace ns = nsMap_[pathKey];
907 lib = dlopen_ns(&ns, path, RTLD_LAZY);
908 } else if (access(path, F_OK) == 0) {
909 lib = dlopen(path, RTLD_LAZY);
910 }
911 if (lib == nullptr) {
912 char* dlerr = dlerror();
913 auto dlerrMsg = dlerr != nullptr ? dlerr :
914 "Error loading path " + std::string(path) + ":No such file or directory";
915 errInfo += "load app module failed. " + std::string(dlerrMsg);
916 }
917 #endif
918 #ifdef ENABLE_HITRACE
919 FinishTrace(HITRACE_TAG_ACE);
920 #endif
921 EmplaceModuleLib(moduleKey, lib);
922
923 return lib;
924 }
925
GetFileBuffer(const std::string & filePath,const std::string & moduleKey,size_t & len)926 const uint8_t* NativeModuleManager::GetFileBuffer(const std::string& filePath,
927 const std::string& moduleKey, size_t &len)
928 {
929 const uint8_t* lib = nullptr;
930 std::ifstream inFile(filePath, std::ios::ate | std::ios::binary);
931 if (!inFile.is_open()) {
932 HILOG_ERROR("%{public}s is not existed.", filePath.c_str());
933 return lib;
934 }
935 len = static_cast<size_t>(inFile.tellg());
936 std::string abcModuleKey = moduleKey;
937 lib = GetBufferHandle(abcModuleKey);
938 if (lib != nullptr) {
939 HILOG_DEBUG("get native abc handle success. moduleKey is %{public}s", moduleKey.c_str());
940 inFile.close();
941 return lib;
942 }
943
944 std::unique_ptr<uint8_t[]> buffer = std::make_unique<uint8_t[]>(len);
945 inFile.seekg(0);
946 inFile.read(reinterpret_cast<char*>(buffer.get()), len);
947 inFile.close();
948 lib = buffer.release();
949 EmplaceModuleBuffer(abcModuleKey, lib);
950 return lib;
951 }
952
UnloadModuleLibrary(LIBHANDLE handle)953 bool NativeModuleManager::UnloadModuleLibrary(LIBHANDLE handle)
954 {
955 if (handle == nullptr) {
956 HILOG_WARN("handle is nullptr");
957 return false;
958 }
959 #if !defined(WINDOWS_PLATFORM) && !defined(IOS_PLATFORM)
960 if (!dlclose(handle)) {
961 return true;
962 }
963 char* dlerr = dlerror();
964 auto dlerrMsg = dlerr != nullptr ? dlerr : "dlerror msg is empty";
965 HILOG_WARN("dlclose failed: %{public}s", dlerrMsg);
966 #endif
967 return false;
968 }
969
CheckModuleExist(const char * modulePath)970 bool NativeModuleManager::CheckModuleExist(const char* modulePath)
971 {
972 if (modulePath) {
973 std::ifstream inFile(modulePath, std::ios::ate | std::ios::binary);
974 if (inFile.is_open()) {
975 inFile.close();
976 return true;
977 }
978 }
979 return false;
980 }
981
FindNativeModuleByDisk(const char * moduleName,const char * path,const char * relativePath,bool internal,const bool isAppModule,std::string & errInfo,char nativeModulePath[][NAPI_PATH_MAX],NativeModule * cacheNativeModule)982 NativeModule* NativeModuleManager::FindNativeModuleByDisk(const char* moduleName, const char* path,
983 const char* relativePath, bool internal, const bool isAppModule, std::string& errInfo,
984 char nativeModulePath[][NAPI_PATH_MAX], NativeModule* cacheNativeModule)
985 {
986 std::unique_ptr<ApiAllowListChecker> apiAllowListChecker = nullptr;
987 if (moduleLoadChecker_ && !moduleLoadChecker_->CheckModuleLoadable(moduleName, apiAllowListChecker)) {
988 errInfo = "module " + std::string(moduleName) + " is in blocklist, loading prohibited";
989 HILOG_WARN("%{public}s", errInfo.c_str());
990 return nullptr;
991 }
992
993 std::string moduleKey(moduleName);
994 if (isAppModule) {
995 moduleKey = path;
996 moduleKey = moduleKey + '/' + moduleName;
997 }
998 loadingModuleName_ = moduleKey;
999
1000 // load primary module path first
1001 char* loadPath = nativeModulePath[0];
1002 HILOG_DEBUG("moduleName is %{public}s. get primary module path is %{public}s", moduleName, loadPath);
1003 uint32_t errReason0 = MODULE_LOAD_SUCCESS;
1004 errInfo = "First attempt: ";
1005 LIBHANDLE lib = LoadModuleLibrary(moduleKey, loadPath, path, isAppModule, errInfo, errReason0);
1006 if (lib == nullptr) {
1007 errInfo += "\nSecond attempt: ";
1008 loadPath = nativeModulePath[1];
1009 HILOG_DEBUG("try to load secondary module path: %{public}s", loadPath);
1010 uint32_t errReason1 = MODULE_LOAD_SUCCESS;
1011 lib = LoadModuleLibrary(moduleKey, loadPath, path, isAppModule, errInfo, errReason1);
1012 if (lib == nullptr && errReason0 == MODULE_NOT_EXIST && errReason1 == MODULE_NOT_EXIST) {
1013 HILOG_ERROR("%{public}s does not exist, errMsg %{public}s", nativeModulePath[0], errInfo.c_str());
1014 }
1015 }
1016
1017 //Maintain compatibility
1018 if (lib == nullptr && cacheNativeModule != nullptr) {
1019 HILOG_DEBUG("Maintain compatibility.");
1020 return cacheNativeModule;
1021 }
1022
1023 const uint8_t* abcBuffer = nullptr;
1024 size_t len = 0;
1025 if (lib == nullptr) {
1026 loadPath = nativeModulePath[2]; // 2 : Element index value
1027 HILOG_DEBUG("try to load abc module path: %{public}s", loadPath);
1028 abcBuffer = GetFileBuffer(loadPath, moduleKey, len);
1029 if (!abcBuffer) {
1030 errInfo += "\ntry to load abc file from " + std::string(loadPath) + " failed";
1031 HILOG_ERROR("%{public}s", errInfo.c_str());
1032 return nullptr;
1033 }
1034 }
1035
1036 std::lock_guard<std::mutex> lock(nativeModuleListMutex_);
1037 if (tailNativeModule_ && !abcBuffer) {
1038 const char* moduleName = strdup(moduleKey.c_str());
1039 if (moduleName == nullptr) {
1040 HILOG_ERROR("strdup failed. moduleKey is %{public}s", moduleKey.c_str());
1041 return nullptr;
1042 }
1043
1044 tailNativeModule_->moduleName = moduleName;
1045 tailNativeModule_->systemFilePath = strdup(loadPath);
1046 if (strcmp(tailNativeModule_->moduleName, tailNativeModule_->name)) {
1047 HILOG_WARN("mismatch: moduleName is %{public}s, name is %{public}s",
1048 tailNativeModule_->moduleName, tailNativeModule_->name);
1049 HILOG_WARN("suggestion: keep .nm_modname the same as moduleName imported or required");
1050 }
1051 }
1052
1053 if (!internal) {
1054 char symbol[NAPI_PATH_MAX] = { 0 };
1055 if (sprintf_s(symbol, sizeof(symbol), "NAPI_%s_GetABCCode", moduleKey.c_str()) == -1) {
1056 if (lib != nullptr) {
1057 LIBFREE(lib);
1058 }
1059 errInfo = "sprintf symbol NAPI_" + moduleKey + "_GetABCCode failed";
1060 HILOG_ERROR("%{public}s", errInfo.c_str());
1061 return nullptr;
1062 }
1063
1064 // replace '.' and '/' with '_'
1065 for (char* p = strchr(symbol, '.'); p != nullptr; p = strchr(p + 1, '.')) {
1066 *p = '_';
1067 }
1068 for (char* p = strchr(symbol, '/'); p != nullptr; p = strchr(p + 1, '/')) {
1069 *p = '_';
1070 }
1071
1072 if (lib != nullptr) {
1073 auto getJSCode = reinterpret_cast<GetJSCodeCallback>(LIBSYM(lib, symbol));
1074 if (getJSCode == nullptr) {
1075 HILOG_DEBUG("ignore: no %{public}s in %{public}s", symbol, loadPath);
1076 MoveApiAllowListCheckerPtr(apiAllowListChecker, tailNativeModule_);
1077 return tailNativeModule_;
1078 }
1079 const char* buf = nullptr;
1080 int bufLen = 0;
1081 getJSCode(&buf, &bufLen);
1082 if (tailNativeModule_) {
1083 HILOG_DEBUG("get js code from module: bufLen: %{public}d", bufLen);
1084 tailNativeModule_->jsCode = buf;
1085 tailNativeModule_->jsCodeLen = bufLen;
1086 }
1087 } else {
1088 RegisterByBuffer(moduleKey, abcBuffer, len);
1089 tailNativeModule_->systemFilePath = strdup(loadPath);
1090 }
1091 }
1092 if (tailNativeModule_) {
1093 tailNativeModule_->moduleLoaded = true;
1094 if (tailNativeModule_->name && tailNativeModule_->moduleName) {
1095 HILOG_DEBUG("last native info: name is %{public}s, moduleName is %{public}s",
1096 tailNativeModule_->name, tailNativeModule_->moduleName);
1097 }
1098 MoveApiAllowListCheckerPtr(apiAllowListChecker, tailNativeModule_);
1099 }
1100 return tailNativeModule_;
1101 }
1102
RegisterByBuffer(const std::string & moduleKey,const uint8_t * abcBuffer,size_t len)1103 void NativeModuleManager::RegisterByBuffer(const std::string& moduleKey, const uint8_t* abcBuffer, size_t len)
1104 {
1105 HILOG_DEBUG("native module name is '%{public}s'", moduleKey.c_str());
1106 if (!CreateTailNativeModule()) {
1107 HILOG_ERROR("create tail nativeModule failed");
1108 return;
1109 }
1110
1111 char *moduleName = strdup(moduleKey.c_str());
1112 if (moduleName == nullptr) {
1113 HILOG_ERROR("strdup failed. tmpName is %{public}s", moduleKey.c_str());
1114 return;
1115 }
1116 tailNativeModule_->moduleName = moduleName;
1117 tailNativeModule_->name = strdup(moduleName);
1118 if (tailNativeModule_->name == nullptr) {
1119 HILOG_ERROR("strdup failed. moduleKey is %{public}s", moduleName);
1120 free(moduleName);
1121 tailNativeModule_->moduleName = nullptr;
1122 return;
1123 }
1124 tailNativeModule_->jsABCCode = abcBuffer;
1125 tailNativeModule_->jsCodeLen = static_cast<int32_t>(len);
1126 tailNativeModule_->next = nullptr;
1127
1128 HILOG_INFO("Register by buffer success. module name is '%{public}s'", tailNativeModule_->moduleName);
1129 }
1130
RemoveNativeModuleByCache(const std::string & moduleKey)1131 bool NativeModuleManager::RemoveNativeModuleByCache(const std::string& moduleKey)
1132 {
1133 std::lock_guard<std::mutex> lock(nativeModuleListMutex_);
1134
1135 if (headNativeModule_ == nullptr) {
1136 HILOG_WARN("NativeModule list is empty");
1137 return false;
1138 }
1139
1140 NativeModule* nativeModule = headNativeModule_;
1141 if (!strcasecmp(nativeModule->moduleName, moduleKey.c_str())) {
1142 if (headNativeModule_ == tailNativeModule_) {
1143 tailNativeModule_ = nullptr;
1144 }
1145 headNativeModule_ = headNativeModule_->next;
1146 delete[] nativeModule->name;
1147 if (nativeModule->moduleName) {
1148 delete[] nativeModule->moduleName;
1149 }
1150 if (headNativeModule_->jsABCCode) {
1151 delete[] headNativeModule_->jsABCCode;
1152 }
1153 delete nativeModule;
1154 HILOG_DEBUG("module %{public}s deleted from cache", moduleKey.c_str());
1155 return true;
1156 }
1157
1158 bool moduleDeleted = false;
1159 NativeModule* prev = headNativeModule_;
1160 NativeModule* curr = prev->next;
1161 while (curr != nullptr) {
1162 if (!strcasecmp(curr->moduleName, moduleKey.c_str())) {
1163 if (curr == tailNativeModule_) {
1164 tailNativeModule_ = prev;
1165 }
1166 prev->next = curr->next;
1167 delete[] curr->name;
1168 if (curr->moduleName) {
1169 delete[] curr->moduleName;
1170 }
1171 if (curr->jsABCCode) {
1172 delete[] curr->jsABCCode;
1173 }
1174 delete curr;
1175 HILOG_DEBUG("module %{public}s deleted from cache", moduleKey.c_str());
1176 moduleDeleted = true;
1177 break;
1178 }
1179 prev = prev->next;
1180 curr = prev->next;
1181 }
1182
1183 return moduleDeleted;
1184 }
1185
FindNativeModuleByCache(const char * moduleName,char nativeModulePath[][NAPI_PATH_MAX],NativeModule * & cacheNativeModule,NativeModuleHeadTailStruct & cacheHeadTailStruct)1186 NativeModule* NativeModuleManager::FindNativeModuleByCache(const char* moduleName,
1187 char nativeModulePath[][NAPI_PATH_MAX],
1188 NativeModule*& cacheNativeModule,
1189 NativeModuleHeadTailStruct& cacheHeadTailStruct)
1190 {
1191 NativeModule* result = nullptr;
1192
1193 std::lock_guard<std::mutex> lock(nativeModuleListMutex_);
1194 cacheNativeModule = nullptr;
1195 for (NativeModule* temp = headNativeModule_; temp != nullptr; temp = temp->next) {
1196 if ((temp->moduleName && !strcmp(temp->moduleName, moduleName))
1197 || !strcasecmp(temp->name, moduleName)) {
1198 if (strcmp(temp->name, moduleName)) {
1199 HILOG_WARN("moduleName '%{public}s' seems not match plugin's name '%{public}s'",
1200 moduleName, temp->name);
1201 }
1202 int label = 0;
1203 #if !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM)
1204 while (label < NATIVE_PATH_NUMBER && strcmp(temp->systemFilePath, nativeModulePath[label])) {
1205 label++;
1206 }
1207 #endif
1208 if (label < NATIVE_PATH_NUMBER || !strcmp(temp->systemFilePath, "")) {
1209 result = temp;
1210 break;
1211 } else {
1212 HILOG_WARN("moduleName '%{public}s' is in different path", moduleName);
1213 cacheNativeModule = temp;
1214 }
1215 }
1216 }
1217 cacheHeadTailStruct.headNativeModule = headNativeModule_;
1218 cacheHeadTailStruct.tailNativeModule = tailNativeModule_;
1219
1220 return result;
1221 }
1222
IsExistedPath(const char * pathKey) const1223 bool NativeModuleManager::IsExistedPath(const char* pathKey) const
1224 {
1225 HILOG_DEBUG("pathKey is '%{public}s'", pathKey);
1226 std::lock_guard<std::mutex> guard(appLibPathMapMutex_);
1227 return pathKey && appLibPathMap_.find(pathKey) != appLibPathMap_.end();
1228 }
1229
SetModuleLoadChecker(const std::shared_ptr<ModuleCheckerDelegate> & moduleCheckerDelegate)1230 void NativeModuleManager::SetModuleLoadChecker(const std::shared_ptr<ModuleCheckerDelegate>& moduleCheckerDelegate)
1231 {
1232 HILOG_DEBUG("enter");
1233 if (!moduleLoadChecker_) {
1234 HILOG_ERROR("SetModuleLoadChecker failed, moduleLoadChecker_ is nullptr");
1235 return;
1236 }
1237 moduleLoadChecker_->SetDelegate(moduleCheckerDelegate);
1238 }
1239
SetPreviewSearchPath(const std::string & previewSearchPath)1240 void NativeModuleManager::SetPreviewSearchPath(const std::string& previewSearchPath)
1241 {
1242 HILOG_DEBUG("previewSearchPath is '%{public}s'", previewSearchPath.c_str());
1243 previewSearchPath_ = previewSearchPath;
1244 }
1245