diff --git a/BUILD.gn b/BUILD.gn index 9f0e9b9b144499bb2430d11a5bd86a360b7ba361..193a2c2681c41c513be0f5c411508e0c843bcf21 100755 --- a/BUILD.gn +++ b/BUILD.gn @@ -83,6 +83,7 @@ ohos_static_library("appspawn_server") { "hilog_native:libhilog", "hiviewdfx_hilog_native:libhilog", "ipc:ipc_core", + "os_account_standard:os_account_innerkits", "safwk:system_ability_fwk", "samgr_standard:samgr_proxy", ] @@ -95,6 +96,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" @@ -146,6 +161,7 @@ ohos_static_library("webviewspawn_server") { "hilog_native:libhilog", "hiviewdfx_hilog_native:libhilog", "ipc:ipc_core", + "os_account_standard:os_account_innerkits", "safwk:system_ability_fwk", "samgr_standard:samgr_proxy", ] diff --git a/bundle.json b/bundle.json index 502b4725a8bfcc741895290b0bde391ed34e194d..c0f8b74ecde951e6c8a6f0c9d90304bf2cf76ad3 100644 --- a/bundle.json +++ b/bundle.json @@ -29,7 +29,8 @@ "ipc", "safwk", "samgr_standard", - "utils_base" + "utils_base", + "bundle_framework" ] }, "build": { @@ -38,6 +39,7 @@ "//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/interfaces/innerkits:appspawn_socket_client" ], "inner_kits": [ diff --git a/src/appspawn_server.cpp b/src/appspawn_server.cpp index e5679e6a08d39c2421efb6aa53601afad5e3c158..fefae587a0ce79a60f0fc03bbcf7d077141453a8 100644 --- a/src/appspawn_server.cpp +++ b/src/appspawn_server.cpp @@ -41,6 +41,7 @@ #include "token_setproc.h" #include "parameter.h" #include "beget_ext.h" +#include "os_account_manager.h" #ifdef WITH_SELINUX #include "hap_restorecon.h" #endif @@ -80,6 +81,50 @@ static constexpr HiLogLabel LABEL = {LOG_CORE, 0, "AppSpawnServer"}; extern "C" { #endif +static sptr GetBundleMgrProxy() +{ + sptr systemAbilityManager = + SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (!systemAbilityManager) { + APPSPAWN_LOGI("Failed to get for systemAbilityManager"); + return nullptr; + } + + sptr remoteObject = systemAbilityManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID); + if (!remoteObject) { + APPSPAWN_LOGI("Failed to get for remoteObject"); + return nullptr; + } + sptr bundleMgr = iface_cast(remoteObject); + if (!bundleMgr) { + APPSPAWN_LOGI("Failed to get for bundleMgr"); + return nullptr; + } + return bundleMgr; +} + +static int GetApplicationInfo(const std::string &bundleName, int applicationFlag, int userId, + AppExecFwk::ApplicationInfo &appInfo) +{ + sptr bundleMgr = GetBundleMgrProxy(); + if (!bundleMgr) { + APPSPAWN_LOGI("appInfo can not get bundleMgr for %s", bundleName.c_str()); + HiLog::Error(LABEL, "can not get bundleMgr for %{public}s", bundleName.c_str()); + return -1; + } + + APPSPAWN_LOGI("GetApplicationInfo userId %d", userId); + if (!bundleMgr->GetApplicationInfo(bundleName, applicationFlag, userId, appInfo)) { + APPSPAWN_LOGI("Failed to cold start %s", bundleName.c_str()); + HiLog::Error(LABEL, "Failed to cold start %{public}s", bundleName.c_str()); + return -1; + } + APPSPAWN_LOGI("GetApplicationInfo bundleName %s", appInfo.bundleName.c_str()); + APPSPAWN_LOGI("GetApplicationInfo accessTokenId %d", appInfo.accessTokenId); + APPSPAWN_LOGI("GetApplicationInfo appPrivilegeLevel %s", appInfo.appPrivilegeLevel.c_str()); + return 0; +} + static void SignalHandler([[maybe_unused]] int sig) { pid_t pid; @@ -327,7 +372,8 @@ bool AppSpawnServer::ServerMain(char *longProcName, int64_t longProcNameLen) 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) { @@ -794,14 +840,16 @@ 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", + appProperty->accessTokenId, ret); + #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); + } else { + HiLog::Info(LABEL, "AppSpawnServer::Success to hap domain set context, ret = %{public}d", ret); } #endif } @@ -873,8 +921,10 @@ bool AppSpawnServer::SetAppProcProperty(const ClientSocket::AppProperty *appProp void AppSpawnServer::NotifyResToParentProc(const int32_t fd, const int32_t value) { - write(fd, &value, sizeof(value)); - close(fd); + if (fd != FD_INIT_VALUE) { + write(fd, &value, sizeof(value)); + close(fd); + } } void AppSpawnServer::SpecialHandle(ClientSocket::AppProperty *appProperty) @@ -927,5 +977,54 @@ bool AppSpawnServer::CheckAppProperty(const ClientSocket::AppProperty *appProper return true; } + +int AppSpawnServer::AppColdStart(char *longProcName, + int64_t longProcNameLen, const std::string &appName, const std::string uidStr) +{ + APPSPAWN_LOGI("AppColdStart appName %s uid %s", appName.c_str(), uidStr.c_str()); + LoadAceLib(); + AppExecFwk::ApplicationInfo appInfo = {}; + int ret = -1; + if (uidStr.empty()) { + std::vector activeUserIds = {}; + OHOS::AccountSA::OsAccountManager::QueryActiveOsAccountIds(activeUserIds); + APPSPAWN_LOGI("AppColdStart activeUserIds %d", activeUserIds.size()); + for (int userId : activeUserIds) { + APPSPAWN_LOGI("AppColdStart appName %s uid %d", appName.c_str(), userId); + ret = GetApplicationInfo(appName, OHOS::AppExecFwk::GET_BASIC_APPLICATION_INFO, userId, appInfo); + if (ret == 0) { + break; + } + } + } else { + uint32_t uid = atoi(uidStr.c_str()); + int32_t userId = uid / 200000; // 200000 uid to userId + ret = GetApplicationInfo(appName, OHOS::AppExecFwk::GET_BASIC_APPLICATION_INFO, userId, appInfo); + } + if (ret != 0) { + return ret; + } + auto appProperty = std::make_unique(); + if (appProperty == nullptr) { + return -1; + } + appProperty->uid = appInfo.uid; + appProperty->accessTokenId = appInfo.accessTokenId; + (void)strcpy_s(appProperty->processName, sizeof(appProperty->processName), appInfo.name.c_str()); + (void)strcpy_s(appProperty->bundleName, sizeof(appProperty->bundleName), appInfo.bundleName.c_str()); + (void)strcpy_s(appProperty->apl, sizeof(appProperty->apl), appInfo.appPrivilegeLevel.c_str()); + + int32_t fd[FDLEN2] = {FD_INIT_VALUE, FD_INIT_VALUE}; + SpecialHandle(appProperty.get()); + SetAppProcProperty(appProperty.get(), longProcName, longProcNameLen, fd); + if (ret != 0) { + return ret; + } + while (1) { + pause(); + } + printf("Clod start %s success. \n", appName.c_str()); + return 0; +} } // namespace AppSpawn } // namespace OHOS diff --git a/src/include/appspawn_server.h b/src/include/appspawn_server.h index 6e2192a8a70764d16a6eb0ea7ae6acb51e1dd37e..2d4701b46f4f16945aecbbdaa74005ebface9fbc 100644 --- a/src/include/appspawn_server.h +++ b/src/include/appspawn_server.h @@ -70,6 +70,7 @@ public: */ void SetServerSocket(const std::shared_ptr &serverSocket); + int AppColdStart(char *longProcName, int64_t longProcNameLen, const std::string &appName, const std::string uid); private: static constexpr uint8_t BITLEN32 = 32; static constexpr uint8_t FDLEN2 = 2; diff --git a/test/unittest/app_spawn_server_test/BUILD.gn b/test/unittest/app_spawn_server_test/BUILD.gn index 83a07f4e460c9845231b0c329dfc9569dea90fb6..17deadc381824c1bde1f96c8b86c377dfa48dcf4 100755 --- a/test/unittest/app_spawn_server_test/BUILD.gn +++ b/test/unittest/app_spawn_server_test/BUILD.gn @@ -51,6 +51,7 @@ ohos_unittest("AppSpawnServerOverrideTest") { "hilog_native:libhilog", "hiviewdfx_hilog_native:libhilog", "ipc:ipc_core", + "os_account_standard:os_account_innerkits", "safwk:system_ability_fwk", "samgr_standard:samgr_proxy", ] @@ -99,6 +100,7 @@ ohos_unittest("AppSpawnServerMockTest") { "hilog_native:libhilog", "hiviewdfx_hilog_native:libhilog", "ipc:ipc_core", + "os_account_standard:os_account_innerkits", "safwk:system_ability_fwk", "samgr_standard:samgr_proxy", ] diff --git a/tools/appspawn_start_app.cpp b/tools/appspawn_start_app.cpp new file mode 100644 index 0000000000000000000000000000000000000000..50c2d16005cb6854d418bb534e5bc726092a2847 --- /dev/null +++ b/tools/appspawn_start_app.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2021 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 "hilog/log.h" + +int main(int argc, char *const argv[]) +{ + if (argc <= 1) { + printf("appspawntools xxxx \n"); + return 0; + } + + // calculate child process long name size + uintptr_t start = reinterpret_cast(argv[0]); + uintptr_t end = reinterpret_cast(strchr(argv[argc - 1], 0)); + uintptr_t argvSize = end - start; + + std::string appName(argv[1]); + std::string uid ((argc > 2) ? argv[2] : ""); // 2 uid index + auto appspawnServer = std::make_shared("AppSpawn"); + if (appspawnServer != nullptr) { + int ret = appspawnServer->AppColdStart(argv[0], argvSize, appName, uid); + if (ret != 0) { + printf("Cold start %s fail \n", appName.c_str()); + } + } + return 0; +}