mirror of
https://github.com/openharmony/ability_ability_runtime.git
synced 2026-08-24 12:43:16 -04:00
增加StartNativeChildProcess
Signed-off-by: zhangyuhang72 <zhangyuhang72@huawei.com> Change-Id: I242c494947e702a58ddaf092651d76a5d1c6d48a
This commit is contained in:
@@ -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 ¶m)
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
||||
+11
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
+15
-2
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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.");
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
+1
-1
@@ -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);
|
||||
|
||||
+1
-1
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user