1eace7efcSopenharmony_ci/*
2eace7efcSopenharmony_ci * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
3eace7efcSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4eace7efcSopenharmony_ci * you may not use this file except in compliance with the License.
5eace7efcSopenharmony_ci * You may obtain a copy of the License at
6eace7efcSopenharmony_ci *
7eace7efcSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8eace7efcSopenharmony_ci *
9eace7efcSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10eace7efcSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11eace7efcSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12eace7efcSopenharmony_ci * See the License for the specific language governing permissions and
13eace7efcSopenharmony_ci * limitations under the License.
14eace7efcSopenharmony_ci */
15eace7efcSopenharmony_ci#include "app_spawn_client.h"
16eace7efcSopenharmony_ci
17eace7efcSopenharmony_ci#include <unordered_set>
18eace7efcSopenharmony_ci
19eace7efcSopenharmony_ci#include "hitrace_meter.h"
20eace7efcSopenharmony_ci#include "hilog_tag_wrapper.h"
21eace7efcSopenharmony_ci#include "nlohmann/json.hpp"
22eace7efcSopenharmony_ci#include "securec.h"
23eace7efcSopenharmony_ci#include "time_util.h"
24eace7efcSopenharmony_ci
25eace7efcSopenharmony_cinamespace OHOS {
26eace7efcSopenharmony_cinamespace AppExecFwk {
27eace7efcSopenharmony_ciusing namespace OHOS::AbilityRuntime;
28eace7efcSopenharmony_cinamespace {
29eace7efcSopenharmony_ciconstexpr const char* HSPLIST_BUNDLES = "bundles";
30eace7efcSopenharmony_ciconstexpr const char* HSPLIST_MODULES = "modules";
31eace7efcSopenharmony_ciconstexpr const char* HSPLIST_VERSIONS = "versions";
32eace7efcSopenharmony_ciconstexpr const char* DATAGROUPINFOLIST_DATAGROUPID = "dataGroupId";
33eace7efcSopenharmony_ciconstexpr const char* DATAGROUPINFOLIST_GID = "gid";
34eace7efcSopenharmony_ciconstexpr const char* DATAGROUPINFOLIST_DIR = "dir";
35eace7efcSopenharmony_ciconstexpr const char* JSON_DATA_APP = "/data/app/el2/";
36eace7efcSopenharmony_ciconstexpr const char* JSON_GROUP = "/group/";
37eace7efcSopenharmony_ciconstexpr const char* VERSION_PREFIX = "v";
38eace7efcSopenharmony_ciconstexpr const char* APPSPAWN_CLIENT_USER_NAME = "APP_MANAGER_SERVICE";
39eace7efcSopenharmony_ciconstexpr int32_t RIGHT_SHIFT_STEP = 1;
40eace7efcSopenharmony_ciconstexpr int32_t START_FLAG_TEST_NUM = 1;
41eace7efcSopenharmony_ci}
42eace7efcSopenharmony_ciAppSpawnClient::AppSpawnClient(bool isNWebSpawn)
43eace7efcSopenharmony_ci{
44eace7efcSopenharmony_ci    TAG_LOGD(AAFwkTag::APPMGR, "call");
45eace7efcSopenharmony_ci    if (isNWebSpawn) {
46eace7efcSopenharmony_ci        serviceName_ = NWEBSPAWN_SERVER_NAME;
47eace7efcSopenharmony_ci    }
48eace7efcSopenharmony_ci    state_ = SpawnConnectionState::STATE_NOT_CONNECT;
49eace7efcSopenharmony_ci}
50eace7efcSopenharmony_ci
51eace7efcSopenharmony_ciAppSpawnClient::AppSpawnClient(const char* serviceName)
52eace7efcSopenharmony_ci{
53eace7efcSopenharmony_ci    TAG_LOGD(AAFwkTag::APPMGR, "call");
54eace7efcSopenharmony_ci    std::string serviceName__ = serviceName;
55eace7efcSopenharmony_ci    if (serviceName__ == APPSPAWN_SERVER_NAME) {
56eace7efcSopenharmony_ci        serviceName_ = APPSPAWN_SERVER_NAME;
57eace7efcSopenharmony_ci    } else if (serviceName__ == CJAPPSPAWN_SERVER_NAME) {
58eace7efcSopenharmony_ci        serviceName_ = CJAPPSPAWN_SERVER_NAME;
59eace7efcSopenharmony_ci    } else if (serviceName__ == NWEBSPAWN_SERVER_NAME) {
60eace7efcSopenharmony_ci        serviceName_ = NWEBSPAWN_SERVER_NAME;
61eace7efcSopenharmony_ci    } else if (serviceName__ == NATIVESPAWN_SERVER_NAME) {
62eace7efcSopenharmony_ci        serviceName_ = NATIVESPAWN_SERVER_NAME;
63eace7efcSopenharmony_ci    } else {
64eace7efcSopenharmony_ci        TAG_LOGE(AAFwkTag::APPMGR, "unknown service name");
65eace7efcSopenharmony_ci        serviceName_ = NWEBSPAWN_SERVER_NAME;
66eace7efcSopenharmony_ci    }
67eace7efcSopenharmony_ci    state_ = SpawnConnectionState::STATE_NOT_CONNECT;
68eace7efcSopenharmony_ci}
69eace7efcSopenharmony_ci
70eace7efcSopenharmony_ciAppSpawnClient::~AppSpawnClient()
71eace7efcSopenharmony_ci{
72eace7efcSopenharmony_ci    CloseConnection();
73eace7efcSopenharmony_ci}
74eace7efcSopenharmony_ci
75eace7efcSopenharmony_ciErrCode AppSpawnClient::OpenConnection()
76eace7efcSopenharmony_ci{
77eace7efcSopenharmony_ci    HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__);
78eace7efcSopenharmony_ci    if (state_ == SpawnConnectionState::STATE_CONNECTED) {
79eace7efcSopenharmony_ci        return 0;
80eace7efcSopenharmony_ci    }
81eace7efcSopenharmony_ci    TAG_LOGI(AAFwkTag::APPMGR, "call");
82eace7efcSopenharmony_ci    int64_t startTime = AbilityRuntime::TimeUtil::SystemTimeMillisecond();
83eace7efcSopenharmony_ci    AppSpawnClientHandle handle = nullptr;
84eace7efcSopenharmony_ci    ErrCode ret = 0;
85eace7efcSopenharmony_ci    ret = AppSpawnClientInit(serviceName_.c_str(), &handle);
86eace7efcSopenharmony_ci    int64_t costTime = AbilityRuntime::TimeUtil::SystemTimeMillisecond() - startTime;
87eace7efcSopenharmony_ci    if (costTime > MAX_COST_TIME) {
88eace7efcSopenharmony_ci        TAG_LOGW(AAFwkTag::APPMGR, "appspawnclientInit cost %{public}" PRId64 "ms!", costTime);
89eace7efcSopenharmony_ci    }
90eace7efcSopenharmony_ci
91eace7efcSopenharmony_ci    if (FAILED(ret)) {
92eace7efcSopenharmony_ci        TAG_LOGE(AAFwkTag::APPMGR, "appspawnclientInit failed");
93eace7efcSopenharmony_ci        state_ = SpawnConnectionState::STATE_CONNECT_FAILED;
94eace7efcSopenharmony_ci        return ret;
95eace7efcSopenharmony_ci    }
96eace7efcSopenharmony_ci    handle_ = handle;
97eace7efcSopenharmony_ci    state_ = SpawnConnectionState::STATE_CONNECTED;
98eace7efcSopenharmony_ci
99eace7efcSopenharmony_ci    return ret;
100eace7efcSopenharmony_ci}
101eace7efcSopenharmony_ci
102eace7efcSopenharmony_civoid AppSpawnClient::CloseConnection()
103eace7efcSopenharmony_ci{
104eace7efcSopenharmony_ci    TAG_LOGD(AAFwkTag::APPMGR, "call");
105eace7efcSopenharmony_ci    if (state_ == SpawnConnectionState::STATE_CONNECTED) {
106eace7efcSopenharmony_ci        AppSpawnClientDestroy(handle_);
107eace7efcSopenharmony_ci    }
108eace7efcSopenharmony_ci    state_ = SpawnConnectionState::STATE_NOT_CONNECT;
109eace7efcSopenharmony_ci}
110eace7efcSopenharmony_ci
111eace7efcSopenharmony_ciSpawnConnectionState AppSpawnClient::QueryConnectionState() const
112eace7efcSopenharmony_ci{
113eace7efcSopenharmony_ci    return state_;
114eace7efcSopenharmony_ci}
115eace7efcSopenharmony_ci
116eace7efcSopenharmony_ciAppSpawnClientHandle AppSpawnClient::GetAppSpawnClientHandle() const
117eace7efcSopenharmony_ci{
118eace7efcSopenharmony_ci    if (state_ == SpawnConnectionState::STATE_CONNECTED) {
119eace7efcSopenharmony_ci        return handle_;
120eace7efcSopenharmony_ci    }
121eace7efcSopenharmony_ci    return nullptr;
122eace7efcSopenharmony_ci}
123eace7efcSopenharmony_ci
124eace7efcSopenharmony_cistatic std::string DumpDataGroupInfoListToJson(const DataGroupInfoList &dataGroupInfoList)
125eace7efcSopenharmony_ci{
126eace7efcSopenharmony_ci    nlohmann::json dataGroupInfoListJson;
127eace7efcSopenharmony_ci    for (auto& dataGroupInfo : dataGroupInfoList) {
128eace7efcSopenharmony_ci        dataGroupInfoListJson[DATAGROUPINFOLIST_DATAGROUPID].emplace_back(dataGroupInfo.dataGroupId);
129eace7efcSopenharmony_ci        dataGroupInfoListJson[DATAGROUPINFOLIST_GID].emplace_back(std::to_string(dataGroupInfo.gid));
130eace7efcSopenharmony_ci        std::string dir = JSON_DATA_APP + std::to_string(dataGroupInfo.userId)
131eace7efcSopenharmony_ci            + JSON_GROUP + dataGroupInfo.uuid;
132eace7efcSopenharmony_ci        dataGroupInfoListJson[DATAGROUPINFOLIST_DIR].emplace_back(dir);
133eace7efcSopenharmony_ci    }
134eace7efcSopenharmony_ci    return dataGroupInfoListJson.dump();
135eace7efcSopenharmony_ci}
136eace7efcSopenharmony_ci
137eace7efcSopenharmony_cistatic std::string DumpHspListToJson(const HspList &hspList)
138eace7efcSopenharmony_ci{
139eace7efcSopenharmony_ci    nlohmann::json hspListJson;
140eace7efcSopenharmony_ci    for (auto& hsp : hspList) {
141eace7efcSopenharmony_ci        hspListJson[HSPLIST_BUNDLES].emplace_back(hsp.bundleName);
142eace7efcSopenharmony_ci        hspListJson[HSPLIST_MODULES].emplace_back(hsp.moduleName);
143eace7efcSopenharmony_ci        hspListJson[HSPLIST_VERSIONS].emplace_back(VERSION_PREFIX + std::to_string(hsp.versionCode));
144eace7efcSopenharmony_ci    }
145eace7efcSopenharmony_ci    return hspListJson.dump();
146eace7efcSopenharmony_ci}
147eace7efcSopenharmony_ci
148eace7efcSopenharmony_cistatic std::string DumpAppEnvToJson(const std::map<std::string, std::string> &appEnv)
149eace7efcSopenharmony_ci{
150eace7efcSopenharmony_ci    nlohmann::json appEnvJson;
151eace7efcSopenharmony_ci    for (const auto &[envName, envValue] : appEnv) {
152eace7efcSopenharmony_ci        appEnvJson[envName] = envValue;
153eace7efcSopenharmony_ci    }
154eace7efcSopenharmony_ci    return appEnvJson.dump();
155eace7efcSopenharmony_ci}
156eace7efcSopenharmony_ci
157eace7efcSopenharmony_cistatic std::string DumpExtensionSandboxDirsToJson(const std::map<std::string, std::string> &extensionSandboxDirs)
158eace7efcSopenharmony_ci{
159eace7efcSopenharmony_ci    nlohmann::json extensionSandboxDirsJson;
160eace7efcSopenharmony_ci    for (auto &[userId, sandboxDir] : extensionSandboxDirs) {
161eace7efcSopenharmony_ci        extensionSandboxDirsJson[userId] = sandboxDir;
162eace7efcSopenharmony_ci    }
163eace7efcSopenharmony_ci    return extensionSandboxDirsJson.dump();
164eace7efcSopenharmony_ci}
165eace7efcSopenharmony_ci
166eace7efcSopenharmony_ciint32_t AppSpawnClient::SetDacInfo(const AppSpawnStartMsg &startMsg, AppSpawnReqMsgHandle reqHandle)
167eace7efcSopenharmony_ci{
168eace7efcSopenharmony_ci    int32_t ret = 0;
169eace7efcSopenharmony_ci    AppDacInfo appDacInfo = {0};
170eace7efcSopenharmony_ci    appDacInfo.uid = startMsg.uid;
171eace7efcSopenharmony_ci    appDacInfo.gid = startMsg.gid;
172eace7efcSopenharmony_ci    appDacInfo.gidCount = startMsg.gids.size() + startMsg.dataGroupInfoList.size();
173eace7efcSopenharmony_ci    for (uint32_t i = 0; i < startMsg.gids.size(); i++) {
174eace7efcSopenharmony_ci        appDacInfo.gidTable[i] = startMsg.gids[i];
175eace7efcSopenharmony_ci    }
176eace7efcSopenharmony_ci    for (uint32_t i = startMsg.gids.size(); i < appDacInfo.gidCount; i++) {
177eace7efcSopenharmony_ci        appDacInfo.gidTable[i] = startMsg.dataGroupInfoList[i - startMsg.gids.size()].gid;
178eace7efcSopenharmony_ci    }
179eace7efcSopenharmony_ci    ret = strcpy_s(appDacInfo.userName, sizeof(appDacInfo.userName), APPSPAWN_CLIENT_USER_NAME);
180eace7efcSopenharmony_ci    if (ret) {
181eace7efcSopenharmony_ci        TAG_LOGE(AAFwkTag::APPMGR, "set dac userName fail");
182eace7efcSopenharmony_ci        return ret;
183eace7efcSopenharmony_ci    }
184eace7efcSopenharmony_ci    return AppSpawnReqMsgSetAppDacInfo(reqHandle, &appDacInfo);
185eace7efcSopenharmony_ci}
186eace7efcSopenharmony_ci
187eace7efcSopenharmony_ciint32_t AppSpawnClient::SetMountPermission(const AppSpawnStartMsg &startMsg, AppSpawnReqMsgHandle reqHandle)
188eace7efcSopenharmony_ci{
189eace7efcSopenharmony_ci    int32_t ret = 0;
190eace7efcSopenharmony_ci    std::set<std::string> mountPermissionList = startMsg.permissions;
191eace7efcSopenharmony_ci    for (std::string permission : mountPermissionList) {
192eace7efcSopenharmony_ci        ret = AppSpawnClientAddPermission(handle_, reqHandle, permission.c_str());
193eace7efcSopenharmony_ci        if (ret != 0) {
194eace7efcSopenharmony_ci            TAG_LOGE(AAFwkTag::APPMGR, "AppSpawnReqMsgAddPermission %{public}s failed", permission.c_str());
195eace7efcSopenharmony_ci            return ret;
196eace7efcSopenharmony_ci        }
197eace7efcSopenharmony_ci    }
198eace7efcSopenharmony_ci    return ret;
199eace7efcSopenharmony_ci}
200eace7efcSopenharmony_ci
201eace7efcSopenharmony_ciint32_t AppSpawnClient::SetStartFlags(const AppSpawnStartMsg &startMsg, AppSpawnReqMsgHandle reqHandle)
202eace7efcSopenharmony_ci{
203eace7efcSopenharmony_ci    int32_t ret = 0;
204eace7efcSopenharmony_ci    uint32_t startFlagTmp = startMsg.flags;
205eace7efcSopenharmony_ci    int flagIndex = 0;
206eace7efcSopenharmony_ci    while (startFlagTmp > 0) {
207eace7efcSopenharmony_ci        if (startFlagTmp & START_FLAG_TEST_NUM) {
208eace7efcSopenharmony_ci            ret = AppSpawnReqMsgSetAppFlag(reqHandle, static_cast<AppFlagsIndex>(flagIndex));
209eace7efcSopenharmony_ci            if (ret != 0) {
210eace7efcSopenharmony_ci                TAG_LOGE(AAFwkTag::APPMGR, "SetFlagIdx %{public}d failed, ret: %{public}d", flagIndex, ret);
211eace7efcSopenharmony_ci                return ret;
212eace7efcSopenharmony_ci            }
213eace7efcSopenharmony_ci        }
214eace7efcSopenharmony_ci        startFlagTmp = startFlagTmp >> RIGHT_SHIFT_STEP;
215eace7efcSopenharmony_ci        flagIndex++;
216eace7efcSopenharmony_ci    }
217eace7efcSopenharmony_ci    if (startMsg.atomicServiceFlag) {
218eace7efcSopenharmony_ci        ret = AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_ATOMIC_SERVICE);
219eace7efcSopenharmony_ci        if (ret != 0) {
220eace7efcSopenharmony_ci            TAG_LOGE(AAFwkTag::APPMGR, "fail, ret: %{public}d", ret);
221eace7efcSopenharmony_ci            return ret;
222eace7efcSopenharmony_ci        }
223eace7efcSopenharmony_ci    }
224eace7efcSopenharmony_ci    if (startMsg.strictMode) {
225eace7efcSopenharmony_ci        ret = AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_ISOLATED_SANDBOX);
226eace7efcSopenharmony_ci        if (ret != 0) {
227eace7efcSopenharmony_ci            TAG_LOGE(AAFwkTag::APPMGR, "fail, ret: %{public}d", ret);
228eace7efcSopenharmony_ci            return ret;
229eace7efcSopenharmony_ci        }
230eace7efcSopenharmony_ci    }
231eace7efcSopenharmony_ci    if (startMsg.isolatedExtension) {
232eace7efcSopenharmony_ci        ret = AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_EXTENSION_SANDBOX);
233eace7efcSopenharmony_ci        if (ret != 0) {
234eace7efcSopenharmony_ci            TAG_LOGE(AAFwkTag::APPMGR, "fail, ret: %{public}d", ret);
235eace7efcSopenharmony_ci            return ret;
236eace7efcSopenharmony_ci        }
237eace7efcSopenharmony_ci    }
238eace7efcSopenharmony_ci    if (startMsg.flags & APP_FLAGS_CLONE_ENABLE) {
239eace7efcSopenharmony_ci        ret = AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_CLONE_ENABLE);
240eace7efcSopenharmony_ci        if (ret != 0) {
241eace7efcSopenharmony_ci            TAG_LOGE(AAFwkTag::APPMGR, "fail, ret: %{public}d", ret);
242eace7efcSopenharmony_ci            return ret;
243eace7efcSopenharmony_ci        }
244eace7efcSopenharmony_ci    }
245eace7efcSopenharmony_ci    ret = SetChildProcessTypeStartFlag(reqHandle, startMsg.childProcessType);
246eace7efcSopenharmony_ci    if (ret != ERR_OK) {
247eace7efcSopenharmony_ci        TAG_LOGE(AAFwkTag::APPMGR, "fail, ret: %{public}d", ret);
248eace7efcSopenharmony_ci        return ret;
249eace7efcSopenharmony_ci    }
250eace7efcSopenharmony_ci    ret = SetIsolationModeFlag(startMsg, reqHandle);
251eace7efcSopenharmony_ci    return ret;
252eace7efcSopenharmony_ci}
253eace7efcSopenharmony_ci
254eace7efcSopenharmony_ciint32_t AppSpawnClient::AppspawnSetExtMsg(const AppSpawnStartMsg &startMsg, AppSpawnReqMsgHandle reqHandle)
255eace7efcSopenharmony_ci{
256eace7efcSopenharmony_ci    int32_t ret = 0;
257eace7efcSopenharmony_ci    ret = AppSpawnReqMsgAddStringInfo(reqHandle, MSG_EXT_NAME_RENDER_CMD, startMsg.renderParam.c_str());
258eace7efcSopenharmony_ci    if (ret) {
259eace7efcSopenharmony_ci        TAG_LOGE(AAFwkTag::APPMGR, "fail, ret: %{public}d", ret);
260eace7efcSopenharmony_ci        return ret;
261eace7efcSopenharmony_ci    }
262eace7efcSopenharmony_ci
263eace7efcSopenharmony_ci    if (!startMsg.hspList.empty()) {
264eace7efcSopenharmony_ci        ret = AppSpawnReqMsgAddStringInfo(reqHandle, MSG_EXT_NAME_HSP_LIST,
265eace7efcSopenharmony_ci            DumpHspListToJson(startMsg.hspList).c_str());
266eace7efcSopenharmony_ci        if (ret) {
267eace7efcSopenharmony_ci            TAG_LOGE(AAFwkTag::APPMGR, "fail, ret: %{public}d", ret);
268eace7efcSopenharmony_ci            return ret;
269eace7efcSopenharmony_ci        }
270eace7efcSopenharmony_ci    }
271eace7efcSopenharmony_ci
272eace7efcSopenharmony_ci    if (!startMsg.dataGroupInfoList.empty()) {
273eace7efcSopenharmony_ci        ret = AppSpawnReqMsgAddStringInfo(reqHandle, MSG_EXT_NAME_DATA_GROUP,
274eace7efcSopenharmony_ci            DumpDataGroupInfoListToJson(startMsg.dataGroupInfoList).c_str());
275eace7efcSopenharmony_ci        if (ret) {
276eace7efcSopenharmony_ci            TAG_LOGE(AAFwkTag::APPMGR, "fail, ret: %{public}d", ret);
277eace7efcSopenharmony_ci            return ret;
278eace7efcSopenharmony_ci        }
279eace7efcSopenharmony_ci    }
280eace7efcSopenharmony_ci
281eace7efcSopenharmony_ci    if (!startMsg.overlayInfo.empty()) {
282eace7efcSopenharmony_ci        ret = AppSpawnReqMsgAddStringInfo(reqHandle, MSG_EXT_NAME_OVERLAY, startMsg.overlayInfo.c_str());
283eace7efcSopenharmony_ci        if (ret) {
284eace7efcSopenharmony_ci            TAG_LOGE(AAFwkTag::APPMGR, "fail, ret: %{public}d", ret);
285eace7efcSopenharmony_ci            return ret;
286eace7efcSopenharmony_ci        }
287eace7efcSopenharmony_ci    }
288eace7efcSopenharmony_ci
289eace7efcSopenharmony_ci    if (!startMsg.appEnv.empty()) {
290eace7efcSopenharmony_ci        ret = AppSpawnReqMsgAddStringInfo(reqHandle, MSG_EXT_NAME_APP_ENV, DumpAppEnvToJson(startMsg.appEnv).c_str());
291eace7efcSopenharmony_ci        if (ret) {
292eace7efcSopenharmony_ci            TAG_LOGE(AAFwkTag::APPMGR, "fail, ret: %{public}d", ret);
293eace7efcSopenharmony_ci            return ret;
294eace7efcSopenharmony_ci        }
295eace7efcSopenharmony_ci    }
296eace7efcSopenharmony_ci
297eace7efcSopenharmony_ci    if (!startMsg.atomicAccount.empty()) {
298eace7efcSopenharmony_ci        ret = AppSpawnReqMsgAddStringInfo(reqHandle, MSG_EXT_NAME_ACCOUNT_ID, startMsg.atomicAccount.c_str());
299eace7efcSopenharmony_ci        if (ret) {
300eace7efcSopenharmony_ci            TAG_LOGE(AAFwkTag::APPMGR, "fail, ret: %{public}d", ret);
301eace7efcSopenharmony_ci            return ret;
302eace7efcSopenharmony_ci        }
303eace7efcSopenharmony_ci    }
304eace7efcSopenharmony_ci
305eace7efcSopenharmony_ci    return AppspawnSetExtMsgMore(startMsg, reqHandle);
306eace7efcSopenharmony_ci}
307eace7efcSopenharmony_ci
308eace7efcSopenharmony_ciint32_t AppSpawnClient::AppspawnSetExtMsgMore(const AppSpawnStartMsg &startMsg, AppSpawnReqMsgHandle reqHandle)
309eace7efcSopenharmony_ci{
310eace7efcSopenharmony_ci    int32_t ret = 0;
311eace7efcSopenharmony_ci
312eace7efcSopenharmony_ci    if (!startMsg.provisionType.empty()) {
313eace7efcSopenharmony_ci        ret = AppSpawnReqMsgAddStringInfo(reqHandle, MSG_EXT_NAME_PROVISION_TYPE, startMsg.provisionType.c_str());
314eace7efcSopenharmony_ci        if (ret) {
315eace7efcSopenharmony_ci            TAG_LOGE(AAFwkTag::APPMGR, "fail, ret: %{public}d", ret);
316eace7efcSopenharmony_ci            return ret;
317eace7efcSopenharmony_ci        }
318eace7efcSopenharmony_ci    }
319eace7efcSopenharmony_ci
320eace7efcSopenharmony_ci    if (!startMsg.processType.empty()) {
321eace7efcSopenharmony_ci        ret = AppSpawnReqMsgAddStringInfo(reqHandle, MSG_EXT_NAME_PROCESS_TYPE, startMsg.processType.c_str());
322eace7efcSopenharmony_ci        if (ret) {
323eace7efcSopenharmony_ci            TAG_LOGE(AAFwkTag::APPMGR, "fail, ret: %{public}d", ret);
324eace7efcSopenharmony_ci            return ret;
325eace7efcSopenharmony_ci        }
326eace7efcSopenharmony_ci    }
327eace7efcSopenharmony_ci
328eace7efcSopenharmony_ci    std::string maxChildProcessStr = std::to_string(startMsg.maxChildProcess);
329eace7efcSopenharmony_ci    ret = AppSpawnReqMsgAddStringInfo(reqHandle, MSG_EXT_NAME_MAX_CHILD_PROCCESS_MAX, maxChildProcessStr.c_str());
330eace7efcSopenharmony_ci    if (ret) {
331eace7efcSopenharmony_ci        TAG_LOGE(AAFwkTag::APPMGR, "fail, ret: %{public}d", ret);
332eace7efcSopenharmony_ci        return ret;
333eace7efcSopenharmony_ci    }
334eace7efcSopenharmony_ci    TAG_LOGD(AAFwkTag::APPMGR, "Send maxChildProcess %{public}s success", maxChildProcessStr.c_str());
335eace7efcSopenharmony_ci
336eace7efcSopenharmony_ci    if (!startMsg.extensionSandboxPath.empty()) {
337eace7efcSopenharmony_ci        ret = AppSpawnReqMsgAddStringInfo(reqHandle, MSG_EXT_NAME_APP_EXTENSION,
338eace7efcSopenharmony_ci            startMsg.extensionSandboxPath.c_str());
339eace7efcSopenharmony_ci        if (ret) {
340eace7efcSopenharmony_ci            TAG_LOGE(AAFwkTag::APPMGR, "fail, ret: %{public}d", ret);
341eace7efcSopenharmony_ci            return ret;
342eace7efcSopenharmony_ci        }
343eace7efcSopenharmony_ci    }
344eace7efcSopenharmony_ci
345eace7efcSopenharmony_ci    if (!startMsg.fds.empty()) {
346eace7efcSopenharmony_ci        ret = SetExtMsgFds(reqHandle, startMsg.fds);
347eace7efcSopenharmony_ci        if (ret != ERR_OK) {
348eace7efcSopenharmony_ci            TAG_LOGE(AAFwkTag::APPMGR, "fail, ret: %{public}d", ret);
349eace7efcSopenharmony_ci            return ret;
350eace7efcSopenharmony_ci        }
351eace7efcSopenharmony_ci    }
352eace7efcSopenharmony_ci
353eace7efcSopenharmony_ci    return ret;
354eace7efcSopenharmony_ci}
355eace7efcSopenharmony_ci
356eace7efcSopenharmony_ciint32_t AppSpawnClient::AppspawnCreateDefaultMsg(const AppSpawnStartMsg &startMsg, AppSpawnReqMsgHandle reqHandle)
357eace7efcSopenharmony_ci{
358eace7efcSopenharmony_ci    TAG_LOGD(AAFwkTag::APPMGR, "call");
359eace7efcSopenharmony_ci    int32_t ret = 0;
360eace7efcSopenharmony_ci    do {
361eace7efcSopenharmony_ci        ret = SetDacInfo(startMsg, reqHandle);
362eace7efcSopenharmony_ci        if (ret) {
363eace7efcSopenharmony_ci            TAG_LOGE(AAFwkTag::APPMGR, "fail, ret: %{public}d", ret);
364eace7efcSopenharmony_ci            break;
365eace7efcSopenharmony_ci        }
366eace7efcSopenharmony_ci        ret = AppSpawnReqMsgSetBundleInfo(reqHandle, startMsg.bundleIndex, startMsg.bundleName.c_str());
367eace7efcSopenharmony_ci        if (ret) {
368eace7efcSopenharmony_ci            TAG_LOGE(AAFwkTag::APPMGR, "fail, ret: %{public}d", ret);
369eace7efcSopenharmony_ci            break;
370eace7efcSopenharmony_ci        }
371eace7efcSopenharmony_ci        ret = AppSpawnReqMsgSetAppInternetPermissionInfo(reqHandle, startMsg.allowInternet,
372eace7efcSopenharmony_ci            startMsg.setAllowInternet);
373eace7efcSopenharmony_ci        if (ret) {
374eace7efcSopenharmony_ci            TAG_LOGE(AAFwkTag::APPMGR, "fail, ret: %{public}d", ret);
375eace7efcSopenharmony_ci            break;
376eace7efcSopenharmony_ci        }
377eace7efcSopenharmony_ci        if (startMsg.ownerId.size()) {
378eace7efcSopenharmony_ci            ret = AppSpawnReqMsgSetAppOwnerId(reqHandle, startMsg.ownerId.c_str());
379eace7efcSopenharmony_ci            if (ret) {
380eace7efcSopenharmony_ci                TAG_LOGE(AAFwkTag::APPMGR, "SetOwnerId %{public}s failed, ret: %{public}d",
381eace7efcSopenharmony_ci                    startMsg.ownerId.c_str(), ret);
382eace7efcSopenharmony_ci                break;
383eace7efcSopenharmony_ci            }
384eace7efcSopenharmony_ci        }
385eace7efcSopenharmony_ci        ret = AppSpawnReqMsgSetAppAccessToken(reqHandle, startMsg.accessTokenIdEx);
386eace7efcSopenharmony_ci        if (ret) {
387eace7efcSopenharmony_ci            TAG_LOGE(AAFwkTag::APPMGR, "ret: %{public}d", ret);
388eace7efcSopenharmony_ci            break;
389eace7efcSopenharmony_ci        }
390eace7efcSopenharmony_ci        ret = AppSpawnReqMsgSetAppDomainInfo(reqHandle, startMsg.hapFlags, startMsg.apl.c_str());
391eace7efcSopenharmony_ci        if (ret) {
392eace7efcSopenharmony_ci            TAG_LOGE(AAFwkTag::APPMGR,
393eace7efcSopenharmony_ci                "fail, hapFlags is %{public}d, apl is %{public}s, ret: %{public}d",
394eace7efcSopenharmony_ci                startMsg.hapFlags, startMsg.apl.c_str(), ret);
395eace7efcSopenharmony_ci            break;
396eace7efcSopenharmony_ci        }
397eace7efcSopenharmony_ci        ret = SetStartFlags(startMsg, reqHandle);
398eace7efcSopenharmony_ci        if (ret) {
399eace7efcSopenharmony_ci            TAG_LOGE(AAFwkTag::APPMGR, "fail, ret: %{public}d", ret);
400eace7efcSopenharmony_ci            break;
401eace7efcSopenharmony_ci        }
402eace7efcSopenharmony_ci        ret = SetMountPermission(startMsg, reqHandle);
403eace7efcSopenharmony_ci        if (ret) {
404eace7efcSopenharmony_ci            TAG_LOGE(AAFwkTag::APPMGR, "fail, ret: %{public}d", ret);
405eace7efcSopenharmony_ci            break;
406eace7efcSopenharmony_ci        }
407eace7efcSopenharmony_ci        if (AppspawnSetExtMsg(startMsg, reqHandle)) {
408eace7efcSopenharmony_ci            break;
409eace7efcSopenharmony_ci        }
410eace7efcSopenharmony_ci        return ret;
411eace7efcSopenharmony_ci    } while (0);
412eace7efcSopenharmony_ci
413eace7efcSopenharmony_ci    TAG_LOGI(AAFwkTag::APPMGR, "AppSpawnReqMsgFree");
414eace7efcSopenharmony_ci    AppSpawnReqMsgFree(reqHandle);
415eace7efcSopenharmony_ci
416eace7efcSopenharmony_ci    return ret;
417eace7efcSopenharmony_ci}
418eace7efcSopenharmony_ci
419eace7efcSopenharmony_cibool AppSpawnClient::VerifyMsg(const AppSpawnStartMsg &startMsg)
420eace7efcSopenharmony_ci{
421eace7efcSopenharmony_ci    TAG_LOGD(AAFwkTag::APPMGR, "VerifyMsg");
422eace7efcSopenharmony_ci    if (startMsg.code == MSG_APP_SPAWN ||
423eace7efcSopenharmony_ci        startMsg.code == MSG_SPAWN_NATIVE_PROCESS) {
424eace7efcSopenharmony_ci        if (startMsg.uid < 0) {
425eace7efcSopenharmony_ci            TAG_LOGE(AAFwkTag::APPMGR, "invalid uid! [%{public}d]", startMsg.uid);
426eace7efcSopenharmony_ci            return false;
427eace7efcSopenharmony_ci        }
428eace7efcSopenharmony_ci
429eace7efcSopenharmony_ci        if (startMsg.gid < 0) {
430eace7efcSopenharmony_ci            TAG_LOGE(AAFwkTag::APPMGR, "invalid gid! [%{public}d]", startMsg.gid);
431eace7efcSopenharmony_ci            return false;
432eace7efcSopenharmony_ci        }
433eace7efcSopenharmony_ci
434eace7efcSopenharmony_ci        if (startMsg.gids.size() > APP_MAX_GIDS) {
435eace7efcSopenharmony_ci            TAG_LOGE(AAFwkTag::APPMGR, "many app gids");
436eace7efcSopenharmony_ci            return false;
437eace7efcSopenharmony_ci        }
438eace7efcSopenharmony_ci
439eace7efcSopenharmony_ci        for (uint32_t i = 0; i < startMsg.gids.size(); ++i) {
440eace7efcSopenharmony_ci            if (startMsg.gids[i] < 0) {
441eace7efcSopenharmony_ci                TAG_LOGE(AAFwkTag::APPMGR, "invalid gids array! [%{public}d]", startMsg.gids[i]);
442eace7efcSopenharmony_ci                return false;
443eace7efcSopenharmony_ci            }
444eace7efcSopenharmony_ci        }
445eace7efcSopenharmony_ci        if (startMsg.procName.empty() || startMsg.procName.size() >= MAX_PROC_NAME_LEN) {
446eace7efcSopenharmony_ci            TAG_LOGE(AAFwkTag::APPMGR, "invalid procName");
447eace7efcSopenharmony_ci            return false;
448eace7efcSopenharmony_ci        }
449eace7efcSopenharmony_ci    } else if (startMsg.code == MSG_GET_RENDER_TERMINATION_STATUS) {
450eace7efcSopenharmony_ci        if (startMsg.pid < 0) {
451eace7efcSopenharmony_ci            TAG_LOGE(AAFwkTag::APPMGR, "invalid pid");
452eace7efcSopenharmony_ci            return false;
453eace7efcSopenharmony_ci        }
454eace7efcSopenharmony_ci    } else {
455eace7efcSopenharmony_ci        TAG_LOGE(AAFwkTag::APPMGR, "invalid code");
456eace7efcSopenharmony_ci        return false;
457eace7efcSopenharmony_ci    }
458eace7efcSopenharmony_ci
459eace7efcSopenharmony_ci    return true;
460eace7efcSopenharmony_ci}
461eace7efcSopenharmony_ci
462eace7efcSopenharmony_ciint32_t AppSpawnClient::PreStartNWebSpawnProcess()
463eace7efcSopenharmony_ci{
464eace7efcSopenharmony_ci    TAG_LOGI(AAFwkTag::APPMGR, "call");
465eace7efcSopenharmony_ci    return OpenConnection();
466eace7efcSopenharmony_ci}
467eace7efcSopenharmony_ci
468eace7efcSopenharmony_ciint32_t AppSpawnClient::StartProcess(const AppSpawnStartMsg &startMsg, pid_t &pid)
469eace7efcSopenharmony_ci{
470eace7efcSopenharmony_ci    TAG_LOGD(AAFwkTag::APPMGR, "StartProcess");
471eace7efcSopenharmony_ci    HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__);
472eace7efcSopenharmony_ci    if (!VerifyMsg(startMsg)) {
473eace7efcSopenharmony_ci        return ERR_INVALID_VALUE;
474eace7efcSopenharmony_ci    }
475eace7efcSopenharmony_ci
476eace7efcSopenharmony_ci    int32_t ret = 0;
477eace7efcSopenharmony_ci    AppSpawnReqMsgHandle reqHandle = nullptr;
478eace7efcSopenharmony_ci    int64_t startTime = AbilityRuntime::TimeUtil::SystemTimeMillisecond();
479eace7efcSopenharmony_ci
480eace7efcSopenharmony_ci    ret = OpenConnection();
481eace7efcSopenharmony_ci    if (ret != 0) {
482eace7efcSopenharmony_ci        return ret;
483eace7efcSopenharmony_ci    }
484eace7efcSopenharmony_ci
485eace7efcSopenharmony_ci    ret = AppSpawnReqMsgCreate(static_cast<AppSpawnMsgType>(startMsg.code), startMsg.procName.c_str(), &reqHandle);
486eace7efcSopenharmony_ci    if (ret != 0) {
487eace7efcSopenharmony_ci        TAG_LOGE(AAFwkTag::APPMGR, "AppSpawnReqMsgCreate fail");
488eace7efcSopenharmony_ci        return ret;
489eace7efcSopenharmony_ci    }
490eace7efcSopenharmony_ci
491eace7efcSopenharmony_ci    ret = AppspawnCreateDefaultMsg(startMsg, reqHandle);
492eace7efcSopenharmony_ci    if (ret != 0) {
493eace7efcSopenharmony_ci        return ret; // create msg failed
494eace7efcSopenharmony_ci    }
495eace7efcSopenharmony_ci
496eace7efcSopenharmony_ci    TAG_LOGD(AAFwkTag::APPMGR, "AppspawnSendMsg");
497eace7efcSopenharmony_ci    AppSpawnResult result = {0};
498eace7efcSopenharmony_ci    ret = AppSpawnClientSendMsg(handle_, reqHandle, &result);
499eace7efcSopenharmony_ci
500eace7efcSopenharmony_ci    int64_t costTime = AbilityRuntime::TimeUtil::SystemTimeMillisecond() - startTime;
501eace7efcSopenharmony_ci    if (costTime > MAX_COST_TIME) {
502eace7efcSopenharmony_ci        TAG_LOGW(AAFwkTag::APPMGR, "StartProcess cost %{public}" PRId64 "ms!", costTime);
503eace7efcSopenharmony_ci    }
504eace7efcSopenharmony_ci    if (ret != 0) {
505eace7efcSopenharmony_ci        TAG_LOGE(AAFwkTag::APPMGR, "appspawn send msg fail");
506eace7efcSopenharmony_ci        return ret;
507eace7efcSopenharmony_ci    }
508eace7efcSopenharmony_ci    if (result.pid <= 0) {
509eace7efcSopenharmony_ci        TAG_LOGE(AAFwkTag::APPMGR, "pid invalid");
510eace7efcSopenharmony_ci        return ERR_APPEXECFWK_INVALID_PID;
511eace7efcSopenharmony_ci    } else {
512eace7efcSopenharmony_ci        pid = result.pid;
513eace7efcSopenharmony_ci    }
514eace7efcSopenharmony_ci    TAG_LOGI(AAFwkTag::APPMGR, "pid = [%{public}d]", pid);
515eace7efcSopenharmony_ci    return result.result;
516eace7efcSopenharmony_ci}
517eace7efcSopenharmony_ci
518eace7efcSopenharmony_ciint32_t AppSpawnClient::GetRenderProcessTerminationStatus(const AppSpawnStartMsg &startMsg, int &status)
519eace7efcSopenharmony_ci{
520eace7efcSopenharmony_ci    TAG_LOGI(AAFwkTag::APPMGR, "call");
521eace7efcSopenharmony_ci    int32_t ret = 0;
522eace7efcSopenharmony_ci    AppSpawnReqMsgHandle reqHandle = nullptr;
523eace7efcSopenharmony_ci
524eace7efcSopenharmony_ci    // check parameters
525eace7efcSopenharmony_ci    if (!VerifyMsg(startMsg)) {
526eace7efcSopenharmony_ci        return ERR_INVALID_VALUE;
527eace7efcSopenharmony_ci    }
528eace7efcSopenharmony_ci
529eace7efcSopenharmony_ci    ret = OpenConnection();
530eace7efcSopenharmony_ci    if (ret != 0) {
531eace7efcSopenharmony_ci        return ret;
532eace7efcSopenharmony_ci    }
533eace7efcSopenharmony_ci
534eace7efcSopenharmony_ci    ret = AppSpawnTerminateMsgCreate(startMsg.pid, &reqHandle);
535eace7efcSopenharmony_ci    if (ret != 0) {
536eace7efcSopenharmony_ci        TAG_LOGE(AAFwkTag::APPMGR, "AppSpawnTerminateMsgCreate failed");
537eace7efcSopenharmony_ci        return ret;
538eace7efcSopenharmony_ci    }
539eace7efcSopenharmony_ci
540eace7efcSopenharmony_ci    TAG_LOGI(AAFwkTag::APPMGR, "AppspawnSendMsg");
541eace7efcSopenharmony_ci    AppSpawnResult result = {0};
542eace7efcSopenharmony_ci    ret = AppSpawnClientSendMsg(handle_, reqHandle, &result);
543eace7efcSopenharmony_ci    status = result.result;
544eace7efcSopenharmony_ci    if (ret != 0) {
545eace7efcSopenharmony_ci        TAG_LOGE(AAFwkTag::APPMGR, "appspawn send msg fail");
546eace7efcSopenharmony_ci        return ret;
547eace7efcSopenharmony_ci    }
548eace7efcSopenharmony_ci    TAG_LOGI(AAFwkTag::APPMGR, "status = [%{public}d]", status);
549eace7efcSopenharmony_ci
550eace7efcSopenharmony_ci    return ret;
551eace7efcSopenharmony_ci}
552eace7efcSopenharmony_ci
553eace7efcSopenharmony_ciint32_t AppSpawnClient::SetChildProcessTypeStartFlag(const AppSpawnReqMsgHandle &reqHandle,
554eace7efcSopenharmony_ci    int32_t childProcessType)
555eace7efcSopenharmony_ci{
556eace7efcSopenharmony_ci    TAG_LOGD(AAFwkTag::APPMGR, "SetChildProcessTypeStartFlag, type:%{public}d", childProcessType);
557eace7efcSopenharmony_ci    if (childProcessType != CHILD_PROCESS_TYPE_NOT_CHILD) {
558eace7efcSopenharmony_ci        return AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_CHILDPROCESS);
559eace7efcSopenharmony_ci    }
560eace7efcSopenharmony_ci    return ERR_OK;
561eace7efcSopenharmony_ci}
562eace7efcSopenharmony_ci
563eace7efcSopenharmony_ciint32_t AppSpawnClient::SetExtMsgFds(const AppSpawnReqMsgHandle &reqHandle,
564eace7efcSopenharmony_ci    const std::map<std::string, int32_t> &fds)
565eace7efcSopenharmony_ci{
566eace7efcSopenharmony_ci    TAG_LOGI(AAFwkTag::APPMGR, "size:%{public}zu", fds.size());
567eace7efcSopenharmony_ci    int32_t ret = ERR_OK;
568eace7efcSopenharmony_ci    for (const auto &item : fds) {
569eace7efcSopenharmony_ci        ret = AppSpawnReqMsgAddFd(reqHandle, item.first.c_str(), item.second);
570eace7efcSopenharmony_ci        if (ret != ERR_OK) {
571eace7efcSopenharmony_ci            TAG_LOGE(AAFwkTag::APPMGR, "fail, key:%{public}s, fd:%{public}d, ret:%{public}d",
572eace7efcSopenharmony_ci                item.first.c_str(), item.second, ret);
573eace7efcSopenharmony_ci            return ret;
574eace7efcSopenharmony_ci        }
575eace7efcSopenharmony_ci    }
576eace7efcSopenharmony_ci    return ERR_OK;
577eace7efcSopenharmony_ci}
578eace7efcSopenharmony_ci
579eace7efcSopenharmony_ciint32_t AppSpawnClient::SetIsolationModeFlag(const AppSpawnStartMsg &startMsg, const AppSpawnReqMsgHandle &reqHandle)
580eace7efcSopenharmony_ci{
581eace7efcSopenharmony_ci    TAG_LOGD(AAFwkTag::APPMGR, "isolationMode:%{public}d", startMsg.isolationMode);
582eace7efcSopenharmony_ci    if (!startMsg.isolationMode) {
583eace7efcSopenharmony_ci        return ERR_OK;
584eace7efcSopenharmony_ci    }
585eace7efcSopenharmony_ci    auto ret = AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_ISOLATED_SANDBOX_TYPE);
586eace7efcSopenharmony_ci    if (ret != 0) {
587eace7efcSopenharmony_ci        TAG_LOGE(AAFwkTag::APPMGR, "fail, ret: %{public}d", ret);
588eace7efcSopenharmony_ci        return ret;
589eace7efcSopenharmony_ci    }
590eace7efcSopenharmony_ci    ret = AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_ISOLATED_NETWORK);
591eace7efcSopenharmony_ci    if (ret != 0) {
592eace7efcSopenharmony_ci        TAG_LOGE(AAFwkTag::APPMGR, "fail, ret: %{public}d", ret);
593eace7efcSopenharmony_ci        return ret;
594eace7efcSopenharmony_ci    }
595eace7efcSopenharmony_ci    return ERR_OK;
596eace7efcSopenharmony_ci}
597eace7efcSopenharmony_ci}  // namespace AppExecFwk
598eace7efcSopenharmony_ci}  // namespace OHOS
599