OpenHarmony系统服务框架部件介绍
前言
系统服务框架图如下:


文件结构
/foundation/systemabilitymgr │── safwk # 组件目录 │ ├── bundle.json # 组件描述及编译脚本 │ ├── etc # 配置文件 │ ├── interfaces # 对外接口目录 │ ├── services # 组件服务实现 │ ├── test # 测试用例
接口说明
| 接口名 | 接口描述 |
|---|---|
| sptr<IRemoteObject> GetSystemAbility(int32_t systemAbilityId); | 获取指定系统服务的RPC对象。 |
| bool Publish(sptr<IRemoteObject> systemAbility); | 发布系统服务。 |
| virtual void DoStartSAProcess(const std::string& profilePath) = 0; | 根据SA profile配置启动System Ability。 |
使用说明
SystemAbility是OpenHarmony的标准服务程序,简称为sa,其实现一般采用XXX.cfg + profile.xml + libXXX.z.so的方式由init进程执行对应的XXX.cfg文件拉起相关SystemAbility进程,启动后注册到samgr。一般来说,一个sa对应一个so,但有个别so同时提供多个sa,比如窗口子系统组件同时提供了dms和wms等2个sa。
SystemAbility的实现代码如下:
-
定义IPC对外接口IXXX
定义该服务对外提供的能力集合函数,统一继承IPC接口类IRemoteBroker;同时实现该IPC对外接口唯一标识符 DECLARE_INTERFACE_DESCRIPTOR(XXX);该 标识符用于IPC通信的校验等目的。
namespace OHOS { class IListenAbility : public IRemoteBroker { public: virtual int AddVolume(int volume) = 0; public: enum { ADD_VOLUME = 1, }; public: DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.test.IListenAbility"); }; }
-
定义客户端通信代码XXXProxy
namespace OHOS { class ListenAbilityProxy : public IRemoteProxy < IListenAbility > { public: int AddVolume(int volume); explicit ListenAbilityProxy(const sptr < IRemoteObject >& impl) : IRemoteProxy < IListenAbility >(impl) { } private: static inline BrokerDelegator < ListenAbilityProxy > delegator_; }; } // namespace OHOS
-
定义服务端通信代码XXXStub
namespace OHOS { int32_t ListenAbilityStub::OnRemoteRequest(uint32_t code,MessageParcel& data, MessageParcel &reply, MessageOption &option) { switch (code) { case ADD_VOLUME: { return reply.WriteInt32(AddVolume(data.ReadInt32())); } default: return IPCObjectStub::OnRemoteRequest(code, data, reply, option); } } }
-
SystemAbility的实现类
nnamespace { constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, 0xD001800, "sa_TST"}; } REGISTER_SYSTEM_ABILITY_BY_ID(ListenAbility, DISTRIBUTED_SCHED_TEST_LISTEN_ID, true); ListenAbility::ListenAbility(int32_t saId, bool runOnCreate) : SystemAbility(saId, runOnCreate) { HiLog::Info(LABEL, ":%s called", __func__); HiLog::Info(LABEL, "ListenAbility()"); } ListenAbility::~ListenAbility() { HiLog::Info(LABEL, "~ListenAbility()"); } int ListenAbility::AddVolume(int volume) { pid_t current = getpid(); HiLog::Info(LABEL, "ListenAbility::AddVolume volume = %d, pid = %d.", volume, current); return (volume + 1); } void ListenAbility::OnDump() { } void ListenAbility::OnStart() { HiLog::Info(LABEL, "ListenAbility::OnStart()"); HiLog::Info(LABEL, "ListenAbility:%s called:-----Publish------", __func__); bool res = Publish(this); if (res) { HiLog::Error(LABEL, "ListenAbility: res == false"); } HiLog::Info(LABEL, "ListenAbility:%s called:AddAbilityListener_OS_TST----beg-----", __func__); AddSystemAbilityListener(DISTRIBUTED_SCHED_TEST_OS_ID); HiLog::Info(LABEL, "ListenAbility:%s called:AddAbilityListener_OS_TST----end-----", __func__); HiLog::Info(LABEL, "ListenAbility:%s called:StopAbility_OS_TST----beg-----", __func__); StopAbility(DISTRIBUTED_SCHED_TEST_OS_ID); HiLog::Info(LABEL, "ListenAbility:%s called:StopAbility_OS_TST----end-----", __func__); return; } void ListenAbility::OnStop() { }amespace { constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, 0xD001800, "sa_TST"}; } REGISTER_SYSTEM_ABILITY_BY_ID(ListenAbility, DISTRIBUTED_SCHED_TEST_LISTEN_ID, true); ListenAbility::ListenAbility(int32_t saId, bool runOnCreate) : SystemAbility(saId, runOnCreate) { HiLog::Info(LABEL, ":%s called", __func__); HiLog::Info(LABEL, "ListenAbility()"); } ListenAbility::~ListenAbility() { HiLog::Info(LABEL, "~ListenAbility()"); } int ListenAbility::AddVolume(int volume) { pid_t current = getpid(); HiLog::Info(LABEL, "ListenAbility::AddVolume volume = %d, pid = %d.", volume, current); return (volume + 1); } void ListenAbility::OnDump() { } void ListenAbility::OnStart() { HiLog::Info(LABEL, "ListenAbility::OnStart()"); HiLog::Info(LABEL, "ListenAbility:%s called:-----Publish------", __func__); bool res = Publish(this); if (res) { HiLog::Error(LABEL, "ListenAbility: res == false"); } HiLog::Info(LABEL, "ListenAbility:%s called:AddAbilityListener_OS_TST----beg-----", __func__); AddSystemAbilityListener(DISTRIBUTED_SCHED_TEST_OS_ID); HiLog::Info(LABEL, "ListenAbility:%s called:AddAbilityListener_OS_TST----end-----", __func__); HiLog::Info(LABEL, "ListenAbility:%s called:StopAbility_OS_TST----beg-----", __func__); StopAbility(DISTRIBUTED_SCHED_TEST_OS_ID); HiLog::Info(LABEL, "ListenAbility:%s called:StopAbility_OS_TST----end-----", __func__); return; } void ListenAbility::OnStop() { }
-
SytemAbility配置
以c++实现的sa必须配置相关System Ability的profile配置文件,才会完成sa的加载注册逻辑,否则没有编写profile配置的System Ability不会完成注册。配置方法如下:在子系统的根目录新建一个以sa_profile为名的文件夹,然后在此文件夹中新建两个文件:一个以serviceId为前缀的xml文件,另外一个为BUILD.gn文件。
serviceid.xml:
<info> <process>listen_test</process> <systemability> <name>serviceid</name> <libpath>/system/lib64/liblistentest.z.so</libpath> <run-on-create>true</run-on-create> <distributed>false</distributed> <dump-level>1</dump-level> </systemability> </info>
-
process:容器程序名。
-
name: sa编号,每个sa都有一个唯一的数字编号。
-
libpath: sa所对应的库。
-
run-on-create: 是否容器运行起来时即刻创建sa。为true表示sa随容器启动,为false表示按需拉起。
-
distributed: 是否分布式。true表示该SystemAbility为分布式SystemAbility,支持跨设备访问;false表示只有本地跨IPC访问。
-
dump-level: 拉起优先级。依次为:引导拉起、核心拉起和其他。
BUILD.gn:
import("//build/ohos/sa_profile/sa_profile.gni") ohos_sa_profile("xxx_sa_profile") { sources = [ "serviceid.xml" ] subsystem_name = "systemabilitymgr" }
5.1. cfg配置文件
cfg配置文件为linux提供的native进程拉起策略,开机启动阶段由init进程解析配置的cfg文件进行拉起。该配置文件表示init在normal阶段会拉起listen_test服务。服务程序为sa_main,配置文件名为listen_test.xml。
{ "jobs" : [{ "name" : "post-fs-data", "cmds" : [ "start listen_test" ] } ], "services" : [{ "name" : "listen_test", "path" : ["/system/bin/sa_main", "/system/profile/listen_test.xml"], "uid" : "system", "gid" : ["system", "shell"] } ] }
5.2. sa的按需启动和创建启动
sa有三种启动模式。
-
创建启动
系统启动时init拉起容器程序,在容器程序启动时,即load该sa的lib库,创建sa对象,并调用其start。
-
按需启动
系统启动时init拉起容器程序,容器程序启动时,并不启动该sa。而是等待需要sa时才创建。
-
动态启动
系统启动时容器程序不拉起,而是后期在运行过程中动态拉起(给init发指令)。
sakfw组件的实现
main
main.cpp文件路径为:foundation\systemabilitymgr\safwk\services\safwk\src\main.cpp。
最多可以传入两个参数:profile xml和sa_id。这两个值默认为:/system/usr/default.xml和-1。这样main的启动方式有3种,目前有两种被使用。一种用于默认拉起,一种用户按需拉起。
namespace { const string TAG = "saMain"; using ProcessNameSetFunc = std::function<void(const string&)>; constexpr auto DEFAULT_XML = "/system/usr/default.xml"; // The pid name can be up to 16 bytes long, including the terminating null byte. // So need to set the max length of pid name to 15 bytes. constexpr size_t MAX_LEN_PID_NAME = 15; constexpr int PROFILE_INDEX = 1; constexpr int saID_INDEX = 2; constexpr int DEFAULT_saID = -1; constexpr int DEFAULT_LOAD = 1; constexpr int ONDEMAND_LOAD = 2; }
LocalAbilityManagerStub类
Stub类,用于和samgr通信,samgr会通过向本类发送拉起ondemand sa指令实现按需拉起。
local_ability_manager_stub.cpp文件路径为:foundation\systemabilitymgr\safwk\services\safwk\src\local_ability_manager_stub.cpp。
SystemAbility类
sa对象的基类,定义了一些通用接口。
system_ability.cpp的文件路径为:\foundation\systemabilitymgr\safwk\services\safwk\src\system_ability.cpp。
-
MakeAndRegisterAbility
将sa加入到本地map。
bool SystemAbility::MakeAndRegisterAbility(SystemAbility* systemAbility) { HILOGD(TAG, "registering system ability..."); return LocalAbilityManager::GetInstance().AddAbility(systemAbility); }
REGISTER_SYSTEM_ABILITY_BY_ID是对MakeAndRegisterAbility的封装。其在so中定义了一个静态变量。当该so被load时REGISTER_SYSTEM_ABILITY_BY_ID会生效,其会调用MakeAndRegisterAbility,传入参数包括:new出来的sa对象(构造参数包括(said和runoncreate),接着会调用AddAbility()。
namespace OHOS { #define REGISTER_SYSTEM_ABILITY_BY_ID(abilityClassName, systemAbilityId, runOnCreate) \ const bool abilityClassName##_##RegisterResult = \ SystemAbility::MakeAndRegisterAbility(new abilityClassName(systemAbilityId, runOnCreate)); ..... }
-
Publish
将sa发布到samgr
bool SystemAbility::Publish(sptr<IRemoteObject> systemAbility) { if (systemAbility == nullptr) { HILOGE(TAG, "systemAbility is nullptr"); return false; } HILOGD(TAG, "[PerformanceTest] saFWK Publish systemAbilityId:%{public}d", saId_); int64_t begin = GetTickCount(); sptr<ISystemAbilityManager> samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); if (samgrProxy == nullptr) { HILOGE(TAG, "failed to get samgrProxy"); return false; } publishObj_ = systemAbility; ISystemAbilityManager::saExtraProp saExtra(GetDistributed(), GetDumpLevel(), capability_, permission_); int32_t result = samgrProxy->AddSystemAbility(saId_, publishObj_, saExtra); HILOGI(TAG, "[PerformanceTest] saFWK Publish sa:%{public}d result : %{public}d, spend:%{public}" PRId64 " ms", saId_, result, (GetTickCount() - begin)); return result == ERR_OK; }
-
Start
启动sa,会回调OnStart。
void SystemAbility::Start() { HILOGD(TAG, "starting system ability..."); if (isRunning_) { return; } HILOGD(TAG, "[PerformanceTest] saFWK OnStart systemAbilityId:%{public}d", saId_); int64_t begin = GetTickCount(); HITRACE_METER_NAME(HITRACE_TAG_saMGR, ToString(saId_) + "_OnStart"); OnStart(); isRunning_ = true; HILOGI(TAG, "[PerformanceTest] saFWK OnStart systemAbilityId:%{public}d finished, spend:%{public}" PRId64 " ms", saId_, (GetTickCount() - begin)); }
-
stop
停止sa,会回调OnStop。
void SystemAbility::Stop() { HILOGD(TAG, "stopping system ability..."); if (!isRunning_) { return; } OnStop(); isRunning_ = false; sptr < ISystemAbilityManager > samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); if (samgrProxy == nullptr) { HILOGE(TAG, "failed to get samgrProxy"); return; } int32_t ret = samgrProxy->RemoveSystemAbility(saId_); HILOGI(TAG, "%{public}s to remove ability", (ret == ERR_OK) ? "success" : "failed"); }
LocalAbilityManager类
本地Ability管理类,继承了LocalAbilityManagerStub。容器程序的大部分逻辑都在本类实现。
local_ability_manager.cpp的文件路径为:\foundation\systemabilitymgr\safwk\services\safwk\src\local_ability_manager.cpp。
DoStartSAProcess
-
CheckAndGetProfilePath
检查profile xml路径合法性。(必须在/system/profile/或/system/usr/)
-
InitSystemAbilityProfiles
解析profile,得到进程名和诸多sainfo, 如解析失败则返回false并退出。检查是否是可信sa,检查方法:查看/system/profile/下是否有xxx_trust.xml文件(xxx为sa进程名), 如果存在则进行可信检查,移走不可信的sainfo。加载sa对应的库:如果sa id指定,则load单个sa的库,否则load所有runOnCreate的库。
bool LocalAbilityManager::InitSystemAbilityProfiles(const std::string& profilePath, int32_t saId) { HILOGD(TAG, "[PerformanceTest] saFWK parse system ability profiles!"); int64_t begin = GetTickCount(); bool ret = profileParser_->ParsesaProfiles(profilePath); if (!ret) { HILOGW(TAG, "ParsesaProfiles failed!"); return false; } procName_ = profileParser_->GetProcessName(); auto saInfos = profileParser_->GetAllsaProfiles(); std::string process = Str16ToStr8(procName_); HILOGI(TAG, "[PerformanceTest] saFWK parse process:%{public}s system ability profiles finished, spend:%{public}" PRId64 " ms", process.c_str(), (GetTickCount() - begin)); std::string path = PREFIX + process + SUFFIX; bool isExist = profileParser_->CheckPathExist(path); if (isExist) { CheckTrustsa(path, process, saInfos); } begin = GetTickCount(); if (saId != DEFAULT_saID) { HILOGD(TAG, "[PerformanceTest] saFWK LoadsaLib systemAbilityId:%{public}d", saId); bool result = profileParser_->LoadsaLib(saId); HILOGI(TAG, "[PerformanceTest] saFWK LoadsaLib systemAbilityId:%{public}d finished, spend:%{public}" PRId64 " ms", saId, (GetTickCount() - begin)); return result; } else { HILOGD(TAG, "[PerformanceTest] saFWK load all libraries"); profileParser_->OpenSo(); HILOGI(TAG, "[PerformanceTest] saFWK load all libraries finished, spend:%{public}" PRId64 " ms", (GetTickCount() - begin)); return true; } }
-
CheckSystemAbilityManagerReady
等待samgr服务启动。
bool LocalAbilityManager::CheckSystemAbilityManagerReady() { int32_t timeout = RETRY_TIMES_FOR_saMGR; constexpr int32_t duration = std::chrono::microseconds(MILLISECONDS_WAITING_saMGR_ONE_TIME).count(); sptr<ISystemAbilityManager> samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); while (samgrProxy == nullptr) { HILOGI(TAG, "waiting for samgr..."); if (timeout > 0) { usleep(duration); samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); } else { HILOGE(TAG, "wait for samgr time out (10s)"); return false; } timeout--; } return true; }
-
InitializesaProfiles
初始化sa。如果sa为-1,则对所有sa操作InitializesaProfilesInnerLocked;否则对指定sa操作InitializesaProfilesInnerLocked。
InitializesaProfilesInnerLocked会把sa分到三个不同等级的map中分别启动。
bool LocalAbilityManager::InitializesaProfiles(int32_t saId) { return (saId == DEFAULT_saID) ? InitializeRunOnCreatesaProfiles() : InitializeOnDemandsaProfile(saId); }
Run
-
启动线程池
-
FindAndStartPhaseTasks
按照3个优先级启动3个等级的sa。
void LocalAbilityManager::FindAndStartPhaseTasks() { std::shared_lock<std::shared_mutex> readLock(abilityMapLock_); for (uint32_t startType = BOOT_START; startType <= OTHER_START; ++startType) { auto iter = abilityPhaseMap_.find(startType); if (iter != abilityPhaseMap_.end()) { StartPhaseTasks(iter->second); } } }
-
RegisterOnDemandSystemAbility
如果是在default load模式,那些非创建时运行的sa会注册到samgr。如果在demand load模式,非当前sa都会被注册到samgr。调用samgr的 AddOnDemandSystemAbilityInfo 。
void LocalAbilityManager::RegisterOnDemandSystemAbility(int32_t saId) { auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); if (samgrProxy == nullptr) { HILOGI(TAG, "failed to get samgrProxy"); return; } auto& saProfileList = profileParser_->GetAllsaProfiles(); for (const auto& saProfile : saProfileList) { if (NeedRegisterOnDemand(saProfile, saId)) { HILOGD(TAG, "register ondemand ability:%{public}d to samgr", saProfile.saId); int32_t ret = samgrProxy->AddOnDemandSystemAbilityInfo(saProfile.saId, procName_); if (ret != ERR_OK) { HILOGI(TAG, "failed to add ability info for on-demand sa:%{public}d", saProfile.saId); } } } }
-
等待子线程结束
-
清理资源
StartSystemAbilityTask
建立对应的sa。如果对应的sa没有依赖,直接调用其Start函数。如果依赖其他sa,则调用samgrProxy->CheckSystemAbility,以保证对应的sa启动。
void LocalAbilityManager::StartSystemAbilityTask(SystemAbility* ability) { if (ability != nullptr) { HILOGD(TAG, "StartSystemAbility is called for %{public}d", ability->GetSystemAbilitId()); if (ability->GetDependsa().empty()) { ability->Start(); } else { int64_t start = GetTickCount(); int64_t dependTimeout = ability->GetDependTimeout(); while (!CheckDependencyStatus(ability->GetDependsa()).empty()) { int64_t end = GetTickCount(); int64_t duration = ((end >= start) ? (end - start) : (INT64_MAX - end + start)); if (duration < dependTimeout) { usleep(CHECK_DEPENDENT_sa_PERIOD); } else { break; } } vector<u16string> unpreparedDeps = CheckDependencyStatus(ability->GetDependsa()); if (unpreparedDeps.empty()) { ability->Start(); } else { for (const auto& unpreparedDep : unpreparedDeps) { HILOGI(TAG, "%{public}d's dependency:%{public}s not started in %{public}d ms", ability->GetSystemAbilitId(), Str16ToStr8(unpreparedDep).c_str(), ability->GetDependTimeout()); } } } } std::lock_guard<std::mutex> lock(startPhaseLock_); if (startTaskNum_ > 0) { --startTaskNum_; } startPhaseCV_.notify_one(); }
-
AddAbility
查找profile。将profile中的参数赋值给sa对象。
bool LocalAbilityManager::AddAbility(SystemAbility* ability) { if (ability == nullptr) { HILOGW(TAG, "try to add null ability!"); return false; } int32_t saId = ability->GetSystemAbilitId(); saProfile saProfile; bool ret = profileParser_->GetProfile(saId, saProfile); if (!ret) { return false; } std::unique_lock < std::shared_mutex > writeLock(abilityMapLock_); auto iter = abilityMap_.find(saId); if (iter != abilityMap_.end()) { HILOGW(TAG, "try to add existed ability:%{public}d!", saId); return false; } HILOGI(TAG, "set profile attributes for sa:%{public}d", saId); ability->SetLibPath(saProfile.libPath); ability->SetRunOnCreate(saProfile.runOnCreate); ability->SetDependsa(saProfile.dependsa); ability->SetDependTimeout(saProfile.dependTimeout); ability->SetDistributed(saProfile.distributed); ability->SetDumpLevel(saProfile.dumpLevel); ability->SetCapability(saProfile.capability); ability->SetPermission(saProfile.permission); abilityMap_.emplace(saId, ability); return true; }
参考文档
更多推荐


所有评论(0)