diff --git a/BUILD.gn b/BUILD.gn index 84894ac9cf7adf00383c806b762d4ba22ae2a45b..7d8656391983bd4eaae24832883c6eea90609655 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -65,6 +65,13 @@ if (!defined(ohos_lite)) { subsystem_name = "${subsystem_name}" part_name = "${part_name}" } + + ohos_prebuilt_etc("hybridspawn.cfg") { + source = "hybridspawn.cfg" + relative_install_dir = "init" + subsystem_name = "${subsystem_name}" + part_name = "${part_name}" + } } group("appspawn_all") { @@ -108,6 +115,12 @@ group("appspawn_all") { "standard:nwebspawn", ] } + if (appspawn_support_hybrid) { # for support hybridspawn + deps += [ + ":hybridspawn.cfg", + "standard:hybridspawn", + ] + } } else { deps += [ "lite:appspawn_lite" ] } diff --git a/appspawn.gni b/appspawn.gni index 2f0fe1f03f3a2aec362682644c947e189b9cb608..341012bfdaf159848a1e5f28f07b1999842b53e2 100644 --- a/appspawn.gni +++ b/appspawn.gni @@ -24,6 +24,7 @@ declare_args() { appspawn_support_nweb = true appspawn_support_cj = true appspawn_support_native = true + appspawn_support_hybrid = true appspawn_report_event = true appspawn_test_cmd = false appspawn_sandbox_new = false diff --git a/appspawn_preload_ets.json b/appspawn_preload_ets.json new file mode 100644 index 0000000000000000000000000000000000000000..bd4af66cea38a33522474907b954e9bb275b8fc5 --- /dev/null +++ b/appspawn_preload_ets.json @@ -0,0 +1,6 @@ +{ + "class" : [ + "L@ohos/app/ability/Want/Want;", + "L@ohos/deviceInfo/deviceInfo;" + ] +} diff --git a/bundle.json b/bundle.json index c72c2116ea26553e9396e304b8f030ec2e4b243c..7f6aeab9e49f4f5bf4c779c6c8e0787d1932f875 100644 --- a/bundle.json +++ b/bundle.json @@ -22,6 +22,7 @@ "appspawn_support_nweb", "appspawn_support_cj", "appspawn_support_native", + "appspawn_support_hybrid", "appspawn_use_encaps", "appspawn_mount_tmpshm", "appspawn_seccomp_privilege", diff --git a/common/appspawn_server.h b/common/appspawn_server.h index 76a299d918e4ba238c509a856e2a9497dde92358..80adb926241b375a254adfa3f078e45a46a21092 100644 --- a/common/appspawn_server.h +++ b/common/appspawn_server.h @@ -32,6 +32,7 @@ typedef enum { MODE_FOR_NWEB_COLD_RUN, MODE_FOR_NATIVE_SPAWN, MODE_FOR_CJAPP_SPAWN, + MODE_FOR_HYBRID_SPAWN, MODE_INVALID } RunMode; @@ -42,6 +43,7 @@ typedef enum { PROCESS_FOR_NWEB_COLD_RUN, PROCESS_FOR_NATIVE_SPAWN, PROCESS_FOR_NWEB_RESTART, + PROCESS_FOR_HYBRID_SPAWN, PROCESS_INVALID } RunProcess; diff --git a/etc/BUILD.gn b/etc/BUILD.gn index 961814940dfed7e0643cf439b403ac7d35a071cd..b9a8a9585b745be2f469d0f3dc5989f1ce75d6da 100644 --- a/etc/BUILD.gn +++ b/etc/BUILD.gn @@ -78,17 +78,40 @@ ohos_prebuilt_etc("appspawn_preload.json") { module_install_dir = "etc/appspawn" } +ohos_prebuilt_etc("appspawn_preload_ets.json") { + source = "../appspawn_preload_ets.json" + part_name = "${part_name}" + module_install_dir = "etc/appspawn" +} + ohos_prebuilt_etc("appspawn_systemLib.json") { source = "../appspawn_systemLib.json" part_name = "${part_name}" module_install_dir = "etc/appspawn" } +ohos_prebuilt_etc("ohos.startup.appspawn.para") { + source = "ohos.startup.appspawn.para" + part_name = "${part_name}" + subsystem_name = "${subsystem_name}" + module_install_dir = "etc/param" +} + +ohos_prebuilt_etc("ohos.startup.appspawn.para.dac") { + source = "ohos.startup.appspawn.para.dac" + part_name = "${part_name}" + subsystem_name = "${subsystem_name}" + module_install_dir = "etc/param" +} + group("etc_files") { deps = [ ":appdata-sandbox.json", ":appspawn_preload.json", + ":appspawn_preload_ets.json", ":appspawn_systemLib.json", + ":ohos.startup.appspawn.para", + ":ohos.startup.appspawn.para.dac" ] if (defined(appspawn_sandbox_new) && appspawn_sandbox_new) { deps += [ diff --git a/etc/ohos.startup.appspawn.para b/etc/ohos.startup.appspawn.para new file mode 100644 index 0000000000000000000000000000000000000000..6ef0a3a4b5e7a6411d0b9f27d5cf8fc17272470e --- /dev/null +++ b/etc/ohos.startup.appspawn.para @@ -0,0 +1,14 @@ +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +persist.appspawn.hybridspawn.enable = false diff --git a/etc/ohos.startup.appspawn.para.dac b/etc/ohos.startup.appspawn.para.dac new file mode 100644 index 0000000000000000000000000000000000000000..c347f2b7627c7039df999d0c6795cdd37fe25fbc --- /dev/null +++ b/etc/ohos.startup.appspawn.para.dac @@ -0,0 +1,15 @@ +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# support hybridspawn start on-demand +persist.appspawn.hybridspawn.enable = foundation:foundation:0755 diff --git a/hybridspawn.cfg b/hybridspawn.cfg new file mode 100644 index 0000000000000000000000000000000000000000..b31803804e8ec62e19f49bdb58ee558f6595cd29 --- /dev/null +++ b/hybridspawn.cfg @@ -0,0 +1,44 @@ +{ + "jobs" : [{ + "name" : "param:persist.appspawn.hybridspawn.enable=false", + "condition" : "persist.appspawn.hybridspawn.enable=false", + "cmds" : [ + "stop hybridspawn" + ] + }, + { + "name" : "param:bootevent.boot.completed=true && persist.appspawn.hybridspawn.enable=true", + "condition" : "bootevent.boot.completed=true && persist.appspawn.hybridspawn.enable=true", + "cmds" : [ + "start hybridspawn" + ] + } + ], + "services" : [{ + "name" : "hybridspawn", + "path" : ["/system/bin/hybridspawn", + "-mode hybridspawn", + "--process-name com.ohos.appspawn.startup --start-flags daemon --type standard ", + "--sandbox-switch on --bundle-name com.ohos.appspawn.startup --app-operate-type operate ", + "--render-command command --app-launch-type singleton --app-visible true"], + "uid" : "root", + "gid" : ["root"], + "setuid" : true, + "importance" : -20, + "socket" : [{ + "name" : "HybridSpawn", + "family" : "AF_LOCAL", + "type" : "SOCK_STREAM", + "protocol" : "default", + "permissions" : "0660", + "uid" : "root", + "gid" : "appspawn", + "option" : [ + ] + }], + "ondemand" : true, + "sandbox" : 0, + "secon" : "u:r:appspawn:s0" + } + ] +} diff --git a/interfaces/innerkits/client/appspawn_client.c b/interfaces/innerkits/client/appspawn_client.c index da504d36b52dcc6414a99dd609231075ca2ba629..bef4315beac8503d3b107e07070d7dbf787893e3 100644 --- a/interfaces/innerkits/client/appspawn_client.c +++ b/interfaces/innerkits/client/appspawn_client.c @@ -112,6 +112,9 @@ APPSPAWN_STATIC int CreateClientSocket(uint32_t type, uint32_t timeout) case CLIENT_FOR_NATIVESPAWN: socketName = NATIVESPAWN_SOCKET_NAME; break; + case CLIENT_FOR_HYBRIDSPAWN: + socketName = HYBRIDSPAWN_SOCKET_NAME; + break; default: socketName = NWEBSPAWN_SOCKET_NAME; break; @@ -389,6 +392,8 @@ int AppSpawnClientInit(const char *serviceName, AppSpawnClientHandle *handle) } else if (strcmp(serviceName, NATIVESPAWN_SERVER_NAME) == 0 || strstr(serviceName, NATIVESPAWN_SOCKET_NAME) != NULL) { type = CLIENT_FOR_NATIVESPAWN; + } else if (strcmp(serviceName, HYBRIDSPAWN_SERVER_NAME) == 0) { + type = CLIENT_FOR_HYBRIDSPAWN; } int ret = InitClientInstance(type); APPSPAWN_CHECK(ret == 0, return APPSPAWN_SYSTEM_ERROR, "Failed to create reqMgr"); diff --git a/interfaces/innerkits/client/appspawn_client.h b/interfaces/innerkits/client/appspawn_client.h index b979e2b6385059c68faf21d10917388e73bb166b..0905f56af37686abaf48b29210f8ca19adf580ff 100644 --- a/interfaces/innerkits/client/appspawn_client.h +++ b/interfaces/innerkits/client/appspawn_client.h @@ -53,6 +53,7 @@ typedef enum { CLIENT_FOR_NWEBSPAWN, CLIENT_FOR_CJAPPSPAWN, CLIENT_FOR_NATIVESPAWN, + CLIENT_FOR_HYBRIDSPAWN, CLIENT_MAX } AppSpawnClientType; diff --git a/interfaces/innerkits/include/appspawn.h b/interfaces/innerkits/include/appspawn.h index 37dacf9a6c013f0fff136dabd6a2067da40daa5f..217363b04777759caf1ce254839894778dd5fd90 100644 --- a/interfaces/innerkits/include/appspawn.h +++ b/interfaces/innerkits/include/appspawn.h @@ -51,6 +51,7 @@ typedef void *AppSpawnClientHandle; #define CJAPPSPAWN_SERVER_NAME "cjappspawn" #define NWEBSPAWN_RESTART "nwebRestart" #define NATIVESPAWN_SERVER_NAME "nativespawn" +#define HYBRIDSPAWN_SERVER_NAME "hybridspawn" #pragma pack(4) #define APP_MAX_GIDS 64 diff --git a/modules/ace_adapter/ace_adapter.cpp b/modules/ace_adapter/ace_adapter.cpp index 3641a3a4cfc32761a9ed6ae9da798af1c85c4520..c24a25259f27173236c34af9a7b9a8488c6f2b85 100644 --- a/modules/ace_adapter/ace_adapter.cpp +++ b/modules/ace_adapter/ace_adapter.cpp @@ -50,52 +50,49 @@ static const bool DEFAULT_PRELOAD_VALUE = false; #else static const bool DEFAULT_PRELOAD_VALUE = true; #endif -static const bool DEFAULT_PRELOAD_ETS_VALUE = false; +static const bool DEFAULT_PRELOAD_ETS_VALUE = true; static const std::string PRELOAD_JSON_CONFIG("/appspawn_preload.json"); +static const std::string PRELOAD_ETS_JSON_CONFIG("/appspawn_preload_ets.json"); typedef struct TagParseJsonContext { - std::set modules; + std::set names; + std::string key; } ParseJsonContext; -static void GetModules(const cJSON *root, std::set &modules) +static void GetNames(const cJSON *root, std::set &names, std::string key) { - // no config - cJSON *modulesJson = cJSON_GetObjectItemCaseSensitive(root, "napi"); - if (modulesJson == nullptr) { - return; - } - - uint32_t moduleCount = (uint32_t)cJSON_GetArraySize(modulesJson); - for (uint32_t i = 0; i < moduleCount; ++i) { - const char *moduleName = cJSON_GetStringValue(cJSON_GetArrayItem(modulesJson, i)); - if (moduleName == nullptr) { - continue; - } - APPSPAWN_LOGV("moduleName %{public}s", moduleName); - if (!modules.count(moduleName)) { - modules.insert(moduleName); + cJSON *namesJson = cJSON_GetObjectItemCaseSensitive(root, key.c_str()); + APPSPAWN_CHECK_ONLY_EXPER(namesJson != nullptr, return); + + uint32_t count = (uint32_t)cJSON_GetArraySize(namesJson); + for (uint32_t i = 0; i < count; ++i) { + const char *name = cJSON_GetStringValue(cJSON_GetArrayItem(namesJson, i)); + APPSPAWN_CHECK_ONLY_EXPER(name != nullptr, continue); + APPSPAWN_LOGV("name %{public}s", name); + if (!names.count(name)) { + names.insert(name); } } } -static int GetModuleSet(const cJSON *root, ParseJsonContext *context) +static int GetNameSet(const cJSON *root, ParseJsonContext *context) { - GetModules(root, context->modules); + GetNames(root, context->names, context->key); return 0; } -static void PreloadModule(void) +static void PreloadModule(bool isHybrid) { bool preloadEts = OHOS::system::GetBoolParameter("persist.appspawn.preloadets", DEFAULT_PRELOAD_ETS_VALUE); - APPSPAWN_LOGI("LoadExtendLib: preloadets param value is %{public}s", preloadEts ? "true" : "false"); + APPSPAWN_LOGI("LoadExtendLib: preloadets param value is %{public}s, isHybrid is %{public}s", + preloadEts ? "true" : "false", isHybrid ? "true" : "false"); OHOS::AbilityRuntime::Runtime::Options options; options.loadAce = true; options.preload = true; - if (preloadEts) { + options.lang = OHOS::AbilityRuntime::Runtime::Language::JS; + if (isHybrid && preloadEts) { options.lang = OHOS::AbilityRuntime::Runtime::Language::ETS; - } else { - options.lang = OHOS::AbilityRuntime::Runtime::Language::JS; } auto runtime = OHOS::AbilityRuntime::Runtime::Create(options); if (!runtime) { @@ -103,17 +100,24 @@ static void PreloadModule(void) return; } - ParseJsonContext context = {}; - (void)ParseJsonConfig("etc/appspawn", PRELOAD_JSON_CONFIG.c_str(), GetModuleSet, &context); - for (std::string moduleName : context.modules) { + ParseJsonContext jsContext = {{}, "napi"}; + (void)ParseJsonConfig("etc/appspawn", PRELOAD_JSON_CONFIG.c_str(), GetNameSet, &jsContext); + for (std::string moduleName : jsContext.names) { APPSPAWN_LOGI("moduleName %{public}s", moduleName.c_str()); runtime->PreloadSystemModule(moduleName); } - // Save preloaded runtime + + ParseJsonContext etsContext = {{}, "class"}; + (void)ParseJsonConfig("etc/appspawn", PRELOAD_ETS_JSON_CONFIG.c_str(), GetNameSet, &etsContext); + for (std::string className : etsContext.names) { + APPSPAWN_LOGI("className %{public}s", className.c_str()); + runtime->PreloadSystemClass(className.c_str()); + } + OHOS::AbilityRuntime::Runtime::SavePreloaded(std::move(runtime)); } -static void LoadExtendLib(void) +static void LoadExtendLib(bool isHybrid) { const char *acelibdir = OHOS::Ace::AceForwardCompatibility::GetAceLibName(); APPSPAWN_LOGI("LoadExtendLib: Start calling dlopen acelibdir"); @@ -130,7 +134,7 @@ static void LoadExtendLib(void) APPSPAWN_LOGI("LoadExtendLib: Start preload VM"); SetTraceDisabled(true); - PreloadModule(); + PreloadModule(isHybrid); SetTraceDisabled(false); Resource::ResourceManager *systemResMgr = Resource::GetSystemResourceManagerNoSandBox(); @@ -290,7 +294,12 @@ APPSPAWN_STATIC int PreLoadAppSpawn(AppSpawnMgr *content) LoadExtendCJLib(); return 0; } - LoadExtendLib(); + + bool isHybrid = IsHybridSpawnMode(content) ? true : false; + APPSPAWN_LOGI("PreLoadAppSpawn: mode %{public}d, isHybrid is %{public}d", content->content.mode, isHybrid); + if (content->content.mode != MODE_FOR_APP_COLD_RUN) { + LoadExtendLib(isHybrid); + } return 0; } @@ -350,7 +359,7 @@ static void DlopenArkWebLib() APPSPAWN_STATIC int DlopenAppSpawn(AppSpawnMgr *content) { - if (!IsAppSpawnMode(content)) { + if (!(IsAppSpawnMode(content) || IsHybridSpawnMode(content))) { return 0; } diff --git a/modules/asan/asan_detector.c b/modules/asan/asan_detector.c index 3bbecf98ed17fc39f8362689d17a5a1eeb4bfaeb..54993f2b0178f84b628531dd7ea1e9448a969799 100644 --- a/modules/asan/asan_detector.c +++ b/modules/asan/asan_detector.c @@ -147,6 +147,8 @@ static int AsanSpawnGetSpawningFlag(AppSpawnMgr *content, AppSpawningCtx *proper property->forkCtx.coldRunPath = strdup("/system/asan/bin/nativespawn"); #elif NWEB_SPAWN property->forkCtx.coldRunPath = strdup("/system/asan/bin/nwebspawn"); +#elif HYBRID_SPAWN + property->forkCtx.coldRunPath = strdup("/system/asan/bin/hybridspawn"); #else property->forkCtx.coldRunPath = strdup("/system/asan/bin/appspawn"); #endif diff --git a/modules/common/appspawn_common.c b/modules/common/appspawn_common.c index 57342e197ba358ef5563d82c736168036960ff7f..073fe3870a73cb1f534daf291478cd9a266987fc 100644 --- a/modules/common/appspawn_common.c +++ b/modules/common/appspawn_common.c @@ -291,7 +291,7 @@ static int SetXpmConfig(const AppSpawnMgr *content, const AppSpawningCtx *proper static int SetUidGid(const AppSpawnMgr *content, const AppSpawningCtx *property) { - if (IsAppSpawnMode(content)) { + if (IsAppSpawnMode(content) || IsHybridSpawnMode(content)) { struct sched_param param = { 0 }; param.sched_priority = 0; int ret = sched_setscheduler(0, SCHED_OTHER, ¶m); @@ -513,7 +513,7 @@ static int SpawnInitSpawningEnv(AppSpawnMgr *content, AppSpawningCtx *property) ret = SetAppAccessToken(content, property); APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return ret); - if ((IsAppSpawnMode(content) || IsNativeSpawnMode(content))) { + if ((IsAppSpawnMode(content) || IsHybridSpawnMode(content) || IsNativeSpawnMode(content))) { ret = SetIsolateDir(property); APPSPAWN_CHECK_ONLY_LOG(ret == 0, "Failed to set isolate dir, ret %{public}d", ret); } diff --git a/modules/common/appspawn_encaps.c b/modules/common/appspawn_encaps.c index 302c256fe9440b069d4ab388540363640f2d86c4..1ec93b977a65d4521b052d8a57a03be787eb84cb 100644 --- a/modules/common/appspawn_encaps.c +++ b/modules/common/appspawn_encaps.c @@ -391,7 +391,7 @@ APPSPAWN_STATIC int SpawnSetEncapsPermissions(AppSpawnMgr *content, AppSpawningC } // The trustlist is used to control not appspawn or nativespawn - if (!(IsAppSpawnMode(content) || IsNativeSpawnMode(content))) { + if (!(IsAppSpawnMode(content) || IsHybridSpawnMode(content) || IsNativeSpawnMode(content))) { return 0; } diff --git a/modules/module_engine/include/appspawn_msg.h b/modules/module_engine/include/appspawn_msg.h index 94f966b95b47f94395dd893a1dc5878b8eaa787e..5a9eabeada82fd572841a84ec9a33c69df4a9fbb 100644 --- a/modules/module_engine/include/appspawn_msg.h +++ b/modules/module_engine/include/appspawn_msg.h @@ -32,6 +32,7 @@ extern "C" { #define KEEPALIVE_NAME "keepalive" #define NATIVESPAWN_SOCKET_NAME "NativeSpawn" #define SPAWN_LISTEN_FD_NAME "SpawnListenFd" +#define HYBRIDSPAWN_SOCKET_NAME "HybridSpawn" #define APPSPAWN_ALIGN(len) (((len) + 0x03) & (~0x03)) #define APPSPAWN_TLV_NAME_LEN 32 diff --git a/modules/modulemgr/appspawn_modulemgr.c b/modules/modulemgr/appspawn_modulemgr.c index c29076de3db7191a0ca7198efa7a3d39299236ab..75e9e666724a4eff18b087fd4a04fe42e803e3ff 100644 --- a/modules/modulemgr/appspawn_modulemgr.c +++ b/modules/modulemgr/appspawn_modulemgr.c @@ -36,6 +36,7 @@ static struct { {NULL, MODULE_NWEBSPAWN, "appspawn/nwebspawn"}, {NULL, MODULE_COMMON, "appspawn/common"}, {NULL, MODULE_NATIVESPAWN, "appspawn/nativespawn"}, + {NULL, MODULE_HYBRIDSPAWN, "appspawn/appspawn"}, }; static HOOK_MGR *g_appspawnHookMgr = NULL; diff --git a/modules/modulemgr/appspawn_modulemgr.h b/modules/modulemgr/appspawn_modulemgr.h index 53d0efb55663a30ea4e91bdb8f40c918c66a27c2..cb9fcd486ff1a3313d37e78904d53f60c1871c62 100644 --- a/modules/modulemgr/appspawn_modulemgr.h +++ b/modules/modulemgr/appspawn_modulemgr.h @@ -41,6 +41,7 @@ typedef enum { MODULE_NWEBSPAWN, MODULE_COMMON, MODULE_NATIVESPAWN, + MODULE_HYBRIDSPAWN, MODULE_MAX } AppSpawnModuleType; diff --git a/standard/BUILD.gn b/standard/BUILD.gn index 9d6f694d9155361ee2be3f52301b0e4bf960aeef..69e0637800332984d8d401b98561eeb98e70ef96 100644 --- a/standard/BUILD.gn +++ b/standard/BUILD.gn @@ -392,3 +392,88 @@ ohos_executable("nwebspawn") { subsystem_name = "${subsystem_name}" part_name = "${part_name}" } + +# to support hybridspawn +ohos_executable("hybridspawn") { + sources = [ + "${appspawn_path}/common/appspawn_server.c", + "${appspawn_path}/common/appspawn_trace.cpp", + "${appspawn_path}/modules/common/appspawn_dfx_dump.cpp", + "${appspawn_path}/modules/modulemgr/appspawn_modulemgr.c", + "${appspawn_path}/standard/appspawn_appmgr.c", + "${appspawn_path}/standard/appspawn_kickdog.c", + "${appspawn_path}/standard/appspawn_main.c", + "${appspawn_path}/standard/appspawn_msgmgr.c", + "${appspawn_path}/standard/appspawn_service.c", + ] + + defines = [ "HYBRID_SPAWN" ] + configs = [ + ":appspawn_server_config", + "${appspawn_path}:appspawn_config", + ] + deps = [ + "${appspawn_path}/modules/module_engine:libappspawn_stub_versionscript", + "${appspawn_path}/util:libappspawn_util", + ] + if (asan_detector || is_asan) { + defines += [ "ASAN_DETECTOR" ] + } + if (is_debug || build_variant == "root") { + defines += [ "DEBUG_BEGETCTL_BOOT" ] + } + if (appspawn_support_prefork) { + defines += [ "APPSPAWN_SUPPORT_PREFORK" ] + } + + external_deps = [ + "cJSON:cjson", + "c_utils:utils", + "config_policy:configpolicy_util", + "ffrt:libffrt", + "hilog:libhilog", + "hitrace:hitrace_meter", + "init:libbegetutil", + ] + if (enable_appspawn_dump_catcher) { + external_deps += [ "faultloggerd:libdfx_dumpcatcher" ] + } + + if (appspawn_report_event) { + defines += [ "APPSPAWN_HISYSEVENT" ] + external_deps += [ "hisysevent:libhisysevent" ] + sources += [ + "${appspawn_path}/modules/sysevent/appspawn_hisysevent.cpp", + "${appspawn_path}/modules/sysevent/hisysevent_adapter.cpp", + ] + } + if (build_selinux) { + defines += [ "WITH_SELINUX" ] + external_deps += [ + "selinux:libselinux", + "selinux_adapter:libhap_restorecon", + ] + } + cflags = [] + + if (defined(appspawn_sandbox_new) && appspawn_sandbox_new) { + defines += [ "APPSPAWN_SANDBOX_NEW" ] + } + + #ldflags = [ "-Wl,--dynamic-linker,/system/bin/linker64z" ] + if (defined(global_parts_info) && + defined(global_parts_info.security_code_signature)) { + defines += [ "CODE_SIGNATURE_ENABLE" ] + external_deps += [ "code_signature:libcode_sign_attr_utils" ] + } + + version_script = get_label_info( + "${appspawn_path}/modules/module_engine:libappspawn_stub_versionscript", + "target_gen_dir") + "/" + get_label_info( + "${appspawn_path}/modules/module_engine:libappspawn_stub_versionscript", + "name") + stub_version_script_suffix + + install_enable = true + subsystem_name = "${subsystem_name}" + part_name = "${part_name}" +} diff --git a/standard/appspawn_kickdog.c b/standard/appspawn_kickdog.c index 2628a5717082cd9f1b5ee0d81e758f86dbf59f99..ef01677b8802e50df7c776abfa727d1e3bfed14c 100644 --- a/standard/appspawn_kickdog.c +++ b/standard/appspawn_kickdog.c @@ -55,13 +55,19 @@ static const char *GetProcContent(bool isLinux, bool isOpen, int mode) if (isLinux) { return LINUX_APPSPAWN_WATCHDOG_ON; } - return (mode == MODE_FOR_NWEB_SPAWN) ? HM_NWEBSPAWN_WATCHDOG_ON : HM_APPSPAWN_WATCHDOG_ON; + if (mode == MODE_FOR_NWEB_SPAWN) { + return HM_NWEBSPAWN_WATCHDOG_ON; + } + return (mode == MODE_FOR_HYBRID_SPAWN) ? HM_HYBRIDSPAWN_WATCHDOG_ON : HM_APPSPAWN_WATCHDOG_ON; } if (isLinux) { return LINUX_APPSPAWN_WATCHDOG_KICK; } - return (mode == MODE_FOR_NWEB_SPAWN) ? HM_NWEBSPAWN_WATCHDOG_KICK : HM_APPSPAWN_WATCHDOG_KICK; + if (mode == MODE_FOR_NWEB_SPAWN) { + return HM_NWEBSPAWN_WATCHDOG_KICK; + } + return (mode == MODE_FOR_HYBRID_SPAWN) ? HM_HYBRIDSPAWN_WATCHDOG_KICK : HM_APPSPAWN_WATCHDOG_KICK; } static void DealSpawnWatchdog(AppSpawnContent *content, bool isOpen) @@ -73,9 +79,8 @@ static void DealSpawnWatchdog(AppSpawnContent *content, bool isOpen) if (isOpen) { content->wdgOpened = (result != -1); } - APPSPAWN_KLOGI("%{public}s %{public}s %{public}d", - (content->mode == MODE_FOR_NWEB_SPAWN) ? - "Nweb" : "Apps", isOpen ? "enable" : "kick", result); + APPSPAWN_KLOGI("%{public}s %{public}s %{public}d", (content->mode == MODE_FOR_NWEB_SPAWN) ? "Nweb" : + ((content->mode == MODE_FOR_HYBRID_SPAWN) ? "Hybrid" : "App"), isOpen ? "enable" : "kick", result); } static void ProcessTimerHandle(const TimerHandle taskHandle, void *context) @@ -123,8 +128,8 @@ APPSPAWN_STATIC int SpawnKickDogStart(AppSpawnMgr *mgrContent) { APPSPAWN_CHECK(mgrContent != NULL, return 0, "content is null"); APPSPAWN_CHECK((mgrContent->content.mode == MODE_FOR_APP_SPAWN) || - (mgrContent->content.mode == MODE_FOR_NWEB_SPAWN), return 0, "Mode %{public}u no need enable watchdog", - mgrContent->content.mode); + (mgrContent->content.mode == MODE_FOR_NWEB_SPAWN) || (mgrContent->content.mode == MODE_FOR_HYBRID_SPAWN), + return 0, "Mode %{public}u no need enable watchdog", mgrContent->content.mode); if (CheckKernelType(&mgrContent->content.isLinux) != 0) { return 0; diff --git a/standard/appspawn_kickdog.h b/standard/appspawn_kickdog.h index 6a45b9808b4c8968ec9d246830fe0cd2a94f0e70..cf20193364427bbdeb8442b52116871941c53ef4 100644 --- a/standard/appspawn_kickdog.h +++ b/standard/appspawn_kickdog.h @@ -43,6 +43,8 @@ extern "C" { #define HM_APPSPAWN_WATCHDOG_KICK "kick,appspawn" #define HM_NWEBSPAWN_WATCHDOG_ON "on,10,nwebspawn" #define HM_NWEBSPAWN_WATCHDOG_KICK "kick,nwebspawn" +#define HM_HYBRIDSPAWN_WATCHDOG_ON "on,10,hybridspawn" +#define HM_HYBRIDSPAWN_WATCHDOG_KICK "kick,hybridspawn" #define APPSPAWN_WATCHDOG_KICKTIME (10 * 1000) //10s diff --git a/standard/appspawn_main.c b/standard/appspawn_main.c index df5fe79f011b8e226c2ca7380164794f9226c2c4..103ad1554c5d318f1bc2f824d1a535d6c6bc0062 100644 --- a/standard/appspawn_main.c +++ b/standard/appspawn_main.c @@ -35,6 +35,8 @@ static AppSpawnStartArgTemplate g_appSpawnStartArgTemplate[PROCESS_INVALID] = { {NATIVESPAWN_SERVER_NAME, {MODE_FOR_NATIVE_SPAWN, MODULE_NATIVESPAWN, NATIVESPAWN_SOCKET_NAME, NATIVESPAWN_SERVER_NAME, 1}}, {NWEBSPAWN_RESTART, {MODE_FOR_NWEB_SPAWN, MODULE_NWEBSPAWN, NWEBSPAWN_SOCKET_NAME, NWEBSPAWN_SERVER_NAME, 1}}, + {HYBRIDSPAWN_SERVER_NAME, {MODE_FOR_HYBRID_SPAWN, MODULE_HYBRIDSPAWN, HYBRIDSPAWN_SOCKET_NAME, + HYBRIDSPAWN_SERVER_NAME, 1}}, }; #else static AppSpawnStartArgTemplate g_appCJSpawnStartArgTemplate[CJPROCESS_INVALID] = { @@ -80,6 +82,9 @@ static AppSpawnStartArgTemplate *GetAppSpawnStartArg(const char *serverName, App AppSpawnStartArgTemplate *argTemp, int count) { for (int i = 0; i < count; i++) { + if (serverName == NULL || argTemplate[i].serverName == NULL) { + continue; + } if (strcmp(serverName, argTemplate[i].serverName) == 0) { return &argTemplate[i]; } @@ -116,6 +121,12 @@ int main(int argc, char *const argv[]) } #elif NATIVE_SPAWN argTemp = &g_appSpawnStartArgTemplate[PROCESS_FOR_NATIVE_SPAWN]; +#elif HYBRID_SPAWN + argTemp = &g_appSpawnStartArgTemplate[PROCESS_FOR_HYBRID_SPAWN]; + if (argc > MODE_VALUE_INDEX) { + argTemp = GetAppSpawnStartArg(argv[MODE_VALUE_INDEX], g_appSpawnStartArgTemplate, + argTemp, ARRAY_LENGTH(g_appSpawnStartArgTemplate)); + } #elif NWEB_SPAWN argTemp = &g_appSpawnStartArgTemplate[PROCESS_FOR_NWEB_SPAWN]; if (argc > MODE_VALUE_INDEX) { diff --git a/standard/appspawn_manager.h b/standard/appspawn_manager.h index 39f6a785197dc3cc85fe8b166e2a176437f3c286..0ff876863194b849efd4810193b68716648506ae 100644 --- a/standard/appspawn_manager.h +++ b/standard/appspawn_manager.h @@ -224,6 +224,12 @@ APPSPAWN_INLINE int IsNativeSpawnMode(const AppSpawnMgr *content) (content->content.mode == MODE_FOR_NATIVE_SPAWN); } +APPSPAWN_INLINE int IsHybridSpawnMode(const AppSpawnMgr *content) +{ + return (content != NULL) && + (content->content.mode == MODE_FOR_HYBRID_SPAWN); +} + APPSPAWN_INLINE int IsColdRunMode(const AppSpawnMgr *content) { return (content != NULL) && diff --git a/standard/appspawn_service.c b/standard/appspawn_service.c index 31d6cf9cb03dd90bbba6b8bb3748c7584b4a8214..d80261f10a9954c44d0ad004d2bc34bafa3fd5a8 100644 --- a/standard/appspawn_service.c +++ b/standard/appspawn_service.c @@ -95,27 +95,6 @@ static void AppQueueDestroyProc(const AppSpawnMgr *mgr, AppSpawnedProcess *appIn static void StopAppSpawn(void) { - // delete nwespawn, and wait exit. Otherwise, the process of nwebspawn spawning will become zombie - AppSpawnedProcess *appInfo = GetSpawnedProcessByName(NWEBSPAWN_SERVER_NAME); - if (appInfo != NULL) { - APPSPAWN_LOGI("kill %{public}s pid: %{public}d", appInfo->name, appInfo->pid); - int exitStatus = 0; - KillAndWaitStatus(appInfo->pid, SIGTERM, &exitStatus); - OH_ListRemove(&appInfo->node); - OH_ListInit(&appInfo->node); - free(appInfo); - } - // delete nativespawn, and wait exit. Otherwise, the process of nativespawn spawning will become zombie - appInfo = GetSpawnedProcessByName(NATIVESPAWN_SERVER_NAME); - if (appInfo != NULL) { - APPSPAWN_LOGI("kill %{public}s pid: %{public}d", appInfo->name, appInfo->pid); - int exitStatus = 0; - KillAndWaitStatus(appInfo->pid, SIGTERM, &exitStatus); - OH_ListRemove(&appInfo->node); - OH_ListInit(&appInfo->node); - free(appInfo); - } - AppSpawnContent *content = GetAppSpawnContent(); if (content != NULL && content->reservedPid > 0) { int ret = kill(content->reservedPid, SIGKILL); @@ -1200,6 +1179,8 @@ APPSPAWN_STATIC int AppSpawnColdStartApp(struct AppSpawnContent *content, AppSpa char *path = property->forkCtx.coldRunPath != NULL ? property->forkCtx.coldRunPath : "/system/bin/cjappspawn"; #elif NATIVE_SPAWN char *path = property->forkCtx.coldRunPath != NULL ? property->forkCtx.coldRunPath : "/system/bin/nativespawn"; +#elif HYBRID_SPAWN + char *path = property->forkCtx.coldRunPath != NULL ? property->forkCtx.coldRunPath : "/system/bin/hybridspawn"; #elif NWEB_SPAWN char *path = property->forkCtx.coldRunPath != NULL ? property->forkCtx.coldRunPath : "/system/bin/nwebspawn"; #else @@ -1330,7 +1311,7 @@ static void AppSpawnRun(AppSpawnContent *content, int argc, char *const argv[]) (void)LE_AddSignal(LE_GetDefaultLoop(), appSpawnContent->sigHandler, SIGTERM); } - if (IsAppSpawnMode(appSpawnContent)) { + if (IsAppSpawnMode(appSpawnContent) || IsHybridSpawnMode(appSpawnContent)) { struct sched_param param = { 0 }; param.sched_priority = 1; int ret = sched_setscheduler(0, SCHED_FIFO, ¶m); diff --git a/test/mock/js_runtime.h b/test/mock/js_runtime.h index 4e05753fdc702c4c35825411f845965c820aa41d..ba46bac9d7c0bcb5b276315060becc8a3a46eb28 100644 --- a/test/mock/js_runtime.h +++ b/test/mock/js_runtime.h @@ -27,7 +27,9 @@ namespace AbilityRuntime { public: enum class Language { JS = 0, - ETS = 1, + CJ, + ETS, + UNKNOWN, }; struct Options { @@ -60,6 +62,11 @@ namespace AbilityRuntime { return; } + void PreloadSystemClass(const char *className) + { + return; + } + Runtime(const Runtime &) = delete; Runtime(Runtime &&) = delete; Runtime &operator=(const Runtime &) = delete; diff --git a/test/moduletest/appspawn_client_test.cpp b/test/moduletest/appspawn_client_test.cpp index 411d3bfe1aa9656878ef26d7f38026b222d7e8bc..3e285594d1223717493d74d07f41e4eaa0a7f917 100644 --- a/test/moduletest/appspawn_client_test.cpp +++ b/test/moduletest/appspawn_client_test.cpp @@ -160,5 +160,25 @@ HWTEST_F(AppSpawnClientTest, AppSpawn_Client_test004, TestSize.Level0) AppSpawnClientDestroy(clientHandle); } +/** + * @tc.name: AppSpawn_Client_test005 + * @tc.desc: 模拟hybridspawn的客户端向hybridspawn服务端发送应用孵化请求 + * @tc.type: FUNC + */ +HWTEST_F(AppSpawnClientTest, AppSpawn_Client_test005, TestSize.Level0) +{ + AppSpawnClientHandle clientHandle = CreateClient(HYBRIDSPAWN_SERVER_NAME); + ASSERT_EQ(clientHandle != NULL, 1); + AppSpawnReqMsgHandle reqHandle = CreateMsg(clientHandle, "ohos.samples.clock", MODE_FOR_HYBRID_SPAWN); + ASSERT_EQ(reqHandle != INVALID_REQ_HANDLE, 1); + + AppSpawnResult result = {}; + int ret = AppSpawnClientSendMsg(clientHandle, reqHandle, &result); + if (ret == 0 && result.pid > 0) { + kill(result.pid, SIGKILL); + } + AppSpawnClientDestroy(clientHandle); +} + } // namespace AppSpawn } // namespace OHOS diff --git a/test/moduletest/appspawn_test_cmder.cpp b/test/moduletest/appspawn_test_cmder.cpp index 4aa7461dae0e8eec4a1ff869f2a6e78a518442a6..f24498216b418ba2a90bc0dfc4e707484bf3f1ec 100644 --- a/test/moduletest/appspawn_test_cmder.cpp +++ b/test/moduletest/appspawn_test_cmder.cpp @@ -337,8 +337,8 @@ int AppSpawnTestCommander::CreateMsg(AppSpawnReqMsgHandle &reqHandle, { int ret = APPSPAWN_SYSTEM_ERROR; if (clientHandle_ == NULL) { - ret = AppSpawnClientInit(appSpawn_ ? APPSPAWN_SERVER_NAME : NWEBSPAWN_SERVER_NAME, &clientHandle_); - APPSPAWN_CHECK(ret == 0, return -1, "Failed to create client %{public}d", appSpawn_); + ret = AppSpawnClientInit(appSpawn_ == 1 ? APPSPAWN_SERVER_NAME : (appSpawn_ == 2 ? NATIVESPAWN_SERVER_NAME : + (appSpawn_ == 3 ? HYBRIDSPAWN_SERVER_NAME : NWEBSPAWN_SERVER_NAME)), &clientHandle_); } reqHandle = INVALID_REQ_HANDLE; if (appInfoConfig_) { @@ -388,7 +388,7 @@ int AppSpawnTestCommander::CreateMsg(AppSpawnReqMsgHandle &reqHandle, int AppSpawnTestCommander::SendMsg() { const char *server = appSpawn_ == 1 ? APPSPAWN_SERVER_NAME : (appSpawn_ == 2 ? NATIVESPAWN_SERVER_NAME : - NWEBSPAWN_SERVER_NAME); + (appSpawn_ == 3 ? HYBRIDSPAWN_SERVER_NAME : NWEBSPAWN_SERVER_NAME)); printf("Send msg to server '%s' \n", server); AppSpawnReqMsgHandle reqHandle = INVALID_REQ_HANDLE; int ret = 0; @@ -556,7 +556,7 @@ int AppSpawnTestCommander::Run() { int ret = 0; const char *name = appSpawn_ == 1 ? APPSPAWN_SERVER_NAME : (appSpawn_ == 2 ? NATIVESPAWN_SERVER_NAME : - NWEBSPAWN_SERVER_NAME); + (appSpawn_ == 3 ? HYBRIDSPAWN_SERVER_NAME : NWEBSPAWN_SERVER_NAME)); if (clientHandle_ == NULL) { ret = AppSpawnClientInit(name, &clientHandle_); APPSPAWN_CHECK(ret == 0, return -1, "Failed to create client %{public}s", name); diff --git a/test/moduletest/test_app_info.json b/test/moduletest/test_app_info.json index fea0f4b3c90cb662798e64df2c2c14c1dd0c2db2..549e4699e261abbb79d734862da9133dd40a9c4b 100644 --- a/test/moduletest/test_app_info.json +++ b/test/moduletest/test_app_info.json @@ -1,6 +1,6 @@ { "msg-type": 0, - "msg-flags": [1, 2, 14], + "msg-flags": [1, 2, 4, 14], "process-name" : "com.example.myapplication", "pid": 328018, "dac-info" : { diff --git a/test/unittest/app_spawn_standard_test/app_spawn_ace_test.cpp b/test/unittest/app_spawn_standard_test/app_spawn_ace_test.cpp index 3516d98a634071b6bc08266666aa1af728ac7bdb..042de65a0352623746ae3f809634dbe76f32610a 100644 --- a/test/unittest/app_spawn_standard_test/app_spawn_ace_test.cpp +++ b/test/unittest/app_spawn_standard_test/app_spawn_ace_test.cpp @@ -134,6 +134,63 @@ HWTEST_F(AppSpawnAceTest, App_Spawn_Ace_Preload_005, TestSize.Level0) EXPECT_EQ(ret, 0); } +/** + * @brief 未设置preload参数时(使用参数默认值),hybridspawn进行预加载 + * @note 预期结果: appspawn根据参数默认值判断是否执行preload预加载 + * + */ +HWTEST_F(AppSpawnAceTest, App_Spawn_Ace_Preload_006, TestSize.Level0) +{ + AppSpawnMgr *mgr = CreateAppSpawnMgr(MODE_FOR_HYBRID_SPAWN); + ASSERT_NE(mgr, nullptr); + mgr->content.longProcName = const_cast(HYBRIDSPAWN_SERVER_NAME); + mgr->content.longProcNameLen = APP_LEN_PROC_NAME; + + int ret = PreLoadAppSpawn(mgr); + DeleteAppSpawnMgr(mgr); + EXPECT_EQ(ret, 0); +} + +/** + * @brief preload参数设置为true时,测试hybridspawn进行预加载 + * @note 预期结果: appspawn执行preload预加载 + * + */ +HWTEST_F(AppSpawnAceTest, App_Spawn_Ace_Preload_007, TestSize.Level0) +{ + AppSpawnMgr *mgr = CreateAppSpawnMgr(MODE_FOR_HYBRID_SPAWN); + ASSERT_NE(mgr, nullptr); + mgr->content.longProcName = const_cast(HYBRIDSPAWN_SERVER_NAME); + mgr->content.longProcNameLen = APP_LEN_PROC_NAME; + + SetBoolParamResult("persist.appspawn.preload", true); + int ret = PreLoadAppSpawn(mgr); + SetBoolParamResult("persist.appspawn.preload", false); + DeleteAppSpawnMgr(mgr); + EXPECT_EQ(ret, 0); +} + +/** + * @brief preload参数和preloadets参数均设置为true时,测试hybridspawn进行预加载 + * @note 预期结果: appspawn执行preload和preloadets预加载 + * + */ +HWTEST_F(AppSpawnAceTest, App_Spawn_Ace_Preload_008, TestSize.Level0) +{ + AppSpawnMgr *mgr = CreateAppSpawnMgr(MODE_FOR_HYBRID_SPAWN); + ASSERT_NE(mgr, nullptr); + mgr->content.longProcName = const_cast(HYBRIDSPAWN_SERVER_NAME); + mgr->content.longProcNameLen = APP_LEN_PROC_NAME; + + SetBoolParamResult("persist.appspawn.preload", true); + SetBoolParamResult("persist.appspawn.preloadets", true); + int ret = PreLoadAppSpawn(mgr); + SetBoolParamResult("persist.appspawn.preload", false); + SetBoolParamResult("persist.appspawn.preloadets", false); + DeleteAppSpawnMgr(mgr); + EXPECT_EQ(ret, 0); +} + /** * @brief nwebspawn进行加载system libs * @note 预期结果: nwebspawn不支持加载system libs,直接返回 diff --git a/test/unittest/app_spawn_standard_test/app_spawn_child_test.cpp b/test/unittest/app_spawn_standard_test/app_spawn_child_test.cpp index 5ba53ec5ae49d74ea862ff3ac2c785a33a0dbf71..4552f66efecee86f1523be2e5be83f048a8a4ae2 100644 --- a/test/unittest/app_spawn_standard_test/app_spawn_child_test.cpp +++ b/test/unittest/app_spawn_standard_test/app_spawn_child_test.cpp @@ -692,6 +692,454 @@ HWTEST_F(AppSpawnChildTest, NWeb_Spawn_Child_008, TestSize.Level0) ASSERT_EQ(ret, 0); } +/** + * @brief 测试hybridspawn spawn的后半部分,子进程的处理 + * @note 创建基础的应用请求信息 + * + */ +HWTEST_F(AppSpawnChildTest, Hybrid_Spawn_Child_001, TestSize.Level0) +{ + AppSpawnClientHandle clientHandle = nullptr; + AppSpawnReqMsgHandle reqHandle = 0; + AppSpawningCtx *property = nullptr; + AppSpawnContent *content = nullptr; + int ret = -1; + do { + ret = AppSpawnClientInit(HYBRIDSPAWN_SERVER_NAME, &clientHandle); + APPSPAWN_CHECK(ret == 0, break, "Failed to create reqMgr %{public}s", HYBRIDSPAWN_SERVER_NAME); + reqHandle = g_testHelper.CreateMsg(clientHandle, MSG_APP_SPAWN, 0); + APPSPAWN_CHECK(reqHandle != INVALID_REQ_HANDLE, break, "Failed to create req %{public}s", + HYBRIDSPAWN_SERVER_NAME); + content = CreateTestAppSpawnContent(HYBRIDSPAWN_SOCKET_NAME, MODE_FOR_HYBRID_SPAWN); + APPSPAWN_CHECK_ONLY_EXPER(content != nullptr, break); + + ret = APPSPAWN_ARG_INVALID; + property = g_testHelper.GetAppProperty(clientHandle, reqHandle); + reqHandle = nullptr; + APPSPAWN_CHECK_ONLY_EXPER(property != nullptr, break); + + // spawn prepare process + AppSpawnHookExecute(STAGE_PARENT_PRE_FORK, 0, content, &property->client); + + // spawn + ret = AppSpawnChild(content, &property->client); + property = nullptr; + } while (0); + DeleteAppSpawningCtx(property); + AppSpawnReqMsgFree(reqHandle); + AppSpawnClientDestroy(clientHandle); + ASSERT_EQ(ret, 0); +} + +/** + * @brief 测试hybridspawn spawn的后半部分,子进程的处理 + * @note 创建基础的应用请求信息,设置多个flag位 + * + */ +HWTEST_F(AppSpawnChildTest, Hybrid_Spawn_Child_002, TestSize.Level0) +{ + AppSpawnClientHandle clientHandle = nullptr; + AppSpawnReqMsgHandle reqHandle = 0; + AppSpawningCtx *property = nullptr; + AppSpawnContent *content = nullptr; + int ret = -1; + do { + ret = AppSpawnClientInit(HYBRIDSPAWN_SERVER_NAME, &clientHandle); + APPSPAWN_CHECK(ret == 0, break, "Failed to create reqMgr %{public}s", HYBRIDSPAWN_SERVER_NAME); + reqHandle = g_testHelper.CreateMsg(clientHandle, MSG_APP_SPAWN, 0); + APPSPAWN_CHECK(reqHandle != INVALID_REQ_HANDLE, break, "Failed to create req %{public}s", + HYBRIDSPAWN_SERVER_NAME); + AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_DEBUGGABLE); + AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_NATIVEDEBUG); + AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_BUNDLE_RESOURCES); + AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_ACCESS_BUNDLE_DIR); + + content = CreateTestAppSpawnContent(HYBRIDSPAWN_SOCKET_NAME, MODE_FOR_HYBRID_SPAWN); + APPSPAWN_CHECK_ONLY_EXPER(content != nullptr, break); + + ret = APPSPAWN_ARG_INVALID; + property = g_testHelper.GetAppProperty(clientHandle, reqHandle); + reqHandle = nullptr; + APPSPAWN_CHECK_ONLY_EXPER(property != nullptr, break); + + // spawn prepare process + AppSpawnHookExecute(STAGE_PARENT_PRE_FORK, 0, content, &property->client); + // spawn + ret = AppSpawnChild(content, &property->client); + property = nullptr; + } while (0); + DeleteAppSpawningCtx(property); + AppSpawnReqMsgFree(reqHandle); + AppSpawnClientDestroy(clientHandle); + ASSERT_EQ(ret, 0); +} + +/** + * @brief 测试hybridspawn spawn的后半部分,子进程的处理 + * @note 创建基础的应用请求信息中不含有拓展字段,设置多个flag位 + * + */ +HWTEST_F(AppSpawnChildTest, Hybrid_Spawn_Child_003, TestSize.Level0) +{ + AppSpawnClientHandle clientHandle = nullptr; + AppSpawnReqMsgHandle reqHandle = 0; + AppSpawningCtx *property = nullptr; + AppSpawnContent *content = nullptr; + int ret = -1; + do { + ret = AppSpawnClientInit(HYBRIDSPAWN_SERVER_NAME, &clientHandle); + APPSPAWN_CHECK(ret == 0, break, "Failed to create reqMgr %{public}s", HYBRIDSPAWN_SERVER_NAME); + + g_testHelper.SetTestUid(10010029); // 10010029 + reqHandle = g_testHelper.CreateMsg(clientHandle, MSG_APP_SPAWN, 1); + APPSPAWN_CHECK(reqHandle != INVALID_REQ_HANDLE, break, "Failed to create req %{public}s", + HYBRIDSPAWN_SERVER_NAME); + AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_DEBUGGABLE); + AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_NATIVEDEBUG); + AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_BUNDLE_RESOURCES); + AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_ACCESS_BUNDLE_DIR); + + content = CreateTestAppSpawnContent(HYBRIDSPAWN_SOCKET_NAME, MODE_FOR_HYBRID_SPAWN); + APPSPAWN_CHECK_ONLY_EXPER(content != nullptr, break); + + ret = APPSPAWN_ARG_INVALID; + property = g_testHelper.GetAppProperty(clientHandle, reqHandle); + reqHandle = nullptr; + APPSPAWN_CHECK_ONLY_EXPER(property != nullptr, break); + + // spawn prepare process + AppSpawnHookExecute(STAGE_PARENT_PRE_FORK, 0, content, &property->client); + // spawn + ret = AppSpawnChild(content, &property->client); + property = nullptr; + } while (0); + DeleteAppSpawningCtx(property); + AppSpawnReqMsgFree(reqHandle); + AppSpawnClientDestroy(clientHandle); + ASSERT_EQ(ret, 0); +} + +/** + * @brief 测试hybridspawn spawn的后半部分,子进程的处理 + * @note 测试native process进程的孵化请求,创建基础的消息中不含有拓展字段,设置多个flag位 + * + */ +HWTEST_F(AppSpawnChildTest, Hybrid_Spawn_Child_004, TestSize.Level0) +{ + AppSpawnClientHandle clientHandle = nullptr; + AppSpawnReqMsgHandle reqHandle = 0; + AppSpawningCtx *property = nullptr; + AppSpawnContent *content = nullptr; + int ret = -1; + do { + ret = AppSpawnClientInit(HYBRIDSPAWN_SERVER_NAME, &clientHandle); + APPSPAWN_CHECK(ret == 0, break, "Failed to create reqMgr %{public}s", HYBRIDSPAWN_SERVER_NAME); + // MSG_SPAWN_NATIVE_PROCESS and no render cmd + g_testHelper.SetTestUid(10010029); // 10010029 + reqHandle = g_testHelper.CreateMsg(clientHandle, MSG_SPAWN_NATIVE_PROCESS, 1); + APPSPAWN_CHECK(reqHandle != INVALID_REQ_HANDLE, break, "Failed to create req %{public}s", + HYBRIDSPAWN_SERVER_NAME); + AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_DEBUGGABLE); + AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_NATIVEDEBUG); + AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_BUNDLE_RESOURCES); + AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_ACCESS_BUNDLE_DIR); + AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_GWP_ENABLED_NORMAL); + + ret = APPSPAWN_ARG_INVALID; + property = g_testHelper.GetAppProperty(clientHandle, reqHandle); + reqHandle = nullptr; + APPSPAWN_CHECK_ONLY_EXPER(property != nullptr, break); + + content = CreateTestAppSpawnContent(HYBRIDSPAWN_SOCKET_NAME, MODE_FOR_HYBRID_SPAWN); + APPSPAWN_CHECK_ONLY_EXPER(content != nullptr, break); + + // spawn prepare process + AppSpawnHookExecute(STAGE_PARENT_PRE_FORK, 0, content, &property->client); + // spawn + ret = AppSpawnChild(content, &property->client); + property = nullptr; + } while (0); + DeleteAppSpawningCtx(property); + AppSpawnReqMsgFree(reqHandle); + AppSpawnClientDestroy(clientHandle); + ASSERT_EQ(ret, 0); +} + +/** + * @brief 测试hybridspawn spawn的后半部分,子进程的处理 + * @note 测试native process进程的孵化请求,创建基础的消息,设置多个flag位 + * + */ +HWTEST_F(AppSpawnChildTest, Hybrid_Spawn_Child_005, TestSize.Level0) +{ + AppSpawnClientHandle clientHandle = nullptr; + AppSpawnReqMsgHandle reqHandle = 0; + AppSpawningCtx *property = nullptr; + AppSpawnContent *content = nullptr; + int ret = -1; + do { + ret = AppSpawnClientInit(HYBRIDSPAWN_SERVER_NAME, &clientHandle); + APPSPAWN_CHECK(ret == 0, break, "Failed to create reqMgr %{public}s", HYBRIDSPAWN_SERVER_NAME); + // MSG_SPAWN_NATIVE_PROCESS and render + g_testHelper.SetTestUid(10010029); // 10010029 + reqHandle = g_testHelper.CreateMsg(clientHandle, MSG_SPAWN_NATIVE_PROCESS, 0); + APPSPAWN_CHECK(reqHandle != INVALID_REQ_HANDLE, break, "Failed to create req %{public}s", + HYBRIDSPAWN_SERVER_NAME); + AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_DEBUGGABLE); + AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_NATIVEDEBUG); + AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_BUNDLE_RESOURCES); + AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_ACCESS_BUNDLE_DIR); + AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_GWP_ENABLED_NORMAL); + + ret = APPSPAWN_ARG_INVALID; + property = g_testHelper.GetAppProperty(clientHandle, reqHandle); + reqHandle = nullptr; + APPSPAWN_CHECK_ONLY_EXPER(property != nullptr, break); + + content = CreateTestAppSpawnContent(HYBRIDSPAWN_SOCKET_NAME, MODE_FOR_HYBRID_SPAWN); + APPSPAWN_CHECK_ONLY_EXPER(content != nullptr, break); + + // spawn prepare process + AppSpawnHookExecute(STAGE_PARENT_PRE_FORK, 0, content, &property->client); + // spawn + ret = AppSpawnChild(content, &property->client); + property = nullptr; + ASSERT_EQ(ret, 0); + } while (0); + DeleteAppSpawningCtx(property); + AppSpawnReqMsgFree(reqHandle); + AppSpawnClientDestroy(clientHandle); + ASSERT_EQ(ret, 0); +} + +/** + * @brief 测试hybridspawn spawn的后半部分,子进程的处理 + * @note 测试native process的孵化请求,创建基础的信息,添加多个flag位,新增环境变量扩展字段 + * + */ +HWTEST_F(AppSpawnChildTest, Hybrid_Spawn_Child_006, TestSize.Level0) +{ + AppSpawnClientHandle clientHandle = nullptr; + AppSpawnReqMsgHandle reqHandle = 0; + AppSpawningCtx *property = nullptr; + AppSpawnContent *content = nullptr; + int ret = -1; + do { + ret = AppSpawnClientInit(HYBRIDSPAWN_SERVER_NAME, &clientHandle); + APPSPAWN_CHECK(ret == 0, break, "Failed to create reqMgr %{public}s", HYBRIDSPAWN_SERVER_NAME); + // MSG_SPAWN_NATIVE_PROCESS and no render cmd + g_testHelper.SetTestUid(10010029); // 10010029 + reqHandle = g_testHelper.CreateMsg(clientHandle, MSG_SPAWN_NATIVE_PROCESS, 0); + APPSPAWN_CHECK(reqHandle != INVALID_REQ_HANDLE, break, "Failed to create req %{public}s", + HYBRIDSPAWN_SERVER_NAME); + AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_DEBUGGABLE); + AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_NATIVEDEBUG); + AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_BUNDLE_RESOURCES); + AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_ACCESS_BUNDLE_DIR); + const char *appEnv = "{\"test.name1\": \"test.value1\", \"test.name2\": \"test.value2\"}"; + ret = AppSpawnReqMsgAddExtInfo(reqHandle, "AppEnv", + reinterpret_cast(const_cast(appEnv)), strlen(appEnv) + 1); + APPSPAWN_CHECK(ret == 0, break, "Failed to add ext tlv %{public}s", appEnv); + + ret = APPSPAWN_ARG_INVALID; + property = g_testHelper.GetAppProperty(clientHandle, reqHandle); + reqHandle = nullptr; + APPSPAWN_CHECK_ONLY_EXPER(property != nullptr, break); + + content = CreateTestAppSpawnContent(HYBRIDSPAWN_SOCKET_NAME, MODE_FOR_HYBRID_SPAWN); + APPSPAWN_CHECK_ONLY_EXPER(content != nullptr, break); + + // spawn prepare process + AppSpawnHookExecute(STAGE_PARENT_PRE_FORK, 0, content, &property->client); + // spawn + ret = AppSpawnChild(content, &property->client); + property = nullptr; + ASSERT_EQ(ret, 0); + } while (0); + DeleteAppSpawningCtx(property); + AppSpawnReqMsgFree(reqHandle); + AppSpawnClientDestroy(clientHandle); + ASSERT_EQ(ret, 0); +} + +/** + * @brief 测试hybridspawn spawn的后半部分,子进程的处理 + * @note 测试native process的孵化请求,创建基础的信息,添加多个flag位,使能冷启动 + * + */ +HWTEST_F(AppSpawnChildTest, Hybrid_Spawn_Child_007, TestSize.Level0) +{ + AppSpawnClientHandle clientHandle = nullptr; + AppSpawnReqMsgHandle reqHandle = 0; + AppSpawningCtx *property = nullptr; + AppSpawnContent *content = nullptr; + int ret = -1; + do { + ret = AppSpawnClientInit(HYBRIDSPAWN_SERVER_NAME, &clientHandle); + APPSPAWN_CHECK(ret == 0, break, "Failed to create reqMgr %{public}s", HYBRIDSPAWN_SERVER_NAME); + // MSG_SPAWN_NATIVE_PROCESS and render + g_testHelper.SetTestUid(10010029); // 10010029 + reqHandle = g_testHelper.CreateMsg(clientHandle, MSG_SPAWN_NATIVE_PROCESS, 0); + APPSPAWN_CHECK(reqHandle != INVALID_REQ_HANDLE, break, "Failed to create req"); + AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_DEBUGGABLE); + AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_NATIVEDEBUG); + AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_BUNDLE_RESOURCES); + AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_ACCESS_BUNDLE_DIR); + AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_GWP_ENABLED_NORMAL); + + content = CreateTestAppSpawnContent(HYBRIDSPAWN_SOCKET_NAME, MODE_FOR_HYBRID_SPAWN); + APPSPAWN_CHECK_ONLY_EXPER(content != nullptr, break); + + ret = APPSPAWN_ARG_INVALID; + property = g_testHelper.GetAppProperty(clientHandle, reqHandle); + APPSPAWN_CHECK_ONLY_EXPER(property != nullptr, break); + + // spawn prepare process + AppSpawnHookExecute(STAGE_PARENT_PRE_FORK, 0, content, &property->client); + + // spawn + property->client.flags = APP_COLD_START; + ret = AppSpawnChild(content, &property->client); + property = nullptr; + content = nullptr; + } while (0); + DeleteAppSpawningCtx(property); + AppSpawnClientDestroy(clientHandle); + AppSpawnDestroyContent(content); + LE_StopLoop(LE_GetDefaultLoop()); + LE_CloseLoop(LE_GetDefaultLoop()); + ASSERT_EQ(ret, 0); +} + +/** + * @brief 测试hybridspawn spawn的后半部分,子进程的处理 + * @note 测试普通应用的孵化请求,创建基础的信息,添加多个flag位,使能冷启动 + * + */ +HWTEST_F(AppSpawnChildTest, Hybrid_Spawn_Child_008, TestSize.Level0) +{ + AppSpawnClientHandle clientHandle = nullptr; + AppSpawnReqMsgHandle reqHandle = 0; + AppSpawningCtx *property = nullptr; + AppSpawnContent *content = nullptr; + int ret = -1; + do { + ret = AppSpawnClientInit(HYBRIDSPAWN_SERVER_NAME, &clientHandle); + APPSPAWN_CHECK(ret == 0, break, "Failed to create reqMgr %{public}s", HYBRIDSPAWN_SERVER_NAME); + // MSG_SPAWN_NATIVE_PROCESS and render + g_testHelper.SetTestUid(10010029); // 10010029 + reqHandle = g_testHelper.CreateMsg(clientHandle, MSG_APP_SPAWN, 0); + APPSPAWN_CHECK(reqHandle != INVALID_REQ_HANDLE, break, "Failed to create req"); + AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_DEBUGGABLE); + AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_NATIVEDEBUG); + AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_BUNDLE_RESOURCES); + AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_ACCESS_BUNDLE_DIR); + AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_GWP_ENABLED_NORMAL); + + content = CreateTestAppSpawnContent(HYBRIDSPAWN_SOCKET_NAME, MODE_FOR_APP_COLD_RUN); + APPSPAWN_CHECK_ONLY_EXPER(content != nullptr, break); + content->coldStartApp = nullptr; + + ret = APPSPAWN_ARG_INVALID; + property = g_testHelper.GetAppProperty(clientHandle, reqHandle); + APPSPAWN_CHECK_ONLY_EXPER(property != nullptr, break); + // spawn + property->client.flags = APP_COLD_START; + ret = AppSpawnChild(content, &property->client); + property = nullptr; + content = nullptr; + } while (0); + DeleteAppSpawningCtx(property); + AppSpawnClientDestroy(clientHandle); + AppSpawnDestroyContent(content); + LE_StopLoop(LE_GetDefaultLoop()); + LE_CloseLoop(LE_GetDefaultLoop()); + ASSERT_EQ(ret, 0); +} + + +/** + * @brief 测试nativespawn spawn的后半部分,子进程的处理 + * @note 创建基础的应用请求信息 + * + */ +HWTEST_F(AppSpawnChildTest, Native_Spawn_Child_001, TestSize.Level0) +{ + AppSpawnClientHandle clientHandle = nullptr; + AppSpawnReqMsgHandle reqHandle = 0; + AppSpawningCtx *property = nullptr; + AppSpawnContent *content = nullptr; + int ret = -1; + do { + ret = AppSpawnClientInit(NATIVESPAWN_SERVER_NAME, &clientHandle); + APPSPAWN_CHECK(ret == 0, break, "Failed to create reqMgr %{public}s", NATIVESPAWN_SERVER_NAME); + reqHandle = g_testHelper.CreateMsg(clientHandle, MSG_APP_SPAWN, 0); + APPSPAWN_CHECK(reqHandle != INVALID_REQ_HANDLE, break, "Failed to create req %{public}s", + NATIVESPAWN_SERVER_NAME); + content = CreateTestAppSpawnContent(NATIVESPAWN_SOCKET_NAME, MODE_FOR_NATIVE_SPAWN); + APPSPAWN_CHECK_ONLY_EXPER(content != nullptr, break); + + ret = APPSPAWN_ARG_INVALID; + property = g_testHelper.GetAppProperty(clientHandle, reqHandle); + reqHandle = nullptr; + APPSPAWN_CHECK_ONLY_EXPER(property != nullptr, break); + + // spawn prepare process + AppSpawnHookExecute(STAGE_PARENT_PRE_FORK, 0, content, &property->client); + + // spawn + ret = AppSpawnChild(content, &property->client); + property = nullptr; + } while (0); + DeleteAppSpawningCtx(property); + AppSpawnReqMsgFree(reqHandle); + AppSpawnClientDestroy(clientHandle); + ASSERT_EQ(ret, 0); +} + +/** + * @brief 测试nativespawn spawn的后半部分,子进程的处理 + * @note 创建基础的应用请求信息,设置多个flag位 + * + */ +HWTEST_F(AppSpawnChildTest, Native_Spawn_Child_002, TestSize.Level0) +{ + AppSpawnClientHandle clientHandle = nullptr; + AppSpawnReqMsgHandle reqHandle = 0; + AppSpawningCtx *property = nullptr; + AppSpawnContent *content = nullptr; + int ret = -1; + do { + ret = AppSpawnClientInit(NATIVESPAWN_SERVER_NAME, &clientHandle); + APPSPAWN_CHECK(ret == 0, break, "Failed to create reqMgr %{public}s", NATIVESPAWN_SERVER_NAME); + reqHandle = g_testHelper.CreateMsg(clientHandle, MSG_APP_SPAWN, 0); + APPSPAWN_CHECK(reqHandle != INVALID_REQ_HANDLE, break, "Failed to create req %{public}s", + NATIVESPAWN_SERVER_NAME); + AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_DEBUGGABLE); + AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_NATIVEDEBUG); + AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_BUNDLE_RESOURCES); + AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_ACCESS_BUNDLE_DIR); + + content = CreateTestAppSpawnContent(NATIVESPAWN_SOCKET_NAME, MODE_FOR_NATIVE_SPAWN); + APPSPAWN_CHECK_ONLY_EXPER(content != nullptr, break); + + ret = APPSPAWN_ARG_INVALID; + property = g_testHelper.GetAppProperty(clientHandle, reqHandle); + reqHandle = nullptr; + APPSPAWN_CHECK_ONLY_EXPER(property != nullptr, break); + + // spawn prepare process + AppSpawnHookExecute(STAGE_PARENT_PRE_FORK, 0, content, &property->client); + // spawn + ret = AppSpawnChild(content, &property->client); + property = nullptr; + } while (0); + DeleteAppSpawningCtx(property); + AppSpawnReqMsgFree(reqHandle); + AppSpawnClientDestroy(clientHandle); + ASSERT_EQ(ret, 0); +} + HWTEST_F(AppSpawnChildTest, App_Spawn_Child_Illegal_001, TestSize.Level0) { ASSERT_EQ(AppSpawnChild(nullptr, nullptr), -1); diff --git a/test/unittest/app_spawn_standard_test/app_spawn_common_test.cpp b/test/unittest/app_spawn_standard_test/app_spawn_common_test.cpp index 52e09332600c2225ce63e2c166bdb5dfe8382253..266cb7beae1c362dcfa3a8b6c408db3199bafdce 100644 --- a/test/unittest/app_spawn_standard_test/app_spawn_common_test.cpp +++ b/test/unittest/app_spawn_standard_test/app_spawn_common_test.cpp @@ -1305,6 +1305,72 @@ HWTEST_F(AppSpawnCommonTest, App_Spawn_Encaps_031, TestSize.Level0) FreeEncapsInfo(&encapsInfo); } +HWTEST_F(AppSpawnCommonTest, App_Spawn_Encaps_032, TestSize.Level0) +{ + AppSpawnClientHandle clientHandle = nullptr; + AppSpawnReqMsgHandle reqHandle = 0; + AppSpawningCtx *property = nullptr; + AppSpawnMgr *mgr = nullptr; + int ret = -1; + do { + mgr = CreateAppSpawnMgr(MODE_FOR_HYBRID_SPAWN); + EXPECT_EQ(mgr != nullptr, 1); + // create msg + ret = AppSpawnClientInit(HYBRIDSPAWN_SERVER_NAME, &clientHandle); + APPSPAWN_CHECK(ret == 0, break, "Failed to create reqMgr %{public}s", HYBRIDSPAWN_SERVER_NAME); + reqHandle = g_testHelper.CreateMsg(clientHandle, MSG_APP_SPAWN, 0); + APPSPAWN_CHECK(reqHandle != INVALID_REQ_HANDLE, break, "Failed to create req %{public}s", + HYBRIDSPAWN_SERVER_NAME); + const char *permissions = "{\"name\":\"Permissions\",\"ohos.encaps.count\":6,\"permissions\":" + "[{\"ohos.permission.bool\":true},{\"ohos.permission.int\":3225},{\"ohos.permission.string\":\"nihaoma\"}," + "{\"ohos.permission.strarray\":[\"abc\",\"def\"]},{\"ohos.permission.intarray\":[1,2,3,4,5]}," + "{\"ohos.permission.boolarray\":[true,false,true]}]}"; + ret = AppSpawnReqMsgAddExtInfo(reqHandle, MSG_EXT_NAME_JIT_PERMISSIONS, + reinterpret_cast(const_cast(permissions)), strlen(permissions) + 1); + APPSPAWN_CHECK(ret == 0, break, "Failed to add permissions"); + const char *maxChildProcess = "512"; + ret = AppSpawnReqMsgAddExtInfo(reqHandle, MSG_EXT_NAME_MAX_CHILD_PROCCESS_MAX, + reinterpret_cast(const_cast(maxChildProcess)), strlen(maxChildProcess) + 1); + APPSPAWN_CHECK(ret == 0, break, "Failed to add maxChildProcess"); + property = g_testHelper.GetAppProperty(clientHandle, reqHandle); + APPSPAWN_CHECK_ONLY_EXPER(property != nullptr, break); + + ret = SpawnSetEncapsPermissions(mgr, property); + } while (0); + + EXPECT_EQ(ret, 0); + DeleteAppSpawningCtx(property); + AppSpawnClientDestroy(clientHandle); + DeleteAppSpawnMgr(mgr); +} + +HWTEST_F(AppSpawnCommonTest, App_Spawn_Encaps_033, TestSize.Level0) +{ + AppSpawnClientHandle clientHandle = nullptr; + AppSpawnReqMsgHandle reqHandle = 0; + AppSpawningCtx *property = nullptr; + AppSpawnMgr *mgr = nullptr; + int ret = -1; + do { + mgr = CreateAppSpawnMgr(MODE_FOR_HYBRID_SPAWN); + EXPECT_EQ(mgr != nullptr, 1); + // create msg + ret = AppSpawnClientInit(HYBRIDSPAWN_SERVER_NAME, &clientHandle); + APPSPAWN_CHECK(ret == 0, break, "Failed to create reqMgr %{public}s", HYBRIDSPAWN_SERVER_NAME); + reqHandle = g_testHelper.CreateMsg(clientHandle, MSG_APP_SPAWN, 0); + APPSPAWN_CHECK(reqHandle != INVALID_REQ_HANDLE, break, + "Failed to create req %{public}s", HYBRIDSPAWN_SERVER_NAME); + property = g_testHelper.GetAppProperty(clientHandle, reqHandle); + APPSPAWN_CHECK_ONLY_EXPER(property != nullptr, break); + ret = SpawnSetEncapsPermissions(mgr, property); + } while (0); + + EXPECT_EQ(ret, 0); + DeleteAppSpawningCtx(property); + AppSpawnClientDestroy(clientHandle); + DeleteAppSpawnMgr(mgr); +} + HWTEST_F(AppSpawnCommonTest, App_Spawn_SetFdEnv, TestSize.Level0) { int ret = SetFdEnv(nullptr, nullptr);