diff --git a/interfaces/innerkits/include/appspawn.h b/interfaces/innerkits/include/appspawn.h index 8a53fdc7edd61fce45602d948c2617b6d35105a8..5ae89a2246244e854b24cca403dbdde39cce5620 100644 --- a/interfaces/innerkits/include/appspawn.h +++ b/interfaces/innerkits/include/appspawn.h @@ -122,6 +122,7 @@ typedef enum { MSG_UNINSTALL_DEBUG_HAP, MSG_LOCK_STATUS, MSG_OBSERVE_PROCESS_SIGNAL_STATUS, + MSG_LOAD_WEBLIB_IN_APPSPAWN, MAX_TYPE_INVALID } AppSpawnMsgType; diff --git a/modules/ace_adapter/BUILD.gn b/modules/ace_adapter/BUILD.gn index 6b6489020af5cb67cd7901e41d5587808c8a57b2..5f94d3bb8fdc8d42364f9bf404bcc4b26c206115 100644 --- a/modules/ace_adapter/BUILD.gn +++ b/modules/ace_adapter/BUILD.gn @@ -30,6 +30,9 @@ ohos_shared_library("appspawn_ace") { "${appspawn_path}/util:libappspawn_util", ] defines = [] + if (target_cpu == "arm64") { + defines += [ "PRE_DLOPEN_ARKWEB_LIB" ] + } if (asan_detector || is_asan) { defines += [ "ASAN_DETECTOR" ] } diff --git a/modules/ace_adapter/ace_adapter.cpp b/modules/ace_adapter/ace_adapter.cpp index 1b00fe42a0d013d1913e92d26b1c167b6d9ec1f3..3641a3a4cfc32761a9ed6ae9da798af1c85c4520 100644 --- a/modules/ace_adapter/ace_adapter.cpp +++ b/modules/ace_adapter/ace_adapter.cpp @@ -32,6 +32,7 @@ #include "hitrace_meter.h" #include "js_runtime.h" #include "json_utils.h" +#include "parameter.h" #include "parameters.h" #include "resource_manager.h" #ifndef APPSPAWN_TEST @@ -132,8 +133,6 @@ static void LoadExtendLib(void) PreloadModule(); SetTraceDisabled(false); - APPSPAWN_LOGI("LoadExtendLib: Start reclaim file cache"); - OHOS::Ace::AceForwardCompatibility::ReclaimFileCache(getpid()); Resource::ResourceManager *systemResMgr = Resource::GetSystemResourceManagerNoSandBox(); APPSPAWN_CHECK(systemResMgr != nullptr, return, "Fail to get system resource manager"); APPSPAWN_LOGI("LoadExtendLib: End preload VM"); @@ -318,6 +317,37 @@ APPSPAWN_STATIC int DoDlopenLibs(const cJSON *root, ParseJsonContext *context) return 0; } +#ifdef PRE_DLOPEN_ARKWEB_LIB +static void DlopenArkWebLib() +{ + char packageName[PATH_MAX] = {0}; + GetParameter("persist.arkwebcore.package_name", "", packageName, PATH_MAX); + if (strlen(packageName) == 0) { + APPSPAWN_LOGE("persist.arkwebcore.package_name is empty"); + return; + } + + std::string arkwebLibPath = "/data/app/el1/bundle/public/" + std::string(packageName) + + "/libs/arm64:/data/storage/el1/bundle/arkwebcore/libs/arm64"; + APPSPAWN_LOGI("DlopenArkWebLib arkwebLibPath: %{public}s", arkwebLibPath.c_str()); + + Dl_namespace dlns; + dlns_init(&dlns, "nweb_ns"); + dlns_create(&dlns, arkwebLibPath.c_str()); + + Dl_namespace ndkns; + dlns_get("ndk", &ndkns); + dlns_inherit(&dlns, &ndkns, "allow_all_shared_libs"); + + void* webEngineHandle = dlopen_ns(&dlns, "libarkweb_engine.so", RTLD_NOW | RTLD_GLOBAL); + if (!webEngineHandle) { + APPSPAWN_LOGE("FAILED to dlopen libarkweb_engine.so in appspawn %{public}s", dlerror()); + } else { + APPSPAWN_LOGI("SUCCESS to dlopen libarkweb_engine.so in appspawn"); + } +} +#endif + APPSPAWN_STATIC int DlopenAppSpawn(AppSpawnMgr *content) { if (!IsAppSpawnMode(content)) { @@ -325,6 +355,11 @@ APPSPAWN_STATIC int DlopenAppSpawn(AppSpawnMgr *content) } (void)ParseJsonConfig("etc/appspawn", SYSTEMLIB_JSON, DoDlopenLibs, nullptr); +#ifdef PRE_DLOPEN_ARKWEB_LIB + DlopenArkWebLib(); +#endif + APPSPAWN_LOGI("DlopenAppSpawn: Start reclaim file cache"); + OHOS::Ace::AceForwardCompatibility::ReclaimFileCache(getpid()); return 0; } diff --git a/standard/BUILD.gn b/standard/BUILD.gn index f04763ddff415df47065d4578ef38d6d9afd488a..9d6f694d9155361ee2be3f52301b0e4bf960aeef 100644 --- a/standard/BUILD.gn +++ b/standard/BUILD.gn @@ -52,6 +52,9 @@ ohos_executable("appspawn") { ] defines = [] + if (target_cpu == "arm64") { + defines += [ "PRE_DLOPEN_ARKWEB_LIB" ] + } configs = [ ":appspawn_server_config", "${appspawn_path}:appspawn_config", diff --git a/standard/appspawn_service.c b/standard/appspawn_service.c index 49fce14418250f28518c439434987f0676078b5a..459311a024f4d0a9fd6e5e8143eb5cd61d206f52 100644 --- a/standard/appspawn_service.c +++ b/standard/appspawn_service.c @@ -15,6 +15,7 @@ #include "appspawn_service.h" +#include #include #include #include @@ -1765,6 +1766,51 @@ APPSPAWN_STATIC void ProcessObserveProcessSignalMsg(AppSpawnConnection *connecti DeleteAppSpawnMsg(&message); } +static void ProcessSpawnDlopenMsg(AppSpawnConnection *connection, AppSpawnMsgNode *message) +{ + AppSpawnMsg* msg = &message->msgHeader; + APPSPAWN_LOGI("Recv ProcessSpawnReqMsg message header magic: 0x%{public}x type: %{public}u" + "id: %{public}u len: %{public}u processName: %{public}s", + msg->magic, + msg->msgType, + msg->msgId, + msg->msgLen, + msg->processName); + +#ifdef PRE_DLOPEN_ARKWEB_LIB + Dl_namespace dlns; + if (dlns_get("nweb_ns", &dlns) != 0) { + char arkwebLibPath[PATH_SIZE] = ""; + if (snprintf_s(arkwebLibPath, sizeof(arkwebLibPath), sizeof(arkwebLibPath) - 1, + "%s%s%s", "/data/app/el1/bundle/public/", msg->processName, + "/libs/arm64:/data/storage/el1/bundle/arkwebcore/libs/arm64") < 0) { + APPSPAWN_LOGE("FAILED to get arkwebLibPath"); + SendResponse(connection, msg, -1, 0); + return; + } + APPSPAWN_LOGI("ProcessSpawnDlopenMsg arkwebLibPath: %{public}s", arkwebLibPath); + + dlns_init(&dlns, "nweb_ns"); + dlns_create(&dlns, arkwebLibPath); + + Dl_namespace ndkns; + dlns_get("ndk", &ndkns); + dlns_inherit(&dlns, &ndkns, "allow_all_shared_libs"); + } + + void* webEngineHandle = dlopen_ns(&dlns, "libarkweb_engine.so", RTLD_NOW | RTLD_GLOBAL); + if (!webEngineHandle) { + APPSPAWN_LOGE("FAILED to dlopen libarkweb_engine.so in appspawn %{public}s", dlerror()); + SendResponse(connection, msg, -1, 0); + } else { + APPSPAWN_LOGI("SUCCESS to dlopen libarkweb_engine.so in appspawn"); + SendResponse(connection, msg, 0, 0); + } +#else + SendResponse(connection, msg, 0, 0); +#endif +} + static void ProcessRecvMsg(AppSpawnConnection *connection, AppSpawnMsgNode *message) { AppSpawnMsg *msg = &message->msgHeader; @@ -1825,6 +1871,10 @@ static void ProcessRecvMsg(AppSpawnConnection *connection, AppSpawnMsgNode *mess case MSG_OBSERVE_PROCESS_SIGNAL_STATUS: ProcessObserveProcessSignalMsg(connection, message); break; + case MSG_LOAD_WEBLIB_IN_APPSPAWN: + ProcessSpawnDlopenMsg(connection, message); + DeleteAppSpawnMsg(&message); + break; default: SendResponse(connection, msg, APPSPAWN_MSG_INVALID, 0); DeleteAppSpawnMsg(&message);