已合并
startchildprocess接口支持拉起静态和动态运行时子进程 #18746
startchildprocess接口支持拉起静态和动态运行时子进程 #18746
已合并
renjh5496创建于 3月23日
25 个文件变更+660-64
@@ -16,7 +16,6 @@ import("//foundation/ability/ability_runtime/ability_runtime.gni")
16 16 
17ohos_shared_library("ability_child_process_manager_ani_kit") {17ohos_shared_library("ability_child_process_manager_ani_kit") {
18 branch_protector_ret = "pac_ret"18 branch_protector_ret = "pac_ret"
19- shlib_type = "ani"
20 sanitize = {19 sanitize = {
21 cfi = true20 cfi = true
22 cfi_cross_dso = true21 cfi_cross_dso = true
@@ -58,7 +57,10 @@ ohos_shared_library("ability_child_process_manager_ani_kit") {
58 ]57 ]
59 58 
60 if (ability_runtime_child_process) {59 if (ability_runtime_child_process) {
61- sources += [ "./src/ets_child_process_manager.cpp" ]60+ sources += [
61+ "./src/ets_child_process.cpp",
62+ "./src/ets_child_process_manager.cpp",
63+ ]
62 deps += [ "${ability_runtime_innerkits_path}/child_process_manager:child_process_manager" ]64 deps += [ "${ability_runtime_innerkits_path}/child_process_manager:child_process_manager" ]
63 external_deps += [ "ipc:ipc_single" ]65 external_deps += [ "ipc:ipc_single" ]
64 }66 }
@@ -0,0 +1,44 @@
1+/*
2+ * Copyright (c) 2026 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+ 
16+#ifndef OHOS_ABILITY_RUNTIME_ETS_CHILD_PROCESS_H
17+#define OHOS_ABILITY_RUNTIME_ETS_CHILD_PROCESS_H
18+ 
19+#include "child_process.h"
20+#include "ets_runtime.h"
21+#include "ets_native_reference.h"
22+ 
23+namespace OHOS {
24+namespace AbilityRuntime {
25+class EtsChildProcess : public ChildProcess {
26+public:
27+ explicit EtsChildProcess(ETSRuntime &etsRuntime);
28+ ~EtsChildProcess() override;
29+ 
30+ static EtsChildProcess* Create(const std::unique_ptr<Runtime> &runtime);
31+ 
32+ bool Init(const std::shared_ptr<ChildProcessStartInfo> &info) override;
33+ void OnStart() override;
34+ void OnStart(std::shared_ptr<AppExecFwk::ChildProcessArgs> args) override;
35+ 
36+private:
37+ ani_ref CallObjectMethod(bool withResult, const char *name, const char *signature, ...);
38+ 
39+ ETSRuntime &etsRuntime_;
40+ std::unique_ptr<AppExecFwk::ETSNativeReference> etsChildProcessObj_;
41+};
42+} // namespace AbilityRuntime
43+} // namespace OHOS
44+#endif // OHOS_ABILITY_RUNTIME_ETS_CHILD_PROCESS_H
@@ -0,0 +1,29 @@
1+/*
2+ * Copyright (c) 2026 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+ 
16+#ifndef OHOS_ABILITY_RUNTIME_ETS_CHILD_PROCESS_INSTANCE_H
17+#define OHOS_ABILITY_RUNTIME_ETS_CHILD_PROCESS_INSTANCE_H
18+ 
19+#include "child_process.h"
20+ 
21+namespace OHOS {
22+namespace AbilityRuntime {
23+class ChildProcess;
24+class Runtime;
25+ 
26+ChildProcess *CreateETSChildProcess(const std::unique_ptr<Runtime> &runtime);
27+} // namespace AbilityRuntime
28+} // namespace OHOS
29+#endif // OHOS_ABILITY_RUNTIME_ETS_CHILD_PROCESS_INSTANCE_H
@@ -0,0 +1,189 @@
1+/*
2+ * Copyright (c) 2026 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+ 
16+#include "ets_child_process.h"
17+ 
18+#include "ani_common_child_process_param.h"
xialiangwei
xialiangweixialiangwei3月31日

字母序

likedislike
renjh5496
3月31日 评论:
19+#include "hilog_tag_wrapper.h"
20+ 
21+#ifdef WINDOWS_PLATFORM
22+#define ETS_EXPORT __declspec(dllexport)
23+#else
24+#define ETS_EXPORT __attribute__((visibility("default")))
25+#endif
26+ 
27+namespace OHOS {
28+namespace AbilityRuntime {
29+ 
30+EtsChildProcess* EtsChildProcess::Create(const std::unique_ptr<Runtime> &runtime)
31+{
32+ if (!runtime) {
33+ TAG_LOGE(AAFwkTag::PROCESSMGR, "null runtime");
34+ return nullptr;
35+ }
36+ return new (std::nothrow) EtsChildProcess(static_cast<ETSRuntime &>(*runtime));
37+}
38+ 
39+EtsChildProcess::EtsChildProcess(ETSRuntime &etsRuntime) : etsRuntime_(etsRuntime) {}
40+ 
41+EtsChildProcess::~EtsChildProcess()
42+{
43+ TAG_LOGD(AAFwkTag::PROCESSMGR, "EtsChildProcess destroy");
44+ etsChildProcessObj_.reset();
45+}
46+ 
47+bool EtsChildProcess::Init(const std::shared_ptr<ChildProcessStartInfo> &info)
48+{
49+ TAG_LOGI(AAFwkTag::PROCESSMGR, "EtsChildProcess Init called");
50+ if (info == nullptr) {
51+ TAG_LOGE(AAFwkTag::PROCESSMGR, "null info");
52+ return false;
53+ }
54+ bool ret = ChildProcess::Init(info);
55+ if (!ret) {
56+ TAG_LOGE(AAFwkTag::PROCESSMGR, "ChildProcess init failed");
57+ return false;
58+ }
59+ if (info->srcEntry.empty()) {
60+ TAG_LOGE(AAFwkTag::PROCESSMGR, "Empty info srcEntry");
61+ return false;
62+ }
63+ 
64+ std::string srcEntrance = info->srcEntry;
65+ auto pos = srcEntrance.rfind(".ets");
66+ if (pos != std::string::npos) {
xialiangwei
xialiangweixialiangwei3月31日

确认下是否冗余

likedislike
renjh5496
3月31日 评论:
67+ srcEntrance.erase(pos);
68+ }
69+ 
70+ std::string srcPath(info->moduleName);
71+ srcPath.append("/").append(srcEntrance);
72+ if (pos != std::string::npos) {
73+ srcPath.append(".abc");
74+ }
75+ 
76+ std::string moduleName(info->moduleName);
77+ moduleName.append("::").append(info->name);
78+ 
79+ auto env = etsRuntime_.GetAniEnv();
80+ if (env == nullptr) {
81+ TAG_LOGE(AAFwkTag::PROCESSMGR, "null env");
82+ return false;
83+ }
84+ 
85+ etsChildProcessObj_ = etsRuntime_.LoadModule(moduleName, srcPath, info->hapPath, info->isEsModule, false,
86+ srcEntrance);
87+ if (etsChildProcessObj_ == nullptr) {
88+ TAG_LOGE(AAFwkTag::PROCESSMGR, "null etsChildProcessObj_");
89+ return false;
90+ }
91+ return true;
92+}
93+ 
94+void EtsChildProcess::OnStart()
95+{
96+ TAG_LOGI(AAFwkTag::PROCESSMGR, "EtsChildProcess OnStart called");
97+ ChildProcess::OnStart();
98+ auto env = etsRuntime_.GetAniEnv();
99+ if (env == nullptr) {
100+ TAG_LOGE(AAFwkTag::PROCESSMGR, "null env");
101+ return;
102+ }
103+ ani_ref undefinedRef = nullptr;
104+ ani_status status = ANI_ERROR;
105+ if ((status = env->GetUndefined(&undefinedRef)) != ANI_OK) {
106+ TAG_LOGE(AAFwkTag::PROCESSMGR, "GetUndefined failed, status: %{public}d", status);
107+ return;
108+ }
109+ CallObjectMethod(false, "onStart", nullptr, reinterpret_cast<ani_object>(undefinedRef));
110+}
111+ 
112+void EtsChildProcess::OnStart(std::shared_ptr<AppExecFwk::ChildProcessArgs> args)
113+{
114+ TAG_LOGI(AAFwkTag::PROCESSMGR, "EtsChildProcess OnStart with args called");
115+ if (!args) {
116+ TAG_LOGE(AAFwkTag::PROCESSMGR, "null args");
117+ return;
118+ }
119+ ChildProcess::OnStart(args);
120+ 
121+ auto env = etsRuntime_.GetAniEnv();
122+ if (env == nullptr) {
123+ TAG_LOGE(AAFwkTag::PROCESSMGR, "null env");
124+ return;
125+ }
126+ 
127+ if (etsChildProcessObj_ == nullptr || etsChildProcessObj_->aniCls == nullptr) {
128+ TAG_LOGE(AAFwkTag::PROCESSMGR, "null etsChildProcessObj_ or aniCls");
129+ return;
130+ }
131+ 
132+ // Convert ChildProcessArgs to ANI object
133+ ani_object aniArgs = AppExecFwk::WrapChildProcessArgs(env, *args);
134+ if (aniArgs == nullptr) {
135+ TAG_LOGE(AAFwkTag::PROCESSMGR, "WrapChildProcessArgs failed");
136+ return;
137+ }
138+ CallObjectMethod(false, "onStart", nullptr, aniArgs);
139+}
140+ 
141+ani_ref EtsChildProcess::CallObjectMethod(bool withResult, const char *name, const char *signature, ...)
142+{
143+ TAG_LOGI(AAFwkTag::PROCESSMGR, "EtsChildProcess CallObjectMethod");
144+ ani_status status = ANI_ERROR;
145+ ani_method method = nullptr;
146+ auto env = etsRuntime_.GetAniEnv();
147+ if (env == nullptr) {
148+ TAG_LOGE(AAFwkTag::PROCESSMGR, "null env");
149+ return nullptr;
150+ }
151+ if (etsChildProcessObj_ == nullptr) {
152+ TAG_LOGE(AAFwkTag::PROCESSMGR, "null etsChildProcessObj_");
153+ return nullptr;
154+ }
155+ if ((status = env->Class_FindMethod(etsChildProcessObj_->aniCls, name, signature, &method)) != ANI_OK) {
xialiangwei
xialiangweixialiangwei3月31日

etsChildProcessObj_判空

likedislike
renjh5496
3月31日 评论:
156+ TAG_LOGE(AAFwkTag::PROCESSMGR, "Class_FindMethod failed, status: %{public}d", status);
157+ return nullptr;
158+ }
159+ if (method == nullptr) {
160+ TAG_LOGE(AAFwkTag::PROCESSMGR, "null method");
161+ return nullptr;
xialiangwei
xialiangweixialiangwei3月31日

加一下error日志

likedislike
renjh5496
3月31日 评论:
162+ }
163+ ani_ref res = nullptr;
164+ va_list args;
165+ if (withResult) {
166+ va_start(args, signature);
xialiangwei
xialiangweixialiangwei3月31日

了解下va_start和va_end的用途

likedislike
renjh5496
3月31日 评论:
167+ if ((status = env->Object_CallMethod_Ref_V(etsChildProcessObj_->aniObj, method, &res, args)) != ANI_OK) {
168+ TAG_LOGE(AAFwkTag::PROCESSMGR, "status : %{public}d", status);
169+ va_end(args);
170+ return nullptr;
171+ }
172+ va_end(args);
173+ return res;
174+ }
175+ va_start(args, signature);
176+ if ((status = env->Object_CallMethod_Void_V(etsChildProcessObj_->aniObj, method, args)) != ANI_OK) {
177+ TAG_LOGE(AAFwkTag::PROCESSMGR, "status : %{public}d", status);
178+ }
179+ va_end(args);
180+ return nullptr;
181+}
182+} // namespace AbilityRuntime
183+} // namespace OHOS
184+ 
185+ETS_EXPORT extern "C" OHOS::AbilityRuntime::ChildProcess* OHOS_ETS_Child_Process_Create(
186+ const std::unique_ptr<OHOS::AbilityRuntime::Runtime> &runtime)
187+{
188+ return OHOS::AbilityRuntime::EtsChildProcess::Create(runtime);
189+}
@@ -0,0 +1,52 @@
1+/*
2+ * Copyright (c) 2026 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+ 
16+#include "ets_child_process_instance.h"
17+ 
18+#include <cstddef>
19+#include <dlfcn.h>
20+ 
21+#include "hilog_tag_wrapper.h"
22+ 
23+namespace OHOS {
24+namespace AbilityRuntime {
25+namespace {
26+constexpr const char *ETS_ANI_LIBNAME = "libability_child_process_manager_ani_kit.z.so";
27+constexpr const char *ETS_ANI_CREATE_FUNC = "OHOS_ETS_Child_Process_Create";
28+using CreateETSChildProcessFunc = ChildProcess*(*)(const std::unique_ptr<Runtime>&);
29+CreateETSChildProcessFunc g_etsCreateFunc = nullptr;
30+}
31+ 
32+ChildProcess *CreateETSChildProcess(const std::unique_ptr<Runtime> &runtime)
33+{
34+ if (g_etsCreateFunc != nullptr) {
35+ return g_etsCreateFunc(runtime);
36+ }
37+ auto handle = dlopen(ETS_ANI_LIBNAME, RTLD_LAZY);
38+ if (handle == nullptr) {
39+ TAG_LOGE(AAFwkTag::PROCESSMGR, "dlopen failed %{public}s, %{public}s", ETS_ANI_LIBNAME, dlerror());
40+ return nullptr;
41+ }
42+ auto symbol = dlsym(handle, ETS_ANI_CREATE_FUNC);
43+ if (symbol == nullptr) {
44+ TAG_LOGE(AAFwkTag::PROCESSMGR, "dlsym failed %{public}s, %{public}s", ETS_ANI_CREATE_FUNC, dlerror());
45+ dlclose(handle);
46+ return nullptr;
47+ }
48+ g_etsCreateFunc = reinterpret_cast<CreateETSChildProcessFunc>(symbol);
49+ return g_etsCreateFunc(runtime);
50+}
51+} // namespace AbilityRuntime
52+} // namespace OHOS
@@ -27,16 +27,27 @@ namespace OHOS {
27namespace ChildProcessManagerEts {27namespace ChildProcessManagerEts {
28namespace {28namespace {
29constexpr const char* CHILD_PROCESS_MANAGER_NAME_SPACE = "@ohos.app.ability.childProcessManager.childProcessManager";29constexpr const char* CHILD_PROCESS_MANAGER_NAME_SPACE = "@ohos.app.ability.childProcessManager.childProcessManager";
30+constexpr size_t ETS_SUFFIX_LEN = 4;
30enum {31enum {
31 MODE_SELF_FORK = 0,32 MODE_SELF_FORK = 0,
32 MODE_APP_SPAWN_FORK = 1,33 MODE_APP_SPAWN_FORK = 1,
33};34};
34struct ChildProcessAniParam {35struct ChildProcessAniParam {
35 std::string srcEntry;36 std::string srcEntry;
37+ bool isStaticChildProcess = false;
36 AppExecFwk::ChildProcessArgs args;38 AppExecFwk::ChildProcessArgs args;
37 AppExecFwk::ChildProcessOptions options;39 AppExecFwk::ChildProcessOptions options;
38 int32_t childProcessType;40 int32_t childProcessType;
39};41};
42+ 
43+void ProcessSrcEntry(std::string &srcEntry, bool &isStaticChildProcess)
44+{
45+ if (srcEntry.size() >= ETS_SUFFIX_LEN && srcEntry.substr(srcEntry.size() - ETS_SUFFIX_LEN) != ".ets") {
46+ isStaticChildProcess = true;
47+ } else {
48+ isStaticChildProcess = false;
49+ }
50+}
40}51}
41 52 
42class EtsChildProcessManager {53class EtsChildProcessManager {
@@ -118,7 +129,10 @@ private:
118 "Parse param srcEntry failed, must be a valid string.");129 "Parse param srcEntry failed, must be a valid string.");
119 return;130 return;
120 }131 }
121- TAG_LOGD(AAFwkTag::PROCESSMGR, "srcEntry %{public}s", srcEntry.c_str());132+ bool isStaticChildProcess = false;
133+ ProcessSrcEntry(srcEntry, isStaticChildProcess);
134+ TAG_LOGD(AAFwkTag::PROCESSMGR, "srcEntry %{public}s, isStaticChildProcess %{public}d", srcEntry.c_str(),
135+ isStaticChildProcess);
122 int32_t startMode;136 int32_t startMode;
123 if (!AAFwk::AniEnumConvertUtil::EnumConvert_EtsToNative(env, etsStartMode, startMode)) {137 if (!AAFwk::AniEnumConvertUtil::EnumConvert_EtsToNative(env, etsStartMode, startMode)) {
124 TAG_LOGE(AAFwkTag::PROCESSMGR, "Parse startMode failed");138 TAG_LOGE(AAFwkTag::PROCESSMGR, "Parse startMode failed");
@@ -134,13 +148,14 @@ private:
134 return;148 return;
135 }149 }
136 if (startMode == MODE_SELF_FORK) {150 if (startMode == MODE_SELF_FORK) {
137- StartChildProcessSelfForkTask(env, srcEntry, callback);151+ StartChildProcessSelfForkTask(env, srcEntry, callback, isStaticChildProcess);
138 } else {152 } else {
139- StartChildProcessAppSpawnForkTask(env, srcEntry, callback);153+ StartChildProcessAppSpawnForkTask(env, srcEntry, callback, isStaticChildProcess);
140 }154 }
141 }155 }
142 156 
143- void StartChildProcessSelfForkTask(ani_env *env, std::string &etsSrcEntry, ani_object callback)157+ void StartChildProcessSelfForkTask(ani_env *env, std::string &etsSrcEntry, ani_object callback,
158+ bool isStaticChildProcess)
144 {159 {
145 ani_status status = ANI_ERROR;160 ani_status status = ANI_ERROR;
146 ani_vm *aniVM = nullptr;161 ani_vm *aniVM = nullptr;
@@ -155,7 +170,7 @@ private:
155 AbilityRuntime::EtsErrorUtil::ThrowInvalidParamError(env, "GlobalReference_Create failed.");170 AbilityRuntime::EtsErrorUtil::ThrowInvalidParamError(env, "GlobalReference_Create failed.");
156 return;171 return;
157 }172 }
158- auto task = [aniVM, etsSrcEntry, callbackRef]() {173+ auto task = [aniVM, etsSrcEntry, isStaticChildProcess, callbackRef]() {
159 if (aniVM == nullptr || callbackRef == nullptr) {174 if (aniVM == nullptr || callbackRef == nullptr) {
160 TAG_LOGE(AAFwkTag::PROCESSMGR, "aniVM or callbackRef is null");175 TAG_LOGE(AAFwkTag::PROCESSMGR, "aniVM or callbackRef is null");
161 return;176 return;
@@ -167,8 +182,8 @@ private:
167 return;182 return;
168 }183 }
169 pid_t pid = 0;184 pid_t pid = 0;
170- AbilityRuntime::ChildProcessManagerErrorCode errorCode =185+ auto errorCode = AbilityRuntime::ChildProcessManager::GetInstance().StartChildProcessBySelfFork(
171- AbilityRuntime::ChildProcessManager::GetInstance().StartChildProcessBySelfFork(etsSrcEntry, pid);186+ etsSrcEntry, pid, isStaticChildProcess);
172 TAG_LOGD(AAFwkTag::PROCESSMGR, "StartChildProcessBySelfFork errorCode: %{public}d, pid: %{public}d",187 TAG_LOGD(AAFwkTag::PROCESSMGR, "StartChildProcessBySelfFork errorCode: %{public}d, pid: %{public}d",
173 errorCode, pid);188 errorCode, pid);
174 if (errorCode != AbilityRuntime::ChildProcessManagerErrorCode::ERR_OK) {189 if (errorCode != AbilityRuntime::ChildProcessManagerErrorCode::ERR_OK) {
@@ -192,11 +207,13 @@ private:
192 }207 }
193 }208 }
194 209 
195- void StartChildProcessAppSpawnForkTask(ani_env *env, std::string &etsSrcEntry, ani_object callback)210+ void StartChildProcessAppSpawnForkTask(ani_env *env, std::string &etsSrcEntry, ani_object callback,
211+ bool isStaticChildProcess)
196 {212 {
197 pid_t pid = ERR_INVALID_VALUE;213 pid_t pid = ERR_INVALID_VALUE;
198 AbilityRuntime::ChildProcessManagerErrorCode innerErrorCode =214 AbilityRuntime::ChildProcessManagerErrorCode innerErrorCode =
199- AbilityRuntime::ChildProcessManager::GetInstance().StartChildProcessByAppSpawnFork(etsSrcEntry, pid);215+ AbilityRuntime::ChildProcessManager::GetInstance().StartChildProcessByAppSpawnFork(etsSrcEntry, pid,
216+ isStaticChildProcess);
200 TAG_LOGD(AAFwkTag::PROCESSMGR, "StartChildProcessByAppSpawnFork innerErrorCode: %{public}d, pid: %{public}d",217 TAG_LOGD(AAFwkTag::PROCESSMGR, "StartChildProcessByAppSpawnFork innerErrorCode: %{public}d, pid: %{public}d",
201 innerErrorCode, pid);218 innerErrorCode, pid);
202 if (innerErrorCode != AbilityRuntime::ChildProcessManagerErrorCode::ERR_OK) {219 if (innerErrorCode != AbilityRuntime::ChildProcessManagerErrorCode::ERR_OK) {
@@ -238,7 +255,10 @@ private:
238 "Param srcEntry cannot be empty.");255 "Param srcEntry cannot be empty.");
239 return;256 return;
240 }257 }
241- TAG_LOGD(AAFwkTag::PROCESSMGR, "srcEntry: %{public}s", srcEntry.c_str());258+ bool isStaticChildProcess = false;
259+ ProcessSrcEntry(srcEntry, isStaticChildProcess);
260+ TAG_LOGD(AAFwkTag::PROCESSMGR, "srcEntry: %{public}s, isStaticChildProcess: %{public}d", srcEntry.c_str(),
261+ isStaticChildProcess);
242 AppExecFwk::ChildProcessArgs args;262 AppExecFwk::ChildProcessArgs args;
243 AppExecFwk::ChildProcessOptions options;263 AppExecFwk::ChildProcessOptions options;
244 if (!ParseArgsAndOptions(env, childProcessArgs, childProcessOptions, args, options)) {264 if (!ParseArgsAndOptions(env, childProcessArgs, childProcessOptions, args, options)) {
@@ -246,6 +266,7 @@ private:
246 }266 }
247 ChildProcessAniParam param;267 ChildProcessAniParam param;
248 param.srcEntry = srcEntry;268 param.srcEntry = srcEntry;
269+ param.isStaticChildProcess = isStaticChildProcess;
249 param.args = args;270 param.args = args;
250 param.options = options;271 param.options = options;
251 param.childProcessType = AppExecFwk::CHILD_PROCESS_TYPE_ARK;272 param.childProcessType = AppExecFwk::CHILD_PROCESS_TYPE_ARK;
@@ -325,13 +346,14 @@ private:
325 {346 {
326 pid_t pid = 0;347 pid_t pid = 0;
327 TAG_LOGD(AAFwkTag::PROCESSMGR,348 TAG_LOGD(AAFwkTag::PROCESSMGR,
328- "StartChildProcessWithArgs, childProcessType:%{public}d, srcEntry:%{private}s, "349+ "StartChildProcessWithArgs, childProcessType:%{public}d, srcEntry:%{private}s,"
329- "args.entryParams size:%{public}zu, args.fds size:%{public}zu, options.isolationMode:%{public}d",350+ "isStaticChildProcess:%{public}d, args.entryParams size:%{public}zu, args.fds size:%{public}zu, "
330- param.childProcessType, param.srcEntry.c_str(), param.args.entryParams.length(),351+ "options.isolationMode:%{public}d", param.childProcessType, param.srcEntry.c_str(),
331- param.args.fds.size(), param.options.isolationMode);352+ param.isStaticChildProcess, param.args.entryParams.length(), param.args.fds.size(),
353+ param.options.isolationMode);
332 AbilityRuntime::ChildProcessManagerErrorCode errorCode =354 AbilityRuntime::ChildProcessManagerErrorCode errorCode =
333 AbilityRuntime::ChildProcessManager::GetInstance().StartChildProcessWithArgs(355 AbilityRuntime::ChildProcessManager::GetInstance().StartChildProcessWithArgs(
334- param.srcEntry, pid, param.childProcessType, param.args, param.options);356+ param.srcEntry, pid, param.childProcessType, param.args, param.options, param.isStaticChildProcess);
335 if (errorCode != AbilityRuntime::ChildProcessManagerErrorCode::ERR_OK) {357 if (errorCode != AbilityRuntime::ChildProcessManagerErrorCode::ERR_OK) {
336 TAG_LOGE(AAFwkTag::PROCESSMGR, "StartChildProcessWithArgs failed, errorCode: %{public}d", errorCode);358 TAG_LOGE(AAFwkTag::PROCESSMGR, "StartChildProcessWithArgs failed, errorCode: %{public}d", errorCode);
337 AppExecFwk::AsyncCallback(env, callback, AbilityRuntime::EtsErrorUtil::CreateError(env,359 AppExecFwk::AsyncCallback(env, callback, AbilityRuntime::EtsErrorUtil::CreateError(env,
@@ -0,0 +1,20 @@
1+/*
2+ * Copyright (c) 2026 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+ 
16+import { ChildProcessArgs } from '@ohos.app.ability.ChildProcessArgs';
17+ 
18+export default class ChildProcess {
19+ onStart(args?: ChildProcessArgs): void {}
20+}
@@ -197,6 +197,23 @@ ohos_prebuilt_etc("ability_runtime_extension_context_abc_etc") {
197 deps = [ ":ability_runtime_extension_context_abc" ]197 deps = [ ":ability_runtime_extension_context_abc" ]
198}198}
199 199 
200+generate_static_abc("ability_runtime_child_process_abc") {
201+ base_url = "./"
202+ files = [ "./@ohos.app.ability.ChildProcess.ets" ]
203+ 
204+ is_boot_abc = "True"
205+ device_dst_file =
206+ "/system/framework/ability_runtime_child_process_abc.abc"
207+}
208+ 
209+ohos_prebuilt_etc("ability_runtime_child_process_abc_etc") {
210+ source = "$target_out_dir/ability_runtime_child_process_abc.abc"
211+ module_install_dir = "framework"
212+ subsystem_name = "ability"
213+ part_name = "ability_runtime"
214+ deps = [ ":ability_runtime_child_process_abc" ]
215+}
216+ 
200generate_static_abc("ability_runtime_child_process_args_abc") {217generate_static_abc("ability_runtime_child_process_args_abc") {
201 base_url = "./"218 base_url = "./"
202 files = [ "./@ohos.app.ability.ChildProcessArgs.ets" ]219 files = [ "./@ohos.app.ability.ChildProcessArgs.ets" ]
@@ -2105,6 +2122,7 @@ group("ets_packages") {
2105 ":ability_runtime_auto_startup_manager_abc_etc",2122 ":ability_runtime_auto_startup_manager_abc_etc",
2106 ":ability_runtime_base_context_abc_etc",2123 ":ability_runtime_base_context_abc_etc",
2107 ":ability_runtime_caller_callee_abc_etc",2124 ":ability_runtime_caller_callee_abc_etc",
2125+ ":ability_runtime_child_process_abc_etc",
2108 ":ability_runtime_child_process_args_abc_etc",2126 ":ability_runtime_child_process_args_abc_etc",
2109 ":ability_runtime_child_process_manager_abc_etc",2127 ":ability_runtime_child_process_manager_abc_etc",
2110 ":ability_runtime_child_process_options_abc_etc",2128 ":ability_runtime_child_process_options_abc_etc",
@@ -31,16 +31,27 @@ namespace AbilityRuntime {
31namespace {31namespace {
32constexpr const char *PROCESS_MANAGER_NAME = "JsChildProcessManager";32constexpr const char *PROCESS_MANAGER_NAME = "JsChildProcessManager";
33constexpr size_t ARGC_TWO = 2;33constexpr size_t ARGC_TWO = 2;
34+constexpr size_t ETS_SUFFIX_LEN = 4;
34enum {35enum {
35 MODE_SELF_FORK = 0,36 MODE_SELF_FORK = 0,
36 MODE_APP_SPAWN_FORK = 1,37 MODE_APP_SPAWN_FORK = 1,
37};38};
38struct ChildProcessNApiParam {39struct ChildProcessNApiParam {
39 std::string srcEntry;40 std::string srcEntry;
41+ bool isStaticChildProcess = false;
40 AppExecFwk::ChildProcessArgs args;42 AppExecFwk::ChildProcessArgs args;
41 AppExecFwk::ChildProcessOptions options;43 AppExecFwk::ChildProcessOptions options;
42 int32_t childProcessType;44 int32_t childProcessType;
43};45};
46+ 
47+void ProcessSrcEntry(std::string &srcEntry, bool &isStaticChildProcess)
48+{
49+ if (srcEntry.size() >= ETS_SUFFIX_LEN && srcEntry.substr(srcEntry.size() - ETS_SUFFIX_LEN) != ".ets") {
50+ isStaticChildProcess = true;
51+ } else {
52+ isStaticChildProcess = false;
53+ }
54+}
44}55}
45 56 
46class JsChildProcessManager {57class JsChildProcessManager {
@@ -90,6 +101,8 @@ private:
90 ThrowInvalidParamError(env, "Parse param srcEntry failed, must be a valid string.");101 ThrowInvalidParamError(env, "Parse param srcEntry failed, must be a valid string.");
91 return CreateJsUndefined(env);102 return CreateJsUndefined(env);
92 }103 }
104+ bool isStaticChildProcess = false;
105+ ProcessSrcEntry(srcEntry, isStaticChildProcess);
93 if (!ConvertFromJsValue(env, argv[PARAM1], startMode)) {106 if (!ConvertFromJsValue(env, argv[PARAM1], startMode)) {
94 TAG_LOGE(AAFwkTag::PROCESSMGR, "Parse startMode failed");107 TAG_LOGE(AAFwkTag::PROCESSMGR, "Parse startMode failed");
95 ThrowInvalidParamError(env,108 ThrowInvalidParamError(env,
@@ -106,20 +119,21 @@ private:
106 napi_value result = nullptr;119 napi_value result = nullptr;
107 napi_value lastParam = (argc <= ARGC_TWO) ? nullptr : argv[ARGC_TWO];120 napi_value lastParam = (argc <= ARGC_TWO) ? nullptr : argv[ARGC_TWO];
108 if (startMode == MODE_SELF_FORK) {121 if (startMode == MODE_SELF_FORK) {
109- StartChildProcessSelfForkTask(env, lastParam, result, srcEntry);122+ StartChildProcessSelfForkTask(env, lastParam, result, srcEntry, isStaticChildProcess);
110 } else {123 } else {
111- StartChildProcessAppSpawnForkTask(env, lastParam, result, srcEntry);124+ StartChildProcessAppSpawnForkTask(env, lastParam, result, srcEntry, isStaticChildProcess);
112 }125 }
113 return result;126 return result;
114 }127 }
115 128 
116 void StartChildProcessSelfForkTask(const napi_env &env, const napi_value &lastParam, napi_value &result,129 void StartChildProcessSelfForkTask(const napi_env &env, const napi_value &lastParam, napi_value &result,
117- const std::string &srcEntry)130+ const std::string &srcEntry, bool isStaticChildProcess)
118 {131 {
119- NapiAsyncTask::CompleteCallback complete = [srcEntry](napi_env env, NapiAsyncTask &task, int32_t status) {132+ NapiAsyncTask::CompleteCallback complete =
133+ [srcEntry, isStaticChildProcess](napi_env env, NapiAsyncTask &task, int32_t status) {
120 pid_t pid = 0;134 pid_t pid = 0;
121 ChildProcessManagerErrorCode errorCode =135 ChildProcessManagerErrorCode errorCode =
122- ChildProcessManager::GetInstance().StartChildProcessBySelfFork(srcEntry, pid);136+ ChildProcessManager::GetInstance().StartChildProcessBySelfFork(srcEntry, pid, isStaticChildProcess);
123 if (errorCode == ChildProcessManagerErrorCode::ERR_OK) {137 if (errorCode == ChildProcessManagerErrorCode::ERR_OK) {
124 task.ResolveWithNoError(env, CreateJsValue(env, pid));138 task.ResolveWithNoError(env, CreateJsValue(env, pid));
125 } else {139 } else {
@@ -132,16 +146,17 @@ private:
132 }146 }
133 147 
134 void StartChildProcessAppSpawnForkTask(const napi_env &env, const napi_value &lastParam, napi_value &result,148 void StartChildProcessAppSpawnForkTask(const napi_env &env, const napi_value &lastParam, napi_value &result,
135- const std::string &srcEntry)149+ const std::string &srcEntry, bool isStaticChildProcess)
136 {150 {
137 auto innerErrorCode = std::make_shared<ChildProcessManagerErrorCode>(ChildProcessManagerErrorCode::ERR_OK);151 auto innerErrorCode = std::make_shared<ChildProcessManagerErrorCode>(ChildProcessManagerErrorCode::ERR_OK);
138 auto pid = std::make_shared<pid_t>(ERR_INVALID_VALUE);152 auto pid = std::make_shared<pid_t>(ERR_INVALID_VALUE);
139- NapiAsyncTask::ExecuteCallback execute = [srcEntry, pid, innerErrorCode]() {153+ NapiAsyncTask::ExecuteCallback execute = [srcEntry, isStaticChildProcess, pid, innerErrorCode]() {
140 if (!pid || !innerErrorCode) {154 if (!pid || !innerErrorCode) {
141 TAG_LOGE(AAFwkTag::PROCESSMGR, "null innerErrorCode or pid");155 TAG_LOGE(AAFwkTag::PROCESSMGR, "null innerErrorCode or pid");
142 return;156 return;
143 }157 }
144- *innerErrorCode = ChildProcessManager::GetInstance().StartChildProcessByAppSpawnFork(srcEntry, *pid);158+ *innerErrorCode = ChildProcessManager::GetInstance().StartChildProcessByAppSpawnFork(srcEntry, *pid,
159+ isStaticChildProcess);
145 };160 };
146 NapiAsyncTask::CompleteCallback complete =161 NapiAsyncTask::CompleteCallback complete =
147 [pid, innerErrorCode](napi_env env, NapiAsyncTask &task, int32_t status) {162 [pid, innerErrorCode](napi_env env, NapiAsyncTask &task, int32_t status) {
@@ -187,11 +202,14 @@ private:
187 ThrowInvalidParamError(env, "Param srcEntry cannot be empty.");202 ThrowInvalidParamError(env, "Param srcEntry cannot be empty.");
188 return CreateJsUndefined(env);203 return CreateJsUndefined(env);
189 }204 }
205+ bool isStaticChildProcess = false;
206+ ProcessSrcEntry(srcEntry, isStaticChildProcess);
190 if (!ParseArgsAndOptions(env, argv, argc, args, options)) {207 if (!ParseArgsAndOptions(env, argv, argc, args, options)) {
191 return CreateJsUndefined(env);208 return CreateJsUndefined(env);
192 }209 }
193 ChildProcessNApiParam param;210 ChildProcessNApiParam param;
194 param.srcEntry = srcEntry;211 param.srcEntry = srcEntry;
212+ param.isStaticChildProcess = isStaticChildProcess;
195 param.args = args;213 param.args = args;
196 param.options = options;214 param.options = options;
197 param.childProcessType = AppExecFwk::CHILD_PROCESS_TYPE_ARK;215 param.childProcessType = AppExecFwk::CHILD_PROCESS_TYPE_ARK;
@@ -266,21 +284,24 @@ private:
266 void StartChildProcessWithArgsTask(const napi_env &env, napi_value &result, const ChildProcessNApiParam &param)284 void StartChildProcessWithArgsTask(const napi_env &env, napi_value &result, const ChildProcessNApiParam &param)
267 {285 {
268 auto &srcEntry = param.srcEntry;286 auto &srcEntry = param.srcEntry;
287+ auto isStaticChildProcess = param.isStaticChildProcess;
269 auto &args = param.args;288 auto &args = param.args;
270 auto &options = param.options;289 auto &options = param.options;
271 auto childProcessType = param.childProcessType;290 auto childProcessType = param.childProcessType;
272 TAG_LOGD(AAFwkTag::PROCESSMGR, "StartChildProcessWithArgs, childProcessType:%{public}d, srcEntry:%{private}s, "291 TAG_LOGD(AAFwkTag::PROCESSMGR, "StartChildProcessWithArgs, childProcessType:%{public}d, srcEntry:%{private}s, "
273- "args.entryParams size:%{public}zu, args.fds size:%{public}zu, options.isolationMode:%{public}d",292+ "isStaticChildProcess:%{public}d, args.entryParams size:%{public}zu, args.fds size:%{public}zu, "
274- childProcessType, srcEntry.c_str(), args.entryParams.length(), args.fds.size(), options.isolationMode);293+ "options.isolationMode:%{public}d", childProcessType, srcEntry.c_str(), isStaticChildProcess,
294+ args.entryParams.length(), args.fds.size(), options.isolationMode);
275 auto innerErrorCode = std::make_shared<ChildProcessManagerErrorCode>(ChildProcessManagerErrorCode::ERR_OK);295 auto innerErrorCode = std::make_shared<ChildProcessManagerErrorCode>(ChildProcessManagerErrorCode::ERR_OK);
276 auto pid = std::make_shared<pid_t>(0);296 auto pid = std::make_shared<pid_t>(0);
277- NapiAsyncTask::ExecuteCallback execute = [srcEntry, args, options, childProcessType, pid, innerErrorCode]() {297+ NapiAsyncTask::ExecuteCallback execute = [srcEntry, isStaticChildProcess, args, options, childProcessType, pid,
298+ innerErrorCode]() {
278 if (!pid || !innerErrorCode) {299 if (!pid || !innerErrorCode) {
279 TAG_LOGE(AAFwkTag::PROCESSMGR, "null pid or innerErrorCode");300 TAG_LOGE(AAFwkTag::PROCESSMGR, "null pid or innerErrorCode");
280 return;301 return;
281 }302 }
282 *innerErrorCode = ChildProcessManager::GetInstance().StartChildProcessWithArgs(srcEntry, *pid,303 *innerErrorCode = ChildProcessManager::GetInstance().StartChildProcessWithArgs(srcEntry, *pid,
283- childProcessType, args, options);304+ childProcessType, args, options, isStaticChildProcess);
284 };305 };
285 NapiAsyncTask::CompleteCallback complete =306 NapiAsyncTask::CompleteCallback complete =
286 [pid, innerErrorCode](napi_env env, NapiAsyncTask &task, int32_t status) {307 [pid, innerErrorCode](napi_env env, NapiAsyncTask &task, int32_t status) {
@@ -16,6 +16,7 @@
16#include "child_process.h"16#include "child_process.h"
17 17 
18#include "js_child_process.h"18#include "js_child_process.h"
19+#include "ets_child_process_instance.h"
19 20 
20namespace OHOS {21namespace OHOS {
21namespace AbilityRuntime {22namespace AbilityRuntime {
@@ -27,6 +28,13 @@ std::shared_ptr<ChildProcess> ChildProcess::Create(const std::unique_ptr<Runtime
27 switch (runtime->GetLanguage()) {28 switch (runtime->GetLanguage()) {
28 case AbilityRuntime::Runtime::Language::JS:29 case AbilityRuntime::Runtime::Language::JS:
29 return AbilityRuntime::JsChildProcess::Create(runtime);30 return AbilityRuntime::JsChildProcess::Create(runtime);
31+ case AbilityRuntime::Runtime::Language::ETS: {
32+ auto* childProcess = AbilityRuntime::CreateETSChildProcess(runtime);
33+ if (childProcess == nullptr) {
34+ return nullptr;
35+ }
36+ return std::shared_ptr<ChildProcess>(childProcess);
37+ }
30 default:38 default:
31 return std::make_shared<ChildProcess>();39 return std::make_shared<ChildProcess>();
32 }40 }
@@ -39,6 +39,7 @@
39#include "errors.h"39#include "errors.h"
40#include "hap_module_info.h"40#include "hap_module_info.h"
41#include "hilog_tag_wrapper.h"41#include "hilog_tag_wrapper.h"
42+#include "ohos_application.h"
42#include "parameters.h"43#include "parameters.h"
43#include "runtime.h"44#include "runtime.h"
44#include "sys_mgr_client.h"45#include "sys_mgr_client.h"
@@ -70,7 +71,8 @@ ChildProcessManager::~ChildProcessManager()
70 TAG_LOGD(AAFwkTag::PROCESSMGR, "called");71 TAG_LOGD(AAFwkTag::PROCESSMGR, "called");
71}72}
72 73 
73-ChildProcessManagerErrorCode ChildProcessManager::StartChildProcessBySelfFork(const std::string &srcEntry, pid_t &pid)74+ChildProcessManagerErrorCode ChildProcessManager::StartChildProcessBySelfFork(
75+ const std::string &srcEntry, pid_t &pid, bool isStaticChildProcess)
74{76{
75 TAG_LOGI(AAFwkTag::PROCESSMGR, "called");77 TAG_LOGI(AAFwkTag::PROCESSMGR, "called");
76 ChildProcessManagerErrorCode errorCode = PreCheckSelfFork();78 ChildProcessManagerErrorCode errorCode = PreCheckSelfFork();
@@ -101,7 +103,7 @@ ChildProcessManagerErrorCode ChildProcessManager::StartChildProcessBySelfFork(co
101 if (prctl(PR_SET_NAME, processName) < 0) {103 if (prctl(PR_SET_NAME, processName) < 0) {
102 TAG_LOGW(AAFwkTag::PROCESSMGR, "set process name failed %{public}d", errno);104 TAG_LOGW(AAFwkTag::PROCESSMGR, "set process name failed %{public}d", errno);
103 }105 }
104- HandleChildProcessBySelfFork(srcEntry, bundleInfo);106+ HandleChildProcessBySelfFork(srcEntry, bundleInfo, isStaticChildProcess);
105 }107 }
106 return ChildProcessManagerErrorCode::ERR_OK;108 return ChildProcessManagerErrorCode::ERR_OK;
107}109}
@@ -124,16 +126,17 @@ bool ChildProcessManager::IsMultiProcessFeatureApp(const AppExecFwk::BundleInfo
124}126}
125 127 
126ChildProcessManagerErrorCode ChildProcessManager::StartChildProcessByAppSpawnFork(128ChildProcessManagerErrorCode ChildProcessManager::StartChildProcessByAppSpawnFork(
127- const std::string &srcEntry, pid_t &pid)129+ const std::string &srcEntry, pid_t &pid, bool isStaticChildProcess)
128{130{
129 AppExecFwk::ChildProcessArgs args;131 AppExecFwk::ChildProcessArgs args;
130 AppExecFwk::ChildProcessOptions options;132 AppExecFwk::ChildProcessOptions options;
131- return StartChildProcessWithArgs(srcEntry, pid, AppExecFwk::CHILD_PROCESS_TYPE_JS, args, options);133+ return StartChildProcessWithArgs(srcEntry, pid, AppExecFwk::CHILD_PROCESS_TYPE_JS, args, options,
134+ isStaticChildProcess);
132}135}
133 136 
134ChildProcessManagerErrorCode ChildProcessManager::StartChildProcessWithArgs(137ChildProcessManagerErrorCode ChildProcessManager::StartChildProcessWithArgs(
135 const std::string &srcEntry, pid_t &pid, int32_t childProcessType, const AppExecFwk::ChildProcessArgs &args,138 const std::string &srcEntry, pid_t &pid, int32_t childProcessType, const AppExecFwk::ChildProcessArgs &args,
136- const AppExecFwk::ChildProcessOptions &options)139+ const AppExecFwk::ChildProcessOptions &options, bool isStaticChildProcess)
137{140{
138 TAG_LOGI(AAFwkTag::PROCESSMGR, "StartChildProcessWithArgs, childProcessType:%{public}d, startWitDebug: %{public}d,"141 TAG_LOGI(AAFwkTag::PROCESSMGR, "StartChildProcessWithArgs, childProcessType:%{public}d, startWitDebug: %{public}d,"
139 "processName:%{public}s, native:%{public}d, entryParams size:%{public}zu, fdsSize:%{public}zu, "142 "processName:%{public}s, native:%{public}d, entryParams size:%{public}zu, fdsSize:%{public}zu, "
@@ -154,6 +157,7 @@ ChildProcessManagerErrorCode ChildProcessManager::StartChildProcessWithArgs(
154 request.srcEntry = srcEntry;157 request.srcEntry = srcEntry;
155 request.childProcessType = childProcessType;158 request.childProcessType = childProcessType;
156 request.isStartWithDebug = g_debugOption.isStartWithDebug;159 request.isStartWithDebug = g_debugOption.isStartWithDebug;
160+ request.isStaticChildProcess = isStaticChildProcess;
157 request.args = args;161 request.args = args;
158 request.options = options;162 request.options = options;
159 request.childProcessCount = childProcessCount_.fetch_add(1);163 request.childProcessCount = childProcessCount_.fetch_add(1);
@@ -271,8 +275,37 @@ bool ChildProcessManager::IsChildProcessBySelfFork()
271 return isChildProcessBySelfFork_;275 return isChildProcessBySelfFork_;
272}276}
273 277 
278+bool ChildProcessManager::LoadFromAppRuntime(const std::string &srcEntry,
279+ const AppExecFwk::HapModuleInfo &hapModuleInfo)
280+{
281+ std::shared_ptr<AppExecFwk::OHOSApplication> application;
282+ {
283+ std::lock_guard<std::mutex> lock(appMutex_);
284+ application = application_.lock();
285+ }
286+ if (application == nullptr) {
287+ TAG_LOGE(AAFwkTag::PROCESSMGR, "null application");
288+ return false;
289+ }
290+ auto &appRuntime = application->GetRuntime();
291+ if (appRuntime == nullptr) {
292+ TAG_LOGE(AAFwkTag::PROCESSMGR, "null appRuntime");
293+ return false;
294+ }
295+ if (appRuntime->GetLanguage() == AbilityRuntime::Runtime::Language::ETS) {
296+ TAG_LOGD(AAFwkTag::PROCESSMGR, "Reuse main process runtime");
297+ TAG_LOGD(AAFwkTag::PROCESSMGR, "StartDebugMode, isStartWithDebug: %{public}d, processName: %{public}s, "
298+ "isDebugApp: %{public}d, isStartWithNative: %{public}d", g_debugOption.isStartWithDebug,
299+ g_debugOption.processName.c_str(), g_debugOption.isDebugApp, g_debugOption.isStartWithNative);
300+ appRuntime->StartDebugMode(g_debugOption);
301+ LoadJsFile(srcEntry, hapModuleInfo, appRuntime);
302+ return true;
303+ }
304+ return false;
305+}
306+ 
274void ChildProcessManager::HandleChildProcessBySelfFork(const std::string &srcEntry,307void ChildProcessManager::HandleChildProcessBySelfFork(const std::string &srcEntry,
275- const AppExecFwk::BundleInfo &bundleInfo)308+ const AppExecFwk::BundleInfo &bundleInfo, bool isStaticChildProcess)
276{309{
277 TAG_LOGD(AAFwkTag::PROCESSMGR, "start");310 TAG_LOGD(AAFwkTag::PROCESSMGR, "start");
278 isChildProcessBySelfFork_ = true;311 isChildProcessBySelfFork_ = true;
@@ -289,24 +322,37 @@ void ChildProcessManager::HandleChildProcessBySelfFork(const std::string &srcEnt
289 return;322 return;
290 }323 }
291 324 
292- auto runtime = CreateRuntime(bundleInfo, hapModuleInfo, false, g_jitEnabled);325+ if (isStaticChildProcess) {
326+ auto pos = srcEntry.find('/');
327+ std::string prefix = (pos != std::string::npos) ? srcEntry.substr(0, pos) : srcEntry;
328+ if (prefix != "entry") {
329+ TAG_LOGE(AAFwkTag::PROCESSMGR, "srcEntry prefix is not entry, prefix: %{public}s", prefix.c_str());
330+ exit(0);
331+ }
332+ }
333+ 
334+ if (isStaticChildProcess && LoadFromAppRuntime(srcEntry, hapModuleInfo)) {
335+ TAG_LOGD(AAFwkTag::PROCESSMGR, "end");
336+ exit(0);
337+ }
338+ 
339+ auto runtime = CreateRuntime(bundleInfo, hapModuleInfo, false, g_jitEnabled, isStaticChildProcess);
293 if (!runtime) {340 if (!runtime) {
294 TAG_LOGE(AAFwkTag::PROCESSMGR, "Create runtime failed");341 TAG_LOGE(AAFwkTag::PROCESSMGR, "Create runtime failed");
295 return;342 return;
296 }343 }
344+ std::string srcPath = isStaticChildProcess ? srcEntry : hapModuleInfo.moduleName + "/" + srcEntry;
297 TAG_LOGD(AAFwkTag::PROCESSMGR, "StartDebugMode, isStartWithDebug: %{public}d, processName: %{public}s, "345 TAG_LOGD(AAFwkTag::PROCESSMGR, "StartDebugMode, isStartWithDebug: %{public}d, processName: %{public}s, "
298 "isDebugApp: %{public}d, isStartWithNative: %{public}d", g_debugOption.isStartWithDebug,346 "isDebugApp: %{public}d, isStartWithNative: %{public}d", g_debugOption.isStartWithDebug,
299 g_debugOption.processName.c_str(), g_debugOption.isDebugApp, g_debugOption.isStartWithNative);347 g_debugOption.processName.c_str(), g_debugOption.isDebugApp, g_debugOption.isStartWithNative);
300 runtime->StartDebugMode(g_debugOption);348 runtime->StartDebugMode(g_debugOption);
301- std::string srcPath;
302- srcPath.append(hapModuleInfo.moduleName).append("/").append(srcEntry);
303 LoadJsFile(srcPath, hapModuleInfo, runtime);349 LoadJsFile(srcPath, hapModuleInfo, runtime);
304 TAG_LOGD(AAFwkTag::PROCESSMGR, "end");350 TAG_LOGD(AAFwkTag::PROCESSMGR, "end");
305 exit(0);351 exit(0);
306}352}
307 353 
308bool ChildProcessManager::LoadJsFile(const std::string &srcEntry, const AppExecFwk::HapModuleInfo &hapModuleInfo,354bool ChildProcessManager::LoadJsFile(const std::string &srcEntry, const AppExecFwk::HapModuleInfo &hapModuleInfo,
309- std::unique_ptr<AbilityRuntime::Runtime> &runtime, std::shared_ptr<AppExecFwk::ChildProcessArgs> args)355+ const std::unique_ptr<AbilityRuntime::Runtime> &runtime, std::shared_ptr<AppExecFwk::ChildProcessArgs> args)
310{356{
311 std::shared_ptr<ChildProcessStartInfo> processStartInfo = std::make_shared<ChildProcessStartInfo>();357 std::shared_ptr<ChildProcessStartInfo> processStartInfo = std::make_shared<ChildProcessStartInfo>();
312 std::string filename = std::filesystem::path(srcEntry).stem();358 std::string filename = std::filesystem::path(srcEntry).stem();
@@ -384,8 +430,9 @@ bool ChildProcessManager::LoadNativeLibWithArgs(const std::string &moduleName, c
384 return true;430 return true;
385}431}
386 432 
387-std::unique_ptr<AbilityRuntime::Runtime> ChildProcessManager::CreateRuntime(const AppExecFwk::BundleInfo &bundleInfo,433+std::unique_ptr<AbilityRuntime::Runtime> ChildProcessManager::CreateRuntime(
388- const AppExecFwk::HapModuleInfo &hapModuleInfo, const bool fromAppSpawn, const bool jitEnabled)434+ const AppExecFwk::BundleInfo &bundleInfo, const AppExecFwk::HapModuleInfo &hapModuleInfo,
435+ const bool fromAppSpawn, const bool jitEnabled, bool isStaticChildProcess)
389{436{
390 AppExecFwk::ApplicationInfo applicationInfo = bundleInfo.applicationInfo;437 AppExecFwk::ApplicationInfo applicationInfo = bundleInfo.applicationInfo;
391 AbilityRuntime::Runtime::Options options;438 AbilityRuntime::Runtime::Options options;
@@ -400,6 +447,8 @@ std::unique_ptr<AbilityRuntime::Runtime> ChildProcessManager::CreateRuntime(cons
400 options.apiTargetVersion = applicationInfo.apiTargetVersion;447 options.apiTargetVersion = applicationInfo.apiTargetVersion;
401 options.loadAce = true;448 options.loadAce = true;
402 options.jitEnabled = jitEnabled;449 options.jitEnabled = jitEnabled;
450+ options.lang = isStaticChildProcess ? AbilityRuntime::Runtime::Language::ETS :
451+ AbilityRuntime::Runtime::Language::JS;
403 452 
404 for (auto &moduleItem : bundleInfo.hapModuleInfos) {453 for (auto &moduleItem : bundleInfo.hapModuleInfos) {
405 options.pkgContextInfoJsonStringMap[moduleItem.moduleName] = moduleItem.hapPath;454 options.pkgContextInfoJsonStringMap[moduleItem.moduleName] = moduleItem.hapPath;
@@ -559,6 +608,11 @@ std::string ChildProcessManager::GetModuleNameFromSrcEntry(const std::string &sr
559 return moduleName;608 return moduleName;
560}609}
561 610 
611+void ChildProcessManager::SetApplication(std::shared_ptr<AppExecFwk::OHOSApplication> application)
612+{
613+ application_ = application;
614+}
615+ 
562ChildProcessManagerErrorCode ChildProcessManager::KillChildProcessByPid(int32_t pid)616ChildProcessManagerErrorCode ChildProcessManager::KillChildProcessByPid(int32_t pid)
563{617{
564 TAG_LOGD(AAFwkTag::PROCESSMGR, "pid:%{public}d", pid);618 TAG_LOGD(AAFwkTag::PROCESSMGR, "pid:%{public}d", pid);
@@ -204,7 +204,8 @@ void ChildMainThread::HandleLoadJs()
204 return;204 return;
205 }205 }
206 206 
207- runtime_ = childProcessManager.CreateRuntime(bundleInfoCopy, hapModuleInfo, true, processInfo_->jitEnabled);207+ runtime_ = childProcessManager.CreateRuntime(bundleInfoCopy, hapModuleInfo, true, processInfo_->jitEnabled,
208+ processInfo_->isStaticChildProcess);
208 if (!runtime_) {209 if (!runtime_) {
209 TAG_LOGE(AAFwkTag::APPKIT, "null runtime");210 TAG_LOGE(AAFwkTag::APPKIT, "null runtime");
210 return;211 return;
@@ -217,7 +218,17 @@ void ChildMainThread::HandleLoadJs()
217 runtime_->StartDebugMode(debugOption);218 runtime_->StartDebugMode(debugOption);
218 std::string srcPath;219 std::string srcPath;
219 srcPath.append(hapModuleInfo.moduleName).append("/").append(processInfo_->srcEntry);220 srcPath.append(hapModuleInfo.moduleName).append("/").append(processInfo_->srcEntry);
220- childProcessManager.LoadJsFile(srcPath, hapModuleInfo, runtime_);221+ 
222+ if (processInfo_->isStaticChildProcess) {
223+ auto pos = processInfo_->srcEntry.find('/');
224+ std::string prefix = (pos != std::string::npos) ?
225+ processInfo_->srcEntry.substr(0, pos) : processInfo_->srcEntry;
226+ if (prefix == "entry") {
227+ childProcessManager.LoadJsFile(processInfo_->srcEntry, hapModuleInfo, runtime_);
228+ }
229+ } else {
230+ childProcessManager.LoadJsFile(srcPath, hapModuleInfo, runtime_);
231+ }
221 ExitProcessSafely();232 ExitProcessSafely();
222}233}
223 234 
@@ -245,7 +256,8 @@ void ChildMainThread::HandleLoadArkTs()
245 return;256 return;
246 }257 }
247 258 
248- runtime_ = childProcessManager.CreateRuntime(*bundleInfo_, hapModuleInfo, true, processInfo_->jitEnabled);259+ runtime_ = childProcessManager.CreateRuntime(*bundleInfo_, hapModuleInfo, true, processInfo_->jitEnabled,
260+ processInfo_->isStaticChildProcess);
249 if (!runtime_) {261 if (!runtime_) {
250 TAG_LOGE(AAFwkTag::APPKIT, "null runtime");262 TAG_LOGE(AAFwkTag::APPKIT, "null runtime");
251 return;263 return;
@@ -1777,6 +1777,7 @@ void MainThread::HandleLaunchApplication(const AppLaunchData &appLaunchData, con
1777 appLaunchData.GetDebugApp(), appInfo.debug, appLaunchData.isNativeStart());1777 appLaunchData.GetDebugApp(), appInfo.debug, appLaunchData.isNativeStart());
1778 AbilityRuntime::ChildProcessManager::GetInstance().SetForkProcessDebugOption(appInfo.bundleName,1778 AbilityRuntime::ChildProcessManager::GetInstance().SetForkProcessDebugOption(appInfo.bundleName,
1779 appLaunchData.GetDebugApp(), appInfo.debug, appLaunchData.isNativeStart());1779 appLaunchData.GetDebugApp(), appInfo.debug, appLaunchData.isNativeStart());
1780+ AbilityRuntime::ChildProcessManager::GetInstance().SetApplication(application_);
1780#endif // SUPPORT_CHILD_PROCESS1781#endif // SUPPORT_CHILD_PROCESS
1781 if (!pluginBundleInfos.empty()) {1782 if (!pluginBundleInfos.empty()) {
1782 for (auto &pluginBundleInfo : pluginBundleInfos) {1783 for (auto &pluginBundleInfo : pluginBundleInfos) {
@@ -36,6 +36,7 @@ struct ChildProcessInfo : public Parcelable {
36 bool isDebugApp = true;36 bool isDebugApp = true;
37 bool isStartWithDebug = false;37 bool isStartWithDebug = false;
38 bool isStartWithNative = false;38 bool isStartWithNative = false;
39+ bool isStaticChildProcess = false;
39 int32_t pid = 0;40 int32_t pid = 0;
40 int32_t hostPid = 0;41 int32_t hostPid = 0;
41 int32_t uid = -1;42 int32_t uid = -1;
@@ -27,6 +27,7 @@ namespace OHOS {
27namespace AppExecFwk {27namespace AppExecFwk {
28struct ChildProcessRequest : public Parcelable {28struct ChildProcessRequest : public Parcelable {
29 bool isStartWithDebug = false;29 bool isStartWithDebug = false;
30+ bool isStaticChildProcess = false;
30 int32_t childProcessType = CHILD_PROCESS_TYPE_JS;31 int32_t childProcessType = CHILD_PROCESS_TYPE_JS;
31 int32_t childProcessCount = 0;32 int32_t childProcessCount = 0;
32 std::string srcEntry;33 std::string srcEntry;
@@ -55,6 +55,7 @@ bool ChildProcessInfo::ReadFromParcel(Parcel &parcel)
55 isDebugApp = parcel.ReadBool();55 isDebugApp = parcel.ReadBool();
56 isStartWithDebug = parcel.ReadBool();56 isStartWithDebug = parcel.ReadBool();
57 isStartWithNative = parcel.ReadBool();57 isStartWithNative = parcel.ReadBool();
58+ isStaticChildProcess = parcel.ReadBool();
58 bool hasBundleInfo = parcel.ReadBool();59 bool hasBundleInfo = parcel.ReadBool();
59 if (hasBundleInfo) {60 if (hasBundleInfo) {
60 bundleInfo.reset(parcel.ReadParcelable<BundleInfo>());61 bundleInfo.reset(parcel.ReadParcelable<BundleInfo>());
@@ -103,6 +104,7 @@ bool ChildProcessInfo::Marshalling(Parcel &parcel) const
103 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Bool, parcel, isDebugApp);104 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Bool, parcel, isDebugApp);
104 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Bool, parcel, isStartWithDebug);105 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Bool, parcel, isStartWithDebug);
105 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Bool, parcel, isStartWithNative);106 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Bool, parcel, isStartWithNative);
107+ WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Bool, parcel, isStaticChildProcess);
106 bool hasBundleInfo = bundleInfo != nullptr;108 bool hasBundleInfo = bundleInfo != nullptr;
107 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Bool, parcel, hasBundleInfo);109 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Bool, parcel, hasBundleInfo);
108 if (hasBundleInfo) {110 if (hasBundleInfo) {
@@ -30,6 +30,7 @@ bool ChildProcessRequest::ReadFromParcel(Parcel &parcel)
30 READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, childProcessType);30 READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, childProcessType);
31 READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, childProcessCount);31 READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, childProcessCount);
32 READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Bool, parcel, isStartWithDebug);32 READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Bool, parcel, isStartWithDebug);
33+ READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Bool, parcel, isStaticChildProcess);
33 34 
34 std::unique_ptr<ChildProcessArgs> argsRead(parcel.ReadParcelable<ChildProcessArgs>());35 std::unique_ptr<ChildProcessArgs> argsRead(parcel.ReadParcelable<ChildProcessArgs>());
35 if (!argsRead) {36 if (!argsRead) {
@@ -65,6 +66,7 @@ bool ChildProcessRequest::Marshalling(Parcel &parcel) const
65 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, static_cast<int32_t>(childProcessType));66 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, static_cast<int32_t>(childProcessType));
66 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, static_cast<int32_t>(childProcessCount));67 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, static_cast<int32_t>(childProcessCount));
67 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Bool, parcel, isStartWithDebug);68 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Bool, parcel, isStartWithDebug);
69+ WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Bool, parcel, isStaticChildProcess);
68 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Parcelable, parcel, &args);70 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Parcelable, parcel, &args);
69 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Parcelable, parcel, &options);71 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Parcelable, parcel, &options);
70 return true;72 return true;
@@ -27,6 +27,11 @@ config("child_process_manager_config") {
27}27}
28 28 
29ohos_shared_library("child_process_manager") {29ohos_shared_library("child_process_manager") {
30+ include_dirs = [
31+ "${ability_runtime_path}/frameworks/ets/ani/child_process_manager/include",
32+ "${ability_runtime_path}/frameworks/ets/ani/ani_common/include",
33+ ]
34+ 
30 configs = [35 configs = [
31 "${ability_runtime_services_path}/common:common_config",36 "${ability_runtime_services_path}/common:common_config",
32 "${ability_runtime_services_path}/common:optimize_config",37 "${ability_runtime_services_path}/common:optimize_config",
@@ -67,6 +72,7 @@ ohos_shared_library("child_process_manager") {
67 "${ability_runtime_native_path}/ability/native/child_process_manager/js_child_process.cpp",72 "${ability_runtime_native_path}/ability/native/child_process_manager/js_child_process.cpp",
68 "${ability_runtime_native_path}/ability/native/child_process_manager/native_args_child_process.cpp",73 "${ability_runtime_native_path}/ability/native/child_process_manager/native_args_child_process.cpp",
69 "${ability_runtime_native_path}/ability/native/child_process_manager/native_child_ipc_process.cpp",74 "${ability_runtime_native_path}/ability/native/child_process_manager/native_child_ipc_process.cpp",
75+ "${ability_runtime_path}/frameworks/ets/ani/child_process_manager/src/ets_child_process_instance.cpp",
70 ]76 ]
71 }77 }
72 if (background_task_mgr_continuous_task_enable) {78 if (background_task_mgr_continuous_task_enable) {
@@ -32,6 +32,9 @@
32#include "iremote_object.h"32#include "iremote_object.h"
33 33 
34namespace OHOS {34namespace OHOS {
35+namespace AppExecFwk {
36+class OHOSApplication;
37+}
35namespace AbilityRuntime {38namespace AbilityRuntime {
36class ChildProcessManager {39class ChildProcessManager {
37public:40public:
@@ -41,11 +44,13 @@ public:
41 static void HandleSigChild(int32_t signo);44 static void HandleSigChild(int32_t signo);
42 bool IsChildProcess();45 bool IsChildProcess();
43 bool IsChildProcessBySelfFork();46 bool IsChildProcessBySelfFork();
44- ChildProcessManagerErrorCode StartChildProcessBySelfFork(const std::string &srcEntry, pid_t &pid);47+ ChildProcessManagerErrorCode StartChildProcessBySelfFork(const std::string &srcEntry, pid_t &pid,
45- ChildProcessManagerErrorCode StartChildProcessByAppSpawnFork(const std::string &srcEntry, pid_t &pid);48+ bool isStaticChildProcess = false);
49+ ChildProcessManagerErrorCode StartChildProcessByAppSpawnFork(const std::string &srcEntry, pid_t &pid,
50+ bool isStaticChildProcess = false);
46 ChildProcessManagerErrorCode StartChildProcessWithArgs(const std::string &srcEntry, pid_t &pid,51 ChildProcessManagerErrorCode StartChildProcessWithArgs(const std::string &srcEntry, pid_t &pid,
47 int32_t childProcessType, const AppExecFwk::ChildProcessArgs &args,52 int32_t childProcessType, const AppExecFwk::ChildProcessArgs &args,
48- const AppExecFwk::ChildProcessOptions &options);53+ const AppExecFwk::ChildProcessOptions &options, bool isStaticChildProcess = false);
49 ChildProcessManagerErrorCode CreateNativeChildProcessByAppSpawnFork(54 ChildProcessManagerErrorCode CreateNativeChildProcessByAppSpawnFork(
50 const std::string &libName, const sptr<IRemoteObject> &callbackStub, const std::string &customProcessName = "",55 const std::string &libName, const sptr<IRemoteObject> &callbackStub, const std::string &customProcessName = "",
51 const bool isolationMode = false, const bool isolationUid = false);56 const bool isolationMode = false, const bool isolationUid = false);
@@ -54,9 +59,10 @@ public:
54 bool GetHapModuleInfo(const AppExecFwk::BundleInfo &bundleInfo, const std::string &moduleName,59 bool GetHapModuleInfo(const AppExecFwk::BundleInfo &bundleInfo, const std::string &moduleName,
55 AppExecFwk::HapModuleInfo &hapModuleInfo);60 AppExecFwk::HapModuleInfo &hapModuleInfo);
56 std::unique_ptr<AbilityRuntime::Runtime> CreateRuntime(const AppExecFwk::BundleInfo &bundleInfo,61 std::unique_ptr<AbilityRuntime::Runtime> CreateRuntime(const AppExecFwk::BundleInfo &bundleInfo,
57- const AppExecFwk::HapModuleInfo &hapModuleInfo, const bool fromAppSpawn, const bool jitEnabled);62+ const AppExecFwk::HapModuleInfo &hapModuleInfo, const bool fromAppSpawn, const bool jitEnabled,
63+ bool isStaticChildProcess = false);
58 bool LoadJsFile(const std::string &srcEntry, const AppExecFwk::HapModuleInfo &hapModuleInfo,64 bool LoadJsFile(const std::string &srcEntry, const AppExecFwk::HapModuleInfo &hapModuleInfo,
59- std::unique_ptr<AbilityRuntime::Runtime> &runtime,65+ const std::unique_ptr<AbilityRuntime::Runtime> &runtime,
60 std::shared_ptr<AppExecFwk::ChildProcessArgs> args = nullptr);66 std::shared_ptr<AppExecFwk::ChildProcessArgs> args = nullptr);
61 bool LoadNativeLib(const std::string &moduleName, const std::string &libPath,67 bool LoadNativeLib(const std::string &moduleName, const std::string &libPath,
62 const sptr<IRemoteObject> &mainProcessCb);68 const sptr<IRemoteObject> &mainProcessCb);
@@ -68,6 +74,7 @@ public:
68 void SetAppSpawnForkDebugOption(Runtime::DebugOption &debugOption,74 void SetAppSpawnForkDebugOption(Runtime::DebugOption &debugOption,
69 std::shared_ptr<AppExecFwk::ChildProcessInfo> processInfo);75 std::shared_ptr<AppExecFwk::ChildProcessInfo> processInfo);
70 std::string GetModuleNameFromSrcEntry(const std::string &srcEntry);76 std::string GetModuleNameFromSrcEntry(const std::string &srcEntry);
77+ void SetApplication(std::shared_ptr<AppExecFwk::OHOSApplication> application);
71 ChildProcessManagerErrorCode KillChildProcessByPid(int32_t pid);78 ChildProcessManagerErrorCode KillChildProcessByPid(int32_t pid);
72 79 
73private:80private:
@@ -77,7 +84,9 @@ private:
77 ChildProcessManagerErrorCode PreCheckSelfFork();84 ChildProcessManagerErrorCode PreCheckSelfFork();
78 ChildProcessManagerErrorCode PreCheck(int32_t childProcessType);85 ChildProcessManagerErrorCode PreCheck(int32_t childProcessType);
79 void RegisterSignal();86 void RegisterSignal();
80- void HandleChildProcessBySelfFork(const std::string &srcEntry, const AppExecFwk::BundleInfo &bundleInfo);87+ void HandleChildProcessBySelfFork(const std::string &srcEntry, const AppExecFwk::BundleInfo &bundleInfo,
88+ bool isStaticChildProcess = false);
89+ bool LoadFromAppRuntime(const std::string &srcEntry, const AppExecFwk::HapModuleInfo &hapModuleInfo);
81 bool HasChildProcessRecord();90 bool HasChildProcessRecord();
82 sptr<AppExecFwk::IAppMgr> GetAppMgr();91 sptr<AppExecFwk::IAppMgr> GetAppMgr();
83 void MakeProcessName(const std::string &srcEntry);92 void MakeProcessName(const std::string &srcEntry);
@@ -87,6 +96,8 @@ private:
87 static bool signalRegistered_;96 static bool signalRegistered_;
88 bool isChildProcessBySelfFork_ = false;97 bool isChildProcessBySelfFork_ = false;
89 std::atomic<int32_t> childProcessCount_ = 0;98 std::atomic<int32_t> childProcessCount_ = 0;
99+ mutable std::mutex appMutex_;
100+ std::weak_ptr<AppExecFwk::OHOSApplication> application_;
90 101 
91 DISALLOW_COPY_AND_MOVE(ChildProcessManager);102 DISALLOW_COPY_AND_MOVE(ChildProcessManager);
92};103};
@@ -70,11 +70,13 @@ public:
70 bool IsNativeSpawnStarted() const;70 bool IsNativeSpawnStarted() const;
71 void SetAttachTimeoutStartTime(const std::chrono::system_clock::time_point &time);71 void SetAttachTimeoutStartTime(const std::chrono::system_clock::time_point &time);
72 std::chrono::system_clock::time_point GetAttachTimeoutStartTime() const;72 std::chrono::system_clock::time_point GetAttachTimeoutStartTime() const;
73+ bool IsStatic() const;
73 74 
74private:75private:
75 void MakeProcessName(const std::shared_ptr<AppRunningRecord> hostRecord, const std::string &customProcessName);76 void MakeProcessName(const std::shared_ptr<AppRunningRecord> hostRecord, const std::string &customProcessName);
76 77 
77 bool isStartWithDebug_;78 bool isStartWithDebug_;
79+ bool isStaticChildProcess_ = false;
78 pid_t hostPid_ = 0;80 pid_t hostPid_ = 0;
79 int32_t childProcessCount_ = 0;81 int32_t childProcessCount_ = 0;
80 int32_t childProcessType_ = CHILD_PROCESS_TYPE_JS;82 int32_t childProcessType_ = CHILD_PROCESS_TYPE_JS;
@@ -9513,6 +9513,7 @@ int32_t AppMgrServiceInner::GetChildProcessInfoEx(const std::shared_ptr<ChildPro
9513 info.srcEntry = childProcessRecord->GetSrcEntry();9513 info.srcEntry = childProcessRecord->GetSrcEntry();
9514 info.entryFunc = childProcessRecord->GetEntryFunc();9514 info.entryFunc = childProcessRecord->GetEntryFunc();
9515 info.entryParams = childProcessRecord->GetEntryParams();9515 info.entryParams = childProcessRecord->GetEntryParams();
9516+ info.isStaticChildProcess = childProcessRecord->IsStatic();
9516 info.jitEnabled = appRecord->IsJITEnabled();9517 info.jitEnabled = appRecord->IsJITEnabled();
9517 info.isStartWithDebug = childProcessRecord->isStartWithDebug();9518 info.isStartWithDebug = childProcessRecord->isStartWithDebug();
9518 auto applicationInfo = appRecord->GetApplicationInfo();9519 auto applicationInfo = appRecord->GetApplicationInfo();
@@ -23,8 +23,9 @@ namespace OHOS {
23namespace AppExecFwk {23namespace AppExecFwk {
24ChildProcessRecord::ChildProcessRecord(pid_t hostPid, const ChildProcessRequest &request,24ChildProcessRecord::ChildProcessRecord(pid_t hostPid, const ChildProcessRequest &request,
25 const std::shared_ptr<AppRunningRecord> hostRecord)25 const std::shared_ptr<AppRunningRecord> hostRecord)
26- : isStartWithDebug_(request.isStartWithDebug), hostPid_(hostPid), childProcessCount_(request.childProcessCount),26+ : isStartWithDebug_(request.isStartWithDebug), isStaticChildProcess_(request.isStaticChildProcess),
27- childProcessType_(request.childProcessType), hostRecord_(hostRecord)27+ hostPid_(hostPid), childProcessCount_(request.childProcessCount), childProcessType_(request.childProcessType),
28+ hostRecord_(hostRecord)
28{29{
29 srcEntry_ = request.srcEntry;30 srcEntry_ = request.srcEntry;
30 if (childProcessType_ == CHILD_PROCESS_TYPE_NATIVE_ARGS) {31 if (childProcessType_ == CHILD_PROCESS_TYPE_NATIVE_ARGS) {
@@ -249,5 +250,10 @@ std::chrono::system_clock::time_point ChildProcessRecord::GetAttachTimeoutStartT
249{250{
250 return attachTimeoutStartTime_;251 return attachTimeoutStartTime_;
251}252}
253+ 
254+bool ChildProcessRecord::IsStatic() const
255+{
256+ return isStaticChildProcess_;
257+}
252} // namespace AppExecFwk258} // namespace AppExecFwk
253} // namespace OHOS259} // namespace OHOS
@@ -596,5 +596,91 @@ HWTEST_F(ChildProcessManagerTest, GetErrorCodeCompat_0100, TestSize.Level2)
596 596 
597 TAG_LOGI(AAFwkTag::TEST, "GetErrorCodeCompat_0100 end.");597 TAG_LOGI(AAFwkTag::TEST, "GetErrorCodeCompat_0100 end.");
598}598}
599+ 
600+/**
601+ * @tc.number: StartChildProcessWithArgs_Static_0100
602+ * @tc.desc: Test StartChildProcessWithArgs with isStaticChildProcess=true
603+ * @tc.type: FUNC
604+ */
605+HWTEST_F(ChildProcessManagerTest, StartChildProcessWithArgs_Static_0100, TestSize.Level1)
606+{
607+ TAG_LOGI(AAFwkTag::TEST, "StartChildProcessWithArgs_Static_0100 start.");
608+ pid_t pid;
609+ AppExecFwk::ChildProcessArgs args;
610+ AppExecFwk::ChildProcessOptions options;
611+ auto ret = ChildProcessManager::GetInstance().StartChildProcessWithArgs(
612+ "./ets/process/DemoProcess.ts", pid, AppExecFwk::CHILD_PROCESS_TYPE_JS, args, options, true);
613+ EXPECT_NE(ret, ChildProcessManagerErrorCode::ERR_FORK_FAILED);
614+}
615+ 
616+/**
617+ * @tc.number: CreateRuntime_Static_0100
618+ * @tc.desc: Test CreateRuntime with isStaticChildProcess=true for ETS language
619+ * @tc.type: FUNC
620+ */
621+HWTEST_F(ChildProcessManagerTest, CreateRuntime_Static_0100, TestSize.Level2)
622+{
623+ TAG_LOGI(AAFwkTag::TEST, "CreateRuntime_Static_0100 start.");
624+ AppExecFwk::BundleInfo bundleInfo;
625+ auto ret = ChildProcessManager::GetInstance().GetBundleInfo(bundleInfo);
626+ EXPECT_TRUE(ret);
627+ 
628+ AppExecFwk::HapModuleInfo hapModuleInfo;
629+ ret = ChildProcessManager::GetInstance().GetEntryHapModuleInfo(bundleInfo, hapModuleInfo);
630+ EXPECT_TRUE(ret);
631+ 
632+ auto runtime = ChildProcessManager::GetInstance().CreateRuntime(bundleInfo, hapModuleInfo, false, false, true);
633+ TAG_LOGI(AAFwkTag::TEST, "CreateRuntime with isStaticChildProcess=true end.");
634+ EXPECT_EQ(runtime, nullptr);
635+}
636+ 
637+/**
638+ * @tc.number: LoadFromAppRuntime_0100
639+ * @tc.desc: Test LoadFromAppRuntime when application is null
640+ * @tc.type: FUNC
641+ */
642+HWTEST_F(ChildProcessManagerTest, LoadFromAppRuntime_0100, TestSize.Level2)
643+{
644+ TAG_LOGI(AAFwkTag::TEST, "LoadFromAppRuntime_0100 start.");
645+ AppExecFwk::HapModuleInfo hapModuleInfo;
646+ hapModuleInfo.moduleName = "entry";
647+ hapModuleInfo.hapPath = "/data/test";
648+ hapModuleInfo.isLibIsolated = false;
649+ 
650+ auto ret = ChildProcessManager::GetInstance().LoadFromAppRuntime("./ets/process/DemoProcess.ts", hapModuleInfo);
651+ EXPECT_FALSE(ret);
652+}
653+ 
654+/**
655+ * @tc.number: LoadFromAppRuntime_0200
656+ * @tc.desc: Test LoadFromAppRuntime with empty srcEntry
657+ * @tc.type: FUNC
658+ */
659+HWTEST_F(ChildProcessManagerTest, LoadFromAppRuntime_0200, TestSize.Level2)
660+{
661+ TAG_LOGI(AAFwkTag::TEST, "LoadFromAppRuntime_0200 start.");
662+ AppExecFwk::HapModuleInfo hapModuleInfo;
663+ hapModuleInfo.moduleName = "entry";
664+ 
665+ auto ret = ChildProcessManager::GetInstance().LoadFromAppRuntime("", hapModuleInfo);
666+ EXPECT_FALSE(ret);
667+}
668+ 
669+/**
670+ * @tc.number: LoadFromAppRuntime_0300
671+ * @tc.desc: Test LoadFromAppRuntime with different hapModuleInfo
672+ * @tc.type: FUNC
673+ */
674+HWTEST_F(ChildProcessManagerTest, LoadFromAppRuntime_0300, TestSize.Level2)
675+{
676+ TAG_LOGI(AAFwkTag::TEST, "LoadFromAppRuntime_0300 start.");
677+ AppExecFwk::HapModuleInfo hapModuleInfo;
678+ hapModuleInfo.moduleName = "feature";
679+ hapModuleInfo.hapPath = "/data/test/feature.hap";
680+ hapModuleInfo.isLibIsolated = true;
681+ 
682+ auto ret = ChildProcessManager::GetInstance().LoadFromAppRuntime("./ets/process/FeatureProcess.ts", hapModuleInfo);
683+ EXPECT_FALSE(ret);
684+}
599} // namespace AbilityRuntime685} // namespace AbilityRuntime
600} // namespace OHOS686} // namespace OHOS
@@ -40,11 +40,13 @@ public:
40 static void HandleSigChild(int32_t signo);40 static void HandleSigChild(int32_t signo);
41 bool IsChildProcess();41 bool IsChildProcess();
42 bool IsChildProcessBySelfFork();42 bool IsChildProcessBySelfFork();
43- ChildProcessManagerErrorCode StartChildProcessBySelfFork(const std::string &srcEntry, pid_t &pid);43+ ChildProcessManagerErrorCode StartChildProcessBySelfFork(const std::string &srcEntry, pid_t &pid,
44- ChildProcessManagerErrorCode StartChildProcessByAppSpawnFork(const std::string &srcEntry, pid_t &pid);44+ bool isStaticChildProcess = false);
45+ ChildProcessManagerErrorCode StartChildProcessByAppSpawnFork(const std::string &srcEntry, pid_t &pid,
46+ bool isStaticChildProcess = false);
45 ChildProcessManagerErrorCode StartChildProcessWithArgs(const std::string &srcEntry, pid_t &pid,47 ChildProcessManagerErrorCode StartChildProcessWithArgs(const std::string &srcEntry, pid_t &pid,
46 int32_t childProcessType, const AppExecFwk::ChildProcessArgs &args,48 int32_t childProcessType, const AppExecFwk::ChildProcessArgs &args,
47- const AppExecFwk::ChildProcessOptions &options);49+ const AppExecFwk::ChildProcessOptions &options, bool isStaticChildProcess = false);
48 ChildProcessManagerErrorCode CreateNativeChildProcessByAppSpawnFork(50 ChildProcessManagerErrorCode CreateNativeChildProcessByAppSpawnFork(
49 const std::string &libName, const sptr<IRemoteObject> &callbackStub, const std::string &customProcessName = "",51 const std::string &libName, const sptr<IRemoteObject> &callbackStub, const std::string &customProcessName = "",
50 const bool isolationMode = false, const bool isIsolationUid = false);52 const bool isolationMode = false, const bool isIsolationUid = false);
@@ -53,9 +55,10 @@ public:
53 bool GetHapModuleInfo(const AppExecFwk::BundleInfo &bundleInfo, const std::string &moduleName,55 bool GetHapModuleInfo(const AppExecFwk::BundleInfo &bundleInfo, const std::string &moduleName,
54 AppExecFwk::HapModuleInfo &hapModuleInfo);56 AppExecFwk::HapModuleInfo &hapModuleInfo);
55 std::unique_ptr<AbilityRuntime::Runtime> CreateRuntime(const AppExecFwk::BundleInfo &bundleInfo,57 std::unique_ptr<AbilityRuntime::Runtime> CreateRuntime(const AppExecFwk::BundleInfo &bundleInfo,
56- const AppExecFwk::HapModuleInfo &hapModuleInfo, const bool fromAppSpawn, const bool jitEnabled);58+ const AppExecFwk::HapModuleInfo &hapModuleInfo, const bool fromAppSpawn, const bool jitEnabled,
59+ bool isStaticChildProcess = false);
57 bool LoadJsFile(const std::string &srcEntry, const AppExecFwk::HapModuleInfo &hapModuleInfo,60 bool LoadJsFile(const std::string &srcEntry, const AppExecFwk::HapModuleInfo &hapModuleInfo,
58- std::unique_ptr<AbilityRuntime::Runtime> &runtime,61+ const std::unique_ptr<AbilityRuntime::Runtime> &runtime,
59 std::shared_ptr<AppExecFwk::ChildProcessArgs> args = nullptr);62 std::shared_ptr<AppExecFwk::ChildProcessArgs> args = nullptr);
60 bool LoadNativeLib(const std::string &moduleName, const std::string &libPath,63 bool LoadNativeLib(const std::string &moduleName, const std::string &libPath,
61 const sptr<IRemoteObject> &mainProcessCb);64 const sptr<IRemoteObject> &mainProcessCb);
@@ -77,7 +80,8 @@ private:
77 ChildProcessManagerErrorCode PreCheckSelfFork();80 ChildProcessManagerErrorCode PreCheckSelfFork();
78 ChildProcessManagerErrorCode PreCheck(int32_t childProcessType);81 ChildProcessManagerErrorCode PreCheck(int32_t childProcessType);
79 void RegisterSignal();82 void RegisterSignal();
80- void HandleChildProcessBySelfFork(const std::string &srcEntry, const AppExecFwk::BundleInfo &bundleInfo);83+ void HandleChildProcessBySelfFork(const std::string &srcEntry, const AppExecFwk::BundleInfo &bundleInfo,
84+ bool isStaticChildProcess = false);
81 bool HasChildProcessRecord();85 bool HasChildProcessRecord();
82 sptr<AppExecFwk::IAppMgr> GetAppMgr();86 sptr<AppExecFwk::IAppMgr> GetAppMgr();
83 void MakeProcessName(const std::string &srcEntry);87 void MakeProcessName(const std::string &srcEntry);
@@ -38,7 +38,8 @@ ChildProcessManager::~ChildProcessManager()
38{38{
39}39}
40 40 
41-ChildProcessManagerErrorCode ChildProcessManager::StartChildProcessBySelfFork(const std::string &srcEntry, pid_t &pid)41+ChildProcessManagerErrorCode ChildProcessManager::StartChildProcessBySelfFork(
42+ const std::string &srcEntry, pid_t &pid, bool isStaticChildProcess)
42{43{
43 return ChildProcessManagerErrorCode::ERR_OK;44 return ChildProcessManagerErrorCode::ERR_OK;
44}45}
@@ -49,14 +50,14 @@ bool ChildProcessManager::IsMultiProcessFeatureApp(const AppExecFwk::BundleInfo
49}50}
50 51 
51ChildProcessManagerErrorCode ChildProcessManager::StartChildProcessByAppSpawnFork(52ChildProcessManagerErrorCode ChildProcessManager::StartChildProcessByAppSpawnFork(
52- const std::string &srcEntry, pid_t &pid)53+ const std::string &srcEntry, pid_t &pid, bool isStaticChildProcess)
53{54{
54 return ChildProcessManagerErrorCode::ERR_ALREADY_IN_CHILD_PROCESS;55 return ChildProcessManagerErrorCode::ERR_ALREADY_IN_CHILD_PROCESS;
55}56}
56 57 
57ChildProcessManagerErrorCode ChildProcessManager::StartChildProcessWithArgs(58ChildProcessManagerErrorCode ChildProcessManager::StartChildProcessWithArgs(
58 const std::string &srcEntry, pid_t &pid, int32_t childProcessType, const AppExecFwk::ChildProcessArgs &args,59 const std::string &srcEntry, pid_t &pid, int32_t childProcessType, const AppExecFwk::ChildProcessArgs &args,
59- const AppExecFwk::ChildProcessOptions &options)60+ const AppExecFwk::ChildProcessOptions &options, bool isStaticChildProcess)
60{61{
61 return startErrorCode_;62 return startErrorCode_;
62}63}
@@ -102,12 +103,12 @@ bool ChildProcessManager::IsChildProcessBySelfFork()
102}103}
103 104 
104void ChildProcessManager::HandleChildProcessBySelfFork(const std::string &srcEntry,105void ChildProcessManager::HandleChildProcessBySelfFork(const std::string &srcEntry,
105- const AppExecFwk::BundleInfo &bundleInfo)106+ const AppExecFwk::BundleInfo &bundleInfo, bool isStaticChildProcess)
106{107{
107}108}
108 109 
109bool ChildProcessManager::LoadJsFile(const std::string &srcEntry, const AppExecFwk::HapModuleInfo &hapModuleInfo,110bool ChildProcessManager::LoadJsFile(const std::string &srcEntry, const AppExecFwk::HapModuleInfo &hapModuleInfo,
110- std::unique_ptr<AbilityRuntime::Runtime> &runtime, std::shared_ptr<AppExecFwk::ChildProcessArgs> args)111+ const std::unique_ptr<AbilityRuntime::Runtime> &runtime, std::shared_ptr<AppExecFwk::ChildProcessArgs> args)
111{112{
112 return true;113 return true;
113}114}
@@ -125,7 +126,8 @@ bool ChildProcessManager::LoadNativeLibWithArgs(const std::string &moduleName, c
125}126}
126 127 
127std::unique_ptr<AbilityRuntime::Runtime> ChildProcessManager::CreateRuntime(const AppExecFwk::BundleInfo &bundleInfo,128std::unique_ptr<AbilityRuntime::Runtime> ChildProcessManager::CreateRuntime(const AppExecFwk::BundleInfo &bundleInfo,
128- const AppExecFwk::HapModuleInfo &hapModuleInfo, const bool fromAppSpawn, const bool jitEnabled)129+ const AppExecFwk::HapModuleInfo &hapModuleInfo, const bool fromAppSpawn, const bool jitEnabled,
130+ bool isStaticChildProcess)
129{131{
130 return nullptr;132 return nullptr;
131}133}