diff --git a/BUILD.gn b/BUILD.gn index 3efba0f54878c4bc5942459f85fef1046cf95cb9..9f0e9b9b144499bb2430d11a5bd86a360b7ba361 100755 --- a/BUILD.gn +++ b/BUILD.gn @@ -101,3 +101,76 @@ ohos_prebuilt_etc("appspawn.rc") { subsystem_name = "${subsystem_name}" part_name = "${part_name}" } + +ohos_executable("webviewspawn") { + defines = [ "WEBVIEW_SPAWN" ] + sources = [ "${appspawn_path}/src/main.cpp" ] + configs = [ ":appspawn_config" ] + deps = [ + "${appspawn_path}:webviewspawn_server", + "//base/security/access_token/interfaces/innerkits/token_setproc:libtoken_setproc", + ] + external_deps = [ "hiviewdfx_hilog_native:libhilog" ] + + install_enable = true + subsystem_name = "${subsystem_name}" + part_name = "${part_name}" +} + +ohos_static_library("webviewspawn_server") { + defines = [ + "INIT_AGENT", + "WEBVIEW_SPAWN", + ] + sources = [ + "${appspawn_path}/src/appspawn_msg_peer.cpp", + "${appspawn_path}/src/appspawn_server.cpp", + "${appspawn_path}/src/socket/appspawn_socket.cpp", + "${appspawn_path}/src/socket/server_socket.cpp", + ] + configs = [ ":appspawn_config" ] + ldflags = [ "-Wl,--dynamic-linker,/system/bin/linker64z" ] + deps = [ + "${aafwk_path}/frameworks/kits/ability/native:abilitykit_native", + "${aafwk_path}/frameworks/kits/appkit:appkit_native", + "//base/startup/init_lite/interfaces/innerkits:libbegetutil", + "//base/startup/init_lite/interfaces/innerkits/socket:libsocket_static", + "//base/startup/init_lite/services/log:init_log", + "//base/startup/syspara_lite/interfaces/innerkits/native/syspara:syspara", + "//utils/native/base:utils", + ] + external_deps = [ + "ability_base:want", + "bundle_framework:appexecfwk_base", + "bundle_framework:appexecfwk_core", + "hilog_native:libhilog", + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_core", + "safwk:system_ability_fwk", + "samgr_standard:samgr_proxy", + ] + + if (build_selinux) { + external_deps += [ "selinux:libhap_restorecon" ] + } + + subsystem_name = "${subsystem_name}" + part_name = "${part_name}" +} + +ohos_prebuilt_etc("webviewspawn.rc") { + source = "webviewspawn.cfg" + relative_install_dir = "init" + subsystem_name = "${subsystem_name}" + part_name = "${part_name}" +} + +group("webview") { + deps = [] + if (appspawn_support_webview) { + deps += [ + ":webviewspawn", + ":webviewspawn.rc", + ] + } +} diff --git a/appspawn.gni b/appspawn.gni index f5be4ce05599bff8f6d8c0c0edf5e47a896c08ed..5fc789cff540a0654aee1845bf600fea7ed8d101 100644 --- a/appspawn.gni +++ b/appspawn.gni @@ -19,3 +19,7 @@ distributedschedule_path = "//foundation/distributedschedule/dmsfwk" subsystem_name = "startup" part_name = "appspawn" module_output_path = "${part_name}/appspawn_l2" + +declare_args() { + appspawn_support_webview = true +} diff --git a/bundle.json b/bundle.json index 5a941f362dc7cb99e5c2c64b6b0ef8c43b2db853..502b4725a8bfcc741895290b0bde391ed34e194d 100644 --- a/bundle.json +++ b/bundle.json @@ -17,6 +17,9 @@ "adapted_system_type": [ "standard" ], + "features": [ + "appspawn_support_webview" + ], "rom": "", "ram": "", "deps": { @@ -34,6 +37,7 @@ "//base/startup/appspawn_standard:appspawn", "//base/startup/appspawn_standard:appspawn.rc", "//base/startup/appspawn_standard:appspawn_server", + "//base/startup/appspawn_standard:webview", "//base/startup/appspawn_standard/interfaces/innerkits:appspawn_socket_client" ], "inner_kits": [ diff --git a/interfaces/innerkits/include/client_socket.h b/interfaces/innerkits/include/client_socket.h index 7783a3728b2afb02d585b99f5abd51b850798aa2..7be38b87cd41192ff3f9793b5f0d4fcf4b957d56 100644 --- a/interfaces/innerkits/include/client_socket.h +++ b/interfaces/innerkits/include/client_socket.h @@ -89,6 +89,7 @@ public: static constexpr int LEN_SO_PATH = 256; // load so lib static constexpr int MAX_GIDS = 64; static constexpr int APL_MAX_LEN = 32; + static constexpr int RENDER_CMD_MAX_LEN = 1024; struct AppProperty { uint32_t uid; // the UNIX uid that the child process setuid() to after fork() @@ -100,6 +101,7 @@ public: char soPath[LEN_SO_PATH]; // so lib path uint32_t accessTokenId; char apl[APL_MAX_LEN]; + char renderCmd[RENDER_CMD_MAX_LEN]; }; private: diff --git a/src/appspawn_server.cpp b/src/appspawn_server.cpp index 3f414fed31d336fc07d0eb9a5919b3867e1158ff..e5679e6a08d39c2421efb6aa53601afad5e3c158 100644 --- a/src/appspawn_server.cpp +++ b/src/appspawn_server.cpp @@ -210,6 +210,29 @@ void AppSpawnServer::HandleSignal() void AppSpawnServer::LoadAceLib() { +#ifdef WEBVIEW_SPAWN + std::string enginelibdir("/data/app/el1/bundle/public/com.ohos.webviewhap" + "/entry/libs/armeabi/libweb_engine.so"); + HiLog::Info(LABEL, "MainThread::LoadAbilityLibrary libweb_engine. Start calling dlopen enginelibdir."); + void *handle = dlopen(enginelibdir.c_str(), RTLD_NOW | RTLD_GLOBAL); + if (handle == nullptr) { + HiLog::Error(LABEL, "Fail to dlopen %{public}s, [%{public}s]", enginelibdir.c_str(), dlerror()); + } else { + HiLog::Info(LABEL, "Success to dlopen %{public}s", enginelibdir.c_str()); + } + HiLog::Info(LABEL, "MainThread::LoadAbilityLibrary libweb_engine. End calling dlopen."); + + std::string execlibdir("/data/app/el1/bundle/public/com.ohos.webviewhap" + "/entry/libs/armeabi/libwebview_exec_proc.so"); + HiLog::Info(LABEL, "MainThread::LoadAbilityLibrary libwebview_exec_proc. Start calling dlopen execlibdir."); + webviewHandle = dlopen(execlibdir.c_str(), RTLD_NOW | RTLD_GLOBAL); + if (webviewHandle == nullptr) { + HiLog::Error(LABEL, "Fail to dlopen %{public}s, [%{public}s]", execlibdir.c_str(), dlerror()); + } else { + HiLog::Info(LABEL, "Success to dlopen %{public}s", execlibdir.c_str()); + } + HiLog::Info(LABEL, "MainThread::LoadAbilityLibrary libwebview_exec_proc. End calling dlopen."); +#else std::string acelibdir("/system/lib/libace.z.so"); void *AceAbilityLib = nullptr; HiLog::Info(LABEL, "MainThread::LoadAbilityLibrary. Start calling dlopen acelibdir."); @@ -220,6 +243,7 @@ void AppSpawnServer::LoadAceLib() HiLog::Info(LABEL, "Success to dlopen %{public}s", acelibdir.c_str()); } HiLog::Info(LABEL, "MainThread::LoadAbilityLibrary. End calling dlopen."); +#endif } int AppSpawnServer::StartApp(char *longProcName, int64_t longProcNameLen, @@ -830,7 +854,18 @@ bool AppSpawnServer::SetAppProcProperty(const ClientSocket::AppProperty *appProp } // notify success to father process and start app process NotifyResToParentProc(fd[1], ret); + +#ifdef WEBVIEW_SPAWN + using FuncType = void (*)(const char *cmd); + FuncType funcWebViewExecuteProcess = reinterpret_cast(dlsym(webviewHandle, "WebViewExecuteProcess")); + if (funcWebViewExecuteProcess == nullptr) { + HiLog::Error(LABEL, "webviewspawn dlsym ERROR=%{public}s", dlerror()); + return false; + } + funcWebViewExecuteProcess(appProperty->renderCmd); +#else AppExecFwk::MainThread::Start(); +#endif HiLog::Error(LABEL, "Failed to start process, pid = %{public}d", newPid); return false; diff --git a/src/include/appspawn_server.h b/src/include/appspawn_server.h index 100779ffdd2b4a3fdab4ce69443bebd90c50765f..6e2192a8a70764d16a6eb0ea7ae6acb51e1dd37e 100644 --- a/src/include/appspawn_server.h +++ b/src/include/appspawn_server.h @@ -203,6 +203,9 @@ private: bool isChildDie_ { false }; pid_t childPid_ {}; std::map appMap_; +#ifdef WEBVIEW_SPAWN + void *webviewHandle = nullptr; +#endif }; } // namespace AppSpawn } // namespace OHOS diff --git a/src/main.cpp b/src/main.cpp index b6bb8a587e4f5e70c1dabc31ba1ad7246059bb4d..41e40b2a5ddb0f64347af8541c8fdd171895ef2f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -26,7 +26,11 @@ int main(int argc, char *const argv[]) uintptr_t end = reinterpret_cast(strchr(argv[argc - 1], 0)); uintptr_t argvSize = end - start; +#ifdef WEBVIEW_SPAWN + OHOS::AppSpawn::AppSpawnServer appspawnServer("/dev/unix/socket/WebViewSpawn"); +#else OHOS::AppSpawn::AppSpawnServer appspawnServer("AppSpawn"); +#endif appspawnServer.ServerMain(argv[0], argvSize); } diff --git a/src/socket/appspawn_socket.cpp b/src/socket/appspawn_socket.cpp index 4e63b4d164ea98da779939325c7d67b98cfc5246..4c0caf6a3461c85ae32ab4714386d11273d73ea4 100755 --- a/src/socket/appspawn_socket.cpp +++ b/src/socket/appspawn_socket.cpp @@ -58,15 +58,25 @@ int AppSpawnSocket::PackSocketAddr() return -1; } - socklen_t pathLen = socketDir_.length() + socketName_.length(); + socklen_t pathLen = 0; + if (socketName_[0] == '/') { + pathLen = socketName_.length(); + } else { + pathLen = socketDir_.length() + socketName_.length(); + } socklen_t pathSize = sizeof(socketAddr_.sun_path); if (pathLen >= pathSize) { HiLog::Error(LABEL, "Invalid socket name: '%s' too long", socketName_.c_str()); return -1; } - int len = - snprintf_s(socketAddr_.sun_path, pathSize, (pathSize - 1), "%s%s", socketDir_.c_str(), socketName_.c_str()); + int len = 0; + if (socketName_[0] == '/') { + len = snprintf_s(socketAddr_.sun_path, pathSize, (pathSize - 1), "%s", socketName_.c_str()); + } else { + len = snprintf_s(socketAddr_.sun_path, pathSize, (pathSize - 1), "%s%s", + socketDir_.c_str(), socketName_.c_str()); + } if (static_cast(pathLen) != len) { HiLog::Error(LABEL, "Failed to copy socket path"); return -1; diff --git a/src/socket/server_socket.cpp b/src/socket/server_socket.cpp index 6a632b63e0789c022656a1469f828d7e94119d5a..c7def0294a8c7fdc5e9139bc76fcbf95871d02da 100644 --- a/src/socket/server_socket.cpp +++ b/src/socket/server_socket.cpp @@ -20,6 +20,7 @@ #include #include "hilog/log.h" +#include "init_socket.h" #include "securec.h" namespace OHOS { @@ -152,11 +153,16 @@ int ServerSocket::RegisterServerSocket(int &connectFd) return -EINVAL; } +#ifdef WEBVIEW_SPAWN + connectFd = GetControlSocket("WebViewSpawn"); +#else connectFd = CreateSocket(); +#endif if (connectFd < 0) { return connectFd; } +#ifndef WEBVIEW_SPAWN if ((BindSocket(connectFd) != 0) || (listen(connectFd, listenBacklog_) < 0)) { HiLog::Error(LABEL, "Server: Register socket fd %d with backlog %d error: %d", @@ -170,7 +176,7 @@ int ServerSocket::RegisterServerSocket(int &connectFd) connectFd = -1; return (-errno); } - +#endif HiLog::Debug(LABEL, "Server: Suc to register server socket fd %d", connectFd); return 0; } diff --git a/test/unittest/app_spawn_server_test/BUILD.gn b/test/unittest/app_spawn_server_test/BUILD.gn index 9c5707db4c2f41cec7e72cc80b92920aa9615ef4..83a07f4e460c9845231b0c329dfc9569dea90fb6 100755 --- a/test/unittest/app_spawn_server_test/BUILD.gn +++ b/test/unittest/app_spawn_server_test/BUILD.gn @@ -87,6 +87,7 @@ ohos_unittest("AppSpawnServerMockTest") { "${appspawn_path}/test:appspawn_test_source", "//base/security/access_token/interfaces/innerkits/token_setproc:libtoken_setproc", "//base/startup/init_lite/interfaces/innerkits:libbegetutil", + "//base/startup/init_lite/interfaces/innerkits/socket:libsocket_static", "//base/startup/init_lite/services/log:init_log", "//base/startup/syspara_lite/interfaces/innerkits/native/syspara:syspara", ] diff --git a/webviewspawn.cfg b/webviewspawn.cfg new file mode 100644 index 0000000000000000000000000000000000000000..dc23b829830a8cf22ce53c354a497b79ac288864 --- /dev/null +++ b/webviewspawn.cfg @@ -0,0 +1,19 @@ +{ + "services" : [{ + "name" : "webviewspawn", + "path" : ["/system/bin/webviewspawn"], + "socket" : [{ + "name" : "WebViewSpawn", + "family" : "AF_LOCAL", + "type" : "SOCK_SEQPACKET", + "protocol" : "default", + "permissions" : "0666", + "uid" : "root", + "gid" : "root", + "option" : [ + ] + }], + "ondemand" : true + } + ] +} \ No newline at end of file