OpenHarmony服务启动框架
从上面代码我们可以知道服务的启动最终调用到了SystemAbility的start函数,由于我们注册的时候注册的是HCameraService,所以会调用到HCameraService的start函数。可以看到他是通过执行system/bin/sa_main程序导入了/system/profile/camera_service.xml配置文件启动的camera_service服务就和Android
三、服务的启动框架
在OpenHarmony Init进程的启动流程
的2.5.3小节我们说过ParseAllServices函数主要用来解析/etc/init目录下的各种以服务名命名的cfg文件,解析完毕后会将服务的信息存储在NODE_TYPE_SERVICES中的InitGroupNode接着在2.5.7小节的TriggerServices去启动它,TriggerServices后续的流程图如下:
这里我们以CameraService为例介绍一下OpenHarmony启动服务的基本流程,
首先camera_service的cfg文件内容如下:
/foundation/multimedia/camera_framework/services/etc/camera_service.cfg
{
"services" : [{
"name" : "camera_service",
"path" : ["/system/bin/sa_main", "/system/profile/camera_service.xml"],
"uid" : "cameraserver",
"gid" : ["system", "shell"],
"secon" : "u:r:camera_service:s0",
"permission" : ["ohos.permission.GET_SENSITIVE_PERMISSIONS", "ohos.permission.PERMISSION_USED_STATS"],
"permission_acls" : ["ohos.permission.GET_SENSITIVE_PERMISSIONS"]
}
]
}
可以看到他是通过执行system/bin/sa_main程序导入了/system/profile/camera_service.xml配置文件启动的camera_service服务就和Android的init.rc中启动native进程是类似的。接着我们看一下camera_service.xml
<!--设备里的/system/profile/camera_service.xml-->
<?xml version="1.0" encoding="utf-8"?>
<info>
<process>camera_service</process>
<loadlibs>
<libpath>libcamera_service.z.so</libpath>
</loadlibs>
<systemability>
<name>3008</name>
<libpath>libcamera_service.z.so</libpath>
<run-on-create>true</run-on-create>
<distributed>false</distributed>
<dump-level>1</dump-level>
</systemability>
</info>
服务的启动流程首先要先知道sa_main可执行程序的入口在哪里,在代码库中搜索sa_main 并在filePath中输入gn即可搜到sa_main的代码路径如下:
/foundation/systemabilitymgr/safwk/services/safwk/src/
3.1 sa.main
入口函数是main.cpp
/foundation/systemabilitymgr/safwk/services/safwk/src/main.cpp
int main(int argc, char *argv[]){
//我们这里一般的服务只有一个参数 就是
HILOGI(TAG, "[PerformanceTest] SAFWK main entry process starting!");
//回调接口
auto setProcessName = [argc, argv](const string& name) -> void {
uintptr_t start = reinterpret_cast<uintptr_t>(argv[0]);
uintptr_t end = reinterpret_cast<uintptr_t>(strchr(argv[argc - 1], 0));
uintptr_t argvSize = end - start;
if (memset_s(argv[0], argvSize, 0, argvSize) != EOK) {
HILOGW(TAG, "failed to clear argv:%s", strerror(errno));
return;
}
if (strcpy_s(argv[0], argvSize, name.c_str()) != EOK) {
HILOGW(TAG, "failed to set process name:%s", strerror(errno));
return;
}
HILOGI(TAG, "Set process name to %{public}s", argv[0]);
};
// Load ondemand system abilities related shared libraries from specific xml-format profile
// when this process starts.
//初始saId为-1
int32_t saId = DEFAULT_SAID;
if (argc > ONDEMAND_LOAD) {
//从参数中解析saId
saId = ParseSaId(argv);
if (!CheckSaId(saId)) {
HILOGE(TAG, "saId is invalid!");
return 0;
}
}
// Load default system abilities related shared libraries from specific xml-format profile,
// when this process starts.
//解析服务的profile文件就是camera_service.xml
string profilePath(DEFAULT_XML);
if (argc > DEFAULT_LOAD) {
string filePath(argv[PROFILE_INDEX]);
if (filePath.empty() || filePath.find(".xml") == string::npos) {
HILOGE(TAG, "profile file path is invalid!");
return 0;
}
//调用SetProcName设置进程的名字
SetProcName(filePath, setProcessName);
profilePath = std::move(filePath);
}
//调用DoStartSAProcess启动服务
LocalAbilityManager::GetInstance().DoStartSAProcess(profilePath, saId);
return 0;
}
3.2 LocalAbilityManager.DoStartSAProcess
可以看到sa_main的main函数主要是设置进程名字接着调用LocalAbilityManager的DoStartSAProcess来启动服务
/foundation/systemabilitymgr/safwk/services/safwk/src/local_ability_manager.cpp
void LocalAbilityManager::DoStartSAProcess(const std::string& profilePath, int32_t saId)
{
HILOGI(TAG, "DoStartSAProcess saId : %d", saId);
string realProfilePath = "";
if (!CheckAndGetProfilePath(profilePath, realProfilePath)) {
HILOGE(TAG, "DoStartSAProcess invalid path");
return;
}
{
std::string traceTag = GetTraceTag(realProfilePath);
HITRACE_METER_NAME(HITRACE_TAG_SAMGR, traceTag);
//InitSystemAbilityProfiles 解析进程名称并打开对应的so文件注册相应的ability
bool ret = InitSystemAbilityProfiles(realProfilePath, saId);
if (!ret) {
HILOGE(TAG, "InitSystemAbilityProfiles no right profile, will exit");
return;
}
//等待SystemAbilityManager启动 SystemAbilityManager和Android的ServiceManager功能类似主要负责系统能力的添加查找
//最多等待10s
ret = CheckSystemAbilityManagerReady();
if (!ret) {
HILOGE(TAG, "CheckSystemAbilityManagerReady failed! will exit");
return;
}
//将注册的ability加入到abilityPhaseMap_中的saList中
ret = InitializeSaProfiles(saId);
if (!ret) {
HILOGE(TAG, "InitializeSaProfiles failed! will exit");
return;
}
//启动ability
ret = Run(saId);
if (!ret) {
HILOGE(TAG, "Run failed! will exit");
return;
}
}
IPCSkeleton::JoinWorkThread();
ClearResource();
HILOGE(TAG, "JoinWorkThread stop, will exit");
}
DoStartSAProcess主要做了三件事情
1.调用InitSystemAbilityProfiles解析进程名称并打开和加载对应的so文件
2.等待SystemAbilityManager启动
3.将解析出来的ability加入到saList中
4.启动ability
3.3 注册Ability
其中第一条在加载so文件时会加载服务的类这时会调用到如下函数:
/foundation/multimedia/camera_framework/services/camera_service/src/hcamera_service.cpp
REGISTER_SYSTEM_ABILITY_BY_ID(HCameraService, CAMERA_SERVICE_ID, true)
/foundation/systemabilitymgr/safwk/services/safwk/include/system_ability.h
#define REGISTER_SYSTEM_ABILITY_BY_ID(abilityClassName, systemAbilityId, runOnCreate) \
const bool abilityClassName##_##RegisterResult = \
SystemAbility::MakeAndRegisterAbility(new abilityClassName(systemAbilityId, runOnCreate));
意思就是将HCameraService注册成为CAMERA_SERVICE_ID的systemability,可以看到最终调用到了 SystemAbility::MakeAndRegisterAbility
/foundation/systemabilitymgr/safwk/services/safwk/src/system_ability.cpp
bool SystemAbility::MakeAndRegisterAbility(SystemAbility* systemAbility)
{
HILOGD(TAG, "registering system ability...");
return LocalAbilityManager::GetInstance().AddAbility(systemAbility);
}
/foundation/systemabilitymgr/safwk/services/safwk/src/local_ability_manager.cpp
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;
}
可以看到最终将ability加入到了abilityMap_中
3.4 启动ability
在3.2小节中启动ability走的时run函数
/foundation/systemabilitymgr/safwk/services/safwk/src/local_ability_manager.cpp
bool LocalAbilityManager::Run(int32_t saId)
{
HILOGD(TAG, "local ability manager is running...");
//把当前的LocalAbilityManager和processName注册给SystemAbilityManager
bool addResult = AddLocalAbilityManager();
if (!addResult) {
HILOGE(TAG, "failed to add local abilitymanager");
return false;
}
HILOGD(TAG, "success to add process name:%{public}s", Str16ToStr8(procName_).c_str());
uint32_t concurrentThreads = std::thread::hardware_concurrency();
HILOGI(TAG, "concurrentThreads is %{public}d", concurrentThreads);
initPool_->Start(concurrentThreads);
initPool_->SetMaxTaskNum(MAX_TASK_NUMBER);
//启动ability
FindAndStartPhaseTasks();
RegisterOnDemandSystemAbility(saId);
initPool_->Stop();
return true;
}
void LocalAbilityManager::FindAndStartPhaseTasks()
{
std::shared_lock<std::shared_mutex> readLock(abilityMapLock_);
for (uint32_t startType = BOOT_START; startType <= OTHER_START; ++startType) {
//将abilityPhaseMap_中的ability全部启动
auto iter = abilityPhaseMap_.find(startType);
if (iter != abilityPhaseMap_.end()) {
StartPhaseTasks(iter->second);
}
}
}
void LocalAbilityManager::StartPhaseTasks(const std::list<SystemAbility*>& systemAbilityList)
{
if (systemAbilityList.empty()) {
return;
}
for (auto systemAbility : systemAbilityList) {
if (systemAbility != nullptr) {
HILOGD(TAG, "add phase task for SA:%{public}d", systemAbility->GetSystemAbilitId());
std::lock_guard<std::mutex> autoLock(startPhaseLock_);
++startTaskNum_;
//使用initPool_调用StartSystemAbilityTask启动systemAbility
auto task = std::bind(&LocalAbilityManager::StartSystemAbilityTask, this, systemAbility);
initPool_->AddTask(task);
}
}
int64_t begin = GetTickCount();
HILOGD(TAG, "start waiting for all tasks!");
std::unique_lock<std::mutex> lck(startPhaseLock_);
if (!startPhaseCV_.wait_for(lck, std::chrono::seconds(MAX_SA_STARTUP_TIME),
[this] () { return startTaskNum_ == 0; })) {
HILOGW(TAG, "start timeout!");
}
startTaskNum_ = 0;
int64_t end = GetTickCount();
HILOGI(TAG, "start tasks finished and spend %{public}" PRId64 " ms", (end - begin));
}
void LocalAbilityManager::StartSystemAbilityTask(SystemAbility* ability)
{
if (ability != nullptr) {
HILOGD(TAG, "StartSystemAbility is called for %{public}d", ability->GetSystemAbilitId());
//如果ability不依赖其他sa那么直接启动
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();
}
从上面代码我们可以知道服务的启动最终调用到了SystemAbility的start函数,由于我们注册的时候注册的是HCameraService,所以会调用到HCameraService的start函数。最终会调用到HCameraService的onStart函数,至此服务就被启动起来了。不同的服务只是需要加载的so库不一样注册的服务不一样,用的都是这一套框架。
更多推荐
所有评论(0)