增加StartNativeChildProcess

Signed-off-by: zhangyuhang72 <zhangyuhang72@huawei.com>
Change-Id: I242c494947e702a58ddaf092651d76a5d1c6d48a
This commit is contained in:
zhangyuhang72
2024-08-21 09:45:43 +08:00
parent 5a8d4647cd
commit e2e422faee
49 changed files with 1073 additions and 201 deletions
@@ -35,6 +35,12 @@ enum {
MODE_SELF_FORK = 0,
MODE_APP_SPAWN_FORK = 1,
};
struct ChildProcessNApiParam {
std::string srcEntry;
AppExecFwk::ChildProcessArgs args;
AppExecFwk::ChildProcessOptions options;
int32_t childProcessType;
};
}
class JsChildProcessManager {
@@ -58,6 +64,11 @@ public:
GET_CB_INFO_AND_CALL(env, info, JsChildProcessManager, OnStartArkChildProcess);
}
static napi_value StartNativeChildProcess(napi_env env, napi_callback_info info)
{
GET_CB_INFO_AND_CALL(env, info, JsChildProcessManager, OnStartNativeChildProcess);
}
private:
napi_value OnStartChildProcess(napi_env env, size_t argc, napi_value* argv)
{
@@ -153,7 +164,7 @@ private:
napi_value OnStartArkChildProcess(napi_env env, size_t argc, napi_value* argv)
{
TAG_LOGI(AAFwkTag::PROCESSMGR, "called");
if (ChildProcessManager::GetInstance().IsChildProcess()) {
if (ChildProcessManager::GetInstance().IsChildProcessBySelfFork()) {
TAG_LOGE(AAFwkTag::PROCESSMGR, "Already in child process");
ThrowError(env, AbilityErrorCode::ERROR_CODE_OPERATION_NOT_SUPPORTED);
return CreateJsUndefined(env);
@@ -176,37 +187,100 @@ private:
ThrowInvalidParamError(env, "Param srcEntry cannot be empty.");
return CreateJsUndefined(env);
}
if (!ParseArgsAndOptions(env, argv, argc, args, options)) {
return CreateJsUndefined(env);
}
ChildProcessNApiParam param;
param.srcEntry = srcEntry;
param.args = args;
param.options = options;
param.childProcessType = AppExecFwk::CHILD_PROCESS_TYPE_ARK;
napi_value result = nullptr;
StartChildProcessWithArgsTask(env, result, param);
return result;
}
napi_value OnStartNativeChildProcess(napi_env env, size_t argc, napi_value* argv)
{
TAG_LOGI(AAFwkTag::PROCESSMGR, "called.");
if (ChildProcessManager::GetInstance().IsChildProcessBySelfFork()) {
TAG_LOGE(AAFwkTag::PROCESSMGR, "Already in child process");
ThrowError(env, AbilityErrorCode::ERROR_CODE_OPERATION_NOT_SUPPORTED);
return CreateJsUndefined(env);
}
if (argc < ARGC_TWO) {
TAG_LOGE(AAFwkTag::PROCESSMGR, "Not enough params.");
ThrowTooFewParametersError(env);
return CreateJsUndefined(env);
}
std::string entryPoint;
AppExecFwk::ChildProcessArgs args;
AppExecFwk::ChildProcessOptions options;
if (!ConvertFromJsValue(env, argv[PARAM0], entryPoint)) {
TAG_LOGE(AAFwkTag::PROCESSMGR, "Parse param entryPoint failed, must be a valid string.");
ThrowInvalidParamError(env, "Parse param entryPoint failed, must be a valid string.");
return CreateJsUndefined(env);
}
if (entryPoint.empty()) {
TAG_LOGE(AAFwkTag::PROCESSMGR, "entryPoint empty.");
ThrowInvalidParamError(env, "Param entryPoint cannot be empty.");
return CreateJsUndefined(env);
}
if (entryPoint.find(":") == std::string::npos) {
TAG_LOGE(AAFwkTag::PROCESSMGR,
"Param entryPoint must contains a colon to separate library name and entry function.");
ThrowInvalidParamError(env,
"Param entryPoint must contains a colon to separate library name and entry function.");
return CreateJsUndefined(env);
}
if (!ParseArgsAndOptions(env, argv, argc, args, options)) {
return CreateJsUndefined(env);
}
ChildProcessNApiParam param;
param.srcEntry = entryPoint;
param.args = args;
param.options = options;
param.childProcessType = AppExecFwk::CHILD_PROCESS_TYPE_NATIVE_ARGS;
napi_value result = nullptr;
StartChildProcessWithArgsTask(env, result, param);
return result;
}
bool ParseArgsAndOptions(const napi_env &env, napi_value* argv, size_t argc, AppExecFwk::ChildProcessArgs &args,
AppExecFwk::ChildProcessOptions &options)
{
std::string errorMsg;
if (!UnwrapChildProcessArgs(env, argv[PARAM1], args, errorMsg)) {
TAG_LOGE(AAFwkTag::PROCESSMGR, "Parse param args failed.");
ThrowInvalidParamError(env, errorMsg);
return CreateJsUndefined(env);
return false;
}
if (argc > ARGS_TWO && !UnwrapChildProcessOptions(env, argv[PARAM2], options, errorMsg)) {
TAG_LOGE(AAFwkTag::PROCESSMGR, "Parse param options failed.");
ThrowInvalidParamError(env, errorMsg);
return CreateJsUndefined(env);
return false;
}
napi_value result = nullptr;
StartArkChildProcessTask(env, result, srcEntry, args, options);
return result;
return true;
}
void StartArkChildProcessTask(const napi_env &env, napi_value &result, const std::string &srcEntry,
const AppExecFwk::ChildProcessArgs &args, const AppExecFwk::ChildProcessOptions &options)
void StartChildProcessWithArgsTask(const napi_env &env, napi_value &result, const ChildProcessNApiParam &param)
{
TAG_LOGD(AAFwkTag::PROCESSMGR, "OnStartArkChildProcess, srcEntry:%{private}s, args.entryParams:%{private}s,"
" args.fds size:%{public}zu, options.isolationMode:%{public}d", srcEntry.c_str(),
args.entryParams.c_str(), args.fds.size(), options.isolationMode);
auto &srcEntry = param.srcEntry;
auto &args = param.args;
auto &options = param.options;
auto childProcessType = param.childProcessType;
TAG_LOGD(AAFwkTag::PROCESSMGR, "StartChildProcessWithArgs, childProcessType:%{public}d, srcEntry:%{private}s, "
"args.entryParams:%{private}s, args.fds size:%{public}zu, options.isolationMode:%{public}d",
childProcessType, srcEntry.c_str(), args.entryParams.c_str(), args.fds.size(), options.isolationMode);
auto innerErrorCode = std::make_shared<ChildProcessManagerErrorCode>(ChildProcessManagerErrorCode::ERR_OK);
auto pid = std::make_shared<pid_t>(0);
NapiAsyncTask::ExecuteCallback execute = [srcEntry, args, options, pid, innerErrorCode]() {
NapiAsyncTask::ExecuteCallback execute = [srcEntry, args, options, childProcessType, pid, innerErrorCode]() {
if (!pid || !innerErrorCode) {
TAG_LOGE(AAFwkTag::PROCESSMGR, "innerErrorCode or pid is nullptr");
return;
}
*innerErrorCode = ChildProcessManager::GetInstance().StartArkChildProcess(srcEntry, *pid,
AppExecFwk::CHILD_PROCESS_TYPE_ARK, args, options);
*innerErrorCode = ChildProcessManager::GetInstance().StartChildProcessWithArgs(srcEntry, *pid,
childProcessType, args, options);
};
NapiAsyncTask::CompleteCallback complete =
[pid, innerErrorCode](napi_env env, NapiAsyncTask &task, int32_t status) {
@@ -222,7 +296,7 @@ private:
ChildProcessManagerErrorUtil::GetAbilityErrorCode(*innerErrorCode)));
}
};
NapiAsyncTask::ScheduleHighQos("JsChildProcessManager::OnStartArkChildProcess",
NapiAsyncTask::ScheduleHighQos("JsChildProcessManager::StartChildProcessWithArgsTask",
env, CreateAsyncTaskWithLastParam(env, nullptr, std::move(execute), std::move(complete), &result));
}
};
@@ -241,6 +315,8 @@ napi_value JsChildProcessManagerInit(napi_env env, napi_value exportObj)
const char *moduleName = PROCESS_MANAGER_NAME;
BindNativeFunction(env, exportObj, "startChildProcess", moduleName, JsChildProcessManager::StartChildProcess);
BindNativeFunction(env, exportObj, "startArkChildProcess", moduleName, JsChildProcessManager::StartArkChildProcess);
BindNativeFunction(env, exportObj, "startNativeChildProcess", moduleName,
JsChildProcessManager::StartNativeChildProcess);
return CreateJsUndefined(env);
}
} // namespace AbilityRuntime
@@ -29,6 +29,7 @@
#include "bundle_info.h"
#include "bundle_mgr_interface.h"
#include "child_process.h"
#include "native_args_child_process.h"
#include "native_child_ipc_process.h"
#include "child_process_manager_error_utils.h"
#include "child_process_request.h"
@@ -103,18 +104,19 @@ ChildProcessManagerErrorCode ChildProcessManager::StartChildProcessByAppSpawnFor
{
AppExecFwk::ChildProcessArgs args;
AppExecFwk::ChildProcessOptions options;
return StartArkChildProcess(srcEntry, pid, AppExecFwk::CHILD_PROCESS_TYPE_JS, args, options);
return StartChildProcessWithArgs(srcEntry, pid, AppExecFwk::CHILD_PROCESS_TYPE_JS, args, options);
}
ChildProcessManagerErrorCode ChildProcessManager::StartArkChildProcess(
ChildProcessManagerErrorCode ChildProcessManager::StartChildProcessWithArgs(
const std::string &srcEntry, pid_t &pid, int32_t childProcessType, const AppExecFwk::ChildProcessArgs &args,
const AppExecFwk::ChildProcessOptions &options)
{
TAG_LOGI(AAFwkTag::PROCESSMGR, "startWitDebug: %{public}d, processName:"
"%{public}s, native:%{public}d, entryParams:%{private}s, fdsSize:%{public}zu, options.isolationMode:%{public}d",
g_debugOption.isStartWithDebug, g_debugOption.processName.c_str(), g_debugOption.isStartWithNative,
args.entryParams.c_str(), args.fds.size(), options.isolationMode);
ChildProcessManagerErrorCode errorCode = PreCheck(childProcessType != AppExecFwk::CHILD_PROCESS_TYPE_JS);
TAG_LOGI(AAFwkTag::PROCESSMGR, "StartChildProcessWithArgs, childProcessType:%{public}d, startWitDebug: %{public}d,"
" processName:%{public}s, native:%{public}d, entryParams:%{private}s, fdsSize:%{public}zu,"
" options.isolationMode:%{public}d", childProcessType, g_debugOption.isStartWithDebug,
g_debugOption.processName.c_str(), g_debugOption.isStartWithNative, args.entryParams.c_str(), args.fds.size(),
options.isolationMode);
ChildProcessManagerErrorCode errorCode = PreCheck(childProcessType);
if (errorCode != ChildProcessManagerErrorCode::ERR_OK) {
return errorCode;
}
@@ -136,7 +138,7 @@ ChildProcessManagerErrorCode ChildProcessManager::StartArkChildProcess(
TAG_LOGD(AAFwkTag::PROCESSMGR, "AppMgr StartChildProcess ret:%{public}d", ret);
if (ret != ERR_OK) {
TAG_LOGE(AAFwkTag::PROCESSMGR, "StartChildProcess error:%{public}d", ret);
return ChildProcessManagerErrorCode::ERR_GET_APP_MGR_START_PROCESS_FAILED;
return ChildProcessManagerErrorUtil::GetChildProcessManagerErrorCode(ret);
}
return ChildProcessManagerErrorCode::ERR_OK;
}
@@ -166,7 +168,7 @@ ChildProcessManagerErrorCode ChildProcessManager::StartNativeChildProcessByAppSp
TAG_LOGE(AAFwkTag::PROCESSMGR, "Max native child processes readched");
return ChildProcessManagerErrorCode::ERR_MAX_NATIVE_CHILD_PROCESSES;
}
return ChildProcessManagerErrorCode::ERR_GET_APP_MGR_START_PROCESS_FAILED;
return ChildProcessManagerErrorCode::ERR_APP_MGR_FAILED_INNER;
}
++childProcessCount_;
@@ -189,14 +191,29 @@ void ChildProcessManager::HandleSigChild(int32_t signo)
}
}
ChildProcessManagerErrorCode ChildProcessManager::PreCheck(bool useNewErrorCode)
ChildProcessManagerErrorCode ChildProcessManager::PreCheck()
{
if (!AAFwk::AppUtils::GetInstance().IsMultiProcessModel()) {
TAG_LOGE(AAFwkTag::PROCESSMGR, "Multi process model disabled");
return ChildProcessManagerErrorCode::ERR_MULTI_PROCESS_MODEL_DISABLED;
}
if (IsChildProcess()) {
TAG_LOGE(AAFwkTag::PROCESSMGR, "Already in child process");
return ChildProcessManagerErrorCode::ERR_ALREADY_IN_CHILD_PROCESS;
}
return ChildProcessManagerErrorCode::ERR_OK;
}
ChildProcessManagerErrorCode ChildProcessManager::PreCheck(int32_t childProcessType)
{
if (!AAFwk::AppUtils::GetInstance().IsMultiProcessModel() &&
childProcessType != AppExecFwk::CHILD_PROCESS_TYPE_NATIVE_ARGS) {
TAG_LOGE(AAFwkTag::PROCESSMGR, "Not support child process.");
auto useNewErrorCode = childProcessType != AppExecFwk::CHILD_PROCESS_TYPE_JS;
return useNewErrorCode ? ChildProcessManagerErrorCode::ERR_MULTI_PROCESS_MODEL_DISABLED_NEW :
ChildProcessManagerErrorCode::ERR_MULTI_PROCESS_MODEL_DISABLED;
}
if (IsChildProcess()) {
if (isChildProcessBySelfFork_) {
TAG_LOGE(AAFwkTag::PROCESSMGR, "Already in child process");
return ChildProcessManagerErrorCode::ERR_ALREADY_IN_CHILD_PROCESS;
}
@@ -223,6 +240,11 @@ bool ChildProcessManager::IsChildProcess()
return isChildProcessBySelfFork_ || HasChildProcessRecord();
}
bool ChildProcessManager::IsChildProcessBySelfFork()
{
return isChildProcessBySelfFork_;
}
void ChildProcessManager::HandleChildProcessBySelfFork(const std::string &srcEntry,
const AppExecFwk::BundleInfo &bundleInfo)
{
@@ -311,6 +333,31 @@ bool ChildProcessManager::LoadNativeLib(const std::string &moduleName,
return true;
}
bool ChildProcessManager::LoadNativeLibWithArgs(const std::string &moduleName, const std::string &srcEntry,
const std::string &entryFunc, std::shared_ptr<AppExecFwk::ChildProcessArgs> args)
{
TAG_LOGI(AAFwkTag::PROCESSMGR, "moduleName:%{public}s, srcEntry:%{public}s, entryFunc:%{public}s.",
moduleName.c_str(), srcEntry.c_str(), entryFunc.c_str());
auto childProcess = NativeArgsChildProcess::Create();
if (childProcess == nullptr) {
TAG_LOGE(AAFwkTag::PROCESSMGR, "Failed create NativeArgsChildProcess.");
return false;
}
std::shared_ptr<ChildProcessStartInfo> processStartInfo = std::make_shared<ChildProcessStartInfo>();
processStartInfo->moduleName = moduleName;
processStartInfo->srcEntry = srcEntry;
processStartInfo->entryFunc = entryFunc;
if (!childProcess->Init(processStartInfo)) {
TAG_LOGE(AAFwkTag::PROCESSMGR, "NativeArgsChildProcess init failed.");
return false;
}
childProcess->OnStart(args);
TAG_LOGD(AAFwkTag::PROCESSMGR, "LoadNativeLibWithArgs end.");
return true;
}
std::unique_ptr<AbilityRuntime::Runtime> ChildProcessManager::CreateRuntime(const AppExecFwk::BundleInfo &bundleInfo,
const AppExecFwk::HapModuleInfo &hapModuleInfo, const bool fromAppSpawn, const bool jitEnabled)
{
@@ -28,5 +28,16 @@ AbilityErrorCode ChildProcessManagerErrorUtil::GetAbilityErrorCode(const ChildPr
return AbilityErrorCode::ERROR_CODE_INNER;
}
ChildProcessManagerErrorCode ChildProcessManagerErrorUtil::GetChildProcessManagerErrorCode(
int32_t abilityManagerErrorCode)
{
auto it = ABILITY_MANAGER_ERR_CODE_MAP.find(abilityManagerErrorCode);
if (it != ABILITY_MANAGER_ERR_CODE_MAP.end()) {
return it->second;
}
return ChildProcessManagerErrorCode::ERR_APP_MGR_FAILED_INNER;
}
} // namespace AbilityRuntime
} // namespace OHOS
@@ -0,0 +1,166 @@
/*
* Copyright (c) 2024 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 "native_args_child_process.h"
#include <dlfcn.h>
#include "hilog_tag_wrapper.h"
#include "securec.h"
namespace OHOS {
namespace AbilityRuntime {
std::shared_ptr<ChildProcess> NativeArgsChildProcess::Create()
{
return std::make_shared<NativeArgsChildProcess>();
}
NativeArgsChildProcess::~NativeArgsChildProcess()
{
UnloadNativeLib();
}
bool NativeArgsChildProcess::Init(const std::shared_ptr<ChildProcessStartInfo> &info)
{
TAG_LOGD(AAFwkTag::PROCESSMGR, "NativeArgsChildProcess init called.");
if (info == nullptr) {
TAG_LOGE(AAFwkTag::PROCESSMGR, "info is nullptr.");
return false;
}
if (!ChildProcess::Init(info)) {
TAG_LOGE(AAFwkTag::PROCESSMGR, "Base class init failed.");
return false;
}
return LoadNativeLib(info);
}
void NativeArgsChildProcess::OnStart(std::shared_ptr<AppExecFwk::ChildProcessArgs> args)
{
if (args == nullptr) {
TAG_LOGE(AAFwkTag::PROCESSMGR, "args is nullptr.");
return;
}
ChildProcess::OnStart(args);
TAG_LOGI(AAFwkTag::PROCESSMGR, "Enter native lib entry function");
auto nativeArgs = ParseToNativeArgs(args->entryParams, args->fds);
if (!entryFunc_) {
TAG_LOGE(AAFwkTag::PROCESSMGR, "entryFunc nullptr.");
return;
}
entryFunc_(nativeArgs);
TAG_LOGI(AAFwkTag::PROCESSMGR, "Native lib entry function returned");
}
NativeChildProcess_Args NativeArgsChildProcess::ParseToNativeArgs(const std::string &entryParams,
const std::map<std::string, int32_t> &fds)
{
NativeChildProcess_Args args;
args.entryParams = new(std::nothrow) char[entryParams.size() + 1];
if (!args.entryParams) {
TAG_LOGE(AAFwkTag::PROCESSMGR, "entryParams nullptr.");
return args;
}
if (strcpy_s(args.entryParams, entryParams.size() + 1, entryParams.c_str()) != ERR_OK) {
TAG_LOGE(AAFwkTag::APPKIT, "strcpy_s failed.");
return args;
}
NativeChildProcess_Fd *tail = nullptr;
for (const auto &fd : fds) {
auto &fdName = fd.first;
auto fdValue = fd.second;
NativeChildProcess_Fd *node = new(std::nothrow) NativeChildProcess_Fd;
if (!node) {
TAG_LOGE(AAFwkTag::PROCESSMGR, "fd node nullptr.");
return args;
}
node->fdName = new char[fdName.size() + 1];
if (strcpy_s(node->fdName, fdName.size() + 1, fdName.c_str()) != ERR_OK) {
TAG_LOGE(AAFwkTag::APPKIT, "strcpy_s failed.");
return args;
}
node->fd = fdValue;
if (!args.fdList.head) {
args.fdList.head = node;
} else {
tail->next = node;
}
tail = node;
}
return args;
}
bool NativeArgsChildProcess::LoadNativeLib(const std::shared_ptr<ChildProcessStartInfo> &info)
{
if (info == nullptr) {
TAG_LOGE(AAFwkTag::PROCESSMGR, "info is nullptr.");
return false;
}
TAG_LOGI(AAFwkTag::PROCESSMGR, "LoadNativeLib, moduleName:%{public}s, srcEntry:%{public}s, entryFunc:%{public}s",
info->moduleName.c_str(), info->srcEntry.c_str(), info->entryFunc.c_str());
if (nativeLibHandle_ != nullptr) {
TAG_LOGE(AAFwkTag::PROCESSMGR, "Native lib already loaded.");
return false;
}
if (info->moduleName.empty()) {
TAG_LOGE(AAFwkTag::PROCESSMGR, "ModuleName is empty");
return false;
}
Dl_namespace dlnsApp;
std::string appDlNameSpace = "moduleNs_" + info->moduleName;
int ret = dlns_get(appDlNameSpace.c_str(), &dlnsApp);
if (ret != 0) {
TAG_LOGE(AAFwkTag::PROCESSMGR, "Get app dlNamespace(%{private}s) failed, err:%{public}d",
appDlNameSpace.c_str(), ret);
return false;
}
void *libHandle = dlopen_ns(&dlnsApp, info->srcEntry.c_str(), RTLD_LAZY);
if (libHandle == nullptr) {
TAG_LOGE(AAFwkTag::PROCESSMGR, "Load lib file %{private}s failed, err %{public}s",
info->srcEntry.c_str(), dlerror());
return false;
}
auto entryFunc = reinterpret_cast<NativeArgsChildProcess_EntryFunc>(dlsym(libHandle, info->entryFunc.c_str()));
if (entryFunc == nullptr) {
TAG_LOGE(AAFwkTag::PROCESSMGR, "Get entryFunc address failed, err %{public}s", dlerror());
dlclose(libHandle);
return false;
}
entryFunc_ = entryFunc;
nativeLibHandle_ = libHandle;
return true;
}
void NativeArgsChildProcess::UnloadNativeLib()
{
if (nativeLibHandle_ != nullptr) {
dlclose(nativeLibHandle_);
nativeLibHandle_ = nullptr;
entryFunc_ = nullptr;
}
}
} // namespace AbilityRuntime
} // namespace OHOS
+1
View File
@@ -124,6 +124,7 @@ ohos_shared_library("appkit_native") {
"${ability_runtime_native_path}/appkit/app/extension_plugin_info.cpp",
"${ability_runtime_native_path}/appkit/app/idle_time.cpp",
"${ability_runtime_native_path}/appkit/app/main_thread.cpp",
"${ability_runtime_native_path}/appkit/app/native_lib_util.cpp",
"${ability_runtime_native_path}/appkit/app/ohos_application.cpp",
"${ability_runtime_native_path}/appkit/app_startup/js_startup_config.cpp",
"${ability_runtime_native_path}/appkit/app_startup/js_startup_task.cpp",
@@ -14,12 +14,16 @@
*/
#include "child_main_thread.h"
#include <unistd.h>
#include "bundle_mgr_helper.h"
#include "bundle_mgr_proxy.h"
#include "child_process_manager.h"
#include "constants.h"
#include "hilog_tag_wrapper.h"
#include "js_runtime.h"
#include "native_lib_util.h"
#include "sys_mgr_client.h"
#include "system_ability_definition.h"
@@ -108,6 +112,7 @@ bool ChildMainThread::Init(const std::shared_ptr<EventRunner> &runner, const Chi
return false;
}
processInfo_ = std::make_shared<ChildProcessInfo>(processInfo);
processArgs_->entryParams = processInfo.entryParams;
mainHandler_ = std::make_shared<EventHandler>(runner);
BundleInfo bundleInfo;
if (!ChildProcessManager::GetInstance().GetBundleInfo(bundleInfo)) {
@@ -141,9 +146,9 @@ bool ChildMainThread::Attach()
return true;
}
bool ChildMainThread::ScheduleLoadJs()
bool ChildMainThread::ScheduleLoadChild()
{
TAG_LOGI(AAFwkTag::APPKIT, "called");
TAG_LOGI(AAFwkTag::APPKIT, "ScheduleLoadChild called.");
if (mainHandler_ == nullptr) {
TAG_LOGE(AAFwkTag::APPKIT, "mainHandler_ is null");
return false;
@@ -157,17 +162,19 @@ bool ChildMainThread::ScheduleLoadJs()
auto task = [weak, childProcessType]() {
auto childMainThread = weak.promote();
if (childMainThread == nullptr) {
TAG_LOGE(AAFwkTag::APPKIT, "childMainThread is nullptr, ScheduleLoadJs failed");
TAG_LOGE(AAFwkTag::APPKIT, "childMainThread is nullptr, ScheduleLoadChild failed.");
return;
}
if (childProcessType == CHILD_PROCESS_TYPE_ARK) {
childMainThread->HandleLoadArkTs();
} else if (childProcessType == CHILD_PROCESS_TYPE_NATIVE_ARGS) {
childMainThread->HandleLoadNative();
} else {
childMainThread->HandleLoadJs();
}
};
if (!mainHandler_->PostTask(task, "ChildMainThread::HandleLoadJs")) {
TAG_LOGE(AAFwkTag::APPKIT, "PostTask task failed");
TAG_LOGE(AAFwkTag::APPKIT, "ChildMainThread::ScheduleLoadChild PostTask task failed.");
return false;
}
return true;
@@ -241,18 +248,43 @@ void ChildMainThread::HandleLoadArkTs()
processInfo_->processName.c_str(), processInfo_->isDebugApp, processInfo_->isStartWithNative);
runtime_->StartDebugMode(debugOption);
processArgs_->entryParams = processInfo_->entryParams;
childProcessManager.LoadJsFile(srcEntry, hapModuleInfo, runtime_, processArgs_);
}
void ChildMainThread::HandleLoadNative()
{
TAG_LOGD(AAFwkTag::APPKIT, "HandleLoadNative called.");
if (!processInfo_) {
TAG_LOGE(AAFwkTag::APPKIT, "processInfo_ is null.");
return;
}
if (!processArgs_) {
TAG_LOGE(AAFwkTag::APPKIT, "processArgs_ is nullptr.");
return;
}
ChildProcessManager &childProcessMgr = ChildProcessManager::GetInstance();
childProcessMgr.LoadNativeLibWithArgs(nativeLibModuleName_, processInfo_->srcEntry, processInfo_->entryFunc,
processArgs_);
TAG_LOGD(AAFwkTag::APPKIT, "HandleLoadNative end.");
ExitProcessSafely();
}
void ChildMainThread::InitNativeLib(const BundleInfo &bundleInfo)
{
HspList hspList;
ErrCode ret = DelayedSingleton<BundleMgrHelper>::GetInstance()->GetBaseSharedBundleInfos(bundleInfo.name, hspList,
AppExecFwk::GetDependentBundleInfoFlag::GET_ALL_DEPENDENT_BUNDLE_INFO);
if (ret != ERR_OK) {
TAG_LOGE(AAFwkTag::APPKIT, "Get base shared bundle infos failed: %{public}d", ret);
}
AppLibPathMap appLibPaths {};
GetNativeLibPath(bundleInfo, appLibPaths);
GetNativeLibPath(bundleInfo, hspList, appLibPaths);
bool isSystemApp = bundleInfo.applicationInfo.isSystemApp;
TAG_LOGD(AAFwkTag::APPKIT, "the application isSystemApp: %{public}d", isSystemApp);
if (processInfo_->childProcessType != CHILD_PROCESS_TYPE_NATIVE) {
if (processInfo_->childProcessType != CHILD_PROCESS_TYPE_NATIVE &&
processInfo_->childProcessType != CHILD_PROCESS_TYPE_NATIVE_ARGS) {
AbilityRuntime::JsRuntime::SetAppLibPath(appLibPaths, isSystemApp);
} else {
UpdateNativeChildLibModuleName(appLibPaths, isSystemApp);
@@ -363,7 +395,6 @@ void ChildMainThread::UpdateNativeChildLibModuleName(const AppLibPathMap &appLib
if (!nativeLibPath.empty() && nativeLibPath.back() != '/') {
nativeLibPath += '/';
}
nativeLibPath += processInfo_->srcEntry;
if (access(nativeLibPath.c_str(), F_OK) == 0) {
nativeLibModuleName_ = libPathPair.first;
@@ -378,7 +409,8 @@ void ChildMainThread::UpdateNativeChildLibModuleName(const AppLibPathMap &appLib
processInfo_->srcEntry.c_str());
}
void ChildMainThread::GetNativeLibPath(const BundleInfo &bundleInfo, AppLibPathMap &appLibPaths)
void ChildMainThread::GetNativeLibPath(const BundleInfo &bundleInfo, const HspList &hspList,
AppLibPathMap &appLibPaths)
{
std::string nativeLibraryPath = bundleInfo.applicationInfo.nativeLibraryPath;
if (!nativeLibraryPath.empty()) {
@@ -397,39 +429,12 @@ void ChildMainThread::GetNativeLibPath(const BundleInfo &bundleInfo, AppLibPathM
hapInfo.moduleName.c_str(), hapInfo.isLibIsolated, hapInfo.compressNativeLibs);
GetHapSoPath(hapInfo, appLibPaths, hapInfo.hapPath.find(ABS_CODE_PATH));
}
}
void ChildMainThread::GetHapSoPath(const HapModuleInfo &hapInfo, AppLibPathMap &appLibPaths, bool isPreInstallApp)
{
if (hapInfo.nativeLibraryPath.empty()) {
TAG_LOGD(AAFwkTag::APPKIT, "Lib path of %{public}s is empty, lib isn't isolated or compressed",
hapInfo.moduleName.c_str());
return;
for (auto &hspInfo : hspList) {
TAG_LOGD(AAFwkTag::APPKIT, "bundle:%s, module:%s, nativeLibraryPath:%s", hspInfo.bundleName.c_str(),
hspInfo.moduleName.c_str(), hspInfo.nativeLibraryPath.c_str());
GetHspNativeLibPath(hspInfo, appLibPaths, hspInfo.hapPath.find(ABS_CODE_PATH) != 0u);
}
std::string appLibPathKey = hapInfo.bundleName + "/" + hapInfo.moduleName;
std::string libPath = LOCAL_CODE_PATH;
if (!hapInfo.compressNativeLibs) {
TAG_LOGD(AAFwkTag::APPKIT, "Lib of %{public}s will not be extracted from hap", hapInfo.moduleName.c_str());
libPath = GetLibPath(hapInfo.hapPath, isPreInstallApp);
}
libPath += (libPath.back() == '/') ? hapInfo.nativeLibraryPath : "/" + hapInfo.nativeLibraryPath;
TAG_LOGI(
AAFwkTag::APPKIT, "appLibPathKey: %{private}s, lib path: %{private}s", appLibPathKey.c_str(), libPath.c_str());
appLibPaths[appLibPathKey].emplace_back(libPath);
}
std::string ChildMainThread::GetLibPath(const std::string &hapPath, bool isPreInstallApp)
{
std::string libPath = LOCAL_CODE_PATH;
if (isPreInstallApp) {
auto pos = hapPath.rfind("/");
if (pos != std::string::npos) {
libPath = hapPath.substr(0, pos);
}
}
return libPath;
}
} // namespace AppExecFwk
} // namespace OHOS
+1 -83
View File
@@ -74,6 +74,7 @@
#ifdef CJ_FRONTEND
#include "cj_runtime.h"
#endif
#include "native_lib_util.h"
#include "nlohmann/json.hpp"
#include "ohos_application.h"
#include "overlay_module_info.h"
@@ -166,89 +167,6 @@ const int32_t TYPE_RESERVE = 1;
const int32_t TYPE_OTHERS = 2;
extern "C" int DFX_SetAppRunningUniqueId(const char* appRunningId, size_t len) __attribute__((weak));
std::string GetLibPath(const std::string &hapPath, bool isPreInstallApp)
{
std::string libPath = LOCAL_CODE_PATH;
if (isPreInstallApp) {
auto pos = hapPath.rfind("/");
libPath = hapPath.substr(0, pos);
}
return libPath;
}
void GetHapSoPath(const HapModuleInfo &hapInfo, AppLibPathMap &appLibPaths, bool isPreInstallApp)
{
if (hapInfo.nativeLibraryPath.empty()) {
TAG_LOGD(AAFwkTag::APPKIT, "Lib path of %{public}s is empty, lib isn't isolated or compressed",
hapInfo.moduleName.c_str());
return;
}
std::string appLibPathKey = hapInfo.bundleName + "/" + hapInfo.moduleName;
std::string libPath = LOCAL_CODE_PATH;
if (!hapInfo.compressNativeLibs) {
TAG_LOGD(AAFwkTag::APPKIT, "Lib of %{public}s will not be extracted from hap", hapInfo.moduleName.c_str());
libPath = GetLibPath(hapInfo.hapPath, isPreInstallApp);
}
libPath += (libPath.back() == '/') ? hapInfo.nativeLibraryPath : "/" + hapInfo.nativeLibraryPath;
TAG_LOGD(
AAFwkTag::APPKIT, "appLibPathKey: %{private}s, lib path: %{private}s", appLibPathKey.c_str(), libPath.c_str());
appLibPaths[appLibPathKey].emplace_back(libPath);
}
void GetHspNativeLibPath(const BaseSharedBundleInfo &hspInfo, AppLibPathMap &appLibPaths, bool isPreInstallApp)
{
if (hspInfo.nativeLibraryPath.empty()) {
return;
}
std::string appLibPathKey = hspInfo.bundleName + "/" + hspInfo.moduleName;
std::string libPath = LOCAL_CODE_PATH;
if (!hspInfo.compressNativeLibs) {
libPath = GetLibPath(hspInfo.hapPath, isPreInstallApp);
libPath = libPath.back() == '/' ? libPath : libPath + "/";
if (isPreInstallApp) {
libPath += hspInfo.nativeLibraryPath;
} else {
libPath += hspInfo.bundleName + "/" + hspInfo.moduleName + "/" + hspInfo.nativeLibraryPath;
}
} else {
libPath = libPath.back() == '/' ? libPath : libPath + "/";
libPath += hspInfo.bundleName + "/" + hspInfo.nativeLibraryPath;
}
TAG_LOGD(
AAFwkTag::APPKIT, "appLibPathKey: %{private}s, libPath: %{private}s", appLibPathKey.c_str(), libPath.c_str());
appLibPaths[appLibPathKey].emplace_back(libPath);
}
void GetPatchNativeLibPath(const HapModuleInfo &hapInfo, std::string &patchNativeLibraryPath,
AppLibPathMap &appLibPaths)
{
if (hapInfo.isLibIsolated) {
patchNativeLibraryPath = hapInfo.hqfInfo.nativeLibraryPath;
}
if (patchNativeLibraryPath.empty()) {
TAG_LOGD(AAFwkTag::APPKIT, "Patch lib path of %{public}s is empty", hapInfo.moduleName.c_str());
return;
}
if (hapInfo.compressNativeLibs && !hapInfo.isLibIsolated) {
TAG_LOGD(AAFwkTag::APPKIT, "Lib of %{public}s has compressed and isn't isolated, no need to set",
hapInfo.moduleName.c_str());
return;
}
std::string appLibPathKey = hapInfo.bundleName + "/" + hapInfo.moduleName;
std::string patchLibPath = LOCAL_CODE_PATH;
patchLibPath += (patchLibPath.back() == '/') ? patchNativeLibraryPath : "/" + patchNativeLibraryPath;
TAG_LOGD(AAFwkTag::APPKIT, "appLibPathKey: %{public}s, patch lib path: %{private}s", appLibPathKey.c_str(),
patchLibPath.c_str());
appLibPaths[appLibPathKey].emplace_back(patchLibPath);
}
} // namespace
void MainThread::GetNativeLibPath(const BundleInfo &bundleInfo, const HspList &hspList, AppLibPathMap &appLibPaths)
@@ -0,0 +1,106 @@
/*
* Copyright (c) 2024 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 "native_lib_util.h"
#include "constants.h"
#include "hilog_tag_wrapper.h"
namespace OHOS {
namespace AppExecFwk {
std::string GetLibPath(const std::string &hapPath, bool isPreInstallApp)
{
std::string libPath = AbilityBase::Constants::LOCAL_CODE_PATH;
if (isPreInstallApp) {
auto pos = hapPath.rfind("/");
libPath = hapPath.substr(0, pos);
}
return libPath;
}
void GetHapSoPath(const HapModuleInfo &hapInfo, AppLibPathMap &appLibPaths, bool isPreInstallApp)
{
if (hapInfo.nativeLibraryPath.empty()) {
TAG_LOGD(AAFwkTag::APPKIT, "Lib path of %{public}s is empty, lib isn't isolated or compressed",
hapInfo.moduleName.c_str());
return;
}
std::string appLibPathKey = hapInfo.bundleName + "/" + hapInfo.moduleName;
std::string libPath = AbilityBase::Constants::LOCAL_CODE_PATH;
if (!hapInfo.compressNativeLibs) {
TAG_LOGD(AAFwkTag::APPKIT, "Lib of %{public}s will not be extracted from hap", hapInfo.moduleName.c_str());
libPath = GetLibPath(hapInfo.hapPath, isPreInstallApp);
}
libPath += (libPath.back() == '/') ? hapInfo.nativeLibraryPath : "/" + hapInfo.nativeLibraryPath;
TAG_LOGD(
AAFwkTag::APPKIT, "appLibPathKey: %{private}s, lib path: %{private}s", appLibPathKey.c_str(), libPath.c_str());
appLibPaths[appLibPathKey].emplace_back(libPath);
}
void GetHspNativeLibPath(const BaseSharedBundleInfo &hspInfo, AppLibPathMap &appLibPaths, bool isPreInstallApp)
{
if (hspInfo.nativeLibraryPath.empty()) {
return;
}
std::string appLibPathKey = hspInfo.bundleName + "/" + hspInfo.moduleName;
std::string libPath = AbilityBase::Constants::LOCAL_CODE_PATH;
if (!hspInfo.compressNativeLibs) {
libPath = GetLibPath(hspInfo.hapPath, isPreInstallApp);
libPath = libPath.back() == '/' ? libPath : libPath + "/";
if (isPreInstallApp) {
libPath += hspInfo.nativeLibraryPath;
} else {
libPath += hspInfo.bundleName + "/" + hspInfo.moduleName + "/" + hspInfo.nativeLibraryPath;
}
} else {
libPath = libPath.back() == '/' ? libPath : libPath + "/";
libPath += hspInfo.bundleName + "/" + hspInfo.nativeLibraryPath;
}
TAG_LOGD(
AAFwkTag::APPKIT, "appLibPathKey: %{private}s, libPath: %{private}s", appLibPathKey.c_str(), libPath.c_str());
appLibPaths[appLibPathKey].emplace_back(libPath);
}
void GetPatchNativeLibPath(const HapModuleInfo &hapInfo, std::string &patchNativeLibraryPath,
AppLibPathMap &appLibPaths)
{
if (hapInfo.isLibIsolated) {
patchNativeLibraryPath = hapInfo.hqfInfo.nativeLibraryPath;
}
if (patchNativeLibraryPath.empty()) {
TAG_LOGD(AAFwkTag::APPKIT, "Patch lib path of %{public}s is empty", hapInfo.moduleName.c_str());
return;
}
if (hapInfo.compressNativeLibs && !hapInfo.isLibIsolated) {
TAG_LOGD(AAFwkTag::APPKIT, "Lib of %{public}s has compressed and isn't isolated, no need to set",
hapInfo.moduleName.c_str());
return;
}
std::string appLibPathKey = hapInfo.bundleName + "/" + hapInfo.moduleName;
std::string patchLibPath = AbilityBase::Constants::LOCAL_CODE_PATH;
patchLibPath += (patchLibPath.back() == '/') ? patchNativeLibraryPath : "/" + patchNativeLibraryPath;
TAG_LOGD(AAFwkTag::APPKIT, "appLibPathKey: %{public}s, patch lib path: %{private}s", appLibPathKey.c_str(),
patchLibPath.c_str());
appLibPaths[appLibPathKey].emplace_back(patchLibPath);
}
} // AppExecFwk
} // namespace OHOS
@@ -28,20 +28,24 @@ namespace {
std::mutex g_mutexCallBackObj;
sptr<IRemoteObject> g_CallbackStub;
OH_Ability_OnNativeChildProcessStarted g_Callback = nullptr;
constexpr size_t MAX_KEY_SIZE = 20;
constexpr size_t MAX_FD_SIZE = 16;
const std::map<ChildProcessManagerErrorCode, Ability_NativeChildProcess_ErrCode> CPM_ERRCODE_MAP = {
{ ChildProcessManagerErrorCode::ERR_OK, NCP_NO_ERROR },
{ ChildProcessManagerErrorCode::ERR_PERMISSION_DENIED, NCP_ERR_NO_PERMISSION },
{ ChildProcessManagerErrorCode::ERR_MULTI_PROCESS_MODEL_DISABLED, NCP_ERR_MULTI_PROCESS_DISABLED },
{ ChildProcessManagerErrorCode::ERR_ALREADY_IN_CHILD_PROCESS, NCP_ERR_ALREADY_IN_CHILD },
{ ChildProcessManagerErrorCode::ERR_GET_APP_MGR_FAILED, NCP_ERR_SERVICE_ERROR },
{ ChildProcessManagerErrorCode::ERR_GET_APP_MGR_START_PROCESS_FAILED, NCP_ERR_SERVICE_ERROR },
{ ChildProcessManagerErrorCode::ERR_APP_MGR_FAILED_INNER, NCP_ERR_SERVICE_ERROR },
{ ChildProcessManagerErrorCode::ERR_UNSUPPORT_NATIVE_CHILD_PROCESS, NCP_ERR_NOT_SUPPORTED },
{ ChildProcessManagerErrorCode::ERR_MAX_NATIVE_CHILD_PROCESSES, NCP_ERR_MAX_CHILD_PROCESSES_REACHED },
{ ChildProcessManagerErrorCode::ERR_LIB_LOADING_FAILED, NCP_ERR_LIB_LOADING_FAILED },
{ ChildProcessManagerErrorCode::ERR_CONNECTION_FAILED, NCP_ERR_CONNECTION_FAILED },
{ ChildProcessManagerErrorCode::ERR_MULTI_PROCESS_MODEL_DISABLED_NEW, NCP_ERR_NOT_SUPPORTED },
};
int CvtChildProcessManagerErrCode(ChildProcessManagerErrorCode cpmErr)
Ability_NativeChildProcess_ErrCode CvtChildProcessManagerErrCode(ChildProcessManagerErrorCode cpmErr)
{
auto it = CPM_ERRCODE_MAP.find(cpmErr);
if (it == CPM_ERRCODE_MAP.end()) {
@@ -101,3 +105,56 @@ int OH_Ability_CreateNativeChildProcess(const char* libName, OH_Ability_OnNative
g_CallbackStub = callbackStub;
return NCP_NO_ERROR;
}
Ability_NativeChildProcess_ErrCode OH_Ability_StartNativeChildProcess(const char* entry,
NativeChildProcess_Args args, NativeChildProcess_Options options, int32_t &pid)
{
if (entry == nullptr || *entry == '\0') {
TAG_LOGE(AAFwkTag::PROCESSMGR, "Invalid entry");
return NCP_ERR_INVALID_PARAM;
}
std::string entryName(entry);
if (entryName.find(":") != std::string::npos) {
TAG_LOGE(AAFwkTag::PROCESSMGR, "entry point misses a colon");
return NCP_ERR_INVALID_PARAM;
}
if (args.entryParams == nullptr || *(args.entryParams) == '\0') {
TAG_LOGE(AAFwkTag::PROCESSMGR, "Invalid args.entryParams");
return NCP_ERR_INVALID_PARAM;
}
std::string entryParams(args.entryParams);
std::map<std::string, int32_t> fds;
NativeChildProcess_Fd* cur = args.fdList.head;
while (cur != nullptr) {
std::string key(cur->fdName);
if (key.size() > MAX_KEY_SIZE) {
TAG_LOGE(AAFwkTag::PROCESSMGR, "fd name too long");
return NCP_ERR_INVALID_PARAM;
}
fds.emplace(key, cur->fd);
cur = cur->next;
}
if (fds.size() > MAX_FD_SIZE) {
TAG_LOGE(AAFwkTag::PROCESSMGR, "too many fds");
return NCP_ERR_INVALID_PARAM;
}
AppExecFwk::ChildProcessArgs childArgs;
childArgs.entryParams = entryParams;
childArgs.fds = fds;
AppExecFwk::ChildProcessOptions childProcessOptions;
childProcessOptions.isolationMode = options.isolationMode == NCP_ISOLATION_MODE_ISOLATED;
int32_t childProcessType = AppExecFwk::CHILD_PROCESS_TYPE_NATIVE_ARGS;
ChildProcessManager &mgr = ChildProcessManager::GetInstance();
auto cpmErr = mgr.StartChildProcessWithArgs(entryName, pid, childProcessType, childArgs, childProcessOptions);
if (cpmErr != ChildProcessManagerErrorCode::ERR_OK) {
return CvtChildProcessManagerErrCode(cpmErr);
}
return NCP_NO_ERROR;
}
@@ -575,6 +575,21 @@ enum {
*/
ERR_KILL_FOUNDATION_UID = 2097261,
/*
* Result (2097264) for not support child process.
*/
ERR_NOT_SUPPORT_CHILD_PROCESS = 2097264,
/*
* Result (2097265) for already in child process.
*/
ERR_ALREADY_IN_CHILD_PROCESS = 2097265,
/*
* Result (2097266) for native args child process reach limit.
*/
ERR_NATIVE_ARGS_CHILD_PROCESS_REACH_LIMIT = 2097266,
/**
* Native error(3000000) for target bundle not exist.
*/
@@ -27,6 +27,7 @@ constexpr int32_t CHILD_PROCESS_TYPE_NOT_CHILD = -1;
constexpr int32_t CHILD_PROCESS_TYPE_JS = 0;
constexpr int32_t CHILD_PROCESS_TYPE_NATIVE = 1;
constexpr int32_t CHILD_PROCESS_TYPE_ARK = 2;
constexpr int32_t CHILD_PROCESS_TYPE_NATIVE_ARGS = 3;
struct ChildProcessInfo : public Parcelable {
int32_t pid = 0;
@@ -36,6 +37,7 @@ struct ChildProcessInfo : public Parcelable {
std::string bundleName;
std::string processName;
std::string srcEntry;
std::string entryFunc;
std::string entryParams;
bool jitEnabled = false;
bool isDebugApp = true;
@@ -27,7 +27,7 @@ public:
/**
* Notify chile process to load js file.
*/
virtual bool ScheduleLoadJs() = 0;
virtual bool ScheduleLoadChild() = 0;
/**
* Notify chile process to exit safely.
@@ -27,7 +27,7 @@ public:
explicit ChildSchedulerProxy(const sptr<IRemoteObject> &impl);
virtual ~ChildSchedulerProxy() = default;
bool ScheduleLoadJs() override;
bool ScheduleLoadChild() override;
bool ScheduleExitProcessSafely() override;
bool ScheduleRunNativeProc(const sptr<IRemoteObject> &mainProcessCb) override;
@@ -34,7 +34,7 @@ public:
uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override;
private:
int32_t HandleScheduleLoadJs(MessageParcel &data, MessageParcel &reply);
int32_t HandleScheduleLoadChild(MessageParcel &data, MessageParcel &reply);
int32_t HandleScheduleExitProcessSafely(MessageParcel &data, MessageParcel &reply);
int32_t HandleScheduleRunNativeProc(MessageParcel &data, MessageParcel &reply);
@@ -66,6 +66,7 @@ struct ProcessData : public Parcelable {
bool isTestMode = false; // Indicates whether the process is started by aa test
int32_t exitReason = 0;
std::string exitMsg = "";
int32_t childUid = -1;
};
} // namespace AppExecFwk
} // namespace OHOS
@@ -41,6 +41,7 @@ bool ChildProcessInfo::ReadFromParcel(Parcel &parcel)
bundleName = Str16ToStr8(parcel.ReadString16());
processName = Str16ToStr8(parcel.ReadString16());
srcEntry = Str16ToStr8(parcel.ReadString16());
entryFunc = Str16ToStr8(parcel.ReadString16());
entryParams = Str16ToStr8(parcel.ReadString16());
jitEnabled = parcel.ReadBool();
isDebugApp = parcel.ReadBool();
@@ -70,6 +71,7 @@ bool ChildProcessInfo::Marshalling(Parcel &parcel) const
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(bundleName));
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(processName));
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(srcEntry));
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(entryFunc));
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(entryParams));
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Bool, parcel, jitEnabled);
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Bool, parcel, isDebugApp);
@@ -32,9 +32,9 @@ bool ChildSchedulerProxy::WriteInterfaceToken(MessageParcel &data)
return true;
}
bool ChildSchedulerProxy::ScheduleLoadJs()
bool ChildSchedulerProxy::ScheduleLoadChild()
{
TAG_LOGD(AAFwkTag::APPMGR, "ScheduleLoadJs start");
TAG_LOGD(AAFwkTag::APPMGR, "ScheduleLoadChild start");
MessageParcel data;
MessageParcel reply;
MessageOption option(MessageOption::TF_ASYNC);
@@ -54,7 +54,7 @@ bool ChildSchedulerProxy::ScheduleLoadJs()
TAG_LOGW(AAFwkTag::APPMGR, "SendRequest is failed, error code: %{public}d", ret);
return false;
}
TAG_LOGD(AAFwkTag::APPMGR, "ScheduleLoadJs end");
TAG_LOGD(AAFwkTag::APPMGR, "ScheduleLoadChild end");
return true;
}
@@ -38,7 +38,7 @@ int32_t ChildSchedulerStub::OnRemoteRequest(uint32_t code, MessageParcel &data,
switch (code) {
case static_cast<uint32_t>(IChildScheduler::Message::SCHEDULE_LOAD_JS):
return HandleScheduleLoadJs(data, reply);
return HandleScheduleLoadChild(data, reply);
case static_cast<uint32_t>(IChildScheduler::Message::SCHEDULE_EXIT_PROCESS_SAFELY):
return HandleScheduleExitProcessSafely(data, reply);
case static_cast<uint32_t>(IChildScheduler::Message::SCHEDULE_RUN_NATIVE_PROC):
@@ -48,9 +48,9 @@ int32_t ChildSchedulerStub::OnRemoteRequest(uint32_t code, MessageParcel &data,
return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
}
int32_t ChildSchedulerStub::HandleScheduleLoadJs(MessageParcel &data, MessageParcel &reply)
int32_t ChildSchedulerStub::HandleScheduleLoadChild(MessageParcel &data, MessageParcel &reply)
{
ScheduleLoadJs();
ScheduleLoadChild();
return ERR_NONE;
}
@@ -30,7 +30,8 @@ bool ProcessData::Marshalling(Parcel &parcel) const
parcel.WriteInt32(processChangeReason) && parcel.WriteString(processName) &&
parcel.WriteInt32(static_cast<int32_t>(processType)) && parcel.WriteInt32(static_cast<int32_t>(extensionType))
&& parcel.WriteInt32(renderUid) && parcel.WriteUint32(accessTokenId) &&
parcel.WriteBool(isTestMode) && parcel.WriteInt32(exitReason) && parcel.WriteString16(Str8ToStr16(exitMsg)));
parcel.WriteBool(isTestMode) && parcel.WriteInt32(exitReason) && parcel.WriteString16(Str8ToStr16(exitMsg)) &&
parcel.WriteInt32(childUid));
}
bool ProcessData::ReadFromParcel(Parcel &parcel)
@@ -54,6 +55,7 @@ bool ProcessData::ReadFromParcel(Parcel &parcel)
isTestMode = parcel.ReadBool();
exitReason = parcel.ReadInt32();
exitMsg = Str16ToStr8(parcel.ReadString16());
childUid = parcel.ReadInt32();
return true;
}
@@ -16,7 +16,10 @@ import("//foundation/ability/ability_runtime/ability_runtime.gni")
config("child_process_manager_config") {
visibility = [ ":*" ]
include_dirs = [ "include" ]
include_dirs = [
"${ability_runtime_ndk_path}/ability/ability_runtime/child_process",
"include",
]
if (target_cpu == "arm") {
cflags = [ "-DBINDER_IPC_32BIT" ]
@@ -32,6 +35,7 @@ ohos_shared_library("child_process_manager") {
"${ability_runtime_native_path}/ability/native/child_process_manager/child_process_manager.cpp",
"${ability_runtime_native_path}/ability/native/child_process_manager/child_process_manager_error_utils.cpp",
"${ability_runtime_native_path}/ability/native/child_process_manager/js_child_process.cpp",
"${ability_runtime_native_path}/ability/native/child_process_manager/native_args_child_process.cpp",
"${ability_runtime_native_path}/ability/native/child_process_manager/native_child_ipc_process.cpp",
]
@@ -39,10 +39,12 @@ public:
static void HandleSigChild(int32_t signo);
bool IsChildProcess();
bool IsChildProcessBySelfFork();
ChildProcessManagerErrorCode StartChildProcessBySelfFork(const std::string &srcEntry, pid_t &pid);
ChildProcessManagerErrorCode StartChildProcessByAppSpawnFork(const std::string &srcEntry, pid_t &pid);
ChildProcessManagerErrorCode StartArkChildProcess(const std::string &srcEntry, pid_t &pid, int32_t childProcessType,
const AppExecFwk::ChildProcessArgs &args, const AppExecFwk::ChildProcessOptions &options);
ChildProcessManagerErrorCode StartChildProcessWithArgs(const std::string &srcEntry, pid_t &pid,
int32_t childProcessType, const AppExecFwk::ChildProcessArgs &args,
const AppExecFwk::ChildProcessOptions &options);
ChildProcessManagerErrorCode StartNativeChildProcessByAppSpawnFork(
const std::string &libName, const sptr<IRemoteObject> &callbackStub);
bool GetBundleInfo(AppExecFwk::BundleInfo &bundleInfo);
@@ -56,6 +58,8 @@ public:
std::shared_ptr<AppExecFwk::ChildProcessArgs> args = nullptr);
bool LoadNativeLib(const std::string &moduleName, const std::string &libPath,
const sptr<IRemoteObject> &mainProcessCb);
bool LoadNativeLibWithArgs(const std::string &moduleName, const std::string &srcEntry,
const std::string &entryFunc, std::shared_ptr<AppExecFwk::ChildProcessArgs> args);
void SetForkProcessJITEnabled(bool jitEnabled);
void SetForkProcessDebugOption(const std::string bundleName, const bool isStartWithDebug, const bool isDebugApp,
const bool isStartWithNative);
@@ -66,7 +70,8 @@ public:
private:
ChildProcessManager();
ChildProcessManagerErrorCode PreCheck(bool useNewErrorCode = false);
ChildProcessManagerErrorCode PreCheck();
ChildProcessManagerErrorCode PreCheck(int32_t childProcessType);
ChildProcessManagerErrorCode PreCheckNativeProcess();
void RegisterSignal();
void HandleChildProcessBySelfFork(const std::string &srcEntry, const AppExecFwk::BundleInfo &bundleInfo);
@@ -19,6 +19,7 @@
#include <map>
#include "ability_business_error.h"
#include "ability_manager_errors.h"
namespace OHOS {
namespace AbilityRuntime {
@@ -30,13 +31,14 @@ enum class ChildProcessManagerErrorCode {
ERR_FORK_FAILED = 4,
ERR_GET_BUNDLE_INFO_FAILED = 5,
ERR_GET_APP_MGR_FAILED = 6,
ERR_GET_APP_MGR_START_PROCESS_FAILED = 7,
ERR_APP_MGR_FAILED_INNER = 7,
ERR_UNSUPPORT_NATIVE_CHILD_PROCESS = 8,
ERR_MAX_NATIVE_CHILD_PROCESSES = 9,
ERR_LIB_LOADING_FAILED = 10,
ERR_CONNECTION_FAILED = 11,
ERR_UNSUPPORTED_START_MODE = 12,
ERR_MULTI_PROCESS_MODEL_DISABLED_NEW = 13,
ERR_PERMISSION_DENIED = 14,
};
const std::map<ChildProcessManagerErrorCode, AbilityErrorCode> INTERNAL_ERR_CODE_MAP = {
@@ -49,15 +51,26 @@ const std::map<ChildProcessManagerErrorCode, AbilityErrorCode> INTERNAL_ERR_CODE
{ ChildProcessManagerErrorCode::ERR_FORK_FAILED, AbilityErrorCode::ERROR_CODE_INNER },
{ ChildProcessManagerErrorCode::ERR_GET_BUNDLE_INFO_FAILED, AbilityErrorCode::ERROR_CODE_INNER },
{ ChildProcessManagerErrorCode::ERR_GET_APP_MGR_FAILED, AbilityErrorCode::ERROR_CODE_INNER },
{ ChildProcessManagerErrorCode::ERR_GET_APP_MGR_START_PROCESS_FAILED, AbilityErrorCode::ERROR_CODE_INNER },
{ ChildProcessManagerErrorCode::ERR_APP_MGR_FAILED_INNER, AbilityErrorCode::ERROR_CODE_INNER },
{ ChildProcessManagerErrorCode::ERR_UNSUPPORTED_START_MODE, AbilityErrorCode::ERROR_CODE_INVALID_PARAM },
{ ChildProcessManagerErrorCode::ERR_MULTI_PROCESS_MODEL_DISABLED_NEW,
AbilityErrorCode::ERROR_CODE_CAPABILITY_NOT_SUPPORT },
{ ChildProcessManagerErrorCode::ERR_MAX_NATIVE_CHILD_PROCESSES,
AbilityErrorCode::ERROR_CODE_CHILD_PROCESS_NUMBER_EXCEEDS_UPPER_BOUND },
{ ChildProcessManagerErrorCode::ERR_PERMISSION_DENIED, AbilityErrorCode::ERROR_CODE_PERMISSION_DENIED },
};
const std::map<int32_t, ChildProcessManagerErrorCode> ABILITY_MANAGER_ERR_CODE_MAP = {
{ ERR_PERMISSION_DENIED, ChildProcessManagerErrorCode::ERR_PERMISSION_DENIED },
{ AAFwk::ERR_NOT_SUPPORT_CHILD_PROCESS, ChildProcessManagerErrorCode::ERR_MULTI_PROCESS_MODEL_DISABLED_NEW },
{ AAFwk::ERR_ALREADY_IN_CHILD_PROCESS, ChildProcessManagerErrorCode::ERR_ALREADY_IN_CHILD_PROCESS },
{ AAFwk::ERR_NATIVE_ARGS_CHILD_PROCESS_REACH_LIMIT, ChildProcessManagerErrorCode::ERR_MAX_NATIVE_CHILD_PROCESSES },
};
class ChildProcessManagerErrorUtil {
public:
static AbilityErrorCode GetAbilityErrorCode(const ChildProcessManagerErrorCode &internalErrCode);
static ChildProcessManagerErrorCode GetChildProcessManagerErrorCode(int32_t abilityManagerErrorCode);
};
} // namespace AbilityRuntime
} // namespace OHOS
@@ -26,6 +26,7 @@ struct ChildProcessStartInfo {
std::string moduleName;
std::string srcEntry;
std::string hapPath;
std::string entryFunc;
bool isEsModule = true;
sptr<IRemoteObject> ipcObj;
};
@@ -0,0 +1,50 @@
/*
* Copyright (c) 2024 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 OHOS_ABILITY_RUNTIME_NATIVE_ARGS_CHILD_PROCESS_H
#define OHOS_ABILITY_RUNTIME_NATIVE_ARGS_CHILD_PROCESS_H
#include <memory>
#include <string>
#include "child_process.h"
#include "native_child_process.h"
namespace OHOS {
namespace AbilityRuntime {
class NativeArgsChildProcess : public ChildProcess {
public:
NativeArgsChildProcess() = default;
~NativeArgsChildProcess();
static std::shared_ptr<ChildProcess> Create();
bool Init(const std::shared_ptr<ChildProcessStartInfo> &info) override;
void OnStart(std::shared_ptr<AppExecFwk::ChildProcessArgs> args) override;
private:
bool LoadNativeLib(const std::shared_ptr<ChildProcessStartInfo> &info);
void UnloadNativeLib();
NativeChildProcess_Args ParseToNativeArgs(const std::string &entryParams,
const std::map<std::string, int32_t> &fds);
typedef void (*NativeArgsChildProcess_EntryFunc)(NativeChildProcess_Args args);
void *nativeLibHandle_ = nullptr;
NativeArgsChildProcess_EntryFunc entryFunc_ = nullptr;
};
} // namespace AbilityRuntime
} // namespace OHOS
#endif // OHOS_ABILITY_RUNTIME_NATIVE_ARGS_CHILD_PROCESS_H
@@ -53,6 +53,11 @@ typedef enum Ability_NativeChildProcess_ErrCode {
*/
NCP_NO_ERROR = 0,
/**
* @error Operation not permitted.
*/
NCP_ERR_NO_PERMISSION = 201,
/**
* @error Invalid parameter.
*/
@@ -172,7 +177,101 @@ typedef void (*OH_Ability_OnNativeChildProcessStarted)(int errCode, OHIPCRemoteP
int OH_Ability_CreateNativeChildProcess(const char* libName,
OH_Ability_OnNativeChildProcessStarted onProcessStarted);
/**
* @brief The info of the file descriptors passed to child process.
* @since 12
*/
typedef struct NativeChildProcess_Fd {
/** the key of the file descriptor. */
char* fdName;
/** the value of the file descriptor. */
int32_t fd;
/** the next pointer of the linked list. */
struct NativeChildProcess_Fd* next;
} NativeChildProcess_Fd;
/**
* @brief The list of the info of the file descriptors passed to child process.
* @since 12
*/
typedef struct NativeChildProcess_FdList {
/** the head of the list.
* For details, see {@link NativeChildProcess_Fd}.
*/
struct NativeChildProcess_Fd* head;
} NativeChildProcess_FdList;
/**
* @brief Enumerates the isolation modes used by the native child process module.
* @since 12
*/
typedef enum NativeChildProcess_IsolationMode {
/**
* Normal isolation mode, parent process shares the same sandbox or internet with the child process.
*/
NCP_ISOLATION_MODE_NORMAL = 0,
/**
* Isolated mode, parent process does not share the same sandbox or internet with the child process.
*/
NCP_ISOLATION_MODE_ISOLATED = 1,
} NativeChildProcess_IsolationMode;
/**
* @brief The options used by the child process.
* @since 12
*/
typedef struct NativeChildProcess_Options {
/** the isolation mode used by the child process.
* For details, see {@link NativeChildProcess_IsolationMode}.
*/
NativeChildProcess_IsolationMode isolationMode;
/** reserved field for future extension purposes */
int64_t reserved;
} NativeChildProcess_Options;
/**
* @brief The arguments passed to the child process.
* @since 12
*/
typedef struct NativeChildProcess_Args {
/** the entry parameter. */
char* entryParams;
/** the list of the info of the file descriptors passed to child process.
* For details, see {@link NativeChildProcess_FdList}.
*/
struct NativeChildProcess_FdList fdList;
} NativeChildProcess_Args;
/**
* @brief Starts a child process, loads the specified dynamic library file.
*
* @permission {@code ohos.permission.START_NATIVE_CHILD_PROCESS}
* @param entry Name of the entry of the dynamic library file loaded in the child process. The value cannot be nullptr.
* @param args The arguments passed to the child process.
* For details, see {@link NativeChildProcess_Args}.
* @param options The child process options.
* For details, see {@link NativeChildProcess_Options}.
* @param pid The started child process id.
* @return Returns {@link NCP_NO_ERROR} if the call is successful.\n
* Returns {@link NCP_ERR_NO_PERMISSION} if the operation is not permitted.
* The permission {@code ohos.permission.START_NATIVE_CHILD_PROCESS} is needed.\n
* Returns {@link NCP_ERR_INVALID_PARAM} if the dynamic library name or callback function pointer is invalid.\n
* Returns {@link NCP_ERR_NOT_SUPPORTED} if the device does not support the creation of native child processes.\n
* Returns {@link NCP_ERR_ALREADY_IN_CHILD} if it is not allowed to create another child process in the child process.\n
* Returns {@link NCP_ERR_MAX_CHILD_PROCESSES_REACHED} if the maximum number of native child processes is reached.\n
* For details, see {@link Ability_NativeChildProcess_ErrCode}.
* @see OH_Ability_OnNativeChildProcessStarted
* @since 12
*/
Ability_NativeChildProcess_ErrCode OH_Ability_StartNativeChildProcess(
const char* entry, NativeChildProcess_Args args,
NativeChildProcess_Options options, int32_t &pid);
#ifdef __cplusplus
} // extern "C"
#endif
@@ -21,6 +21,7 @@
#include <memory>
#include "app_mgr_interface.h"
#include "base_shared_bundle_info.h"
#include "bundle_info.h"
#include "bundle_mgr_interface.h"
#include "child_scheduler_interface.h"
@@ -32,13 +33,14 @@
namespace OHOS {
namespace AppExecFwk {
using HspList = std::vector<BaseSharedBundleInfo>;
class ChildMainThread : public ChildSchedulerStub {
DECLARE_DELAYED_IPCSINGLETON(ChildMainThread);
public:
static void Start(const std::map<std::string, int32_t> &fds);
void SetFds(const std::map<std::string, int32_t> &fds);
bool ScheduleLoadJs() override;
bool ScheduleLoadChild() override;
bool ScheduleExitProcessSafely() override;
bool ScheduleRunNativeProc(const sptr<IRemoteObject> &mainProcessCb) override;
@@ -48,14 +50,13 @@ private:
bool Attach();
void HandleLoadJs();
void HandleLoadArkTs();
void HandleLoadNative();
void InitNativeLib(const BundleInfo &bundleInfo);
void HandleExitProcessSafely();
void ExitProcessSafely();
void GetNativeLibPath(const BundleInfo &bundleInfo, AppLibPathMap &appLibPaths);
void GetHapSoPath(const HapModuleInfo &hapInfo, AppLibPathMap &appLibPaths, bool isPreInstallApp);
void GetNativeLibPath(const BundleInfo &bundleInfo, const HspList &hspList, AppLibPathMap &appLibPaths);
void HandleRunNativeProc(const sptr<IRemoteObject> &mainProcessCb);
void UpdateNativeChildLibModuleName(const AppLibPathMap &appLibPaths, bool isSystemApp);
std::string GetLibPath(const std::string &hapPath, bool isPreInstallApp);
sptr<IAppMgr> appMgr_ = nullptr;
std::shared_ptr<EventHandler> mainHandler_ = nullptr;
@@ -0,0 +1,37 @@
/*
* Copyright (c) 2024 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 OHOS_ABILITY_RUNTIME_NATIVE_LIB_UTIL_H
#define OHOS_ABILITY_RUNTIME_NATIVE_LIB_UTIL_H
#include <string>
#include "base_shared_bundle_info.h"
#include "hap_module_info.h"
#include "js_runtime.h"
namespace OHOS {
namespace AppExecFwk {
std::string GetLibPath(const std::string &hapPath, bool isPreInstallApp);
void GetHapSoPath(const HapModuleInfo &hapInfo, AppLibPathMap &appLibPaths, bool isPreInstallApp);
void GetHspNativeLibPath(const BaseSharedBundleInfo &hspInfo, AppLibPathMap &appLibPaths, bool isPreInstallApp);
void GetPatchNativeLibPath(const HapModuleInfo &hapInfo, std::string &patchNativeLibraryPath,
AppLibPathMap &appLibPaths);
} // namespace AppExecFwk
} // namespace OHOS
#endif // OHOS_ABILITY_RUNTIME_NATIVE_LIB_UTIL_H
+2 -1
View File
@@ -36,4 +36,5 @@ persist.sys.abilityms.prevent_startability = true
const.abilityms.launch_embeded_ui_ability = false
const.sys.abilityms.limit_maximum_extensions_of_per_process = 10
const.sys.abilityms.limit_maximum_extensions_of_per_device = 100
const.sys.abilityms.cache_extension = 260
const.sys.abilityms.cache_extension = 260
const.max_native_child_process = 0
+2 -1
View File
@@ -36,4 +36,5 @@ persist.sys.abilityms.prevent_startability = foundation:foundation:0755
const.abilityms.launch_embeded_ui_ability = foundation:foundation:0755
const.sys.abilityms.limit_maximum_extensions_of_per_process = foundation:foundation:0755
const.sys.abilityms.limit_maximum_extensions_of_per_device = foundation:foundation:0755
const.sys.abilityms.cache_extension = foundation:foundation:0755
const.sys.abilityms.cache_extension = foundation:foundation:0755
const.max_native_child_process = foundation:foundation:0755
@@ -1316,10 +1316,13 @@ private:
void ApplicationTerminatedSendProcessEvent(const std::shared_ptr<AppRunningRecord> &appRecord);
void ClearAppRunningDataForKeepAlive(const std::shared_ptr<AppRunningRecord> &appRecord);
int32_t StartChildProcessPreCheck(const pid_t callingPid);
int32_t StartChildProcessPreCheckNative(const pid_t callingPid);
int32_t StartChildProcessPreCheck(pid_t callingPid, const ChildProcessRequest &request);
int32_t StartChildProcessImpl(const std::shared_ptr<ChildProcessRecord> childProcessRecord,
const std::shared_ptr<AppRunningRecord> appRecord, pid_t &childPid, const ChildProcessArgs &args);
const std::shared_ptr<AppRunningRecord> appRecord, pid_t &childPid, const ChildProcessArgs &args,
const ChildProcessOptions &options);
int32_t GetChildProcessInfo(const std::shared_ptr<ChildProcessRecord> childProcessRecord,
const std::shared_ptr<AppRunningRecord> appRecord, ChildProcessInfo &info);
@@ -302,6 +302,7 @@ public:
std::shared_ptr<AppRunningRecord> GetAppRunningRecordByChildProcessPid(const pid_t pid);
std::shared_ptr<ChildProcessRecord> OnChildProcessRemoteDied(const wptr<IRemoteObject> &remote);
bool IsNativeArgsChildProcessReachLimit(pid_t callingPid);
/**
* @brief Obtain number of app through bundlename.
@@ -76,6 +76,7 @@ struct AppSpawnStartMsg {
int32_t maxChildProcess = 0;
int32_t childProcessType = CHILD_PROCESS_TYPE_NOT_CHILD;
std::map<std::string, int32_t> fds;
bool isolationMode = false;
};
constexpr auto LEN_PID = sizeof(pid_t);
@@ -227,6 +228,8 @@ private:
int32_t SetChildProcessTypeStartFlag(const AppSpawnReqMsgHandle &reqHandle, int32_t childProcessType);
int32_t SetExtMsgFds(const AppSpawnReqMsgHandle &reqHandle, const std::map<std::string, int32_t> &fds);
int32_t SetIsolationModeFlag(const AppSpawnStartMsg &startMsg, const AppSpawnReqMsgHandle &reqHandle);
};
} // namespace AppExecFwk
} // namespace OHOS
@@ -66,8 +66,10 @@ public:
void OnProcessCreated(const std::shared_ptr<AppRunningRecord> &appRecord);
void OnProcessStateChanged(const std::shared_ptr<AppRunningRecord> &appRecord);
void OnRenderProcessCreated(const std::shared_ptr<RenderRecord> &RenderRecord);
void OnChildProcessCreated(std::shared_ptr<ChildProcessRecord> childRecord);
void OnProcessDied(const std::shared_ptr<AppRunningRecord> &appRecord);
void OnRenderProcessDied(const std::shared_ptr<RenderRecord> &renderRecord);
void OnChildProcessDied(std::shared_ptr<ChildProcessRecord> childRecord);
void OnProcessReused(const std::shared_ptr<AppRunningRecord> &appRecord);
void OnPageShow(const PageStateData pageStateData);
void OnPageHide(const PageStateData pageStateData);
@@ -81,8 +83,10 @@ private:
const AbilityStateData abilityStateData, bool isAbility, bool isFromWindowFocusChanged);
void HandleOnAppProcessCreated(const std::shared_ptr<AppRunningRecord> &appRecord);
void HandleOnRenderProcessCreated(const std::shared_ptr<RenderRecord> &RenderRecord);
void HandleOnChildProcessCreated(std::shared_ptr<ChildProcessRecord> childRecord);
void HandleOnAppProcessDied(const std::shared_ptr<AppRunningRecord> &appRecord);
void HandleOnRenderProcessDied(const std::shared_ptr<RenderRecord> &RenderRecord);
void HandleOnChildProcessDied(std::shared_ptr<ChildProcessRecord> childRecord);
bool ObserverExist(const sptr<IRemoteBroker> &observer);
bool IsAppForegroundObserverExist(const sptr<IRemoteBroker> &observer);
bool IsAbilityForegroundObserverExist(const sptr<IRemoteBroker> &observer);
@@ -93,6 +97,7 @@ private:
AbilityforegroundObserverSet GetAbilityforegroundObserverSetCopy();
ProcessData WrapProcessData(const std::shared_ptr<AppRunningRecord> &appRecord);
ProcessData WrapRenderProcessData(const std::shared_ptr<RenderRecord> &renderRecord);
int32_t WrapChildProcessData(ProcessData &processData, std::shared_ptr<ChildProcessRecord> childRecord);
void OnObserverDied(const wptr<IRemoteObject> &remote, const ObserverType &type);
AppStateData WrapAppStateData(const std::shared_ptr<AppRunningRecord> &appRecord,
const ApplicationState state);
@@ -51,6 +51,7 @@ public:
int32_t GetUid() const;
std::string GetProcessName() const;
std::string GetSrcEntry() const;
std::string GetEntryFunc() const;
std::shared_ptr<AppRunningRecord> GetHostRecord() const;
void SetScheduler(const sptr<IChildScheduler> &scheduler);
sptr<IChildScheduler> GetScheduler() const;
@@ -76,6 +77,7 @@ private:
int32_t childProcessType_ = CHILD_PROCESS_TYPE_JS;
std::string processName_;
std::string srcEntry_;
std::string entryFunc_;
std::weak_ptr<AppRunningRecord> hostRecord_;
sptr<IChildScheduler> scheduler_ = nullptr;
sptr<AppDeathRecipient> deathRecipient_ = nullptr;
@@ -61,11 +61,14 @@ public:
std::shared_ptr<AppSpawnClient> GetCJSpawnClient();
std::shared_ptr<AppSpawnClient> GetNativeSpawnClient();
private:
std::shared_ptr<AppSpawnClient> appSpawnClient_;
std::shared_ptr<BundleMgrHelper> bundleManagerHelper_;
std::shared_ptr<AppSpawnClient> nwebSpawnClient_;
std::shared_ptr<AppSpawnClient> cjAppSpawnClient_;
std::shared_ptr<AppSpawnClient> nativeSpawnClient_;
};
} // namespace AppExecFwk
} // namespace OHOS
+66 -16
View File
@@ -6297,8 +6297,8 @@ int32_t AppMgrServiceInner::UnregisterAppRunningStatusListener(const sptr<IRemot
int32_t AppMgrServiceInner::StartChildProcess(const pid_t hostPid, pid_t &childPid, const ChildProcessRequest &request)
{
TAG_LOGI(AAFwkTag::APPMGR, "StarChildProcess, hostPid:%{public}d", hostPid);
auto errCode = StartChildProcessPreCheck(hostPid);
TAG_LOGI(AAFwkTag::APPMGR, "StartChildProcess, hostPid:%{public}d", hostPid);
auto errCode = StartChildProcessPreCheck(hostPid, request);
if (errCode != ERR_OK) {
return errCode;
}
@@ -6318,19 +6318,25 @@ int32_t AppMgrServiceInner::StartChildProcess(const pid_t hostPid, pid_t &childP
return ERR_NULL_OBJECT;
}
auto &args = request.args;
auto &options = request.options;
childProcessRecord->SetEntryParams(args.entryParams);
TAG_LOGI(AAFwkTag::APPMGR, "StartChildProcess, srcEntry:%{private}s, args.entryParams:%{public}s,"
" args.fds size:%{public}zu, options.isolationMode:%{public}d", request.srcEntry.c_str(),
args.entryParams.c_str(), args.fds.size(), request.options.isolationMode);
return StartChildProcessImpl(childProcessRecord, appRecord, childPid, args);
TAG_LOGI(AAFwkTag::APPMGR, "StartChildProcess, srcEntry:%{private}s, args.entryParams:%{private}s,"
" processName:%{public}s, args.fds size:%{public}zu, options.isolationMode:%{public}d",
request.srcEntry.c_str(), args.entryParams.c_str(), childProcessRecord->GetProcessName().c_str(),
args.fds.size(), options.isolationMode);
return StartChildProcessImpl(childProcessRecord, appRecord, childPid, args, options);
}
int32_t AppMgrServiceInner::StartChildProcessPreCheck(const pid_t callingPid)
int32_t AppMgrServiceInner::StartChildProcessPreCheckNative(const pid_t callingPid)
{
if (!AAFwk::AppUtils::GetInstance().IsMultiProcessModel()) {
TAG_LOGE(AAFwkTag::APPMGR, "Multi process model is not enabled");
return ERR_INVALID_OPERATION;
}
if (!appRunningManager_) {
TAG_LOGE(AAFwkTag::APPMGR, "appRunningManager nullptr");
return ERR_NO_INIT;
}
auto appRecord = appRunningManager_->GetAppRunningRecordByChildProcessPid(callingPid);
if (appRecord) {
TAG_LOGE(AAFwkTag::APPMGR, "Already in child process.");
@@ -6339,8 +6345,41 @@ int32_t AppMgrServiceInner::StartChildProcessPreCheck(const pid_t callingPid)
return ERR_OK;
}
int32_t AppMgrServiceInner::StartChildProcessPreCheck(const pid_t callingPid, const ChildProcessRequest &request)
{
TAG_LOGD(AAFwkTag::APPMGR, "called.");
auto childProcessType = request.childProcessType;
auto isMultiProcessModel = AAFwk::AppUtils::GetInstance().IsMultiProcessModel();
if (!isMultiProcessModel) {
if (childProcessType == CHILD_PROCESS_TYPE_NATIVE_ARGS) {
if (!AAFwk::PermissionVerification::GetInstance()->VerifyPreloadApplicationPermission()) {
return ERR_PERMISSION_DENIED;
}
} else {
TAG_LOGE(AAFwkTag::APPMGR, "Not support child process.");
return AAFwk::ERR_NOT_SUPPORT_CHILD_PROCESS;
}
}
if (!appRunningManager_) {
TAG_LOGE(AAFwkTag::APPMGR, "appRunningManager nullptr.");
return ERR_NO_INIT;
}
auto appRecord = appRunningManager_->GetAppRunningRecordByChildProcessPid(callingPid);
if (appRecord) {
TAG_LOGE(AAFwkTag::APPMGR, "Already in child process.");
return AAFwk::ERR_ALREADY_IN_CHILD_PROCESS;
}
if (appRunningManager_->IsNativeArgsChildProcessReachLimit(callingPid)) {
TAG_LOGE(AAFwkTag::APPMGR, "Native child process count reach limit.");
return AAFwk::ERR_NATIVE_ARGS_CHILD_PROCESS_REACH_LIMIT;
}
return ERR_OK;
}
int32_t AppMgrServiceInner::StartChildProcessImpl(const std::shared_ptr<ChildProcessRecord> childProcessRecord,
const std::shared_ptr<AppRunningRecord> appRecord, pid_t &childPid, const ChildProcessArgs &args)
const std::shared_ptr<AppRunningRecord> appRecord, pid_t &childPid, const ChildProcessArgs &args,
const ChildProcessOptions &options)
{
TAG_LOGD(AAFwkTag::APPMGR, "called");
if (!appRecord) {
@@ -6351,7 +6390,9 @@ int32_t AppMgrServiceInner::StartChildProcessImpl(const std::shared_ptr<ChildPro
TAG_LOGE(AAFwkTag::APPMGR, "No such child process record, childPid:%{public}d.", childPid);
return ERR_NAME_NOT_FOUND;
}
auto spawnClient = remoteClientManager_->GetSpawnClient();
bool isNativeFromJs = childProcessRecord->GetChildProcessType() == CHILD_PROCESS_TYPE_NATIVE_ARGS;
auto spawnClient = isNativeFromJs ? remoteClientManager_->GetNativeSpawnClient() :
remoteClientManager_->GetSpawnClient();
if (!spawnClient) {
TAG_LOGE(AAFwkTag::APPMGR, "spawnClient is null");
AppMgrEventUtil::SendChildProcessStartFailedEvent(childProcessRecord,
@@ -6368,6 +6409,7 @@ int32_t AppMgrServiceInner::StartChildProcessImpl(const std::shared_ptr<ChildPro
startMsg.procName = childProcessRecord->GetProcessName();
startMsg.childProcessType = childProcessRecord->GetChildProcessType();
startMsg.fds = args.fds;
startMsg.isolationMode = options.isolationMode;
pid_t pid = 0;
{
std::lock_guard<ffrt::mutex> lock(startChildProcessLock_);
@@ -6378,14 +6420,15 @@ int32_t AppMgrServiceInner::StartChildProcessImpl(const std::shared_ptr<ChildPro
ProcessStartFailedReason::APPSPAWN_FAILED, static_cast<int32_t>(errCode));
return ERR_APPEXECFWK_BAD_APPSPAWN_CLIENT;
}
childPid = pid;
childProcessRecord->SetPid(pid);
childProcessRecord->SetUid(startMsg.uid);
appRecord->AddChildProcessRecord(pid, childProcessRecord);
}
TAG_LOGI(AAFwkTag::APPMGR, "Start child process success, pid:%{public}d, hostPid:%{public}d,uid:%{public}d",
pid, childProcessRecord->GetHostPid(), startMsg.uid);
TAG_LOGI(AAFwkTag::APPMGR, "Start child process success,pid:%{public}d,hostPid:%{public}d,uid:%{public}d,"
"processName:%{public}s", pid, childProcessRecord->GetHostPid(), startMsg.uid,
childProcessRecord->GetProcessName().c_str());
DelayedSingleton<AppStateObserverManager>::GetInstance()->OnChildProcessCreated(childProcessRecord);
return ERR_OK;
}
@@ -6435,6 +6478,7 @@ int32_t AppMgrServiceInner::GetChildProcessInfo(const std::shared_ptr<ChildProce
info.bundleName = appRecord->GetBundleName();
info.processName = childProcessRecord->GetProcessName();
info.srcEntry = childProcessRecord->GetSrcEntry();
info.entryFunc = childProcessRecord->GetEntryFunc();
info.entryParams = childProcessRecord->GetEntryParams();
info.jitEnabled = appRecord->IsJITEnabled();
info.isStartWithDebug = childProcessRecord->isStartWithDebug();
@@ -6482,7 +6526,7 @@ void AppMgrServiceInner::AttachChildProcess(const pid_t pid, const sptr<IChildSc
childRecord->RegisterDeathRecipient();
if (childRecord->GetChildProcessType() != CHILD_PROCESS_TYPE_NATIVE) {
childScheduler->ScheduleLoadJs();
childScheduler->ScheduleLoadChild();
} else {
childScheduler->ScheduleRunNativeProc(childRecord->GetMainProcessCallback());
childRecord->ClearMainProcessCallback();
@@ -6492,7 +6536,10 @@ void AppMgrServiceInner::AttachChildProcess(const pid_t pid, const sptr<IChildSc
void AppMgrServiceInner::OnChildProcessRemoteDied(const wptr<IRemoteObject> &remote)
{
if (appRunningManager_) {
appRunningManager_->OnChildProcessRemoteDied(remote);
auto childRecord = appRunningManager_->OnChildProcessRemoteDied(remote);
if (childRecord) {
DelayedSingleton<AppStateObserverManager>::GetInstance()->OnChildProcessDied(childRecord);
}
}
}
@@ -6515,6 +6562,7 @@ void AppMgrServiceInner::KillChildProcess(const std::shared_ptr<AppRunningRecord
TAG_LOGI(AAFwkTag::APPMGR, "Kill child process when host died, childPid:%{public}d, childUid:%{public}d.",
childPid, childRecord->GetUid());
KillProcessByPid(childPid, "KillChildProcess");
DelayedSingleton<AppStateObserverManager>::GetInstance()->OnChildProcessDied(childRecord);
}
}
}
@@ -6543,6 +6591,7 @@ void AppMgrServiceInner::ExitChildProcessSafelyByChildPid(const pid_t pid)
if (WaitForRemoteProcessExit(pids, startTime)) {
TAG_LOGI(AAFwkTag::APPMGR, "The remote child process exited successfully, pid:%{public}d.", pid);
appRecord->RemoveChildProcessRecord(childRecord);
DelayedSingleton<AppStateObserverManager>::GetInstance()->OnChildProcessDied(childRecord);
return;
}
childRecord->RegisterDeathRecipient();
@@ -7138,7 +7187,7 @@ int32_t AppMgrServiceInner::StartNativeChildProcess(const pid_t hostPid, const s
return ERR_INVALID_OPERATION;
}
int32_t errCode = StartChildProcessPreCheck(hostPid);
int32_t errCode = StartChildProcessPreCheckNative(hostPid);
if (errCode != ERR_OK) {
return errCode;
}
@@ -7164,7 +7213,8 @@ int32_t AppMgrServiceInner::StartNativeChildProcess(const pid_t hostPid, const s
auto nativeChildRecord = ChildProcessRecord::CreateNativeChildProcessRecord(
hostPid, libName, appRecord, callback, childProcessCount, false);
ChildProcessArgs args;
return StartChildProcessImpl(nativeChildRecord, appRecord, dummyChildPid, args);
ChildProcessOptions options;
return StartChildProcessImpl(nativeChildRecord, appRecord, dummyChildPid, args, options);
}
void AppMgrServiceInner::CacheLoabAbilityTask(const LoabAbilityTaskFunc& func)
@@ -1279,6 +1279,23 @@ std::shared_ptr<AppRunningRecord> AppRunningManager::GetAppRunningRecordByChildP
return nullptr;
}
bool AppRunningManager::IsNativeArgsChildProcessReachLimit(pid_t callingPid)
{
TAG_LOGD(AAFwkTag::APPMGR, "called.");
auto hostRecord = GetAppRunningRecordByPid(callingPid);
if (!hostRecord) {
TAG_LOGE(AAFwkTag::APPMGR, "hostRecord nullptr.");
return false;
}
int32_t nativeArgsChildCount = 0;
auto childRecordMap = hostRecord->GetChildProcessRecordMap();
auto count = std::count_if(childRecordMap.begin(), childRecordMap.end(), [](auto &pair) {
auto childRecord = pair.second;
return childRecord && childRecord->GetChildProcessType() == CHILD_PROCESS_TYPE_NATIVE_ARGS;
});
return count >= AAFwk::AppUtils::GetInstance().MaxNativeArgsChildProcess();
}
std::shared_ptr<ChildProcessRecord> AppRunningManager::OnChildProcessRemoteDied(const wptr<IRemoteObject> &remote)
{
TAG_LOGE(AAFwkTag::APPMGR, "On child process remote died.");
+22
View File
@@ -57,6 +57,8 @@ AppSpawnClient::AppSpawnClient(const char* serviceName)
serviceName_ = CJAPPSPAWN_SERVER_NAME;
} else if (serviceName__ == NWEBSPAWN_SERVER_NAME) {
serviceName_ = NWEBSPAWN_SERVER_NAME;
} else if (serviceName__ == NATIVESPAWN_SERVER_NAME) {
serviceName_ = NATIVESPAWN_SERVER_NAME;
} else {
TAG_LOGE(AAFwkTag::APPMGR, "unknown service name");
serviceName_ = NWEBSPAWN_SERVER_NAME;
@@ -239,6 +241,7 @@ int32_t AppSpawnClient::SetStartFlags(const AppSpawnStartMsg &startMsg, AppSpawn
TAG_LOGE(AAFwkTag::APPMGR, "Set childProcessType flag failed, ret: %{public}d", ret);
return ret;
}
ret = SetIsolationModeFlag(startMsg, reqHandle);
return ret;
}
@@ -563,5 +566,24 @@ int32_t AppSpawnClient::SetExtMsgFds(const AppSpawnReqMsgHandle &reqHandle,
}
return ERR_OK;
}
int32_t AppSpawnClient::SetIsolationModeFlag(const AppSpawnStartMsg &startMsg, const AppSpawnReqMsgHandle &reqHandle)
{
TAG_LOGD(AAFwkTag::APPMGR, "SetIsolationFlag, isolationMode:%{public}d", startMsg.isolationMode);
if (!startMsg.isolationMode) {
return ERR_OK;
}
auto ret = AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_ISOLATED_SANDBOX_TYPE);
if (ret != 0) {
TAG_LOGE(AAFwkTag::APPMGR, "SetIsolationFlag failed, ret: %{public}d", ret);
return ret;
}
ret = AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_ISOLATED_NETWORK);
if (ret != 0) {
TAG_LOGE(AAFwkTag::APPMGR, "SetIsolationFlag failed, ret: %{public}d", ret);
return ret;
}
return ERR_OK;
}
} // namespace AppExecFwk
} // namespace OHOS
@@ -297,6 +297,25 @@ void AppStateObserverManager::OnRenderProcessDied(const std::shared_ptr<RenderRe
handler_->SubmitTask(task);
}
void AppStateObserverManager::OnChildProcessDied(std::shared_ptr<ChildProcessRecord> childRecord)
{
if (handler_ == nullptr) {
TAG_LOGE(AAFwkTag::APPMGR, "handler is nullptr, OnChildProcessDied failed.");
return;
}
auto task = [weak = weak_from_this(), childRecord]() {
auto self = weak.lock();
if (self == nullptr) {
TAG_LOGE(AAFwkTag::APPMGR, "self is nullptr, OnChildProcessDied failed.");
return;
}
TAG_LOGD(AAFwkTag::APPMGR, "OnChildProcessDied come.");
self->HandleOnChildProcessDied(childRecord);
};
handler_->SubmitTask(task);
}
void AppStateObserverManager::OnProcessStateChanged(const std::shared_ptr<AppRunningRecord> &appRecord)
{
if (handler_ == nullptr) {
@@ -372,6 +391,25 @@ void AppStateObserverManager::OnRenderProcessCreated(const std::shared_ptr<Rende
handler_->SubmitTask(task);
}
void AppStateObserverManager::OnChildProcessCreated(std::shared_ptr<ChildProcessRecord> childRecord)
{
if (handler_ == nullptr) {
TAG_LOGE(AAFwkTag::APPMGR, "handler is nullptr, OnChildProcessCreated failed.");
return;
}
auto task = [weak = weak_from_this(), childRecord]() {
auto self = weak.lock();
if (self == nullptr) {
TAG_LOGE(AAFwkTag::APPMGR, "self is nullptr, OnChildProcessCreated failed.");
return;
}
TAG_LOGD(AAFwkTag::APPMGR, "OnChildProcessCreated come.");
self->HandleOnChildProcessCreated(childRecord);
};
handler_->SubmitTask(task);
}
void AppStateObserverManager::StateChangedNotifyObserver(
const AbilityStateData abilityStateData, bool isAbility, bool isFromWindowFocusChanged)
{
@@ -580,6 +618,24 @@ void AppStateObserverManager::HandleOnRenderProcessCreated(const std::shared_ptr
HandleOnProcessCreated(data);
}
void AppStateObserverManager::HandleOnChildProcessCreated(std::shared_ptr<ChildProcessRecord> childRecord)
{
if (!childRecord) {
TAG_LOGE(AAFwkTag::APPMGR, "ChildProcessRecord record is nullptr.");
return;
}
ProcessData data;
if (WrapChildProcessData(data, childRecord) != ERR_OK) {
TAG_LOGE(AAFwkTag::APPMGR, "WrapChildProcessData failed.");
return;
}
TAG_LOGD(AAFwkTag::APPMGR,
"ChildProcess Create, bundleName:%{public}s, pid:%{public}d, uid:%{public}d, "
"processType:%{public}d, processName:%{public}s",
data.bundleName.c_str(), data.pid, data.uid, data.processType, data.processName.c_str());
HandleOnProcessCreated(data);
}
void AppStateObserverManager::HandleOnProcessCreated(const ProcessData &data)
{
auto appStateObserverMapCopy = GetAppStateObserverMapCopy();
@@ -643,6 +699,24 @@ void AppStateObserverManager::HandleOnRenderProcessDied(const std::shared_ptr<Re
HandleOnProcessDied(data);
}
void AppStateObserverManager::HandleOnChildProcessDied(std::shared_ptr<ChildProcessRecord> childRecord)
{
if (!childRecord) {
TAG_LOGE(AAFwkTag::APPMGR, "childRecord is nullptr.");
return;
}
ProcessData data;
if (WrapChildProcessData(data, childRecord) != ERR_OK) {
TAG_LOGE(AAFwkTag::APPMGR, "WrapChildProcessData failed.");
return;
}
TAG_LOGD(AAFwkTag::APPMGR,
"ChildProcess died, bundleName:%{public}s, pid:%{public}d, uid:%{public}d, "
"processType:%{public}d, processName:%{public}s",
data.bundleName.c_str(), data.pid, data.uid, data.processType, data.processName.c_str());
HandleOnProcessDied(data);
}
void AppStateObserverManager::HandleOnProcessDied(const ProcessData &data)
{
auto appStateObserverMapCopy = GetAppStateObserverMapCopy();
@@ -696,6 +770,28 @@ ProcessData AppStateObserverManager::WrapRenderProcessData(const std::shared_ptr
return processData;
}
int32_t AppStateObserverManager::WrapChildProcessData(ProcessData &processData,
std::shared_ptr<ChildProcessRecord> childRecord)
{
if (!childRecord) {
TAG_LOGE(AAFwkTag::APPMGR, "childRecord is nullptr.");
return ERR_INVALID_VALUE;
}
auto hostRecord = childRecord->GetHostRecord();
if (!hostRecord) {
TAG_LOGE(AAFwkTag::APPMGR, "hostRecord is nullptr.");
return ERR_INVALID_VALUE;
}
processData.bundleName = hostRecord->GetBundleName();
processData.uid = hostRecord->GetUid();
processData.hostPid = childRecord->GetHostPid();
processData.pid = childRecord->GetPid();
processData.childUid = childRecord->GetUid();
processData.processName = childRecord->GetProcessName();
processData.processType = childRecord->GetProcessType();
return ERR_OK;
}
bool AppStateObserverManager::ObserverExist(const sptr<IRemoteBroker> &observer)
{
if (observer == nullptr) {
+15 -2
View File
@@ -24,8 +24,16 @@ namespace AppExecFwk {
ChildProcessRecord::ChildProcessRecord(pid_t hostPid, const ChildProcessRequest &request,
const std::shared_ptr<AppRunningRecord> hostRecord)
: hostPid_(hostPid), childProcessCount_(request.childProcessCount), childProcessType_(request.childProcessType),
srcEntry_(request.srcEntry), hostRecord_(hostRecord), isStartWithDebug_(request.isStartWithDebug)
hostRecord_(hostRecord), isStartWithDebug_(request.isStartWithDebug)
{
srcEntry_ = request.srcEntry;
if (childProcessType_ == CHILD_PROCESS_TYPE_NATIVE_ARGS) {
auto pos = request.srcEntry.rfind(":");
if (pos != std::string::npos) {
srcEntry_ = request.srcEntry.substr(0, pos);
entryFunc_ = request.srcEntry.substr(pos + 1);
}
}
MakeProcessName(hostRecord);
}
@@ -107,6 +115,11 @@ ProcessType ChildProcessRecord::GetProcessType() const
return processType_;
}
std::string ChildProcessRecord::GetEntryFunc() const
{
return entryFunc_;
}
std::shared_ptr<AppRunningRecord> ChildProcessRecord::GetHostRecord() const
{
return hostRecord_.lock();
@@ -174,7 +187,7 @@ void ChildProcessRecord::MakeProcessName(const std::shared_ptr<AppRunningRecord>
std::string filename = std::filesystem::path(srcEntry_).stem();
if (!filename.empty()) {
processName_.append(":");
if (childProcessType_ == CHILD_PROCESS_TYPE_NATIVE) {
if (childProcessType_ == CHILD_PROCESS_TYPE_NATIVE || childProcessType_ == CHILD_PROCESS_TYPE_NATIVE_ARGS) {
processName_.append("Native_");
}
@@ -24,7 +24,8 @@ namespace OHOS {
namespace AppExecFwk {
RemoteClientManager::RemoteClientManager()
: appSpawnClient_(std::make_shared<AppSpawnClient>()), nwebSpawnClient_(std::make_shared<AppSpawnClient>(true)),
cjAppSpawnClient_(std::make_shared<AppSpawnClient>("cjappspawn"))
cjAppSpawnClient_(std::make_shared<AppSpawnClient>("cjappspawn")),
nativeSpawnClient_(std::make_shared<AppSpawnClient>("nativespawn"))
{}
RemoteClientManager::~RemoteClientManager()
@@ -68,5 +69,10 @@ std::shared_ptr<AppSpawnClient> RemoteClientManager::GetCJSpawnClient()
}
return nullptr;
}
std::shared_ptr<AppSpawnClient> RemoteClientManager::GetNativeSpawnClient()
{
return nativeSpawnClient_;
}
} // namespace AppExecFwk
} // namespace OHOS
+3
View File
@@ -25,6 +25,7 @@ namespace AAFwk {
constexpr const int32_t DEFAULT_MAX_EXT_PER_PROC = 10;
constexpr const int32_t DEFAULT_MAX_EXT_PER_DEV = 100;
constexpr const int32_t DEFAULT_INVALID_VALUE = -1;
constexpr const int32_t DEFAULT_MAX_NATIVE_ARGS_CHILD_PROCESS = 0;
template<typename T>
class DeviceConfiguration {
public:
@@ -60,6 +61,7 @@ public:
std::string GetBrokerDelegateBundleName();
int32_t GetCollaboratorBrokerUID();
int32_t GetCollaboratorBrokerReserveUID();
int32_t MaxNativeArgsChildProcess();
private:
void LoadResidentProcessInExtremeMemory();
@@ -89,6 +91,7 @@ private:
DeviceConfiguration<std::string> brokerDelegateBundleName_ = {false, ""};
volatile DeviceConfiguration<int32_t> collaboratorBrokerUid_ = {false, DEFAULT_INVALID_VALUE};
volatile DeviceConfiguration<int32_t> collaboratorBrokerReserveUid_ = {false, DEFAULT_INVALID_VALUE};
volatile DeviceConfiguration<int32_t> maxNativeArgsChildProcess_ = {false, DEFAULT_MAX_NATIVE_ARGS_CHILD_PROCESS};
DISALLOW_COPY_AND_MOVE(AppUtils);
};
} // namespace AAFwk
@@ -62,6 +62,7 @@ constexpr const char* PERMISSION_PRELOAD_UI_EXTENSION_ABILITY = "ohos.permission
constexpr const char* PERMISSION_PRE_START_ATOMIC_SERVICE = "ohos.permission.PRE_START_ATOMIC_SERVICE";
constexpr const char* PERMISSION_KILL_APP_PROCESSES = "ohos.permission.KILL_APP_PROCESSES";
constexpr const char* PERMISSION_KILL_PROCESS_DEPENDED_ON_WEB = "ohos.permission.KILL_PROCESS_DEPENDED_ON_ARKWEB";
constexpr const char* PERMISSION_START_NATIVE_CHILD_PROCESS = "ohos.permission.START_NATIVE_CHILD_PROCESS";
} // namespace PermissionConstants
} // namespace AAFwk
} // namespace OHOS
@@ -103,6 +103,8 @@ struct VerificationInfo {
bool VerifyKillProcessDependedOnWebPermission() const;
bool VerifyStartNativeChildProcessPermission() const;
private:
DISALLOW_COPY_AND_MOVE(PermissionVerification);
+12
View File
@@ -61,6 +61,7 @@ constexpr const char* START_ABILITY_WITHOUT_CALLERTOKEN_TITLE = "startAbilityWit
constexpr const char* BROKER_DELEGATE_BUNDLE_NAME = "const.sys.abilityms.broker_delegate_bundle_name";
constexpr const char* COLLABORATOR_BROKER_UID = "const.sys.abilityms.collaborator_broker_uid";
constexpr const char* COLLABORATOR_BROKER_RESERVE_UID = "const.sys.abilityms.collaborator_broker_reserve_uid";
constexpr const char* MAX_NATIVE_ARGS_CHILD_PROCESS = "const.max_native_child_process";
}
AppUtils::~AppUtils() {}
@@ -387,5 +388,16 @@ int32_t AppUtils::GetCollaboratorBrokerReserveUID()
TAG_LOGD(AAFwkTag::DEFAULT, "collaboratorBrokerReserveUid_ is %{public}d", collaboratorBrokerReserveUid_.value);
return collaboratorBrokerReserveUid_.value;
}
int32_t AppUtils::MaxNativeArgsChildProcess()
{
if (!maxNativeArgsChildProcess_.isLoaded) {
maxNativeArgsChildProcess_.value =
system::GetIntParameter<int32_t>(MAX_NATIVE_ARGS_CHILD_PROCESS, DEFAULT_MAX_NATIVE_ARGS_CHILD_PROCESS);
maxNativeArgsChildProcess_.isLoaded = true;
}
TAG_LOGD(AAFwkTag::DEFAULT, "maxNativeArgsChildProcess: %{public}d", maxNativeArgsChildProcess_.value);
return maxNativeArgsChildProcess_.value;
}
} // namespace AAFwk
} // namespace OHOS
@@ -496,5 +496,17 @@ bool PermissionVerification::VerifyKillProcessDependedOnWebPermission() const
TAG_LOGW(AAFwkTag::APPMGR, "Permission denied");
return false;
}
bool PermissionVerification::VerifyStartNativeChildProcessPermission() const
{
if (VerifyCallingPermission(PermissionConstants::PERMISSION_START_NATIVE_CHILD_PROCESS)) {
TAG_LOGD(AAFwkTag::DEFAULT, "Permission %{public}s granted",
PermissionConstants::PERMISSION_START_NATIVE_CHILD_PROCESS);
return true;
}
TAG_LOGE(AAFwkTag::DEFAULT, "Permission %{public}s denied",
PermissionConstants::PERMISSION_START_NATIVE_CHILD_PROCESS);
return false;
}
} // namespace AAFwk
} // namespace OHOS
@@ -69,7 +69,7 @@ bool DoSomethingInterestingWithMyAPI(const char* data, size_t size)
{
sptr<IRemoteObject> impl;
std::shared_ptr<ChildSchedulerProxy> infosProxy = std::make_shared<ChildSchedulerProxy>(impl);
infosProxy->ScheduleLoadJs();
infosProxy->ScheduleLoadChild();
infosProxy->ScheduleExitProcessSafely();
sptr<IRemoteObject> mainProcessCb;
infosProxy->ScheduleRunNativeProc(mainProcessCb);
@@ -57,7 +57,7 @@ public:
virtual ~ ChildSchedulerStubFUZZ() {};
int OnRemoteRequest(
uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override{ return 0; };
bool ScheduleLoadJs() override{ return true; };
bool ScheduleLoadChild() override{ return true; };
bool ScheduleExitProcessSafely() override{ return true; };
bool ScheduleRunNativeProc(const sptr<IRemoteObject> &mainProcessCb) override{ return true; };
};
@@ -99,13 +99,13 @@ HWTEST_F(ChildMainThreadTest, Attach_0100, TestSize.Level0)
}
/**
* @tc.number: ScheduleLoadJs_0100
* @tc.desc: Test ScheduleLoadJs_0100 works
* @tc.number: ScheduleLoadChild_0100
* @tc.desc: Test ScheduleLoadChild_0100 works
* @tc.type: FUNC
*/
HWTEST_F(ChildMainThreadTest, ScheduleLoadJs_0100, TestSize.Level0)
HWTEST_F(ChildMainThreadTest, ScheduleLoadChild_0100, TestSize.Level0)
{
TAG_LOGD(AAFwkTag::TEST, "ScheduleLoadJs_0100 called.");
TAG_LOGD(AAFwkTag::TEST, "ScheduleLoadChild_0100 called.");
sptr<ChildMainThread> thread = sptr<ChildMainThread>(new (std::nothrow) ChildMainThread());
ASSERT_NE(thread, nullptr);
@@ -114,7 +114,7 @@ HWTEST_F(ChildMainThreadTest, ScheduleLoadJs_0100, TestSize.Level0)
thread->mainHandler_ = handler;
thread->processInfo_ = std::make_shared<ChildProcessInfo>();
auto ret = thread->ScheduleLoadJs();
auto ret = thread->ScheduleLoadChild();
EXPECT_TRUE(ret);
}