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