参考:
正文:
一. 系统服务的调用过程。
- Natvie 中,先通过 IPC 获取 samgr 的 Server 端的 Binder。
sptr<ISystemAbilityManager> sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
- 在 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_;
}
- 获取到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。
二. 系统服务的注册&启动过程
- 在 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;
}
- 在 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();
}
- 在 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
}
]
}
- 在 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);
}
- 在 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;
}
- 在 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 代码调用系统服务过程
- 在 ArkTs/Ts 代码中,只要导入了so库:import napi from 'libmqtt.so' 或者模块:import hilog from '@ohos.hilog',通过编译后,都会生成相应 js 代码:requireNapi('hilog')。
- 在 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);
...略...
}