当前位置:   article > 正文

OpenHarmony服务启动框架_openharmony sa服务

openharmony sa服务

三、服务的启动框架

OpenHarmony Init进程的启动流程
的2.5.3小节我们说过ParseAllServices函数主要用来解析/etc/init目录下的各种以服务名命名的cfg文件,解析完毕后会将服务的信息存储在NODE_TYPE_SERVICES中的InitGroupNode接着在2.5.7小节的TriggerServices去启动它,TriggerServices后续的流程图如下:
init服务的启动

这里我们以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"]
        }
    ]
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

可以看到他是通过执行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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

服务的启动流程首先要先知道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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50

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");
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43

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));
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

意思就是将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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

可以看到最终将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();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98

从上面代码我们可以知道服务的启动最终调用到了SystemAbility的start函数,由于我们注册的时候注册的是HCameraService,所以会调用到HCameraService的start函数。最终会调用到HCameraService的onStart函数,至此服务就被启动起来了。不同的服务只是需要加载的so库不一样注册的服务不一样,用的都是这一套框架。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/312785
推荐阅读
相关标签
  

闽ICP备14008679号