* 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 <unordered_set>
#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<std::string, std::string> &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<std::string> 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<AppFlagsIndex>(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
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
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<AppSpawnMsgType>(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;
}
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_LOGD(AAFwkTag::APPMGR, "call");
int32_t ret = 0;
AppSpawnReqMsgHandle reqHandle = nullptr;
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_LOGD(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
int32_t AppSpawnClient::SetExtMsgFds(const AppSpawnReqMsgHandle &reqHandle,
const std::map<std::string, int32_t> &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;
}
}
}