169570cc8Sopenharmony_ci/* 269570cc8Sopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 369570cc8Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 469570cc8Sopenharmony_ci * you may not use this file except in compliance with the License. 569570cc8Sopenharmony_ci * You may obtain a copy of the License at 669570cc8Sopenharmony_ci * 769570cc8Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 869570cc8Sopenharmony_ci * 969570cc8Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1069570cc8Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1169570cc8Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1269570cc8Sopenharmony_ci * See the License for the specific language governing permissions and 1369570cc8Sopenharmony_ci * limitations under the License. 1469570cc8Sopenharmony_ci */ 1569570cc8Sopenharmony_ci 1669570cc8Sopenharmony_ci#include "appspawn_modulemgr.h" 1769570cc8Sopenharmony_ci 1869570cc8Sopenharmony_ci#include "appspawn_hook.h" 1969570cc8Sopenharmony_ci#include "appspawn_manager.h" 2069570cc8Sopenharmony_ci#include "appspawn_utils.h" 2169570cc8Sopenharmony_ci#include "hookmgr.h" 2269570cc8Sopenharmony_ci#include "modulemgr.h" 2369570cc8Sopenharmony_ci 2469570cc8Sopenharmony_citypedef struct { 2569570cc8Sopenharmony_ci const AppSpawnContent *content; 2669570cc8Sopenharmony_ci const AppSpawnedProcessInfo *appInfo; 2769570cc8Sopenharmony_ci} AppSpawnAppArg; 2869570cc8Sopenharmony_ci 2969570cc8Sopenharmony_cistatic struct { 3069570cc8Sopenharmony_ci MODULE_MGR *moduleMgr; 3169570cc8Sopenharmony_ci AppSpawnModuleType type; 3269570cc8Sopenharmony_ci const char *moduleName; 3369570cc8Sopenharmony_ci} g_moduleMgr[MODULE_MAX] = { 3469570cc8Sopenharmony_ci {NULL, MODULE_DEFAULT, "appspawn"}, 3569570cc8Sopenharmony_ci {NULL, MODULE_APPSPAWN, "appspawn/appspawn"}, 3669570cc8Sopenharmony_ci {NULL, MODULE_NWEBSPAWN, "appspawn/nwebspawn"}, 3769570cc8Sopenharmony_ci {NULL, MODULE_COMMON, "appspawn/common"}, 3869570cc8Sopenharmony_ci {NULL, MODULE_NATIVESPAWN, "appspawn/nativespawn"}, 3969570cc8Sopenharmony_ci}; 4069570cc8Sopenharmony_cistatic HOOK_MGR *g_appspawnHookMgr = NULL; 4169570cc8Sopenharmony_ci 4269570cc8Sopenharmony_ciint AppSpawnModuleMgrInstall(const char *moduleName) 4369570cc8Sopenharmony_ci{ 4469570cc8Sopenharmony_ci if (moduleName == NULL) { 4569570cc8Sopenharmony_ci return -1; 4669570cc8Sopenharmony_ci } 4769570cc8Sopenharmony_ci int type = MODULE_DEFAULT; 4869570cc8Sopenharmony_ci if (g_moduleMgr[type].moduleMgr == NULL) { 4969570cc8Sopenharmony_ci g_moduleMgr[type].moduleMgr = ModuleMgrCreate(g_moduleMgr[type].moduleName); 5069570cc8Sopenharmony_ci } 5169570cc8Sopenharmony_ci if (g_moduleMgr[type].moduleMgr == NULL) { 5269570cc8Sopenharmony_ci return -1; 5369570cc8Sopenharmony_ci } 5469570cc8Sopenharmony_ci#ifndef APPSPAWN_TEST 5569570cc8Sopenharmony_ci return ModuleMgrInstall(g_moduleMgr[type].moduleMgr, moduleName, 0, NULL); 5669570cc8Sopenharmony_ci#else 5769570cc8Sopenharmony_ci return 0; 5869570cc8Sopenharmony_ci#endif 5969570cc8Sopenharmony_ci} 6069570cc8Sopenharmony_ci 6169570cc8Sopenharmony_civoid AppSpawnModuleMgrUnInstall(int type) 6269570cc8Sopenharmony_ci{ 6369570cc8Sopenharmony_ci if ((type < 0) || (type >= MODULE_MAX)) { 6469570cc8Sopenharmony_ci return; 6569570cc8Sopenharmony_ci } 6669570cc8Sopenharmony_ci if (g_moduleMgr[type].moduleMgr == NULL) { 6769570cc8Sopenharmony_ci return; 6869570cc8Sopenharmony_ci } 6969570cc8Sopenharmony_ci ModuleMgrDestroy(g_moduleMgr[type].moduleMgr); 7069570cc8Sopenharmony_ci g_moduleMgr[type].moduleMgr = NULL; 7169570cc8Sopenharmony_ci} 7269570cc8Sopenharmony_ci 7369570cc8Sopenharmony_ciint AppSpawnLoadAutoRunModules(int type) 7469570cc8Sopenharmony_ci{ 7569570cc8Sopenharmony_ci if ((type < 0) || (type >= MODULE_MAX)) { 7669570cc8Sopenharmony_ci return -1; 7769570cc8Sopenharmony_ci } 7869570cc8Sopenharmony_ci if (g_moduleMgr[type].moduleMgr != NULL) { 7969570cc8Sopenharmony_ci return 0; 8069570cc8Sopenharmony_ci } 8169570cc8Sopenharmony_ci APPSPAWN_LOGI("AppSpawnLoadAutoRunModules: %{public}d moduleName: %{public}s", type, g_moduleMgr[type].moduleName); 8269570cc8Sopenharmony_ci#ifndef APPSPAWN_TEST 8369570cc8Sopenharmony_ci g_moduleMgr[type].moduleMgr = ModuleMgrScan(g_moduleMgr[type].moduleName); 8469570cc8Sopenharmony_ci return g_moduleMgr[type].moduleMgr == NULL ? -1 : 0; 8569570cc8Sopenharmony_ci#else 8669570cc8Sopenharmony_ci return 0; 8769570cc8Sopenharmony_ci#endif 8869570cc8Sopenharmony_ci} 8969570cc8Sopenharmony_ci 9069570cc8Sopenharmony_ciHOOK_MGR *GetAppSpawnHookMgr(void) 9169570cc8Sopenharmony_ci{ 9269570cc8Sopenharmony_ci if (g_appspawnHookMgr != NULL) { 9369570cc8Sopenharmony_ci return g_appspawnHookMgr; 9469570cc8Sopenharmony_ci } 9569570cc8Sopenharmony_ci g_appspawnHookMgr = HookMgrCreate("appspawn"); 9669570cc8Sopenharmony_ci return g_appspawnHookMgr; 9769570cc8Sopenharmony_ci} 9869570cc8Sopenharmony_ci 9969570cc8Sopenharmony_civoid DeleteAppSpawnHookMgr(void) 10069570cc8Sopenharmony_ci{ 10169570cc8Sopenharmony_ci HookMgrDestroy(g_appspawnHookMgr); 10269570cc8Sopenharmony_ci g_appspawnHookMgr = NULL; 10369570cc8Sopenharmony_ci} 10469570cc8Sopenharmony_ci 10569570cc8Sopenharmony_cistatic void UpdateAppSpawnTime(int used) 10669570cc8Sopenharmony_ci{ 10769570cc8Sopenharmony_ci if (used < GetAppSpawnMgr()->spawnTime.minAppspawnTime) { 10869570cc8Sopenharmony_ci GetAppSpawnMgr()->spawnTime.minAppspawnTime = used; 10969570cc8Sopenharmony_ci APPSPAWN_LOGI("spawn min time: %{public}d", GetAppSpawnMgr()->spawnTime.minAppspawnTime); 11069570cc8Sopenharmony_ci } 11169570cc8Sopenharmony_ci if (used > GetAppSpawnMgr()->spawnTime.maxAppspawnTime) { 11269570cc8Sopenharmony_ci GetAppSpawnMgr()->spawnTime.maxAppspawnTime = used; 11369570cc8Sopenharmony_ci APPSPAWN_LOGI("spawn max time: %{public}d", GetAppSpawnMgr()->spawnTime.maxAppspawnTime); 11469570cc8Sopenharmony_ci } 11569570cc8Sopenharmony_ci} 11669570cc8Sopenharmony_ci 11769570cc8Sopenharmony_cistatic int ServerStageHookRun(const HOOK_INFO *hookInfo, void *executionContext) 11869570cc8Sopenharmony_ci{ 11969570cc8Sopenharmony_ci AppSpawnHookArg *arg = (AppSpawnHookArg *)executionContext; 12069570cc8Sopenharmony_ci ServerStageHook realHook = (ServerStageHook)hookInfo->hookCookie; 12169570cc8Sopenharmony_ci return realHook((void *)arg->content); 12269570cc8Sopenharmony_ci} 12369570cc8Sopenharmony_ci 12469570cc8Sopenharmony_cistatic void PreHookExec(const HOOK_INFO *hookInfo, void *executionContext) 12569570cc8Sopenharmony_ci{ 12669570cc8Sopenharmony_ci AppSpawnHookArg *arg = (AppSpawnHookArg *)executionContext; 12769570cc8Sopenharmony_ci AppSpawnMgr *spawnMgr = (AppSpawnMgr *)arg->content; 12869570cc8Sopenharmony_ci clock_gettime(CLOCK_MONOTONIC, &spawnMgr->perLoadStart); 12969570cc8Sopenharmony_ci APPSPAWN_LOGI("Hook stage: %{public}d prio: %{public}d start", hookInfo->stage, hookInfo->prio); 13069570cc8Sopenharmony_ci} 13169570cc8Sopenharmony_ci 13269570cc8Sopenharmony_cistatic void PostHookExec(const HOOK_INFO *hookInfo, void *executionContext, int executionRetVal) 13369570cc8Sopenharmony_ci{ 13469570cc8Sopenharmony_ci AppSpawnHookArg *arg = (AppSpawnHookArg *)executionContext; 13569570cc8Sopenharmony_ci AppSpawnMgr *spawnMgr = (AppSpawnMgr *)arg->content; 13669570cc8Sopenharmony_ci clock_gettime(CLOCK_MONOTONIC, &spawnMgr->perLoadEnd); 13769570cc8Sopenharmony_ci uint64_t diff = DiffTime(&spawnMgr->perLoadStart, &spawnMgr->perLoadEnd); 13869570cc8Sopenharmony_ci APPSPAWN_LOGI("Hook stage: %{public}d prio: %{public}d end time %{public}" PRId64 " ns result: %{public}d", 13969570cc8Sopenharmony_ci hookInfo->stage, hookInfo->prio, diff, executionRetVal); 14069570cc8Sopenharmony_ci UpdateAppSpawnTime(diff); 14169570cc8Sopenharmony_ci} 14269570cc8Sopenharmony_ci 14369570cc8Sopenharmony_ciint ServerStageHookExecute(AppSpawnHookStage stage, AppSpawnContent *content) 14469570cc8Sopenharmony_ci{ 14569570cc8Sopenharmony_ci APPSPAWN_CHECK(content != NULL, return APPSPAWN_ARG_INVALID, "Invalid content"); 14669570cc8Sopenharmony_ci APPSPAWN_CHECK((stage >= STAGE_SERVER_PRELOAD) && (stage <= STAGE_SERVER_EXIT), 14769570cc8Sopenharmony_ci return APPSPAWN_ARG_INVALID, "Invalid stage %{public}d", (int)stage); 14869570cc8Sopenharmony_ci AppSpawnHookArg arg; 14969570cc8Sopenharmony_ci arg.content = content; 15069570cc8Sopenharmony_ci arg.client = NULL; 15169570cc8Sopenharmony_ci HOOK_EXEC_OPTIONS options; 15269570cc8Sopenharmony_ci options.flags = TRAVERSE_STOP_WHEN_ERROR; 15369570cc8Sopenharmony_ci options.preHook = PreHookExec; 15469570cc8Sopenharmony_ci options.postHook = PostHookExec; 15569570cc8Sopenharmony_ci int ret = HookMgrExecute(GetAppSpawnHookMgr(), stage, (void *)(&arg), &options); 15669570cc8Sopenharmony_ci APPSPAWN_LOGV("Execute hook [%{public}d] result %{public}d", stage, ret); 15769570cc8Sopenharmony_ci return ret == ERR_NO_HOOK_STAGE ? 0 : ret; 15869570cc8Sopenharmony_ci} 15969570cc8Sopenharmony_ci 16069570cc8Sopenharmony_ciint AddServerStageHook(AppSpawnHookStage stage, int prio, ServerStageHook hook) 16169570cc8Sopenharmony_ci{ 16269570cc8Sopenharmony_ci APPSPAWN_CHECK(hook != NULL, return APPSPAWN_ARG_INVALID, "Invalid hook"); 16369570cc8Sopenharmony_ci APPSPAWN_CHECK((stage >= STAGE_SERVER_PRELOAD) && (stage <= STAGE_SERVER_EXIT), 16469570cc8Sopenharmony_ci return APPSPAWN_ARG_INVALID, "Invalid stage %{public}d", (int)stage); 16569570cc8Sopenharmony_ci HOOK_INFO info; 16669570cc8Sopenharmony_ci info.stage = stage; 16769570cc8Sopenharmony_ci info.prio = prio; 16869570cc8Sopenharmony_ci info.hook = ServerStageHookRun; 16969570cc8Sopenharmony_ci info.hookCookie = (void *)hook; 17069570cc8Sopenharmony_ci APPSPAWN_LOGI("AddServerStageHook prio: %{public}d", prio); 17169570cc8Sopenharmony_ci return HookMgrAddEx(GetAppSpawnHookMgr(), &info); 17269570cc8Sopenharmony_ci} 17369570cc8Sopenharmony_ci 17469570cc8Sopenharmony_cistatic int AppSpawnHookRun(const HOOK_INFO *hookInfo, void *executionContext) 17569570cc8Sopenharmony_ci{ 17669570cc8Sopenharmony_ci AppSpawnForkArg *arg = (AppSpawnForkArg *)executionContext; 17769570cc8Sopenharmony_ci AppSpawnHook realHook = (AppSpawnHook)hookInfo->hookCookie; 17869570cc8Sopenharmony_ci return realHook((AppSpawnMgr *)arg->content, (AppSpawningCtx *)arg->client); 17969570cc8Sopenharmony_ci} 18069570cc8Sopenharmony_ci 18169570cc8Sopenharmony_cistatic void PreAppSpawnHookExec(const HOOK_INFO *hookInfo, void *executionContext) 18269570cc8Sopenharmony_ci{ 18369570cc8Sopenharmony_ci AppSpawnHookArg *arg = (AppSpawnHookArg *)executionContext; 18469570cc8Sopenharmony_ci clock_gettime(CLOCK_MONOTONIC, &arg->tmStart); 18569570cc8Sopenharmony_ci APPSPAWN_LOGV("Hook stage: %{public}d prio: %{public}d start", hookInfo->stage, hookInfo->prio); 18669570cc8Sopenharmony_ci} 18769570cc8Sopenharmony_ci 18869570cc8Sopenharmony_cistatic void PostAppSpawnHookExec(const HOOK_INFO *hookInfo, void *executionContext, int executionRetVal) 18969570cc8Sopenharmony_ci{ 19069570cc8Sopenharmony_ci AppSpawnHookArg *arg = (AppSpawnHookArg *)executionContext; 19169570cc8Sopenharmony_ci clock_gettime(CLOCK_MONOTONIC, &arg->tmEnd); 19269570cc8Sopenharmony_ci uint64_t diff = DiffTime(&arg->tmStart, &arg->tmEnd); 19369570cc8Sopenharmony_ci APPSPAWN_LOGV("Hook stage: %{public}d prio: %{public}d end time %{public}" PRId64 " ns result: %{public}d", 19469570cc8Sopenharmony_ci hookInfo->stage, hookInfo->prio, diff, executionRetVal); 19569570cc8Sopenharmony_ci} 19669570cc8Sopenharmony_ci 19769570cc8Sopenharmony_ciint AppSpawnHookExecute(AppSpawnHookStage stage, uint32_t flags, AppSpawnContent *content, AppSpawnClient *client) 19869570cc8Sopenharmony_ci{ 19969570cc8Sopenharmony_ci APPSPAWN_CHECK(content != NULL && client != NULL, return APPSPAWN_ARG_INVALID, "Invalid arg"); 20069570cc8Sopenharmony_ci APPSPAWN_LOGV("Execute hook [%{public}d] for app: %{public}s", stage, GetProcessName((AppSpawningCtx *)client)); 20169570cc8Sopenharmony_ci APPSPAWN_CHECK((stage >= STAGE_PARENT_PRE_FORK) && (stage <= STAGE_CHILD_PRE_RUN), 20269570cc8Sopenharmony_ci return APPSPAWN_ARG_INVALID, "Invalid stage %{public}d", (int)stage); 20369570cc8Sopenharmony_ci AppSpawnHookArg forkArg; 20469570cc8Sopenharmony_ci forkArg.client = client; 20569570cc8Sopenharmony_ci forkArg.content = content; 20669570cc8Sopenharmony_ci HOOK_EXEC_OPTIONS options; 20769570cc8Sopenharmony_ci options.flags = (int)flags; // TRAVERSE_STOP_WHEN_ERROR : 0; 20869570cc8Sopenharmony_ci options.preHook = PreAppSpawnHookExec; 20969570cc8Sopenharmony_ci options.postHook = PostAppSpawnHookExec; 21069570cc8Sopenharmony_ci int ret = HookMgrExecute(GetAppSpawnHookMgr(), stage, (void *)(&forkArg), &options); 21169570cc8Sopenharmony_ci ret = (ret == ERR_NO_HOOK_STAGE) ? 0 : ret; 21269570cc8Sopenharmony_ci if (ret != 0) { 21369570cc8Sopenharmony_ci APPSPAWN_LOGE("Execute hook [%{public}d] result %{public}d", stage, ret); 21469570cc8Sopenharmony_ci } 21569570cc8Sopenharmony_ci return ret; 21669570cc8Sopenharmony_ci} 21769570cc8Sopenharmony_ci 21869570cc8Sopenharmony_ciint AppSpawnExecuteClearEnvHook(AppSpawnContent *content, AppSpawnClient *client) 21969570cc8Sopenharmony_ci{ 22069570cc8Sopenharmony_ci return AppSpawnHookExecute(STAGE_CHILD_PRE_COLDBOOT, HOOK_STOP_WHEN_ERROR, content, client); 22169570cc8Sopenharmony_ci} 22269570cc8Sopenharmony_ci 22369570cc8Sopenharmony_ciint AppSpawnExecuteSpawningHook(AppSpawnContent *content, AppSpawnClient *client) 22469570cc8Sopenharmony_ci{ 22569570cc8Sopenharmony_ci return AppSpawnHookExecute(STAGE_CHILD_EXECUTE, HOOK_STOP_WHEN_ERROR, content, client); 22669570cc8Sopenharmony_ci} 22769570cc8Sopenharmony_ci 22869570cc8Sopenharmony_ciint AppSpawnExecutePostReplyHook(AppSpawnContent *content, AppSpawnClient *client) 22969570cc8Sopenharmony_ci{ 23069570cc8Sopenharmony_ci return AppSpawnHookExecute(STAGE_CHILD_POST_RELY, HOOK_STOP_WHEN_ERROR, content, client); 23169570cc8Sopenharmony_ci} 23269570cc8Sopenharmony_ci 23369570cc8Sopenharmony_ciint AppSpawnExecutePreReplyHook(AppSpawnContent *content, AppSpawnClient *client) 23469570cc8Sopenharmony_ci{ 23569570cc8Sopenharmony_ci return AppSpawnHookExecute(STAGE_CHILD_PRE_RELY, HOOK_STOP_WHEN_ERROR, content, client); 23669570cc8Sopenharmony_ci} 23769570cc8Sopenharmony_ci 23869570cc8Sopenharmony_civoid AppSpawnEnvClear(AppSpawnContent *content, AppSpawnClient *client) 23969570cc8Sopenharmony_ci{ 24069570cc8Sopenharmony_ci (void)AppSpawnHookExecute(STAGE_CHILD_PRE_RUN, 0, content, client); 24169570cc8Sopenharmony_ci} 24269570cc8Sopenharmony_ci 24369570cc8Sopenharmony_ciint AddAppSpawnHook(AppSpawnHookStage stage, int prio, AppSpawnHook hook) 24469570cc8Sopenharmony_ci{ 24569570cc8Sopenharmony_ci APPSPAWN_CHECK(hook != NULL, return APPSPAWN_ARG_INVALID, "Invalid hook"); 24669570cc8Sopenharmony_ci APPSPAWN_CHECK((stage >= STAGE_PARENT_PRE_FORK) && (stage <= STAGE_CHILD_PRE_RUN), 24769570cc8Sopenharmony_ci return APPSPAWN_ARG_INVALID, "Invalid stage %{public}d", (int)stage); 24869570cc8Sopenharmony_ci HOOK_INFO info; 24969570cc8Sopenharmony_ci info.stage = stage; 25069570cc8Sopenharmony_ci info.prio = prio; 25169570cc8Sopenharmony_ci info.hook = AppSpawnHookRun; 25269570cc8Sopenharmony_ci info.hookCookie = (void *)hook; 25369570cc8Sopenharmony_ci APPSPAWN_LOGI("AddAppSpawnHook stage: %{public}d prio: %{public}d", stage, prio); 25469570cc8Sopenharmony_ci return HookMgrAddEx(GetAppSpawnHookMgr(), &info); 25569570cc8Sopenharmony_ci} 25669570cc8Sopenharmony_ci 25769570cc8Sopenharmony_ciint ProcessMgrHookExecute(AppSpawnHookStage stage, const AppSpawnContent *content, 25869570cc8Sopenharmony_ci const AppSpawnedProcessInfo *appInfo) 25969570cc8Sopenharmony_ci{ 26069570cc8Sopenharmony_ci APPSPAWN_CHECK(content != NULL && appInfo != NULL, 26169570cc8Sopenharmony_ci return APPSPAWN_ARG_INVALID, "Invalid hook"); 26269570cc8Sopenharmony_ci APPSPAWN_CHECK((stage >= STAGE_SERVER_APP_ADD) && (stage <= STAGE_SERVER_APP_DIED), 26369570cc8Sopenharmony_ci return APPSPAWN_ARG_INVALID, "Invalid stage %{public}d", (int)stage); 26469570cc8Sopenharmony_ci 26569570cc8Sopenharmony_ci AppSpawnAppArg arg; 26669570cc8Sopenharmony_ci arg.appInfo = appInfo; 26769570cc8Sopenharmony_ci arg.content = content; 26869570cc8Sopenharmony_ci int ret = HookMgrExecute(GetAppSpawnHookMgr(), stage, (void *)(&arg), NULL); 26969570cc8Sopenharmony_ci return ret == ERR_NO_HOOK_STAGE ? 0 : ret; 27069570cc8Sopenharmony_ci} 27169570cc8Sopenharmony_ci 27269570cc8Sopenharmony_cistatic int ProcessMgrHookRun(const HOOK_INFO *hookInfo, void *executionContext) 27369570cc8Sopenharmony_ci{ 27469570cc8Sopenharmony_ci AppSpawnAppArg *arg = (AppSpawnAppArg *)executionContext; 27569570cc8Sopenharmony_ci ProcessChangeHook realHook = (ProcessChangeHook)hookInfo->hookCookie; 27669570cc8Sopenharmony_ci return realHook((AppSpawnMgr *)arg->content, arg->appInfo); 27769570cc8Sopenharmony_ci} 27869570cc8Sopenharmony_ci 27969570cc8Sopenharmony_ciint AddProcessMgrHook(AppSpawnHookStage stage, int prio, ProcessChangeHook hook) 28069570cc8Sopenharmony_ci{ 28169570cc8Sopenharmony_ci APPSPAWN_CHECK(hook != NULL, return APPSPAWN_ARG_INVALID, "Invalid hook"); 28269570cc8Sopenharmony_ci APPSPAWN_CHECK((stage >= STAGE_SERVER_APP_ADD) && (stage <= STAGE_SERVER_APP_DIED), 28369570cc8Sopenharmony_ci return APPSPAWN_ARG_INVALID, "Invalid stage %{public}d", (int)stage); 28469570cc8Sopenharmony_ci HOOK_INFO info; 28569570cc8Sopenharmony_ci info.stage = stage; 28669570cc8Sopenharmony_ci info.prio = prio; 28769570cc8Sopenharmony_ci info.hook = ProcessMgrHookRun; 28869570cc8Sopenharmony_ci info.hookCookie = hook; 28969570cc8Sopenharmony_ci return HookMgrAddEx(GetAppSpawnHookMgr(), &info); 29069570cc8Sopenharmony_ci} 29169570cc8Sopenharmony_ci 29269570cc8Sopenharmony_civoid RegChildLooper(struct AppSpawnContent *content, ChildLoop loop) 29369570cc8Sopenharmony_ci{ 29469570cc8Sopenharmony_ci APPSPAWN_CHECK(content != NULL && loop != NULL, return, "Invalid content for RegChildLooper"); 29569570cc8Sopenharmony_ci content->runChildProcessor = loop; 29669570cc8Sopenharmony_ci} 297