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 37namespace { 38constexpr static int32_t NATIVE_PATH_NUMBER = 3; 39constexpr static int32_t IS_APP_MODULE_FLAGS = 100; 40thread_local bool g_isLoadingModule = false; 41enum ModuleLoadFailedReason : uint32_t { 42 MODULE_LOAD_SUCCESS = 0, 43 MODULE_NOT_EXIST = 1, 44}; 45} // namespace 46 47NativeModuleManager* NativeModuleManager::instance_ = NULL; 48std::mutex g_instanceMutex; 49 50NativeModuleManager::NativeModuleManager() 51{ 52 HILOG_DEBUG("enter"); 53 pthread_mutex_init(&mutex_, nullptr); 54 moduleLoadChecker_ = std::make_unique<ModuleLoadChecker>(); 55} 56 57NativeModuleManager::~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 105NativeModuleManager* 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 117void 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 127void 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 136bool 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 150LIBHANDLE 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 161void 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 170bool 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 184const 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 195bool 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 206bool 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 223std::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 256void 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 318bool 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 341bool 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) 366void 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 440void 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 497void 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 529void NativeModuleManager::MoveApiAllowListCheckerPtr( 530 std::unique_ptr<ApiAllowListChecker>& apiAllowListChecker, NativeModule* nativeModule) 531{ 532 if (apiAllowListChecker != nullptr) { 533 nativeModule->apiAllowListChecker.reset(apiAllowListChecker.release()); 534 } 535} 536 537NativeModule* 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 667bool 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} 681bool 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[0], 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[0], 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[1], 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 863LIBHANDLE 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 926const 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 953bool 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 970bool 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 982NativeModule* 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 1103void 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. moduleKey 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 1131bool 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 1186NativeModule* 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 1223bool 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 1230void 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 1240void NativeModuleManager::SetPreviewSearchPath(const std::string& previewSearchPath) 1241{ 1242 HILOG_DEBUG("previewSearchPath is '%{public}s'", previewSearchPath.c_str()); 1243 previewSearchPath_ = previewSearchPath; 1244} 1245