/* * Copyright (c) 2021-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "app_spawn_client.h" #include #include "ability_manager_errors.h" #include "hitrace_meter.h" #include "hilog_tag_wrapper.h" #include "nlohmann/json.hpp" #include "securec.h" #include "time_util.h" namespace OHOS { namespace AppExecFwk { using namespace OHOS::AbilityRuntime; namespace { constexpr const char* HSPLIST_BUNDLES = "bundles"; constexpr const char* HSPLIST_MODULES = "modules"; constexpr const char* HSPLIST_VERSIONS = "versions"; constexpr const char* DATAGROUPINFOLIST_DATAGROUPID = "dataGroupId"; constexpr const char* DATAGROUPINFOLIST_GID = "gid"; constexpr const char* DATAGROUPINFOLIST_UUID = "uuid"; constexpr const char* DATAGROUPINFOLIST_DIR = "dir"; constexpr const char* JSON_DATA_APP_DIR_EL2 = "/data/app/el2/"; constexpr const char* JSON_DATA_APP_DIR_EL3 = "/data/app/el3/"; constexpr const char* JSON_DATA_APP_DIR_EL4 = "/data/app/el4/"; constexpr const char* JSON_DATA_APP_DIR_EL5 = "/data/app/el5/"; constexpr const char* JSON_GROUP = "/group/"; constexpr const char* VERSION_PREFIX = "v"; constexpr const char* APPSPAWN_CLIENT_USER_NAME = "APP_MANAGER_SERVICE"; constexpr int32_t RIGHT_SHIFT_STEP = 1; constexpr int32_t START_FLAG_TEST_NUM = 1; constexpr const char* JITPERMISSIONSLIST_NAME = "name"; constexpr const char* JITPERMISSIONSLIST_NAME_VALUE = "Permissions"; constexpr const char* JITPERMISSIONSLIST_COUNT = "ohos.encaps.count"; constexpr const char* JITPERMISSIONSLIST_PERMISSIONS_NAME = "permissions"; constexpr const char* UNINSTALL_BUNDLE_NAME = "uninstallDebugHapMsg"; } AppSpawnClient::AppSpawnClient(bool isNWebSpawn) { TAG_LOGD(AAFwkTag::APPMGR, "call"); if (isNWebSpawn) { serviceName_ = NWEBSPAWN_SERVER_NAME; } state_ = SpawnConnectionState::STATE_NOT_CONNECT; } AppSpawnClient::AppSpawnClient(const char* serviceName) { TAG_LOGD(AAFwkTag::APPMGR, "call"); std::string serviceName__ = serviceName; if (serviceName__ == APPSPAWN_SERVER_NAME) { serviceName_ = APPSPAWN_SERVER_NAME; } else if (serviceName__ == CJAPPSPAWN_SERVER_NAME) { serviceName_ = CJAPPSPAWN_SERVER_NAME; } else if (serviceName__ == NWEBSPAWN_SERVER_NAME) { serviceName_ = NWEBSPAWN_SERVER_NAME; } else if (serviceName__ == NATIVESPAWN_SERVER_NAME) { serviceName_ = NATIVESPAWN_SERVER_NAME; } else if (serviceName__ == HYBRIDSPAWN_SERVER_NAME) { serviceName_ = HYBRIDSPAWN_SERVER_NAME; } else { TAG_LOGE(AAFwkTag::APPMGR, "unknown service name"); serviceName_ = NWEBSPAWN_SERVER_NAME; } state_ = SpawnConnectionState::STATE_NOT_CONNECT; } AppSpawnClient::~AppSpawnClient() { CloseConnection(); } ErrCode AppSpawnClient::OpenConnection() { HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__); if (state_ == SpawnConnectionState::STATE_CONNECTED) { return 0; } TAG_LOGI(AAFwkTag::APPMGR, "call"); int64_t startTime = AbilityRuntime::TimeUtil::SystemTimeMillisecond(); AppSpawnClientHandle handle = nullptr; ErrCode ret = 0; ret = AppSpawnClientInit(serviceName_.c_str(), &handle); int64_t costTime = AbilityRuntime::TimeUtil::SystemTimeMillisecond() - startTime; if (costTime > MAX_COST_TIME) { TAG_LOGE(AAFwkTag::APPMGR, "appspawnclientInit cost %{public}" PRId64 "ms!", costTime); } if (FAILED(ret)) { TAG_LOGE(AAFwkTag::APPMGR, "appspawnclientInit failed"); state_ = SpawnConnectionState::STATE_CONNECT_FAILED; return ret; } handle_ = handle; state_ = SpawnConnectionState::STATE_CONNECTED; return ret; } void AppSpawnClient::CloseConnection() { TAG_LOGD(AAFwkTag::APPMGR, "call"); if (state_ == SpawnConnectionState::STATE_CONNECTED) { AppSpawnClientDestroy(handle_); } state_ = SpawnConnectionState::STATE_NOT_CONNECT; } SpawnConnectionState AppSpawnClient::QueryConnectionState() const { return state_; } AppSpawnClientHandle AppSpawnClient::GetAppSpawnClientHandle() const { if (state_ == SpawnConnectionState::STATE_CONNECTED) { return handle_; } return nullptr; } static std::string DumpDataGroupInfoListToJson(const DataGroupInfoList &dataGroupInfoList, bool isScreenLockDataProtect) { TAG_LOGD(AAFwkTag::APPMGR, "dataGroupInfoList size: %{public}zu", dataGroupInfoList.size()); nlohmann::json dataGroupInfoListJson; for (auto& dataGroupInfo : dataGroupInfoList) { nlohmann::json dataGroupInfoJson; dataGroupInfoJson[DATAGROUPINFOLIST_DATAGROUPID] = dataGroupInfo.dataGroupId; dataGroupInfoJson[DATAGROUPINFOLIST_GID] = std::to_string(dataGroupInfo.gid); dataGroupInfoJson[DATAGROUPINFOLIST_UUID] = dataGroupInfo.uuid; std::string dir = std::to_string(dataGroupInfo.userId) + JSON_GROUP + dataGroupInfo.uuid; dataGroupInfoJson[DATAGROUPINFOLIST_DIR] = JSON_DATA_APP_DIR_EL2 + dir; dataGroupInfoListJson.emplace_back(dataGroupInfoJson); dataGroupInfoJson[DATAGROUPINFOLIST_DIR] = JSON_DATA_APP_DIR_EL3 + dir; dataGroupInfoListJson.emplace_back(dataGroupInfoJson); dataGroupInfoJson[DATAGROUPINFOLIST_DIR] = JSON_DATA_APP_DIR_EL4 + dir; dataGroupInfoListJson.emplace_back(dataGroupInfoJson); if (isScreenLockDataProtect) { dataGroupInfoJson[DATAGROUPINFOLIST_DIR] = JSON_DATA_APP_DIR_EL5 + dir; dataGroupInfoListJson.emplace_back(dataGroupInfoJson); } } TAG_LOGD(AAFwkTag::APPMGR, "dataGroupInfoListJson %{public}s", dataGroupInfoListJson.dump().c_str()); return dataGroupInfoListJson.dump(); } static std::string DumpHspListToJson(const HspList &hspList) { nlohmann::json hspListJson; for (auto& hsp : hspList) { hspListJson[HSPLIST_BUNDLES].emplace_back(hsp.bundleName); hspListJson[HSPLIST_MODULES].emplace_back(hsp.moduleName); hspListJson[HSPLIST_VERSIONS].emplace_back(VERSION_PREFIX + std::to_string(hsp.versionCode)); } return hspListJson.dump(); } static std::string DumpAppEnvToJson(const std::map &appEnv) { nlohmann::json appEnvJson; for (const auto &[envName, envValue] : appEnv) { appEnvJson[envName] = envValue; } return appEnvJson.dump(); } static std::string DumpJITPermissionListToJson(const JITPermissionsMap &jitPermissionsMap) { nlohmann::json jitPermissionsListJson; jitPermissionsListJson[JITPERMISSIONSLIST_NAME] = JITPERMISSIONSLIST_NAME_VALUE; jitPermissionsListJson[JITPERMISSIONSLIST_COUNT] = jitPermissionsMap.size(); for (const auto &[permissionName, permissionValue] : jitPermissionsMap) { nlohmann::json temp; if (permissionValue.empty()) { temp[permissionName] = true; } else { temp[permissionName] = permissionValue; } jitPermissionsListJson[JITPERMISSIONSLIST_PERMISSIONS_NAME].emplace_back(temp); } return jitPermissionsListJson.dump(); } int32_t AppSpawnClient::SetDacInfo(const AppSpawnStartMsg &startMsg, AppSpawnReqMsgHandle reqHandle) { int32_t ret = 0; AppDacInfo appDacInfo = {0}; appDacInfo.uid = startMsg.uid; appDacInfo.gid = startMsg.gid; appDacInfo.gidCount = startMsg.gids.size() + startMsg.dataGroupInfoList.size(); for (uint32_t i = 0; i < startMsg.gids.size(); i++) { appDacInfo.gidTable[i] = startMsg.gids[i]; } for (uint32_t i = startMsg.gids.size(); i < appDacInfo.gidCount; i++) { appDacInfo.gidTable[i] = startMsg.dataGroupInfoList[i - startMsg.gids.size()].gid; } ret = strcpy_s(appDacInfo.userName, sizeof(appDacInfo.userName), APPSPAWN_CLIENT_USER_NAME); if (ret) { TAG_LOGE(AAFwkTag::APPMGR, "set dac userName fail"); return ret; } return AppSpawnReqMsgSetAppDacInfo(reqHandle, &appDacInfo); } int32_t AppSpawnClient::SetMountPermission(const AppSpawnStartMsg &startMsg, AppSpawnReqMsgHandle reqHandle) { int32_t ret = 0; std::set mountPermissionList = startMsg.permissions; for (std::string permission : mountPermissionList) { ret = AppSpawnClientAddPermission(handle_, reqHandle, permission.c_str()); if (ret != 0) { TAG_LOGE(AAFwkTag::APPMGR, "AppSpawnReqMsgAddPermission %{public}s failed", permission.c_str()); return ret; } } return ret; } int32_t AppSpawnClient::SetStartFlags(const AppSpawnStartMsg &startMsg, AppSpawnReqMsgHandle reqHandle) { int32_t ret = 0; uint32_t startFlagTmp = startMsg.flags; int flagIndex = 0; while (startFlagTmp > 0) { if (startFlagTmp & START_FLAG_TEST_NUM) { ret = AppSpawnReqMsgSetAppFlag(reqHandle, static_cast(flagIndex)); if (ret != 0) { TAG_LOGE(AAFwkTag::APPMGR, "SetFlagIdx %{public}d failed, ret: %{public}d", flagIndex, ret); return ret; } } startFlagTmp = startFlagTmp >> RIGHT_SHIFT_STEP; flagIndex++; } if (startMsg.atomicServiceFlag) { ret = AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_ATOMIC_SERVICE); if (ret != 0) { TAG_LOGE(AAFwkTag::APPMGR, "fail, ret: %{public}d", ret); return ret; } } if (startMsg.strictMode) { ret = SetStrictMode(startMsg, reqHandle); if (ret != ERR_OK) { return ret; } } if (startMsg.isolatedExtension) { ret = AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_EXTENSION_SANDBOX); if (ret != 0) { TAG_LOGE(AAFwkTag::APPMGR, "fail, ret: %{public}d", ret); return ret; } } if (startMsg.flags & APP_FLAGS_CLONE_ENABLE) { ret = AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_CLONE_ENABLE); if (ret != 0) { TAG_LOGE(AAFwkTag::APPMGR, "fail, ret: %{public}d", ret); return ret; } } if (startMsg.isCustomSandboxFlag) { ret = AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_CUSTOM_SANDBOX); if (ret != 0) { TAG_LOGE(AAFwkTag::APPMGR, "fail, ret: %{public}d", ret); return ret; } TAG_LOGD(AAFwkTag::APPMGR, "Set APP_FLAGS_CUSTOM_SANDBOX flag success."); } #ifdef SUPPORT_CHILD_PROCESS ret = SetChildProcessTypeStartFlag(reqHandle, startMsg.childProcessType); if (ret != ERR_OK) { TAG_LOGE(AAFwkTag::APPMGR, "fail, ret: %{public}d", ret); return ret; } #endif // SUPPORT_CHILD_PROCESS ret = SetIsolationModeFlag(startMsg, reqHandle); return ret; } int32_t AppSpawnClient::SetStrictMode(const AppSpawnStartMsg &startMsg, const AppSpawnReqMsgHandle &reqHandle) { int32_t ret = ERR_OK; TAG_LOGD(AAFwkTag::APPMGR, "SetStrictMode"); if (startMsg.isolatedSandboxFlagLegacy) { TAG_LOGD(AAFwkTag::APPMGR, "SetIsolatedSandBoxLegacy"); ret = AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_ISOLATED_SANDBOX); if (ret != 0) { TAG_LOGE(AAFwkTag::APPMGR, "SetIsolatedSandBoxLegacy fail, ret: %{public}d", ret); return ret; } } if (startMsg.isolatedNetworkFlag) { TAG_LOGD(AAFwkTag::APPMGR, "Set isolatedNetwork"); ret = AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_ISOLATED_NETWORK); if (ret != 0) { TAG_LOGE(AAFwkTag::APPMGR, "Set isolatedNetwork fail, ret: %{public}d", ret); return ret; } } if (startMsg.isolatedSELinuxFlag) { TAG_LOGD(AAFwkTag::APPMGR, "Set isolatedSELinux,extType:%{public}s", startMsg.extensionTypeName.c_str()); ret = AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_ISOLATED_SELINUX_LABEL); if (ret != 0) { TAG_LOGE(AAFwkTag::APPMGR, "Set isolatedSELinuxFlag fail, ret: %{public}d", ret); return ret; } } if (startMsg.isolatedNetworkFlag || startMsg.isolatedSELinuxFlag) { ret = AppSpawnReqMsgAddStringInfo(reqHandle, MSG_EXT_NAME_EXTENSION_TYPE, startMsg.extensionTypeName.c_str()); if (ret != 0) { TAG_LOGE(AAFwkTag::APPMGR, "Set extensionTypeName fail, ret: %{public}d", ret); return ret; } } return ERR_OK; } int32_t AppSpawnClient::AppspawnSetExtMsg(const AppSpawnStartMsg &startMsg, AppSpawnReqMsgHandle reqHandle) { int32_t ret = 0; ret = AppSpawnReqMsgAddStringInfo(reqHandle, MSG_EXT_NAME_RENDER_CMD, startMsg.renderParam.c_str()); if (ret) { TAG_LOGE(AAFwkTag::APPMGR, "fail, ret: %{public}d", ret); return ret; } if (!startMsg.hspList.empty()) { ret = AppSpawnReqMsgAddStringInfo(reqHandle, MSG_EXT_NAME_HSP_LIST, DumpHspListToJson(startMsg.hspList).c_str()); if (ret) { TAG_LOGE(AAFwkTag::APPMGR, "fail, ret: %{public}d", ret); return ret; } } if (!startMsg.dataGroupInfoList.empty()) { ret = AppSpawnReqMsgAddStringInfo(reqHandle, MSG_EXT_NAME_DATA_GROUP, DumpDataGroupInfoListToJson(startMsg.dataGroupInfoList, startMsg.isScreenLockDataProtect).c_str()); if (ret) { TAG_LOGE(AAFwkTag::APPMGR, "fail, ret: %{public}d", ret); return ret; } } if (!startMsg.overlayInfo.empty()) { ret = AppSpawnReqMsgAddStringInfo(reqHandle, MSG_EXT_NAME_OVERLAY, startMsg.overlayInfo.c_str()); if (ret) { TAG_LOGE(AAFwkTag::APPMGR, "fail, ret: %{public}d", ret); return ret; } } if (!startMsg.appEnv.empty()) { std::string appEnv = DumpAppEnvToJson(startMsg.appEnv); TAG_LOGD(AAFwkTag::APPMGR, "bundleName: %{public}s, appEnv: %{public}s", startMsg.bundleName.c_str(), appEnv.c_str()); ret = AppSpawnReqMsgAddStringInfo(reqHandle, MSG_EXT_NAME_APP_ENV, appEnv.c_str()); if (ret) { TAG_LOGE(AAFwkTag::APPMGR, "fail, ret: %{public}d", ret); return ret; } } if (!startMsg.atomicAccount.empty()) { ret = AppSpawnReqMsgAddStringInfo(reqHandle, MSG_EXT_NAME_ACCOUNT_ID, startMsg.atomicAccount.c_str()); if (ret) { TAG_LOGE(AAFwkTag::APPMGR, "fail, ret: %{public}d", ret); return ret; } } std::string apiTargetVersionStr = std::to_string(startMsg.apiTargetVersion); ret = AppSpawnReqMsgAddStringInfo(reqHandle, MSG_EXT_NAME_API_TARGET_VERSION, apiTargetVersionStr.c_str()); if (ret) { TAG_LOGE(AAFwkTag::APPMGR, "Send apiTargetVersion fail, ret: %{public}d", ret); return ret; } return AppspawnSetExtMsgMore(startMsg, reqHandle); } int32_t AppSpawnClient::AppspawnSetExtMsgMore(const AppSpawnStartMsg &startMsg, AppSpawnReqMsgHandle reqHandle) { int32_t ret = 0; if (!startMsg.provisionType.empty()) { ret = AppSpawnReqMsgAddStringInfo(reqHandle, MSG_EXT_NAME_PROVISION_TYPE, startMsg.provisionType.c_str()); if (ret) { TAG_LOGE(AAFwkTag::APPMGR, "fail, ret: %{public}d", ret); return ret; } } if (!startMsg.processType.empty()) { ret = AppSpawnReqMsgAddStringInfo(reqHandle, MSG_EXT_NAME_PROCESS_TYPE, startMsg.processType.c_str()); if (ret) { TAG_LOGE(AAFwkTag::APPMGR, "fail, ret: %{public}d", ret); return ret; } } #ifdef SUPPORT_CHILD_PROCESS std::string maxChildProcessStr = std::to_string(startMsg.maxChildProcess); ret = AppSpawnReqMsgAddStringInfo(reqHandle, MSG_EXT_NAME_MAX_CHILD_PROCCESS_MAX, maxChildProcessStr.c_str()); if (ret) { TAG_LOGE(AAFwkTag::APPMGR, "fail, ret: %{public}d", ret); return ret; } TAG_LOGD(AAFwkTag::APPMGR, "Send maxChildProcess %{public}s success", maxChildProcessStr.c_str()); #endif // SUPPORT_CHILD_PROCESS if (!startMsg.extensionSandboxPath.empty()) { ret = AppSpawnReqMsgAddStringInfo(reqHandle, MSG_EXT_NAME_APP_EXTENSION, startMsg.extensionSandboxPath.c_str()); if (ret) { TAG_LOGE(AAFwkTag::APPMGR, "fail, ret: %{public}d", ret); return ret; } } if (!startMsg.fds.empty()) { ret = SetExtMsgFds(reqHandle, startMsg.fds); if (ret != ERR_OK) { TAG_LOGE(AAFwkTag::APPMGR, "fail, ret: %{public}d", ret); return ret; } } if (!startMsg.jitPermissionsMap.empty()) { std::string jitPermissionsStr = DumpJITPermissionListToJson(startMsg.jitPermissionsMap); ret = AppSpawnReqMsgAddStringInfo(reqHandle, MSG_EXT_NAME_JIT_PERMISSIONS, jitPermissionsStr.c_str()); if (ret) { TAG_LOGE(AAFwkTag::APPMGR, "fail, ret: %{public}d", ret); return ret; } TAG_LOGD(AAFwkTag::APPMGR, "Send JIT Permission: %{public}s", jitPermissionsStr.c_str()); } return AppspawnSetExtMsgSec(startMsg, reqHandle); } int32_t AppSpawnClient::AppspawnSetExtMsgSec(const AppSpawnStartMsg &startMsg, AppSpawnReqMsgHandle reqHandle) { int32_t ret = 0; if (startMsg.hostProcessUid != 0) { ret = AppSpawnReqMsgAddStringInfo(reqHandle, MSG_EXT_NAME_PARENT_UID, std::to_string(startMsg.hostProcessUid).c_str()); if (ret) { TAG_LOGE(AAFwkTag::APPMGR, "fail, ret: %{public}d", ret); return ret; } } return ret; } int32_t AppSpawnClient::AppspawnCreateDefaultMsg(const AppSpawnStartMsg &startMsg, AppSpawnReqMsgHandle reqHandle) { TAG_LOGD(AAFwkTag::APPMGR, "call"); int32_t ret = 0; do { ret = SetDacInfo(startMsg, reqHandle); if (ret) { TAG_LOGE(AAFwkTag::APPMGR, "fail, ret: %{public}d", ret); break; } ret = AppSpawnReqMsgSetBundleInfo(reqHandle, startMsg.bundleIndex, startMsg.bundleName.c_str()); if (ret) { TAG_LOGE(AAFwkTag::APPMGR, "fail, ret: %{public}d", ret); break; } ret = AppSpawnReqMsgSetAppInternetPermissionInfo(reqHandle, startMsg.allowInternet, startMsg.setAllowInternet); if (ret) { TAG_LOGE(AAFwkTag::APPMGR, "fail, ret: %{public}d", ret); break; } if (startMsg.ownerId.size()) { ret = AppSpawnReqMsgSetAppOwnerId(reqHandle, startMsg.ownerId.c_str()); if (ret) { TAG_LOGE(AAFwkTag::APPMGR, "SetOwnerId %{public}s failed, ret: %{public}d", startMsg.ownerId.c_str(), ret); break; } } ret = AppSpawnReqMsgSetAppAccessToken(reqHandle, startMsg.accessTokenIdEx); if (ret) { TAG_LOGE(AAFwkTag::APPMGR, "ret: %{public}d", ret); break; } ret = AppSpawnReqMsgSetAppDomainInfo(reqHandle, startMsg.hapFlags, startMsg.apl.c_str()); if (ret) { TAG_LOGE(AAFwkTag::APPMGR, "fail, hapFlags is %{public}d, apl is %{public}s, ret: %{public}d", startMsg.hapFlags, startMsg.apl.c_str(), ret); break; } ret = SetStartFlags(startMsg, reqHandle); if (ret) { TAG_LOGE(AAFwkTag::APPMGR, "fail, ret: %{public}d", ret); break; } ret = SetMountPermission(startMsg, reqHandle); if (ret) { TAG_LOGE(AAFwkTag::APPMGR, "fail, ret: %{public}d", ret); break; } if (AppspawnSetExtMsg(startMsg, reqHandle)) { break; } return ret; } while (0); TAG_LOGI(AAFwkTag::APPMGR, "AppSpawnReqMsgFree"); AppSpawnReqMsgFree(reqHandle); return ret; } bool AppSpawnClient::VerifyMsg(const AppSpawnStartMsg &startMsg) { TAG_LOGD(AAFwkTag::APPMGR, "VerifyMsg"); if (startMsg.code == MSG_APP_SPAWN || startMsg.code == MSG_SPAWN_NATIVE_PROCESS) { if (startMsg.uid < 0) { TAG_LOGE(AAFwkTag::APPMGR, "invalid uid! [%{public}d]", startMsg.uid); return false; } if (startMsg.gid < 0) { TAG_LOGE(AAFwkTag::APPMGR, "invalid gid! [%{public}d]", startMsg.gid); return false; } if (startMsg.gids.size() > APP_MAX_GIDS) { TAG_LOGE(AAFwkTag::APPMGR, "many app gids"); return false; } for (uint32_t i = 0; i < startMsg.gids.size(); ++i) { if (startMsg.gids[i] < 0) { TAG_LOGE(AAFwkTag::APPMGR, "invalid gids array! [%{public}d]", startMsg.gids[i]); return false; } } if (startMsg.procName.empty() || startMsg.procName.size() >= MAX_PROC_NAME_LEN) { TAG_LOGE(AAFwkTag::APPMGR, "invalid procName"); return false; } } else if (startMsg.code == MSG_GET_RENDER_TERMINATION_STATUS) { if (startMsg.pid < 0) { TAG_LOGE(AAFwkTag::APPMGR, "invalid pid"); return false; } } else { TAG_LOGE(AAFwkTag::APPMGR, "invalid code"); return false; } return true; } int32_t AppSpawnClient::PreStartNWebSpawnProcess() { TAG_LOGI(AAFwkTag::APPMGR, "call"); return OpenConnection(); } int32_t AppSpawnClient::StartProcess(const AppSpawnStartMsg &startMsg, pid_t &pid) { TAG_LOGD(AAFwkTag::APPMGR, "StartProcess"); HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__); if (!VerifyMsg(startMsg)) { return ERR_INVALID_VALUE; } int32_t ret = 0; AppSpawnReqMsgHandle reqHandle = nullptr; int64_t startTime = AbilityRuntime::TimeUtil::SystemTimeMillisecond(); ret = OpenConnection(); if (ret != 0) { TAG_LOGE(AAFwkTag::APPMGR, "OpenConnection fail"); return ret; } ret = AppSpawnReqMsgCreate(static_cast(startMsg.code), startMsg.procName.c_str(), &reqHandle); if (ret != 0) { TAG_LOGE(AAFwkTag::APPMGR, "AppSpawnReqMsgCreate fail"); return ret; } ret = AppspawnCreateDefaultMsg(startMsg, reqHandle); if (ret != 0) { TAG_LOGE(AAFwkTag::APPMGR, "AppspawnCreateDefaultMsg fail"); return ret; // create msg failed } TAG_LOGD(AAFwkTag::APPMGR, "AppspawnSendMsg"); AppSpawnResult result = {0}; ret = AppSpawnClientSendMsg(handle_, reqHandle, &result); int64_t costTime = AbilityRuntime::TimeUtil::SystemTimeMillisecond() - startTime; if (costTime > MAX_COST_TIME) { TAG_LOGE(AAFwkTag::APPMGR, "StartProcess cost %{public}" PRId64 "ms!", costTime); } if (ret != 0) { TAG_LOGE(AAFwkTag::APPMGR, "appspawn send msg fail"); return ret; } if (result.pid <= 0) { TAG_LOGE(AAFwkTag::APPMGR, "pid invalid, result is %{public}d", result.result); return AAFwk::ERR_PROCESS_START_INVALID_PID; } else { pid = result.pid; } TAG_LOGI(AAFwkTag::APPMGR, "pid = [%{public}d]", pid); return result.result; } int32_t AppSpawnClient::SendAppSpawnUninstallDebugHapMsg(int32_t userId) { HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__); AppSpawnReqMsgHandle reqHandle = nullptr; int32_t ret = OpenConnection(); if (ret != ERR_OK) { TAG_LOGE(AAFwkTag::APPMGR, "OpenConnection failed"); return ret; } ret = AppSpawnReqMsgCreate(MSG_UNINSTALL_DEBUG_HAP, UNINSTALL_BUNDLE_NAME, &reqHandle); if (ret != ERR_OK) { TAG_LOGE(AAFwkTag::APPMGR, "AppSpawnReqMsgCreate failed"); return ret; } auto msg = std::to_string(userId); ret = AppSpawnReqMsgAddStringInfo(reqHandle, MSG_EXT_NAME_USERID, msg.c_str()); if (ret != ERR_OK) { AppSpawnReqMsgFree(reqHandle); TAG_LOGE(AAFwkTag::APPMGR, "AppSpawnReqMsgAddStringInfo failed"); return ret; } AppSpawnResult result = { 0 }; ret = AppSpawnClientSendMsg(handle_, reqHandle, &result); if (ret != ERR_OK) { TAG_LOGE(AAFwkTag::APPMGR, "AppSpawnClientSendMsg failed"); return ret; } return ret; } int32_t AppSpawnClient::GetRenderProcessTerminationStatus(const AppSpawnStartMsg &startMsg, int &status) { TAG_LOGI(AAFwkTag::APPMGR, "call"); int32_t ret = 0; AppSpawnReqMsgHandle reqHandle = nullptr; // check parameters if (!VerifyMsg(startMsg)) { return ERR_INVALID_VALUE; } ret = OpenConnection(); if (ret != 0) { return ret; } ret = AppSpawnTerminateMsgCreate(startMsg.pid, &reqHandle); if (ret != 0) { TAG_LOGE(AAFwkTag::APPMGR, "AppSpawnTerminateMsgCreate failed"); return ret; } TAG_LOGI(AAFwkTag::APPMGR, "AppspawnSendMsg"); AppSpawnResult result = {0}; ret = AppSpawnClientSendMsg(handle_, reqHandle, &result); status = result.result; if (ret != 0) { TAG_LOGE(AAFwkTag::APPMGR, "appspawn send msg fail"); return ret; } TAG_LOGI(AAFwkTag::APPMGR, "status = [%{public}d]", status); return ret; } #ifdef SUPPORT_CHILD_PROCESS int32_t AppSpawnClient::SetChildProcessTypeStartFlag(const AppSpawnReqMsgHandle &reqHandle, int32_t childProcessType) { TAG_LOGD(AAFwkTag::APPMGR, "SetChildProcessTypeStartFlag, type:%{public}d", childProcessType); if (childProcessType != CHILD_PROCESS_TYPE_NOT_CHILD) { return AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_CHILDPROCESS); } return ERR_OK; } #endif // SUPPORT_CHILD_PROCESS int32_t AppSpawnClient::SetExtMsgFds(const AppSpawnReqMsgHandle &reqHandle, const std::map &fds) { TAG_LOGI(AAFwkTag::APPMGR, "size:%{public}zu", fds.size()); int32_t ret = ERR_OK; for (const auto &item : fds) { ret = AppSpawnReqMsgAddFd(reqHandle, item.first.c_str(), item.second); if (ret != ERR_OK) { TAG_LOGE(AAFwkTag::APPMGR, "fail, key:%{public}s, fd:%{public}d, ret:%{public}d", item.first.c_str(), item.second, ret); return ret; } } return ERR_OK; } int32_t AppSpawnClient::SetIsolationModeFlag(const AppSpawnStartMsg &startMsg, const AppSpawnReqMsgHandle &reqHandle) { TAG_LOGD(AAFwkTag::APPMGR, "isolationMode:%{public}d", startMsg.isolationMode); if (!startMsg.isolationMode) { return ERR_OK; } auto ret = AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_ISOLATED_SANDBOX_TYPE); if (ret != 0) { TAG_LOGE(AAFwkTag::APPMGR, "fail, ret: %{public}d", ret); return ret; } ret = AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_ISOLATED_NETWORK); if (ret != 0) { TAG_LOGE(AAFwkTag::APPMGR, "fail, ret: %{public}d", ret); return ret; } return ERR_OK; } } // namespace AppExecFwk } // namespace OHOS