diff --git a/BUILD.gn b/BUILD.gn old mode 100755 new mode 100644 index 9f0e9b9b144499bb2430d11a5bd86a360b7ba361..c59f4a439f22f65282c806741612f77e5e171f44 --- a/BUILD.gn +++ b/BUILD.gn @@ -95,6 +95,20 @@ ohos_static_library("appspawn_server") { part_name = "${part_name}" } +ohos_executable("appspawntools") { + sources = [ "${appspawn_path}/tools/appspawn_start_app.cpp" ] + configs = [ ":appspawn_config" ] + deps = [ + "${appspawn_path}:appspawn_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_prebuilt_etc("appspawn.rc") { source = "appspawn.cfg" relative_install_dir = "init" @@ -102,12 +116,12 @@ ohos_prebuilt_etc("appspawn.rc") { part_name = "${part_name}" } -ohos_executable("webviewspawn") { - defines = [ "WEBVIEW_SPAWN" ] +ohos_executable("nwebspawn") { + defines = [ "NWEB_SPAWN" ] sources = [ "${appspawn_path}/src/main.cpp" ] configs = [ ":appspawn_config" ] deps = [ - "${appspawn_path}:webviewspawn_server", + "${appspawn_path}:nwebspawn_server", "//base/security/access_token/interfaces/innerkits/token_setproc:libtoken_setproc", ] external_deps = [ "hiviewdfx_hilog_native:libhilog" ] @@ -117,10 +131,10 @@ ohos_executable("webviewspawn") { part_name = "${part_name}" } -ohos_static_library("webviewspawn_server") { +ohos_static_library("nwebspawn_server") { defines = [ "INIT_AGENT", - "WEBVIEW_SPAWN", + "NWEB_SPAWN", ] sources = [ "${appspawn_path}/src/appspawn_msg_peer.cpp", @@ -158,19 +172,19 @@ ohos_static_library("webviewspawn_server") { part_name = "${part_name}" } -ohos_prebuilt_etc("webviewspawn.rc") { - source = "webviewspawn.cfg" +ohos_prebuilt_etc("nwebspawn.rc") { + source = "nwebspawn.cfg" relative_install_dir = "init" subsystem_name = "${subsystem_name}" part_name = "${part_name}" } -group("webview") { +group("nweb") { deps = [] - if (appspawn_support_webview) { + if (appspawn_support_nweb) { deps += [ - ":webviewspawn", - ":webviewspawn.rc", + ":nwebspawn", + ":nwebspawn.rc", ] } } diff --git a/README_zh.md b/README_zh.md old mode 100755 new mode 100644 diff --git a/appspawn.cfg b/appspawn.cfg old mode 100755 new mode 100644 diff --git a/appspawn.gni b/appspawn.gni index 5fc789cff540a0654aee1845bf600fea7ed8d101..6f9789610c16bf20c66194abb0e6621fee322a25 100644 --- a/appspawn.gni +++ b/appspawn.gni @@ -21,5 +21,5 @@ part_name = "appspawn" module_output_path = "${part_name}/appspawn_l2" declare_args() { - appspawn_support_webview = true + appspawn_support_nweb = true } diff --git a/bundle.json b/bundle.json index 502b4725a8bfcc741895290b0bde391ed34e194d..f7b6d59379c913eb76d9397f97c920e83a23b974 100644 --- a/bundle.json +++ b/bundle.json @@ -18,7 +18,7 @@ "standard" ], "features": [ - "appspawn_support_webview" + "appspawn_support_nweb" ], "rom": "", "ram": "", @@ -37,7 +37,8 @@ "//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:appspawntools", + "//base/startup/appspawn_standard:nweb", "//base/startup/appspawn_standard/interfaces/innerkits:appspawn_socket_client" ], "inner_kits": [ diff --git a/interfaces/innerkits/BUILD.gn b/interfaces/innerkits/BUILD.gn old mode 100755 new mode 100644 diff --git a/interfaces/innerkits/include/client_socket.h b/interfaces/innerkits/include/client_socket.h index 7be38b87cd41192ff3f9793b5f0d4fcf4b957d56..85e979a6e27909a0c65bcbe8464253ba7c293a79 100644 --- a/interfaces/innerkits/include/client_socket.h +++ b/interfaces/innerkits/include/client_socket.h @@ -29,7 +29,7 @@ public: explicit ClientSocket(const std::string &client); /** - * Destructor used to destory a ClientSocket + * Destructor used to destroy a ClientSocket */ virtual ~ClientSocket() = default; @@ -90,6 +90,7 @@ public: static constexpr int MAX_GIDS = 64; static constexpr int APL_MAX_LEN = 32; static constexpr int RENDER_CMD_MAX_LEN = 1024; + static constexpr int APPSPAWN_COLD_BOOT = 0x01; struct AppProperty { uint32_t uid; // the UNIX uid that the child process setuid() to after fork() @@ -102,6 +103,7 @@ public: uint32_t accessTokenId; char apl[APL_MAX_LEN]; char renderCmd[RENDER_CMD_MAX_LEN]; + uint32_t flags; }; private: diff --git a/webviewspawn.cfg b/nwebspawn.cfg similarity index 72% rename from webviewspawn.cfg rename to nwebspawn.cfg index dc23b829830a8cf22ce53c354a497b79ac288864..7e5dbc730c59bd57ba7733ad5323be01c78d0d30 100644 --- a/webviewspawn.cfg +++ b/nwebspawn.cfg @@ -1,9 +1,9 @@ { "services" : [{ - "name" : "webviewspawn", - "path" : ["/system/bin/webviewspawn"], + "name" : "nwebspawn", + "path" : ["/system/bin/nwebspawn"], "socket" : [{ - "name" : "WebViewSpawn", + "name" : "NWebSpawn", "family" : "AF_LOCAL", "type" : "SOCK_SEQPACKET", "protocol" : "default", @@ -16,4 +16,4 @@ "ondemand" : true } ] -} \ No newline at end of file +} diff --git a/src/appspawn_server.cpp b/src/appspawn_server.cpp index e5679e6a08d39c2421efb6aa53601afad5e3c158..7fd5ffea3c83dc1e05707318e38758ec910a9a87 100644 --- a/src/appspawn_server.cpp +++ b/src/appspawn_server.cpp @@ -40,6 +40,7 @@ #include "system_ability_definition.h" #include "token_setproc.h" #include "parameter.h" +#include "parameters.h" #include "beget_ext.h" #ifdef WITH_SELINUX #include "hap_restorecon.h" @@ -52,7 +53,7 @@ #include constexpr static mode_t FILE_MODE = 0711; -constexpr static mode_t WEBVIEW_FILE_MODE = 0511; +constexpr static mode_t NWEB_FILE_MODE = 0511; #define APPSPAWN_LOGI(fmt, ...) STARTUP_LOGI("appspawn_server.log", "APPSPAWN", fmt, ##__VA_ARGS__) #define APPSPAWN_LOGE(fmt, ...) STARTUP_LOGE("appspawn_server.log", "APPSPAWN", fmt, ##__VA_ARGS__) @@ -67,7 +68,7 @@ constexpr int32_t WAIT_DELAY_US = 100 * 1000; // 100ms constexpr int32_t GID_USER_DATA_RW = 1008; constexpr int32_t MAX_GIDS = 64; constexpr int32_t UID_BASE = 200000; -constexpr int32_t WAIT_PARAM_TIME = 1000; +constexpr int32_t WAIT_PARAM_TIME = 5; constexpr std::string_view BUNDLE_NAME_MEDIA_LIBRARY("com.ohos.medialibrary.MediaLibraryDataA"); constexpr std::string_view BUNDLE_NAME_SCANNER("com.ohos.medialibrary.MediaScannerAbilityA"); @@ -171,12 +172,20 @@ void AppSpawnServer::WaitRebootEvent() { APPSPAWN_LOGI("wait 'startup.device.ctl' event"); while (isRunning_) { - int ret = WaitParameter("startup.device.ctl", "stop", WAIT_PARAM_TIME); + int ret = WaitParameter("startup.device.ctl", "stop", WAIT_PARAM_TIME); if (ret == 0) { std::lock_guard lock(mut_); isStop_ = true; dataCond_.notify_one(); break; + } else { + std::string value = OHOS::system::GetParameter("startup.device.ctl", ""); + if (value == "stop") { + std::lock_guard lock(mut_); + isStop_ = true; + dataCond_.notify_one(); + break; + } } } } @@ -210,8 +219,8 @@ void AppSpawnServer::HandleSignal() void AppSpawnServer::LoadAceLib() { -#ifdef WEBVIEW_SPAWN - std::string enginelibdir("/data/app/el1/bundle/public/com.ohos.webviewhap" +#ifdef NWEB_SPAWN + std::string enginelibdir("/data/app/el1/bundle/public/com.ohos.nweb" "/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); @@ -222,16 +231,16 @@ void AppSpawnServer::LoadAceLib() } 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) { + std::string execlibdir("/data/app/el1/bundle/public/com.ohos.nweb" + "/entry/libs/armeabi/libnweb_render.so"); + HiLog::Info(LABEL, "MainThread::LoadAbilityLibrary libnweb_render. Start calling dlopen execlibdir."); + nwebHandle = dlopen(execlibdir.c_str(), RTLD_NOW | RTLD_GLOBAL); + if (nwebHandle == 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."); + HiLog::Info(LABEL, "MainThread::LoadAbilityLibrary libnweb_render. End calling dlopen."); #else std::string acelibdir("/system/lib/libace.z.so"); void *AceAbilityLib = nullptr; @@ -246,6 +255,56 @@ void AppSpawnServer::LoadAceLib() #endif } +static void ClearEnvironment(void) +{ + sigset_t mask; + sigemptyset(&mask); + sigaddset(&mask, SIGCHLD); + sigaddset(&mask, SIGTERM); + sigprocmask(SIG_UNBLOCK, &mask, nullptr); + return; +} + +int AppSpawnServer::DoColdStartApp(ClientSocket::AppProperty *appProperty, int fd) +{ + APPSPAWN_LOGI("DoColdStartApp::appName %s", appProperty->processName); + std::vector extractedCmds; + extractedCmds.push_back(const_cast("/system/bin/appspawntools")); + std::string tmp = std::to_string(fd); + APPSPAWN_LOGI("DoColdStartApp::fd %d %s", fd, tmp.c_str()); + extractedCmds.push_back(const_cast(tmp.c_str())); + std::string uid = std::to_string(appProperty->uid); + APPSPAWN_LOGI("DoColdStartApp::uid %d gid %d %s", appProperty->uid, appProperty->gid, uid.c_str()); + extractedCmds.push_back(const_cast(uid.c_str())); + std::string gid = std::to_string(appProperty->gid); + extractedCmds.push_back(const_cast(gid.c_str())); + extractedCmds.push_back(const_cast(appProperty->processName)); + extractedCmds.push_back(const_cast(appProperty->bundleName)); + extractedCmds.push_back(const_cast(appProperty->soPath)); + std::string accessTokenId = std::to_string(appProperty->accessTokenId); + APPSPAWN_LOGI("DoColdStartApp::accessTokenId %d %s", appProperty->accessTokenId, accessTokenId.c_str()); + extractedCmds.push_back(const_cast(accessTokenId.c_str())); + extractedCmds.push_back(const_cast(appProperty->apl)); + APPSPAWN_LOGI("DoColdStartApp renderCmd %s", appProperty->renderCmd); + extractedCmds.push_back(const_cast(appProperty->renderCmd)); + std::string flags = std::to_string(appProperty->flags); + extractedCmds.push_back(const_cast(flags.c_str())); + std::string gidCount = std::to_string(appProperty->gidCount); + APPSPAWN_LOGI("DoColdStartApp gidCount %d %s", appProperty->gidCount, gidCount.c_str()); + extractedCmds.push_back(const_cast(gidCount.c_str())); + for (uint32_t i = 0; i < appProperty->gidCount; i++) { + extractedCmds.push_back(const_cast(std::string(std::to_string(appProperty->gidTable[i])).c_str())); + } + extractedCmds.push_back(nullptr); + APPSPAWN_LOGI("DoColdStartApp extractedCmds %d", extractedCmds.size()); + int ret = execv(extractedCmds[0], extractedCmds.data()); + if (ret) { + HiLog::Error(LABEL, "Failed to execv, errno = %{public}d", errno); + NotifyResToParentProc(fd, -1); + } + return 0; +} + int AppSpawnServer::StartApp(char *longProcName, int64_t longProcNameLen, ClientSocket::AppProperty *appProperty, int connectFd, pid_t &pid) { @@ -274,8 +333,15 @@ int AppSpawnServer::StartApp(char *longProcName, int64_t longProcNameLen, socket_->CloseServerMonitor(); } close(fd[0]); // close read fd + ClearEnvironment(); UninstallSigHandler(); - SetAppProcProperty(appProperty, longProcName, longProcNameLen, fd); + SetAppAccessToken(appProperty); + if ((appProperty->flags == ClientSocket::APPSPAWN_COLD_BOOT) && + OHOS::system::GetBoolParameter("appspawn.cold.boot", false)) { + DoColdStartApp(appProperty, fd[1]); + } else { + SetAppProcProperty(appProperty, longProcName, longProcNameLen, fd[1]); + } _exit(0); } read(fd[0], &buff, sizeof(buff)); // wait child process resutl @@ -286,6 +352,14 @@ int AppSpawnServer::StartApp(char *longProcName, int64_t longProcNameLen, return (buff == ERR_OK) ? 0 : buff; } +void AppSpawnServer::QuickExitMain() +{ +#ifndef TEST_EXIT + quick_exit(0); +#endif + return; +} + bool AppSpawnServer::ServerMain(char *longProcName, int64_t longProcNameLen) { if (socket_->RegisterServerSocket() != 0) { @@ -320,14 +394,15 @@ bool AppSpawnServer::ServerMain(char *longProcName, int64_t longProcNameLen) ClientSocket::AppProperty *appProperty = msg->GetMsg(); pid_t pid = 0; int ret = StartApp(longProcName, longProcNameLen, appProperty, connectFd, pid); - if (ret != 0) { + if (ret) { msg->Response(ret); } else { msg->Response(pid); appMap_[pid] = appProperty->processName; } socket_->CloseConnection(connectFd); // close socket connection - APPSPAWN_LOGI("AppSpawnServer::parent process create app finish, pid = %d %s", pid, appProperty->processName); + APPSPAWN_LOGI("AppSpawnServer::parent process create app finish, pid = %d uid %d %s %s", + pid, appProperty->uid, appProperty->processName, appProperty->bundleName); } while (appMap_.size() > 0) { @@ -336,6 +411,7 @@ bool AppSpawnServer::ServerMain(char *longProcName, int64_t longProcNameLen) kill(iter->first, SIGKILL); appMap_.erase(iter); } + QuickExitMain(); return false; } @@ -540,6 +616,7 @@ int32_t AppSpawnServer::DoAppSandboxMount(const ClientSocket::AppProperty *appPr std::string destel1DataPath = rootPath + "/data/storage/el1/base"; std::string destel2DataPath = rootPath + "/data/storage/el2/base"; std::string destappdataPath = rootPath + oriappdataPath; + int rc = 0; std::string bundleName = appProperty->bundleName; @@ -566,7 +643,7 @@ int32_t AppSpawnServer::DoAppSandboxMount(const ClientSocket::AppProperty *appPr // to create some useful dir when mount point created std::vector mkdirInfo; std::string dirPath; - mkdirInfo.push_back("/data/storage/el1/bundle/webview"); + mkdirInfo.push_back("/data/storage/el1/bundle/nweb"); for (int i = 0; i < mkdirInfo.size(); i++) { dirPath = rootPath + mkdirInfo[i]; @@ -582,14 +659,21 @@ int32_t AppSpawnServer::DoAppSandboxMountCustomized(const ClientSocket::AppPrope std::string currentUserId = std::to_string(appProperty->uid / UID_BASE); std::string destInstallPath = rootPath + "/data/storage/el1/bundle"; - // account_0/applications/ dir can still access other packages' data now for compatibility purpose - std::string oriapplicationsPath = "/data/app/el1/bundle/public/"; - std::string destapplicationsPath = rootPath + "/data/accounts/account_0/applications/"; - DoAppSandboxMountOnce(oriapplicationsPath.c_str(), destapplicationsPath.c_str()); + if (bundleName.find("launcher") != std::string::npos || bundleName.find("systemui") != std::string::npos ||\ + bundleName.find("permissionmanager") != std::string::npos || bundleName == "com.ohos.settings") { + // account_0/applications/ dir can still access other packages' data now for compatibility purpose + std::string oriapplicationsPath = "/data/app/el1/bundle/public/"; + std::string destapplicationsPath = rootPath + "/data/accounts/account_0/applications/"; + DoAppSandboxMountOnce(oriapplicationsPath.c_str(), destapplicationsPath.c_str()); + + // need permission check for system app here + std::string destbundlesPath = rootPath + "/data/bundles/"; + DoAppSandboxMountOnce(oriapplicationsPath.c_str(), destbundlesPath.c_str()); + } - // need permission check for system app here - std::string destbundlesPath = rootPath + "/data/bundles/"; - DoAppSandboxMountOnce(oriapplicationsPath.c_str(), destbundlesPath.c_str()); + std::string orimntHmdfsPath = "/mnt/hmdfs/"; + std::string destmntHmdfsPath = rootPath + orimntHmdfsPath; + DoAppSandboxMountOnce(orimntHmdfsPath.c_str(), destmntHmdfsPath.c_str()); // Add distributedfile module support, later reconstruct it std::string oriDistributedPath = "/mnt/hmdfs/" + currentUserId + "/account/merge_view/data/" + bundleName; @@ -600,11 +684,11 @@ int32_t AppSpawnServer::DoAppSandboxMountCustomized(const ClientSocket::AppPrope std::string destDistributedGroupPath = rootPath + "/data/storage/el2/auth_groups"; DoAppSandboxMountOnce(oriDistributedGroupPath.c_str(), destDistributedGroupPath.c_str()); - // do webview adaption - std::string oriwebviewPath = "/data/app/el1/bundle/public/com.ohos.webviewhap"; - std::string destwebviewPath = destInstallPath + "/webview"; - chmod(destwebviewPath.c_str(), WEBVIEW_FILE_MODE); - DoAppSandboxMountOnce(oriwebviewPath.c_str(), destwebviewPath.c_str()); + // do nweb adaption + std::string orinwebPath = "/data/app/el1/bundle/public/com.ohos.nweb"; + std::string destnwebPath = destInstallPath + "/nweb"; + chmod(destnwebPath.c_str(), NWEB_FILE_MODE); + DoAppSandboxMountOnce(orinwebPath.c_str(), destnwebPath.c_str()); if (bundleName.find("medialibrary") != std::string::npos) { std::string oriMediaPath = "/storage/media/" + currentUserId; @@ -620,6 +704,8 @@ void AppSpawnServer::DoAppSandboxMkdir(std::string sandboxPackagePath, const Cli std::vector mkdirInfo; std::string dirPath; + mkdirInfo.push_back("/mnt/"); + mkdirInfo.push_back("/mnt/hmdfs/"); mkdirInfo.push_back("/data/"); mkdirInfo.push_back("/storage/"); mkdirInfo.push_back("/storage/media"); @@ -656,7 +742,7 @@ int32_t AppSpawnServer::DoSandboxRootFolderCreateAdapt(std::string sandboxPackag } // bind mount "/" to /mnt/sandbox/ path - // rootfs: to do more resouces bind mount here to get more strict resources constraints + // rootfs: to do more resources bind mount here to get more strict resources constraints rc = mount("/", sandboxPackagePath.c_str(), NULL, MS_BIND | MS_REC, NULL); if (rc) { HiLog::Error(LABEL, "mount bind / failed"); @@ -687,7 +773,6 @@ int32_t AppSpawnServer::DoSandboxRootFolderCreate(std::string sandboxPackagePath vecInfo.push_back("/sys"); vecInfo.push_back("/sys-prod"); vecInfo.push_back("/system"); - vecInfo.push_back("/mnt"); for (int i = 0; i < vecInfo.size(); i++) { tmpDir = sandboxPackagePath + vecInfo[i]; @@ -794,80 +879,78 @@ int32_t AppSpawnServer::SetAppSandboxProperty(const ClientSocket::AppProperty *a void AppSpawnServer::SetAppAccessToken(const ClientSocket::AppProperty *appProperty) { int32_t ret = SetSelfTokenID(appProperty->accessTokenId); - if (ret != 0) { - HiLog::Error(LABEL, "AppSpawnServer::Failed to set access token id, errno = %{public}d", errno); - } + HiLog::Info(LABEL, "AppSpawnServer::set access token id = %{public}d, ret = %{public}d %{public}d", + appProperty->accessTokenId, ret, getuid()); + #ifdef WITH_SELINUX HapContext hapContext; ret = hapContext.HapDomainSetcontext(appProperty->apl, appProperty->processName); - if (ret != 0) { - HiLog::Error(LABEL, "AppSpawnServer::Failed to hap domain set context, errno = %{public}d", errno); + if (ret) { + HiLog::Error(LABEL, "AppSpawnServer::Failed to hap domain set context, errno = %{public}d %{public}s", + errno, appProperty->apl); + } else { + HiLog::Info(LABEL, "AppSpawnServer::Success to hap domain set context, ret = %{public}d", ret); } #endif } bool AppSpawnServer::SetAppProcProperty(const ClientSocket::AppProperty *appProperty, char *longProcName, - int64_t longProcNameLen, const int32_t fd[FDLEN2]) + int64_t longProcNameLen, const int32_t fd) { - pid_t newPid = getpid(); - HiLog::Debug(LABEL, "AppSpawnServer::Success to fork new process, pid = %{public}d", newPid); - int32_t ret = ERR_OK; - - ret = SetAppSandboxProperty(appProperty); + HiLog::Debug(LABEL, "AppSpawnServer::Success to fork new process, pid = %{public}d", getpid()); + int32_t ret = SetAppSandboxProperty(appProperty); if (FAILED(ret)) { - NotifyResToParentProc(fd[1], ret); + NotifyResToParentProc(fd, ret); return false; } ret = SetKeepCapabilities(appProperty->uid); if (FAILED(ret)) { - NotifyResToParentProc(fd[1], ret); + NotifyResToParentProc(fd, ret); return false; } - SetAppAccessToken(appProperty); - ret = SetProcessName(longProcName, longProcNameLen, appProperty->processName, strlen(appProperty->processName) + 1); if (FAILED(ret)) { - NotifyResToParentProc(fd[1], ret); + NotifyResToParentProc(fd, ret); return false; } #ifdef GRAPHIC_PERMISSION_CHECK ret = SetUidGid(appProperty->uid, appProperty->gid, appProperty->gidTable, appProperty->gidCount); if (FAILED(ret)) { - NotifyResToParentProc(fd[1], ret); + NotifyResToParentProc(fd, ret); return false; } #endif ret = SetFileDescriptors(); if (FAILED(ret)) { - NotifyResToParentProc(fd[1], ret); + NotifyResToParentProc(fd, ret); return false; } ret = SetCapabilities(); if (FAILED(ret)) { - NotifyResToParentProc(fd[1], ret); + NotifyResToParentProc(fd, ret); return false; } // notify success to father process and start app process - NotifyResToParentProc(fd[1], ret); + NotifyResToParentProc(fd, ret); -#ifdef WEBVIEW_SPAWN +#ifdef NWEB_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()); + FuncType funcNWebRenderMain = reinterpret_cast(dlsym(nwebHandle, "NWebRenderMain")); + if (funcNWebRenderMain == nullptr) { + HiLog::Error(LABEL, "nwebspawn dlsym ERROR=%{public}s", dlerror()); return false; } - funcWebViewExecuteProcess(appProperty->renderCmd); + funcNWebRenderMain(appProperty->renderCmd); #else AppExecFwk::MainThread::Start(); #endif - HiLog::Error(LABEL, "Failed to start process, pid = %{public}d", newPid); + HiLog::Error(LABEL, "Failed to start process, pid = %{public}d", getpid()); return false; } @@ -927,5 +1010,17 @@ bool AppSpawnServer::CheckAppProperty(const ClientSocket::AppProperty *appProper return true; } + +int AppSpawnServer::AppColdStart(char *longProcName, + int64_t longProcNameLen, const ClientSocket::AppProperty *appProperty, int fd) +{ + APPSPAWN_LOGI("AppColdStart appName %s", appProperty->bundleName); + LoadAceLib(); + if (!SetAppProcProperty(appProperty, longProcName, longProcNameLen, fd)) { + return -1; + } + APPSPAWN_LOGI("AppColdStart appName %s success", appProperty->bundleName); + return 0; +} } // namespace AppSpawn } // namespace OHOS diff --git a/src/include/appspawn_msg_peer.h b/src/include/appspawn_msg_peer.h index 0aa10c1999737cfaadcc2e180e890e8f6074e0be..d81b124df96ad2ed6dbb3b8c4f63c87d917c5bcc 100644 --- a/src/include/appspawn_msg_peer.h +++ b/src/include/appspawn_msg_peer.h @@ -37,7 +37,7 @@ public: AppSpawnMsgPeer(const std::shared_ptr &socket, int connectFd); /** - * Destructor used to destory a AppSpawnMsgPeer + * Destructor used to destroy a AppSpawnMsgPeer */ ~AppSpawnMsgPeer(); diff --git a/src/include/appspawn_server.h b/src/include/appspawn_server.h index 6e2192a8a70764d16a6eb0ea7ae6acb51e1dd37e..cda398e7b458cc0702e3f990fc7bff8fe638ee7c 100644 --- a/src/include/appspawn_server.h +++ b/src/include/appspawn_server.h @@ -39,7 +39,7 @@ public: explicit AppSpawnServer(const std::string &socketName); /** - * Destructor used to destory a AppSpawnServer + * Destructor used to destroy a AppSpawnServer */ ~AppSpawnServer() = default; @@ -70,7 +70,11 @@ public: */ void SetServerSocket(const std::shared_ptr &serverSocket); + int AppColdStart(char *longProcName, + int64_t longProcNameLen, const ClientSocket::AppProperty *appProperty, int fd); private: + int DoColdStartApp(ClientSocket::AppProperty *appProperty, int fd); + static constexpr uint8_t BITLEN32 = 32; static constexpr uint8_t FDLEN2 = 2; static constexpr uint8_t FD_INIT_VALUE = 0; @@ -89,7 +93,7 @@ private: void ConnectionPeer(); /** - * Sets a name for an applicaiton process. + * Sets a name for an application process. * * @param longProcName Indicates the length of long process name. * @param longProcNameLen Indicates the long process name. @@ -162,7 +166,7 @@ private: * Sets app process property. */ bool SetAppProcProperty(const ClientSocket::AppProperty *appProperty, char *longProcName, - int64_t longProcNameLen, const int32_t fd[FDLEN2]); + int64_t longProcNameLen, const int32_t fd); /** * Notify @@ -189,6 +193,8 @@ private: void WaitRebootEvent(); void HandleSignal(); + + void QuickExitMain(); private: const std::string deviceNull_ = "/dev/null"; std::string socketName_ {}; @@ -203,8 +209,8 @@ private: bool isChildDie_ { false }; pid_t childPid_ {}; std::map appMap_; -#ifdef WEBVIEW_SPAWN - void *webviewHandle = nullptr; +#ifdef NWEB_SPAWN + void *nwebHandle = nullptr; #endif }; } // namespace AppSpawn diff --git a/src/include/server_socket.h b/src/include/server_socket.h index 84c965cf7b1dff6b4f6b6e199bf61f332f80613b..8bfe2ce46ba9fc67962dd2ad69e6ef665909ccec 100644 --- a/src/include/server_socket.h +++ b/src/include/server_socket.h @@ -34,7 +34,7 @@ public: explicit ServerSocket(const std::string &server); /** - * Destructor used to destory a ServerSocket + * Destructor used to destroy a ServerSocket */ virtual ~ServerSocket(); diff --git a/src/main.cpp b/src/main.cpp index 41e40b2a5ddb0f64347af8541c8fdd171895ef2f..95ae423a273e80495a4aa762ada464ff92f53e2a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -26,8 +26,8 @@ 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"); +#ifdef NWEB_SPAWN + OHOS::AppSpawn::AppSpawnServer appspawnServer("/dev/unix/socket/NWebSpawn"); #else OHOS::AppSpawn::AppSpawnServer appspawnServer("AppSpawn"); #endif diff --git a/src/socket/appspawn_socket.cpp b/src/socket/appspawn_socket.cpp old mode 100755 new mode 100644 diff --git a/src/socket/server_socket.cpp b/src/socket/server_socket.cpp index c7def0294a8c7fdc5e9139bc76fcbf95871d02da..7a0b14440a81d7cf1aa309f696abb45b3b9a7057 100644 --- a/src/socket/server_socket.cpp +++ b/src/socket/server_socket.cpp @@ -153,8 +153,8 @@ int ServerSocket::RegisterServerSocket(int &connectFd) return -EINVAL; } -#ifdef WEBVIEW_SPAWN - connectFd = GetControlSocket("WebViewSpawn"); +#ifdef NWEB_SPAWN + connectFd = GetControlSocket("NWebSpawn"); #else connectFd = CreateSocket(); #endif @@ -162,7 +162,7 @@ int ServerSocket::RegisterServerSocket(int &connectFd) return connectFd; } -#ifndef WEBVIEW_SPAWN +#ifndef NWEB_SPAWN if ((BindSocket(connectFd) != 0) || (listen(connectFd, listenBacklog_) < 0)) { HiLog::Error(LABEL, "Server: Register socket fd %d with backlog %d error: %d", diff --git a/test/BUILD.gn b/test/BUILD.gn index 2df1ee1582165a51f569d6e8d075eb426b7c9b8c..8bc4665dabe3abbbfd749a6973986d91e60bba8a 100644 --- a/test/BUILD.gn +++ b/test/BUILD.gn @@ -35,7 +35,7 @@ group("moduletest") { config("appspawn_test_config") { configs = [] - defines = [] + defines = [ "TEST_EXIT" ] include_dirs = [ "${appspawn_path}/test/mock/include", diff --git a/test/unittest/app_spawn_server_test/BUILD.gn b/test/unittest/app_spawn_server_test/BUILD.gn old mode 100755 new mode 100644 diff --git a/tools/appspawn_start_app.cpp b/tools/appspawn_start_app.cpp new file mode 100755 index 0000000000000000000000000000000000000000..072e69f9c671e1b808ff5448ba239f7db40696fc --- /dev/null +++ b/tools/appspawn_start_app.cpp @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2022 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 + +#include "appspawn_server.h" +#include "client_socket.h" +#include "hilog/log.h" +#include "securec.h" + +using namespace OHOS; +using namespace OHOS::HiviewDFX; +static constexpr HiLogLabel LABEL = {LOG_CORE, 0, "AppSpawnServer"}; +static const int DECIMAL = 10; + +int main(int argc, char *const argv[]) +{ + if (argc <= 11) { // 11 min argc + HiLog::Error(LABEL, "Invalid argc %{public}d", argc); + return -1; + } + HiLog::Debug(LABEL, "AppSpawnServer argc %{public}d app:%{public}s", argc, argv[4]); // 4 name index + // calculate child process long name size + uintptr_t start = reinterpret_cast(argv[0]); + uintptr_t end = reinterpret_cast(strchr(argv[argc - 1], 0)); + if (end == 0) { + return -1; + } + uintptr_t argvSize = end - start; + + auto appProperty = std::make_unique(); + if (appProperty == nullptr) { + HiLog::Error(LABEL, "Failed to create app property %{public}s", argv[4]); // 4 name index + return -1; + } + int index = 1; + int fd = strtoul(argv[index++], nullptr, DECIMAL); + appProperty->uid = strtoul(argv[index++], nullptr, DECIMAL); + appProperty->gid = strtoul(argv[index++], nullptr, DECIMAL); + (void)strcpy_s(appProperty->processName, sizeof(appProperty->processName), argv[index++]); + (void)strcpy_s(appProperty->bundleName, sizeof(appProperty->bundleName), argv[index++]); + (void)strcpy_s(appProperty->soPath, sizeof(appProperty->soPath), argv[index++]); + appProperty->accessTokenId = strtoul(argv[index++], nullptr, DECIMAL); + (void)strcpy_s(appProperty->apl, sizeof(appProperty->apl), argv[index++]); + (void)strcpy_s(appProperty->renderCmd, sizeof(appProperty->renderCmd), argv[index++]); + appProperty->flags = strtoul(argv[index++], nullptr, DECIMAL); + appProperty->gidCount = strtoul(argv[index++], nullptr, DECIMAL); + uint32_t i = 0; + while ((i < appProperty->gidCount) && (i < sizeof(appProperty->gidTable) / sizeof(appProperty->gidTable[0]))) { + if (index >= argc) { + HiLog::Error(LABEL, "Invalid arg %{public}d %{public}d", index, argc); + return -1; + } + appProperty->gidTable[i++] = strtoul(argv[index++], nullptr, DECIMAL); + } + auto appspawnServer = std::make_shared("AppSpawn"); + if (appspawnServer != nullptr) { + int ret = appspawnServer->AppColdStart(argv[0], argvSize, appProperty.get(), fd); + if (ret != 0) { + HiLog::Error(LABEL, "Cold start %{public}s fail.", appProperty->bundleName); + } + } + return 0; +}