OpenHarmony Binder调用过程

参考:

OpenHarmony之NAPI框架介绍

浅谈Openharmony系统服务框架Samgr

Android Binder 驱动框架设计与分析

写给 Android 应用工程师的 Binder 原理剖析

正文:

一. 系统服务的调用过程。

  1. Natvie 中,先通过 IPC 获取 samgr 的 Server 端的 Binder。
sptr<ISystemAbilityManager> sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); 
  1. 在 foundation/systemabilitymgr/samgr/services/samgr/native/source/service_registry.cpp ,GetSystemAbilityManager方法中,通过 IPCSkeleton 开启 IPC 通信,并指定获取 SystemAbilityManager 的 Binder
sptr<ISystemAbilityManager> SystemAbilityManagerClient::GetSystemAbilityManager()
{
    std::lock_guard<std::mutex> lock(systemAbilityManagerLock_);
    if (systemAbilityManager_ != nullptr) {
        return systemAbilityManager_;
    }
    sptr<IRemoteObject> registryObject = IPCSkeleton::GetContextObject();
    systemAbilityManager_ = iface_cast<ISystemAbilityManager>(registryObject);
    return systemAbilityManager_;
}
  1. 获取到SystemAbilityManager的 Binder 后,再通过 Binder 调用 foundation/systemabilitymgr/samgr/services/samgr/native/source/system_ability_manager.cpp 中 CheckSystemAbility 方法,通过 SystemAbilityId 获取指定的系统服务的 Binder。
sptr<IRemoteObject> SystemAbilityManager::CheckSystemAbility(int32_t systemAbilityId)                                                                                                                                    
{                                                                                                                                                                                                                        
    HILOGD("%{public}s called, systemAbilityId = %{public}d", __func__, systemAbilityId);                                                                                                                                    
    if (!CheckInputSysAbilityId(systemAbilityId)) {                                                                                                                                                                          
        HILOGW("CheckSystemAbility CheckSystemAbility invalid!");                                                                                                                                                                
    return nullptr;                                                                                                                                                                                                          
    }                                                                                                                                                                                                                        
    UpdateSaFreMap(IPCSkeleton::GetCallingUid(), systemAbilityId);                                                                                                                                                           
    shared_lock<shared_mutex> readLock(abilityMapLock_);                                                                                                                                                                     
    auto iter = abilityMap_.find(systemAbilityId);                                                                                                                                                                           
    if (iter != abilityMap_.end()) {                                                                                                                                                                                         
        HILOGD("found service : %{public}d.", systemAbilityId);                                                                                                                                                                  
        return iter->second.remoteObj;                                                                                                                                                                                           
    }                                                                                                                                                                                                                        
    HILOGW("NOT found service : %{public}d", systemAbilityId);                                                                                                                                                               
    return nullptr;                                                                                                                                                                                                          
}

在 SystemAbilityManager#CheckSystemAbility 方法里,最终是通过 systemAbilityId 从abilityMap_ 中获取已经初始化完成的系统服务 Binder。

二. 系统服务的注册&启动过程

  1. 在 foundation/systemabilitymgr/samgr/services/samgr/native/source/main.cpp 源码 main 函数中,调取 SystemAbilityManager 的 Init 方法进行初始化操作。
int main(int argc, char *argv[])                                                                                                                                                                                                        
{                                                                                                                                                                                                                                       
    HILOGI("%{public}s called, enter System Ability Manager ", __func__);                                                                                                                                                               
    Samgr::MemoryGuard cacheGuard;                                                                                                                                                                                                      
    OHOS::sptr<OHOS::SystemAbilityManager> manager = OHOS::SystemAbilityManager::GetInstance();                                                                                                                                         
    manager->Init();                                                                                                                                                                                                                    
    OHOS::sptr<OHOS::IRemoteObject> serv = manager->AsObject();                                                                                                                                                                         
        
    if (!IPCSkeleton::SetContextObject(serv)) {                                                                                                                                                                                         
        HILOGE("set context fail!"); // add log for dfx                                                                                                                                                                                 
    }                                                                                                                                                                                                                                   
    int result = SetParameter("bootevent.samgr.ready", "true");                                                                                                                                                                         
    HILOGI("set samgr ready ret : %{public}s", result == 0 ? "succeed" : "failed");                                                                                                                                                     
    manager->StartDfxTimer();                                                                                                                                                                                                           
    OHOS::IPCSkeleton::JoinWorkThread();                                                                                                                                                                                                
    return -1;                                                                                                                                                                                                                          
 }
  1. 在 foundation/systemabilitymgr/samgr/services/samgr/native/source/system_ability_manager.cpp 源码的 Init 方法,来初始化&启动各个系统服务。
void SystemAbilityManager::Init()                                                                                                                                                                                                
{                                                                                                                                                                                                                                
    abilityDeath_ = sptr<IRemoteObject::DeathRecipient>(new AbilityDeathRecipient());                                                                                                                                            
    systemProcessDeath_ = sptr<IRemoteObject::DeathRecipient>(new SystemProcessDeathRecipient());                                                                                                                                
    abilityStatusDeath_ = sptr<IRemoteObject::DeathRecipient>(new AbilityStatusDeathRecipient());                                                                                                                                
    abilityCallbackDeath_ = sptr<IRemoteObject::DeathRecipient>(new AbilityCallbackDeathRecipient());                                                                                                                            
    remoteCallbackDeath_ = sptr<IRemoteObject::DeathRecipient>(new RemoteCallbackDeathRecipient());                                                                                                                              

    rpcCallbackImp_ = make_shared<RpcCallbackImp>();                                                                                                                                                                             
    if (workHandler_ == nullptr) {                                                                                                                                                                                               
    auto runner = AppExecFwk::EventRunner::Create("workHandler");                                                                                                                                                                
    workHandler_ = make_shared<AppExecFwk::EventHandler>(runner);                                                                                                                                                                
          workHandler_->PostTask([]() { Samgr::MemoryGuard cacheGuard; });                                                                                                                                                       
    }                                                                                                                                                                                                                            
    collectManager_ = sptr<DeviceStatusCollectManager>(new DeviceStatusCollectManager());                                                                                                                                        
    abilityStateScheduler_ = std::make_shared<SystemAbilityStateScheduler>();                                                                                                                                                    
    InitSaProfile();                                                                                                                                                                                                             
    WatchDogInit();                                                                                                                                                                                                              
    reportEventTimer_ = std::make_unique<Utils::Timer>("DfxReporter");                                                                                                                                                           
    OndemandLoadForPerf();                                                                                                                                                                                                       
}
  1. 在 InitSaProfile 方法中,通过遍历 /system/profile 路径下所有的 xml / json(4.0+) 文件来初始化服务。(load)
void SystemAbilityManager::InitSaProfile()                                                                                                                                                                                       
{                                                                                                                                                                                                                                
    int64_t begin = GetTickCount();                                                                                                                                                                                              
    std::vector<std::string> fileNames;                                                                                                                                                                                          
    GetDirFiles(PREFIX, fileNames);                                                                                                                                                                                              
    auto parser = std::make_shared<ParseUtil>();                                                                                                                                                                                 
    for (const auto& file : fileNames) {                                                                                                                                                                                         
        if (file.empty() || file.find(".json") == std::string::npos ||                                                                                                                                                           
        file.find("_trust.json") != std::string::npos) {                                                                                                                                                                         
            continue;                                                                                                                                                                                                            
        }                                                                                                                                                                                                                        
        parser->ParseSaProfiles(file);                                                                                                                                                                                           
    }                                                                                                                                                                                                                            
    std::list<SaProfile> saInfos = parser->GetAllSaProfiles();                                                                                                                                                                   
    if (collectManager_ != nullptr) {                                                                                                                                                                                            
        collectManager_->Init(saInfos);                                                                                                                                                                                          
    }                                                                                                                                                                                                                            
    if (abilityStateScheduler_ != nullptr) {                                                                                                                                                                                     
        abilityStateScheduler_->Init(saInfos);                                                                                                                                                                                   
    }                                                                                                                                                                                                                            
    lock_guard<mutex> autoLock(saProfileMapLock_);                                                                                                                                                                               
    for (const auto& saInfo : saInfos) {                                                                                                                                                                                         
        saProfileMap_[saInfo.saId] = saInfo;                                                                                                                                                                                     
    }                                                                                                                                                                                                                            
    HILOGI("[PerformanceTest] InitSaProfile spend %{public}" PRId64 " ms", GetTickCount() - begin);                                                                                                                              
 }
const string PREFIX = "/system/profile/";

/system/profile中.json配置文件示例:

{
  "process": "usb_service",
  "systemability": [
    {
      "name": 4201,
      "libpath": "libusbservice.z.so",
      "run-on-create": false,
      "auto-restart": true,
      "distributed": false,
      "dump_level": 1
    }
  ]
}
  1. 在 OndemandLoadForPerf 方法中开始激活启动(创建服务进程)服务。OndemandLoadForPerf() -> OndemandLoad() -> DoLoadForPerf()//遍历已经init 过的 system ability id -> LoadSystemAbility()
void SystemAbilityManager::OndemandLoadForPerf()                                                                                                                                                                                       
{                                                                                                                                                                                                                                      
    if (workHandler_ == nullptr) {                                                                                                                                                                                                     
        HILOGE("LoadForPerf workHandler_ not init!");                                                                                                                                                                                  
        return;                                                                                                                                                                                                                        
    }                                                                                                                                                                                                                                  
    auto callback = [this] () {                                                                                                                                                                                                        
        OndemandLoad();                                                                                                                                                                                                                
    };                                                                                                                                                                                                                                 
    workHandler_->PostTask(callback, ONDEMAND_PERF_DELAY_TIME);                                                                                                                                                                        
}                                                                                                                                                                                                                                      

void SystemAbilityManager::OndemandLoad()                                                                                                                                                                                              
{                                                                                                                                                                                                                                      
    auto bootEventCallback = [](const char *key, const char *value, void *context) {                                                                                                                                                   
        int64_t begin = GetTickCount();                                                                                                                                                                                                
        SystemAbilityManager::GetInstance()->DoLoadForPerf();                                                                                                                                                                          
        HILOGI("[PerformanceTest] DoLoadForPerf spend %{public}" PRId64 " ms", GetTickCount() - begin);                                                                                                                                
    };                                                                                                                                                                                                                                 
                                                                                                                                                                                                                                       
    int ret = WatchParameter(ONDEMAND_PERF_PARAM, bootEventCallback, nullptr);                                                                                                                                                         
    HILOGD("OndemandLoad ret %{public}d", ret);                                                                                                                                                                                        
}

void SystemAbilityManager::DoLoadForPerf()                                                                                                                                                                                             
{                                                                                                                                                                                                                                      
    bool value = system::GetBoolParameter(ONDEMAND_PARAM, false);                                                                                                                                                                      
    if (value) {                                                                                                                                                                                                                       
        std::list<int32_t> saids = GetAllOndemandSa();                                                                                                                                                                                 
        HILOGD("DoLoadForPerf ondemand size : %{public}zu.", saids.size());                                                                                                                                                            
        sptr<ISystemAbilityLoadCallback> callback(new SystemAbilityLoadCallbackStub());                                                                                                                                                
        for (auto said : saids) {                                                                                                                                                                                                      
            LoadSystemAbility(said, callback);                                                                                                                                                                                         
        }                                                                                                                                                                                                                              
    }                                                                                                                                                                                                                                  
}

int32_t SystemAbilityManager::LoadSystemAbility(int32_t systemAbilityId,                                                                                                                                                               
      const sptr<ISystemAbilityLoadCallback>& callback)                                                                                                                                                                                  
{                                                                                                                                                                                                                                      
    if (!CheckInputSysAbilityId(systemAbilityId) || callback == nullptr) {                                                                                                                                                             
        HILOGW("LoadSystemAbility systemAbilityId or callback invalid!");                                                                                                                                                              
        return ERR_INVALID_VALUE;                                                                                                                                                                                                      
    }                                                                                                                                                                                                                                  
    SaProfile saProfile;                                                                                                                                                                                                               
    bool ret = GetSaProfile(systemAbilityId, saProfile);                                                                                                                                                                               
    if (!ret) {                                                                                                                                                                                                                        
        HILOGE("LoadSystemAbility systemAbilityId:%{public}d not supported!", systemAbilityId);                                                                                                                                        
        return ERR_INVALID_VALUE;                                                                                                                                                                                                      
    }                                                                                                                                                                                                                                  
    auto callingPid = IPCSkeleton::GetCallingPid();                                                                                                                                                                                    
    OnDemandEvent onDemandEvent = {INTERFACE_CALL, "load"};                                                                                                                                                                            
    LoadRequestInfo loadRequestInfo = {systemAbilityId, LOCAL_DEVICE, callback, callingPid, onDemandEvent};                                                                                                                            
    return abilityStateScheduler_->HandleLoadAbilityEvent(loadRequestInfo);                                                                                                                                                            
}
  1. 在 LoadSystemAbility 方法中,通过调用 foundation/systemabilitymgr/samgr/services/samgr/native/source/schedule/system_ability_state_scheduler.cpp 的 HandleLoadAbilityEvent 方法开始单个 SystemAbility 的启动。 HandleLoadAbilityEvent() -> HandleLoadAbilityEventLocked() -> DoLoadSystemAbilityLocked() -> DoLoadSystemAbility()
int32_t SystemAbilityStateScheduler::HandleLoadAbilityEvent(const LoadRequestInfo& loadRequestInfo)                                                                                                                                     
{                                                                                                                                                                                                                                       
    HILOGI("[SA Scheduler][SA: %{public}d] handle load event start, callingpid: %{public}d",                                                                                                                                            
        loadRequestInfo.systemAbilityId, loadRequestInfo.callingPid);                                                                                                                                                                   
    std::shared_ptr<SystemAbilityContext> abilityContext;                                                                                                                                                                               
    if (!GetSystemAbilityContext(loadRequestInfo.systemAbilityId, abilityContext)) {                                                                                                                                                    
        return ERR_INVALID_VALUE;                                                                                                                                                                                                       
    }                                                                                                                                                                                                                                   
    std::lock_guard<std::recursive_mutex> autoLock(abilityContext->ownProcessContext->processLock);                                                                                                                                     
    return HandleLoadAbilityEventLocked(abilityContext, loadRequestInfo);                                                                                                                                                               
}                                                                                                                                                                                                                                       
                                                                                                                                                                                                                                          
int32_t SystemAbilityStateScheduler::HandleLoadAbilityEventLocked(                                                                                                                                                                      
    const std::shared_ptr<SystemAbilityContext>& abilityContext, const LoadRequestInfo& loadRequestInfo)                                                                                                                                
{                                                                                                                                                                                                                                       
    if (abilityContext->state ==SystemAbilityState::UNLOADING                                                                                                                                                                           
        || abilityContext->ownProcessContext->state == SystemProcessState::STOPPING) {                                                                                                                                                  
        return PendLoadEventLocked(abilityContext, loadRequestInfo);                                                                                                                                                                    
    }                                                                                                                                                                                                                                   
    nlohmann::json activeReason;                                                                                                                                                                                                        
    activeReason[KEY_EVENT_ID] = loadRequestInfo.loadEvent.eventId;                                                                                                                                                                     
    activeReason[KEY_NAME] = loadRequestInfo.loadEvent.name;                                                                                                                                                                            
    activeReason[KEY_VALUE] = loadRequestInfo.loadEvent.value;                                                                                                                                                                          
    activeReason[KEY_EXTRA_DATA_ID] = loadRequestInfo.loadEvent.extraDataId;                                                                                                                                                            
    int32_t result = ERR_INVALID_VALUE;                                                                                                                                                                                                 
    switch (abilityContext->state) {                                                                                                                                                                                                    
        case SystemAbilityState::LOADING:                                                                                                                                                                                               
            result = RemovePendingUnloadEventLocked(abilityContext);                                                                                                                                                                    
          break;                                                                                                                                                                                                                      
        case SystemAbilityState::LOADED:                                                                                                                                                                                                
          result = RemoveDelayUnloadEventLocked(abilityContext->systemAbilityId);                                                                                                                                                     
          break;                                                                                                                                                                                                                      
        case SystemAbilityState::UNLOADABLE:                                                                                                                                                                                            
          result = ActiveSystemAbilityLocked(abilityContext, activeReason);                                                                                                                                                           
          break;                                                                                                                                                                                                                      
        case SystemAbilityState::NOT_LOADED:                                                                                                                                                                                            
          result = ERR_OK;                                                                                                                                                                                                            
          break;                                                                                                                                                                                                                      
        default:                                                                                                                                                                                                                        
          result = ERR_INVALID_VALUE;                                                                                                                                                                                                 
          HILOGI("[SA Scheduler][SA: %{public}d] in state %{public}d, cannot load ability",                                                                                                                                           
                loadRequestInfo.systemAbilityId, abilityContext->state);                                                                                                                                                                
         break;                                                                                                                                                                                                                      
    }                                                                                                                                                                                                                                   
    if (result == ERR_OK) {                                                                                                                                                                                                             
        return DoLoadSystemAbilityLocked(abilityContext, loadRequestInfo);                                                                                                                                                              
    }                                                                                                                                                                                                                                   
    return result;                                                                                                                                                                                                                      
}

int32_t SystemAbilityStateScheduler::DoLoadSystemAbilityLocked(                                                                                                                                                                         
     const std::shared_ptr<SystemAbilityContext>& abilityContext, const LoadRequestInfo& loadRequestInfo)                                                                                                                                
{                                                                                                                                                                                                                                       
    int32_t result = ERR_OK;                                                                                                                                                                                                            
    if (loadRequestInfo.deviceId == LOCAL_DEVICE) {                                                                                                                                                                                     
        HILOGD("[SA Scheduler][SA: %{public}d] load ability from local start", abilityContext->systemAbilityId);                                                                                                                        
        result = SystemAbilityManager::GetInstance()->DoLoadSystemAbility(abilityContext->systemAbilityId,                                                                                                                              
            abilityContext->ownProcessContext->processName, loadRequestInfo.callback, loadRequestInfo.callingPid,                                                                                                                       
            loadRequestInfo.loadEvent);                                                                                                                                                                                                 
     } else {                                                                                                                                                                                                                            
        HILOGD("[SA Scheduler][SA: %{public}d] load ability from remote start", abilityContext->systemAbilityId);                                                                                                                       
        result = SystemAbilityManager::GetInstance()->DoLoadSystemAbilityFromRpc(loadRequestInfo.deviceId,                                                                                                                              
             abilityContext->systemAbilityId, abilityContext->ownProcessContext->processName, loadRequestInfo.callback,                                                                                                                  
             loadRequestInfo.loadEvent);                                                                                                                                                                                                 
     }                                                                                                                                                                                                                                   
     if (result == ERR_OK && abilityContext->state == SystemAbilityState::NOT_LOADED) {                                                                                                                                                  
         return stateMachine_->AbilityStateTransitionLocked(abilityContext, SystemAbilityState::LOADING);                                                                                                                                
     }                                                                                                                                                                                                                                   
     return result;                                                                                                                                                                                                                      
}
  1. 在 DoLoadSystemAbility() 方法中执行了 StartingSystemProcess() 开始启动服务进程。
int32_t SystemAbilityManager::DoLoadSystemAbility(int32_t systemAbilityId, const std::u16string& procName,                                                                                                                             
       const sptr<ISystemAbilityLoadCallback>& callback, int32_t callingPid, const OnDemandEvent& event)                                                                                                                                 
   {                                                                                                                                                                                                                                     
       int32_t result = ERR_INVALID_VALUE;                                                                                                                                                                                               
       {                                                                                                                                                                                                                                 
           lock_guard<recursive_mutex> autoLock(onDemandLock_);                                                                                                                                                                          
           sptr<IRemoteObject> targetObject = CheckSystemAbility(systemAbilityId);                                                                                                                                                       
           if (targetObject != nullptr) {                                                                                                                                                                                                
               NotifySystemAbilityLoaded(systemAbilityId, targetObject, callback);                                                                                                                                                       
               return ERR_OK;                                                                                                                                                                                                            
           }                                                                                                                                                                                                                             
           auto& abilityItem = startingAbilityMap_[systemAbilityId];                                                                                                                                                                     
           for (const auto& itemCallback : abilityItem.callbackMap[LOCAL_DEVICE]) {                                                                                                                                                      
               if (callback->AsObject() == itemCallback.first->AsObject()) {                                                                                                                                                             
                   HILOGI("LoadSystemAbility already existed callback object systemAbilityId:%{public}d", systemAbilityId);                                                                                                              
                   return ERR_OK;                                                                                                                                                                                                        
               }                                                                                                                                                                                                                         
           }                                                                                                                                                                                                                             
           auto& count = callbackCountMap_[callingPid];                                                                                                                                                                                  
           if (count >= MAX_SUBSCRIBE_COUNT) {                                                                                                                                                                                           
               HILOGE("LoadSystemAbility pid:%{public}d overflow max callback count!", callingPid);                                                                                                                                      
               return ERR_PERMISSION_DENIED;                                                                                                                                                                                             
           }                                                                                                                                                                                                                             
           ++count;                                                                                                                                                                                                                      
           abilityItem.callbackMap[LOCAL_DEVICE].emplace_back(callback, callingPid);                                                                                                                                                     
           abilityItem.event = event;                                                                                                                                                                                                    
           if (abilityCallbackDeath_ != nullptr) {                                                                                                                                                                                       
               bool ret = callback->AsObject()->AddDeathRecipient(abilityCallbackDeath_);                                                                                                                                                
               HILOGI("LoadSystemAbility systemAbilityId:%{public}d AddDeathRecipient %{public}s",                                                                                                                                       
                   systemAbilityId, ret ? "succeed" : "failed");                                                                                                                                                                         
           }                                                                                                                                                                                                                             
           result = StartingSystemProcess(procName, systemAbilityId, event);                                                                                                                                                             
           HILOGI("LoadSystemAbility systemAbilityId:%{public}d size : %{public}zu",                                                                                                                                                     
               systemAbilityId, abilityItem.callbackMap[LOCAL_DEVICE].size());                                                                                                                                                           
       }                                                                                                                                                                                                                                 
       SendCheckLoadedMsg(systemAbilityId, procName, LOCAL_DEVICE, callback);                                                                                                                                                            
       return result;                                                                                                                                                                                                                    
   }

三. 从 ArkTs/Ts 代码调用系统服务过程

  1. 在 ArkTs/Ts 代码中,只要导入了so库:import napi from 'libmqtt.so' 或者模块:import hilog from '@ohos.hilog',通过编译后,都会生成相应 js 代码:requireNapi('hilog')。
  2. 在 foundation/arkui/napi/native_engine/impl/ark/ark_native_engine.cpp 中,会动态注册 requireNapi 函数,负责加载 so 库。
{
    ...略...
        
  Local<FunctionRef> requireInternal =                                                                                                                                                                                                   
          FunctionRef::New(                                                                                                                                                                                                              
              vm,                                                                                                                                                                                                                        
              [](JsiRuntimeCallInfo *info) -> Local<JSValueRef> {                                                                                                                                                                        
                  EcmaVM *ecmaVm = info->GetVM();                                                                                                                                                                                        
                  panda::EscapeLocalScope scope(ecmaVm);                                                                                                                                                                                 
                  NativeModuleManager* moduleManager = NativeModuleManager::GetInstance();                                                                                                                                               
                  ArkNativeEngine* arkNativeEngine = static_cast<ArkNativeEngine*>(info->GetData());                                                                                                                                     
                  Local<StringRef> moduleName(info->GetCallArgRef(0));                                                                                                                                                                   
                  NativeModule* module = moduleManager->LoadNativeModule(moduleName->ToString().c_str(), nullptr, false);                                                                                                                
                  Local<JSValueRef> exports(JSValueRef::Undefined(ecmaVm));                                                                                                                                                              
                  MoudleNameLocker nameLocker(moduleName->ToString());                                                                                                                                                                   
                  if (module != nullptr && arkNativeEngine) {                                                                                                                                                                            
                      auto it = arkNativeEngine->loadedModules_.find(module);                                                                                                                                                            
                      if (it != arkNativeEngine->loadedModules_.end()) {                                                                                                                                                                 
                          return scope.Escape(it->second.ToLocal(ecmaVm));                                                                                                                                                               
                      }                                                                                                                                                                                                                  
                      std::string strModuleName = moduleName->ToString();                                                                                                                                                                
                      moduleManager->SetNativeEngine(strModuleName, arkNativeEngine);                                                                                                                                                    
                      NativeScopeManager* scopeManager = arkNativeEngine->GetScopeManager();                                                                                                                                             
                      if (scopeManager == nullptr) {                                                                                                                                                                                     
                          HILOG_ERROR("scope manager is null");                                                                                                                                                                          
                          return scope.Escape(exports);                                                                                                                                                                                  
                      }                                                                                                                                                                                                                  
                      NativeScope* nativeScope = scopeManager->Open();                                                                                                                                                                   
                      NativeValue* exportObject = arkNativeEngine->CreateObject();                                                                                                                                                       
                      if (exportObject != nullptr) {                                                                                                                                                                                     
                          if (!arkNativeEngine) {                                                                                                                                                                                        
                              HILOG_ERROR("exportObject is nullptr");                                                                                                                                                                    
                              scopeManager->Close(nativeScope);                                                                                                                                                                          
                              return scope.Escape(exports);                                                                                                                                                                              
                          }                                                                                                                                                                                                              
                          ArkNativeObject* exportObj = reinterpret_cast<ArkNativeObject*>(exportObject);                                                                                                                                 
                          arkNativeEngine->SetModuleName(exportObj, module->name);                                                                                                                                                       
                          module->registerCallback(arkNativeEngine, exportObject);                                                                                                                                                       
                          Global<JSValueRef> globalExports = *exportObject;                                                                                                                                                              
                          exports = globalExports.ToLocal(ecmaVm);                                                                                                                                                                       
                          arkNativeEngine->loadedModules_[module] = Global<JSValueRef>(ecmaVm, exports);                                                                                                                                 
                          scopeManager->Close(nativeScope);                                                                                                                                                                              
                      } else {                                                                                                                                                                                                           
                          HILOG_ERROR("exportObject is nullptr");                                                                                                                                                                        
                          scopeManager->Close(nativeScope);                                                                                                                                                                              
                          return scope.Escape(exports);                                                                                                                                                                                  
                      }                                                                                                                                                                                                                  
                  }                                                                                                                                                                                                                      
                  return scope.Escape(exports);                                                                                                                                                                                          
              },                                                                                                                                                                                                                         
              nullptr,                                                                                                                                                                                                                   
              requireData);                                                                                                                                                                                                              
                                                                                                                                                                                                                                         
      Local<ObjectRef> global = panda::JSNApi::GetGlobalObject(vm);                                                                                                                                                                      
  #if !defined(PREVIEW)                                                                                                                                                                                                                  
      Local<StringRef> requireName = StringRef::NewFromUtf8(vm, "requireNapi");                                                                                                                                                          
      global->Set(vm, requireName, requireNapi);                                                                                                                                                                                         
  #else                                                                                                                                                                                                                                  
      Local<StringRef> requireNapiPreview = StringRef::NewFromUtf8(vm, "requireNapiPreview");                                                                                                                                            
      global->Set(vm, requireNapiPreview, requireNapi);                                                                                                                                                                                  
  #endif                                                                                                                                                                                                                                 
      global->Set(vm, requireInternalName, requireInternal);
    
    ...略...
  }
  • 22
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值