diff --git a/arkweb_utils/BUILD.gn b/arkweb_utils/BUILD.gn index 4f227a9ba1a32757cced28453b1ec56b823d8bfa..14c18d197e3c906a8b495d89c0fdf2ce14943b9f 100644 --- a/arkweb_utils/BUILD.gn +++ b/arkweb_utils/BUILD.gn @@ -12,6 +12,7 @@ # limitations under the License. import("//build/ohos.gni") +import("../config.gni") ohos_shared_library("libarkweb_utils") { output_name = "arkweb_utils" @@ -28,6 +29,8 @@ ohos_shared_library("libarkweb_utils") { "arkweb_preload.cpp", ] + sources += ["arkweb_preload_common.cpp"] + cflags = [ "-Wall", "-Werror", @@ -66,6 +69,10 @@ ohos_shared_library("libarkweb_utils") { innerapi_tags = [ "platformsdk" ] part_name = "webview" subsystem_name = "web" + + if(webview_preload_render_lib){ + defines += ["PRELOAD_RENDER_LIB"] + } } diff --git a/arkweb_utils/arkweb_preload_common.cpp b/arkweb_utils/arkweb_preload_common.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5def97c8b6a6b0b945a7f817fd53d45b723f1906 --- /dev/null +++ b/arkweb_utils/arkweb_preload_common.cpp @@ -0,0 +1,152 @@ +/* + * 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. + */ + +#include "arkweb_preload_common.h" +#include "arkweb_utils.h" +#include "nweb_log.h" +#include "parameters.h" +#include +#ifndef webview_x86_64 +#include +#endif + +namespace OHOS::ArkWeb { + +#if defined(webview_arm64) +const std::string OHOS_ADAPTER_GLUE_SRC_LIB_PATH = "/system/lib64/libohos_adapter_glue_source.z.so"; +#elif defined(webview_x86_64) +const std::string OHOS_ADAPTER_GLUE_SRC_LIB_PATH = ""; +#else +const std::string OHOS_ADAPTER_GLUE_SRC_LIB_PATH = "/system/lib/libohos_adapter_glue_source.z.so"; +#endif + +const std::string ARK_WEB_ENGINE_LIB_NAME = "libarkweb_engine.so"; +const int32_t RAM_SIZE_8G = 8; +const int32_t SIZE_KB = 1024; + +enum class RenderPreLoadMode { + PRELOAD_NO = 0, // 不预加载 + PRELOAD_PARTIAL = 1, // 只预加载libohos_adapter_glue_source.z.so + PRELOAD_FULL = 2 // 预加载libohos_adapter_glue_source.z.so和libarkweb_engine.so +}; + +std::string GetArkwebBundleInstallLibPath() { + std::string bundleName = OHOS::system::GetParameter("persist.arkwebcore.package_name", ""); + if (bundleName.empty()) { + WVLOG_E("Fail to get persist.arkwebcore.package_name"); + return ""; + } + if (getActiveWebEngineType() == ArkWebEngineType::LEGACY) { + bundleName += "legacy"; + } +#ifdef webview_arm64 + const std::string arkwebEngineLibPath = "/data/app/el1/bundle/public/" + std::string(bundleName) + "/libs/arm64"; +#elif webview_x86_64 + const std::string arkwebEngineLibPath = ""; +#else + const std::string arkwebEngineLibPath = "/data/app/el1/bundle/public/" + std::string(bundleName) + "/libs/arm"; +#endif + return arkwebEngineLibPath; +} + +std::string GetOhosAdptGlueSrcLibPath() { + return OHOS_ADAPTER_GLUE_SRC_LIB_PATH; +} + +static void PreloadArkWebEngineLib() +{ + Dl_namespace dlns; + Dl_namespace ndkns; + dlns_init(&dlns, "nweb_ns"); + const std::string arkWebEngineLibPath = GetArkwebBundleInstallLibPath(); + const std::string arkwebEngineSandboxLibPath = GetArkwebLibPath(); + if (arkWebEngineLibPath.empty()) { + WVLOG_E("Fail to get libarkweb_engine.so path"); + return; + } + std::string libNsPath = arkWebEngineLibPath + ":" + arkwebEngineSandboxLibPath; + dlns_create(&dlns, libNsPath.c_str()); + dlns_get("ndk", &ndkns); + dlns_inherit(&dlns, &ndkns, "allow_all_shared_libs"); + void *webEngineHandle = dlopen_ns(&dlns, ARK_WEB_ENGINE_LIB_NAME.c_str(), RTLD_NOW | RTLD_GLOBAL); + if (webEngineHandle == nullptr) { + WVLOG_E("Fail to dlopen libarkweb_engine.so, errno: %{public}d", errno); + } +} + +static void PreloadOHOSAdptGlueSrcLib() +{ + const std::string ohosAdptGlueSrcLibPath = OHOS::ArkWeb::GetOhosAdptGlueSrcLibPath(); + if (ohosAdptGlueSrcLibPath.empty()) { + WVLOG_E("Fail to get libohos_adapter_glue_source.z.so path"); + return; + } + void *ohosAdptGlueSrcHandle = dlopen(ohosAdptGlueSrcLibPath.c_str(), RTLD_NOW | RTLD_GLOBAL); + if (ohosAdptGlueSrcHandle == nullptr) { + WVLOG_E("Fail to dlopen libohos_adapter_glue_source.z.so, errno: %{public}d", errno); + } +} + +static int32_t GetSysTotalRAMInfo() +{ +#if defined(webview_x86_64) || defined(ASAN_DETECTOR) + return 0; +#else + struct sysinfo sysInfo; + if (sysinfo(&sysInfo) != 0) { + return 0; + } + int64_t memSize = static_cast(sysInfo.totalram); + return ceil(memSize / (SIZE_KB * SIZE_KB)); +#endif +} + +static int GetRenderPreLoadMode(const int32_t &ramSize) +{ +#if defined(PRELOAD_RENDER_LIB) && (!defined(ASAN_DETECTOR)) + return static_cast(RenderPreLoadMode::PRELOAD_FULL); +#endif + int preloadMode = OHOS::system::GetIntParameter("const.startup.nwebspawn.preloadMode", 0); + if (preloadMode == static_cast(RenderPreLoadMode::PRELOAD_NO)) { + return preloadMode; + } + if (ramSize <= RAM_SIZE_8G * SIZE_KB) { + return static_cast(RenderPreLoadMode::PRELOAD_NO); + } + return static_cast(RenderPreLoadMode::PRELOAD_PARTIAL); +} + +static void PreloadArkWebLibForRender(const int &preloadMode) +{ + if (preloadMode == static_cast(RenderPreLoadMode::PRELOAD_PARTIAL)) { + PreloadOHOSAdptGlueSrcLib(); + } + if (preloadMode == static_cast(RenderPreLoadMode::PRELOAD_FULL)) { + PreloadOHOSAdptGlueSrcLib(); + PreloadArkWebEngineLib(); + } +} + +void PreloadArkWebLibForRender() +{ +#ifdef ASAN_DETECTOR + return; +#endif + const int32_t ramSize = GetSysTotalRAMInfo(); + const int preloadMode = GetRenderPreLoadMode(ramSize); + WVLOG_I("NwebSpawn preload render lib mode: %{public}d", preloadMode); + PreloadArkWebLibForRender(preloadMode); +} +} // namespace OHOS::ArkWeb \ No newline at end of file diff --git a/arkweb_utils/arkweb_preload_common.h b/arkweb_utils/arkweb_preload_common.h new file mode 100644 index 0000000000000000000000000000000000000000..d663fc7b18c72bc138b319cc01f5e83d852eacb3 --- /dev/null +++ b/arkweb_utils/arkweb_preload_common.h @@ -0,0 +1,30 @@ +/* + * 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. + */ +#ifndef WEB_WEBVIEW_ARKWEB_UTILS_ARKWEB_PRELOAD_COMMON_H +#define WEB_WEBVIEW_ARKWEB_UTILS_ARKWEB_PRELOAD_COMMON_H + +#include + +#ifndef ARKWEB_EXPORT +#define ARKWEB_EXPORT __attribute__((visibility("default"))) +#endif + +namespace OHOS::ArkWeb { +ARKWEB_EXPORT std::string GetArkwebBundleInstallLibPath(); +ARKWEB_EXPORT std::string GetOhosAdptGlueSrcLibPath(); +ARKWEB_EXPORT void PreloadArkWebLibForRender(); +} // namespace OHOS::ArkWeb + +#endif // WEB_WEBVIEW_ARKWEB_UTILS_ARKWEB_PRELOAD_COMMON_H \ No newline at end of file diff --git a/config.gni b/config.gni index 3085542b6840249d02480bda73fc0c2029a3931b..8a85c61519593e971048db4054d98218b3cb6c28 100644 --- a/config.gni +++ b/config.gni @@ -27,6 +27,7 @@ declare_args() { webview_sensors_sensor_enable = true webview_enable_heif_decoder = false webview_drm_enable = true + webview_preload_render_lib = true if (defined(global_parts_info) && !defined(global_parts_info.resourceschedule_soc_perf)) { diff --git a/ohos_nweb/etc/para/web.para b/ohos_nweb/etc/para/web.para index b77bbf1e88433dd9a522218a1bd8ca80ae0b01ef..d4f57b33def525e27ff7c7959dd9fb87d2a4aaf1 100644 --- a/ohos_nweb/etc/para/web.para +++ b/ohos_nweb/etc/para/web.para @@ -27,3 +27,4 @@ web.prppreload.mode = preload web.ohos.dvsync = false web.ohos.enableCWNDSetting = false web.TCPConnectedSocket.initialCongestionWindowSize = -1 +web.engine.install.completed = false diff --git a/ohos_nweb/etc/para/web.para.dac b/ohos_nweb/etc/para/web.para.dac index f41ac035681a3da5dd0b877545bc0aafa30e43b4..1f5a7b2ca87969de2ee74b65082eded7b5d098ea 100644 --- a/ohos_nweb/etc/para/web.para.dac +++ b/ohos_nweb/etc/para/web.para.dac @@ -17,4 +17,5 @@ web.debug.trace = root:shell:0775 persist.arkwebcore.install_path = root:root:0776 persist.arkwebcore.package_name = root:root:0776 web.prppreload.mode = root:root:0644 -persist.scrollable. = root:root:0775 \ No newline at end of file +persist.scrollable. = root:root:0775 +web.engine.install.completed = root:root:0776 \ No newline at end of file diff --git a/sa/IAppFwkUpdateService.idl b/sa/IAppFwkUpdateService.idl index 2d9a27a6a5ab59e3bf0f14e1cc6441cd8f68363a..ba3dbd9c82784d6a651d9966432648f62910bd9c 100644 --- a/sa/IAppFwkUpdateService.idl +++ b/sa/IAppFwkUpdateService.idl @@ -15,4 +15,5 @@ interface OHOS.NWeb.IAppFwkUpdateService { void VerifyPackageInstall([in] String bundleName, [in] String hapPath, [out]int success); [oneway] void NotifyFWKAfterBmsStart(); + void NotifyArkWebInstallSuccess(); } diff --git a/sa/include/app_fwk_update_service.h b/sa/include/app_fwk_update_service.h index c912669c6adf90546ae15c905f2bdcefe4bc2d6f..46d6b04c941dfe25faa89f25d6b72fab8d02ab93 100644 --- a/sa/include/app_fwk_update_service.h +++ b/sa/include/app_fwk_update_service.h @@ -51,6 +51,7 @@ public: ErrCode VerifyPackageInstall(const std::string& bundleName, const std::string& hapPath, int32_t& success) override; ErrCode NotifyFWKAfterBmsStart() override; + ErrCode NotifyArkWebInstallSuccess() override; void SubscribePackageChangedEvent(); void OnPackageChangedEvent(const std::string& bunldeName, const std::string& hapPath); diff --git a/sa/libapp_fwk_update_service.map b/sa/libapp_fwk_update_service.map index cdd06d68d272277e5739605be941618d9e1f78a1..d5bb881970d389cc161941710c492422f5114e2f 100644 --- a/sa/libapp_fwk_update_service.map +++ b/sa/libapp_fwk_update_service.map @@ -4,6 +4,7 @@ OHOS::NWeb::AppFwkUpdateClient::GetInstance*; OHOS::NWeb::AppFwkUpdateClient::VerifyPackageInstall*; OHOS::NWeb::AppFwkUpdateClient::NotifyFWKAfterBmsStart*; + OHOS::NWeb::AppFwkUpdateClient::NotifyArkWebInstallSuccess*; }; local: *; diff --git a/sa/src/app_fwk_update_client.cpp b/sa/src/app_fwk_update_client.cpp index 4d30d41a16e5250375c89199a844bb0e9b1f5335..056676b65be01696a968f4089a0b3bbf831eaa9e 100644 --- a/sa/src/app_fwk_update_client.cpp +++ b/sa/src/app_fwk_update_client.cpp @@ -109,6 +109,16 @@ void AppFwkUpdateClient::NotifyFWKAfterBmsStart() proxy->NotifyFWKAfterBmsStart(); } +void AppFwkUpdateClient::NotifyArkWebInstallSuccess() +{ + auto proxy = GetFwkUpdateProxy(); + if (proxy == nullptr) { + WVLOG_E("NotifyArkWebInstallSuccess failed, proxy is null"); + return; + } + proxy->NotifyArkWebInstallSuccess(); +} + int AppFwkUpdateClient::VerifyPackageInstall(const std::string& bundleName, const std::string& hapPath) { WVLOG_I("verify package install callingUid: %{public}d", IPCSkeleton::GetCallingUid()); diff --git a/sa/src/app_fwk_update_service.cpp b/sa/src/app_fwk_update_service.cpp index 82f1457cdfbcd0d1d586c4615cd1ca2cacf5f13c..c68acf5c7a8bd07d5663365d89be153e39289ac9 100644 --- a/sa/src/app_fwk_update_service.cpp +++ b/sa/src/app_fwk_update_service.cpp @@ -104,6 +104,20 @@ ErrCode AppFwkUpdateService::NotifyFWKAfterBmsStart() return ERR_OK; } +ErrCode AppFwkUpdateService::NotifyArkWebInstallSuccess() +{ + int preloadMode = OHOS::system::GetIntParameter("const.startup.nwebspawn.preloadMode", 0); + WVLOG_I("NwebSpawn preload render lib mode: %{public}d", preloadMode); + if (preloadMode) { + auto ret = OHOS::system::SetParameter("web.engine.install.completed", "true"); + if (!ret) { + WVLOG_E("Set parameter web.engine.install.completed failed"); + return ERR_INVALID_VALUE; + } + } + return ERR_OK; +} + ErrCode AppFwkUpdateService::VerifyPackageInstall( const std::string& bundleName, const std::string& hapPath, int32_t& isSuccess) { diff --git a/test/unittest/app_fwk_update_client_test/app_fwk_update_client_test.cpp b/test/unittest/app_fwk_update_client_test/app_fwk_update_client_test.cpp index 5c8157aacd8bb40a78d0e2ba6414212ea60d5615..f3ed4ac8948aaf60af8773a0dbae0386261906e8 100644 --- a/test/unittest/app_fwk_update_client_test/app_fwk_update_client_test.cpp +++ b/test/unittest/app_fwk_update_client_test/app_fwk_update_client_test.cpp @@ -36,6 +36,7 @@ class MockAppFwkUpdateService : public NWeb::IAppFwkUpdateService { public: MOCK_METHOD3(VerifyPackageInstall, ErrCode(const std::string&, const std::string&, int32_t&)); MOCK_METHOD0(NotifyFWKAfterBmsStart, ErrCode()); + MOCK_METHOD0(NotifyArkWebInstallSuccess, ErrCode()); MOCK_METHOD0(RefPtrCallback, void()); MOCK_METHOD1(OnFirstStrongRef, void(const void*)); MOCK_METHOD1(OnLastStrongRef, void(const void*));