From 98703fbd343872995bee09fe3281ab897aa70cab Mon Sep 17 00:00:00 2001 From: nianyuu Date: Tue, 22 Jul 2025 11:22:41 +0800 Subject: [PATCH] support hybridspawn Signed-off-by: nianyuu --- BUILD.gn | 13 +++ appspawn.gni | 1 + appspawn_preload_ets.json | 6 ++ bundle.json | 1 + common/appspawn_server.h | 2 + etc/BUILD.gn | 23 +++++ etc/ohos.startup.appspawn.para | 14 +++ etc/ohos.startup.appspawn.para.dac | 15 ++++ hybridspawn.cfg | 44 ++++++++++ interfaces/innerkits/client/appspawn_client.c | 5 ++ interfaces/innerkits/client/appspawn_client.h | 1 + interfaces/innerkits/include/appspawn.h | 1 + modules/ace_adapter/ace_adapter.cpp | 69 +++++++++------ modules/asan/asan_detector.c | 2 + modules/common/appspawn_common.c | 4 +- modules/common/appspawn_encaps.c | 2 +- modules/module_engine/include/appspawn_msg.h | 1 + modules/modulemgr/appspawn_modulemgr.c | 1 + modules/modulemgr/appspawn_modulemgr.h | 1 + standard/BUILD.gn | 86 +++++++++++++++++++ standard/appspawn_kickdog.c | 19 ++-- standard/appspawn_kickdog.h | 2 + standard/appspawn_main.c | 11 +++ standard/appspawn_manager.h | 6 ++ standard/appspawn_service.c | 25 +----- test/mock/js_runtime.h | 9 +- test/moduletest/appspawn_test_cmder.cpp | 8 +- test/moduletest/test_app_info.json | 2 +- 28 files changed, 308 insertions(+), 66 deletions(-) create mode 100644 appspawn_preload_ets.json create mode 100644 etc/ohos.startup.appspawn.para create mode 100644 etc/ohos.startup.appspawn.para.dac create mode 100644 hybridspawn.cfg diff --git a/BUILD.gn b/BUILD.gn index fc79436f..0109a897 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") { @@ -107,6 +114,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 3e32920e..7466cb64 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 00000000..bd4af66c --- /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 ac0f60c4..fff1e1ad 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 76a299d9..80adb926 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 b23fdfc1..97a938a6 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 00000000..6ef0a3a4 --- /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 00000000..c347f2b7 --- /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 00000000..b3180380 --- /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 da504d36..bef4315b 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 b979e2b6..0905f56a 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 4d0c6039..c6dbb121 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 1b00fe42..d686fbf5 100644 --- a/modules/ace_adapter/ace_adapter.cpp +++ b/modules/ace_adapter/ace_adapter.cpp @@ -49,52 +49,53 @@ 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) { + cJSON *namesJson = cJSON_GetObjectItemCaseSensitive(root, key.c_str()); + if (namesJson == 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) { + 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)); + if (name == nullptr) { continue; } - APPSPAWN_LOGV("moduleName %{public}s", moduleName); - if (!modules.count(moduleName)) { - modules.insert(moduleName); + 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) { @@ -102,17 +103,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"); @@ -129,7 +137,7 @@ static void LoadExtendLib(void) APPSPAWN_LOGI("LoadExtendLib: Start preload VM"); SetTraceDisabled(true); - PreloadModule(); + PreloadModule(isHybrid); SetTraceDisabled(false); APPSPAWN_LOGI("LoadExtendLib: Start reclaim file cache"); @@ -291,7 +299,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; } @@ -320,7 +333,7 @@ APPSPAWN_STATIC int DoDlopenLibs(const cJSON *root, ParseJsonContext *context) 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 52be5a68..9053c41a 100644 --- a/modules/asan/asan_detector.c +++ b/modules/asan/asan_detector.c @@ -145,6 +145,8 @@ static int AsanSpawnGetSpawningFlag(AppSpawnMgr *content, AppSpawningCtx *proper property->forkCtx.coldRunPath = strdup("/system/asan/bin/appspawn"); #elif NATIVE_SPAWN property->forkCtx.coldRunPath = strdup("/system/asan/bin/nativespawn"); +#elif HYBRID_SPAWN + property->forkCtx.coldRunPath = strdup("/system/asan/bin/hybridspawn"); #else property->forkCtx.coldRunPath = strdup("/system/asan/bin/cjappspawn"); #endif diff --git a/modules/common/appspawn_common.c b/modules/common/appspawn_common.c index f0d4a74d..1243f93f 100644 --- a/modules/common/appspawn_common.c +++ b/modules/common/appspawn_common.c @@ -239,7 +239,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); @@ -439,7 +439,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 3236e976..2dd66725 100644 --- a/modules/common/appspawn_encaps.c +++ b/modules/common/appspawn_encaps.c @@ -341,7 +341,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 94f966b9..5a9eabea 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 c29076de..75e9e666 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 53d0efb5..cb9fcd48 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 779676dc..0d9f32b6 100644 --- a/standard/BUILD.gn +++ b/standard/BUILD.gn @@ -393,3 +393,89 @@ 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", + "${appspawn_path}/standard/nwebspawn_launcher.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 a471c7d1..970c2542 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_DUMP_LOGI("%{public}s %{public}s %{public}d", - (content->mode == MODE_FOR_NWEB_SPAWN) ? - "Nweb" : "Apps", isOpen ? "enable" : "kick", result); + APPSPAWN_DUMP_LOGI("%{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 6a45b980..cf201933 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 df5fe79f..103ad155 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 39f6a785..0ff87686 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 fa68507d..b7f92b62 100644 --- a/standard/appspawn_service.c +++ b/standard/appspawn_service.c @@ -94,27 +94,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); @@ -1196,6 +1175,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 @@ -1326,7 +1307,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 4e05753f..ba46bac9 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_test_cmder.cpp b/test/moduletest/appspawn_test_cmder.cpp index 4aa7461d..f2449821 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 fea0f4b3..549e4699 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" : { -- Gitee