文章大纲
- 引言
- 一、鸿蒙系统能力的启动方式
- 二、SA动态启动的关键流程
- 1、systemAbilityId的采集并缓存为map
- 2、只会在SystemAbilityManager::Init()执行一次
- 2.1、SystemAbilityManager::InitSaProfile()
- 2.2、遍历并ParseUtil::ParseSaProfiles——>ParseUtil::ParseJsonFile 缓存到saProfiles_
- 2.3、遍历时ParseJsonFile
- 2.4、ParseUtil::GetAllSaProfiles() 获取saProfiles_
- 3、SystemAbilityStateScheduler::Init(list<OHOS::SaProfile> &saProfiles) 初始化上下文环境
- 3.1、InitStateContext(std::list<SaProfile>& saProfiles) 遍历初始化列表中sa的上下文环境
- 3.2、DeviceStatusCollectManager::Init(list<OHOS::SaProfile> &saProfiles)DeviceStatusCollectManager::FilterOnDemandSaProfiles 进一步筛选
- 3.2.1、DeviceStatusCollectManager::StartCollect()
- 3.2.2、遍历saInfos 初始化onDemandSaIdsSet_
- 3.2.3、SystemAbilityManager::GetOnDemandSystemAbilityIds 初始化systemAbilityIds
- 三、SystemAbilityManager::LoadSystemAbility
- 1、CheckInputSysAbilityId
- 2、传入SAID 到GetSaProfile从map中获取对应的SaProfile 结构体
- 3、构造LoadRequestInfo
- 4、SystemAbilityStateScheduler::HandleLoadAbilityEvent
- 5、SystemAbilityStateScheduler::HandleLoadAbilityEventLocked
- 四、USB_SERVICE的动态启动概述
引言
SA的全称是System Ability,大致上可以类比Android里的System Service,SA是运行在单独进程的里的服务,同一个进程可以运行多个SA,可以选择开机运行或者不运行。SA的启动方式也与Android的大同小异,接下来就SA的动态启动方式进行总结。
一、鸿蒙系统能力的启动方式
在鸿蒙操作系统中系统能力SA的启动方式主要有两种:
- 一种是由系统启动时的init进程解析对应的cfg 文件然后通过脚本创建并启动进程的;
- 另一种就是由SystemAbilityManager::LoadSystemAbility去解析并创建对应的进程并Load so完成的。
以usb_service.cfg为例,当ondemand 属性被设置为true时就意味着是动态启动方式。
{"services":[{"name":"usb_service","path":["/system/bin/sa_main","/system/profile/usb_service.json"],"ondemand":true,"condition":"bootevent.wms.fullscreen.ready=true","uid":"usb","gid":["usb","shell"],"permission":["ohos.permission.LISTEN_BUNDLE_CHANGE","ohos.permission.DISTRIBUTED_DATASYNC","ohos.permission.ENTERPRISE_MANAGE_USB","ohos.permission.GET_BUNDLE_INFO_PRIVILEGED"],"apl":"system_basic","secon":"u:r:usb_service:s0"}],"jobs":[{"name":"post-fs-data","cmds":["mkdir /data/service/el1/public/usb_service 0770 usb usb","mkdir /data/service/el1/public/usb_service/right 0770 usb usb"]}]}二、SA动态启动的关键流程
1、systemAbilityId的采集并缓存为map
std::map<int32_t,SaProfile>saProfileMap_;std::set<int32_t>onDemandSaIdsSet_;std::list<OHOS::SaProfile>saInfos2、只会在SystemAbilityManager::Init()执行一次
voidSystemAbilityManager::Init(){abilityDeath_=sptr<IRemoteObject::DeathRecipient>(newAbilityDeathRecipient());systemProcessDeath_=sptr<IRemoteObject::DeathRecipient>(newSystemProcessDeathRecipient());abilityStatusDeath_=sptr<IRemoteObject::DeathRecipient>(newAbilityStatusDeathRecipient());abilityCallbackDeath_=sptr<IRemoteObject::DeathRecipient>(newAbilityCallbackDeathRecipient());remoteCallbackDeath_=sptr<IRemoteObject::DeathRecipient>(newRemoteCallbackDeathRecipient());rpcCallbackImp_=make_shared<RpcCallbackImp>();if(workHandler_==nullptr){workHandler_=make_shared<FFRTHandler>("workHandler");}collectManager_=sptr<DeviceStatusCollectManager>(newDeviceStatusCollectManager());abilityStateScheduler_=std::make_shared<SystemAbilityStateScheduler>();InitSaProfile();reportEventTimer_=std::make_unique<Utils::Timer>("DfxReporter");OndemandLoadForPerf();SetKey(DYNAMIC_CACHE_PARAM);}2.1、SystemAbilityManager::InitSaProfile()
而saProfileMap_ 是在 SystemAbilityManager::InitSaProfile() 里被初始化的,去默认的system/profile路径下遍历所有的.json的文件拿到saId 缓存到onDemandSaIdsSet set数据集中并解析为SaProfile对象并缓存起来和saProfileMap_ 中。
voidSystemAbilityManager::InitSaProfile(){int64_tbegin=GetTickCount();std::vector<std::string>fileNames;GetDirFiles(PREFIX,fileNames);GetDirFiles(DYNAMIC_PREFIX,fileNames);autoparser=std::make_shared<ParseUtil>();for(constauto&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(abilityStateScheduler_!=nullptr){abilityStateScheduler_->Init(saInfos);}if(collectManager_!=nullptr){collectManager_->Init(saInfos);}lock_guard<mutex>autoLock(saProfileMapLock_);onDemandSaIdsSet_.insert(DEVICE_INFO_SERVICE_SA);onDemandSaIdsSet_.insert(HIDUMPER_SERVICE_SA);onDemandSaIdsSet_.insert(MEDIA_ANALYSIS_SERVICE_SA);for(constauto&saInfo:saInfos){saProfileMap_[saInfo.saId]=saInfo;if(!saInfo.runOnCreate){HILOGI("[InitSaProfile] saId %{public}d",saInfo.saId);onDemandSaIdsSet_.insert(saInfo.saId);}{autodynamicSaInfos=parser->GetAllDynamicSaProfiles();lock_guard<mutex>autoLock(dynamicSaProfileMapLock_);for(constauto&saInfo:dynamicSaInfos){dynamicSaProfileMap_[saInfo.saId]=saInfo;}}}HILOGI("[PerformanceTest] InitSaProfile spend %{public}"PRId64" ms",GetTickCount()-begin);}2.2、遍历并ParseUtil::ParseSaProfiles——>ParseUtil::ParseJsonFile 缓存到saProfiles_
boolParseUtil::ParseSaProfiles(conststring&profilePath){HILOGD("UB#profilePath:%{private}s",profilePath.c_str());string realPath=GetRealPath(profilePath);if(!CheckPathExist(realPath.c_str())){HILOGE("bad profile path!");returnfalse;}if(Endswith(realPath,".json")){returnParseJsonFile(realPath);}else{HILOGE("Invalid file format, please use json file!");returnfalse;}}2.3、遍历时ParseJsonFile
boolParseUtil::ParseJsonFile(conststring&realPath){nlohmann::json profileJson;boolresult=ParseJsonObj(profileJson,realPath);if(!result){HILOGE("json file parse error!");returnfalse;}HILOGD("profileJson:%{private}s",profileJson.dump().c_str());string process;GetStringFromJson(profileJson,SA_TAG_PROCESS,process);if(process.empty()){HILOGE("profile format error: no process tag");returnfalse;}if(process.length()>MAX_JSON_STRING_LENGTH){HILOGE("profile format error: process is too long");returnfalse;}procName_=Str8ToStr16(process);if(profileJson.find(SA_TAG_SYSTEM_ABILITY)==profileJson.end()){HILOGE("system ability parse error!");returnfalse;}nlohmann::json&systemAbilityJson=profileJson.at(SA_TAG_SYSTEM_ABILITY);HILOGD("systemAbilityJson:%{private}s",systemAbilityJson.dump().c_str());if(!systemAbilityJson.is_array()){HILOGE("system ability is not array!");returnfalse;}size_t size=systemAbilityJson.size();for(size_t i=0;i<size;i++){SaProfile saProfile={procName_};if(!ParseSystemAbility(saProfile,systemAbilityJson[i])){continue;}saProfiles_.emplace_back(saProfile);if(!CheckIsOpenValleySaId(saProfile.saId)){continue;}DynamicSaProfile dynamicSaProfile={.saId=saProfile.saId,.runOnCreate=saProfile.runOnCreate};ParseDynamicSaTag(systemAbilityJson[i],dynamicSaProfile);dynamicSaProfiles_.emplace_back(dynamicSaProfile);}return!saProfiles_.empty();}2.4、ParseUtil::GetAllSaProfiles() 获取saProfiles_
conststd::list<SaProfile>&ParseUtil::GetAllSaProfiles()const{returnsaProfiles_;}3、SystemAbilityStateScheduler::Init(listOHOS::SaProfile &saProfiles) 初始化上下文环境
voidSystemAbilityStateScheduler::Init(conststd::list<SaProfile>&saProfiles){HILOGI("[SA Scheduler] init start");InitStateContext(saProfiles);processListenerDeath_=sptr<IRemoteObject::DeathRecipient>(newSystemProcessListenerDeathRecipient());unloadEventHandler_=std::make_shared<UnloadEventHandler>(weak_from_this());autolistener=std::dynamic_pointer_cast<SystemAbilityStateListener>(shared_from_this());stateMachine_=std::make_shared<SystemAbilityStateMachine>(listener);stateEventHandler_=std::make_shared<SystemAbilityEventHandler>(stateMachine_);processHandler_=std::make_shared<FFRTHandler>("ProcessHandler");HILOGI("[SA Scheduler] init end");}3.1、InitStateContext(std::list& saProfiles) 遍历初始化列表中sa的上下文环境
voidSystemAbilityStateScheduler::InitStateContext(conststd::list<SaProfile>&saProfiles){for(auto&saProfile:saProfiles){if(saProfile.process.empty()){continue;}std::unique_lock<std::shared_mutex>processWriteLock(processMapLock_);if(processContextMap_.count(saProfile.process)==0){autoprocessContext=std::make_shared<SystemProcessContext>();processContext->processName=saProfile.process;processContext->abilityStateCountMap[SystemAbilityState::NOT_LOADED]=0;processContext->abilityStateCountMap[SystemAbilityState::LOADING]=0;processContext->abilityStateCountMap[SystemAbilityState::LOADED]=0;processContext->abilityStateCountMap[SystemAbilityState::UNLOADABLE]=0;processContext->abilityStateCountMap[SystemAbilityState::UNLOADING]=0;processContextMap_[saProfile.process]=processContext;}processContextMap_[saProfile.process]->saList.push_back(saProfile.saId);processContextMap_[saProfile.process]->abilityStateCountMap[SystemAbilityState::NOT_LOADED]++;autoabilityContext=std::make_shared<SystemAbilityContext>();abilityContext->systemAbilityId=saProfile.saId;abilityContext->isAutoRestart=saProfile.autoRestart;int32_tdelayUnloadTime=LimitDelayUnloadTime(saProfile.stopOnDemand.delayTime);abilityContext->delayUnloadTime=delayUnloadTime;abilityContext->ownProcessContext=processContextMap_[saProfile.process];std::unique_lock<std::shared_mutex>abiltyWriteLock(abiltyMapLock_);abilityContextMap_[saProfile.saId]=abilityContext;HILOGD("UB#USB SAID=%{public}d",saProfile.saId);}}3.2、DeviceStatusCollectManager::Init(listOHOS::SaProfile &saProfiles)DeviceStatusCollectManager::FilterOnDemandSaProfiles 进一步筛选
voidDeviceStatusCollectManager::FilterOnDemandSaProfiles(conststd::list<SaProfile>&saProfiles){std::unique_lock<std::shared_mutex>writeLock(saProfilesLock_);for(auto&saProfile:saProfiles){if(saProfile.startOnDemand.onDemandEvents.empty()&&saProfile.stopOnDemand.onDemandEvents.empty()){continue;}onDemandSaProfiles_.emplace_back(saProfile);}}3.2.1、DeviceStatusCollectManager::StartCollect()
voidDeviceStatusCollectManager::StartCollect(){HILOGI("DeviceStatusCollectManager OnStart begin");if(collectHandler_==nullptr){return;}autocallback=[this](){for(auto&iter:collectPluginMap_){iter.second->OnStart();}};collectHandler_->PostTask(callback);}3.2.2、遍历saInfos 初始化onDemandSaIdsSet_
...lock_guard<mutex>autoLock(saProfileMapLock_);onDemandSaIdsSet_.insert(DEVICE_INFO_SERVICE_SA);onDemandSaIdsSet_.insert(HIDUMPER_SERVICE_SA);onDemandSaIdsSet_.insert(MEDIA_ANALYSIS_SERVICE_SA);for(constauto&saInfo:saInfos){saProfileMap_[saInfo.saId]=saInfo;if(!saInfo.runOnCreate){HILOGI("[InitSaProfile] saId %{public}d",saInfo.saId);onDemandSaIdsSet_.insert(saInfo.saId);}...}3.2.3、SystemAbilityManager::GetOnDemandSystemAbilityIds 初始化systemAbilityIds
int32_tSystemAbilityManager::GetOnDemandSystemAbilityIds(std::vector<int32_t>&systemAbilityIds){HILOGD("UB#GetOnDemandSystemAbilityIds start!");if(onDemandSaIdsSet_.empty()){HILOGD("GetOnDemandSystemAbilityIds error!");returnERR_INVALID_VALUE;}for(int32_tonDemandSaId:onDemandSaIdsSet_){HILOGD("UB#GetOnDemandSystemAbilityIds start! sAId=%{public}d",onDemandSaId);systemAbilityIds.emplace_back(onDemandSaId);}returnERR_OK;}三、SystemAbilityManager::LoadSystemAbility
SystemAbilityManager::LoadSystemAbility这里只是提供了一个动态启动SA的函数,并不是意味着所有的动态SA启动都是由固定的某个进程来启动的,这一点与Android 有所不同,事实上可以在任何进程里通过调用该函数动态启动SA。
传入的systemAbilityId 从哪而来的呢?谁去调用?这个不重要,因为并不是由单一进程去拉起的,比如说usb_service 是由usb_host进程调用这个函数拉起的。
/foundation/systemabilitymgr/samgr/services/samgr/native/source/system_ability_manager.cpp
int32_tSystemAbilityManager::LoadSystemAbility(int32_tsystemAbilityId,constsptr<ISystemAbilityLoadCallback>&callback){if(!CheckInputSysAbilityId(systemAbilityId)||callback==nullptr){HILOGW("UB#LoadSystemAbility systemAbilityId or callback invalid! saId=%{public}d",systemAbilityId);returnERR_INVALID_VALUE;}SaProfile saProfile;HILOGE("UB#LoadSystemAbility SA:%{public}d, saProfile->saId=%{public}d",systemAbilityId,saProfile.saId);bool ret=GetSaProfile(systemAbilityId,saProfile);if(!ret){HILOGE("LoadSystemAbility SA:%{public}d not supported!",systemAbilityId);returnERR_INVALID_VALUE;}autocallingPid=IPCSkeleton::GetCallingPid();OnDemandEvent onDemandEvent={INTERFACE_CALL,"load"};LoadRequestInfo loadRequestInfo={systemAbilityId,LOCAL_DEVICE,callback,callingPid,onDemandEvent};returnabilityStateScheduler_->HandleLoadAbilityEvent(loadRequestInfo);}1、CheckInputSysAbilityId
首先检查配置的SAID 的范围是否在[0,16777215] 且callback是否为nullptr。
2、传入SAID 到GetSaProfile从map中获取对应的SaProfile 结构体
std::map<int32_t, SaProfile> saProfileMap_;
3、构造LoadRequestInfo
篇幅问题下次再进行讲解。
4、SystemAbilityStateScheduler::HandleLoadAbilityEvent
同上
5、SystemAbilityStateScheduler::HandleLoadAbilityEventLocked
同上
四、USB_SERVICE的动态启动概述
usb_service 进程是由usb_host进程启动的,从图中可以看到usb_host进程已经由uhdf机制启动了,触发相关的LoadService()函数执行
而HdfUsbInterfaceDriverBind 是由uhdf 触发后从而调用samgr的LoadSystemAbility来启动usb_service
未完待续…