!18687 merge isch into master

IsChildProcess

Created-by: renjh5496
Commit-by: renjh5496;renjianhao
Merged-by: openharmony_ci
Description: **IssueNo**:

**Description**:

**稳定性自检:**
| 自检项                                                       | 自检结果  |
| ------------------------------------------------------------ | -------- |
| 涉及跨进程调用的相关操作需要抛至主线程或加锁防止并发              |          |
| 成员变量进行赋值或创建需要排查并发                               |          |
| 谨慎在lambda表达式中使用引用捕获                                |          |
| 谨慎在未经拷贝的情况下使用外部传入的string、C字符串               |          |
| map\vector\list\set等stl模板类使用时需要排查并发                |          |
| 谨慎考虑加锁范围                                               |          |
| 在IPC通信中谨慎使用同步通信方式                                 |          |
| 禁止传递this指针至其他模块或线程(特别是eventhandler任务)        |          |
| 禁止将外部传入的裸指针在内部直接构造智能指针                      |          |
| 禁止多个独立创建的智能指针管理同一地址                           |          |
| 禁止在析构函数中抛异步任务                                      |          |
| 禁止js对象在非js线程(例如在IPC线程)创建、使用或销毁             |          |
| 禁止在对外接口中未经判空直接使用外部传入的指针                    |          |
| 禁止接口返回局部变量引用                                        |          |
| 禁止在信号函数中加锁                                            |          |
| 禁止在关键流程(SA启动、应用启动等主流程)执行耗时的操作           |          |
| 禁止将同一个cpp编译在不同的so中                                 |          |

**安全编码自检:**
| 自检项                                                          | 自检结果 |
| -------------------------------------------------------------- | -------- |
| 裸指针避免通过隐式转换构造为sptr                                 |          |
| json对象在取值之前必须先判断类型,避免类型不匹配                   |          |
| 序列化时必须对传入的数组大小进行校验,避免出现超大数组              |          |
| 避免使用未明确位宽的整型,选择使用int8_t、uint8_t等类型            |          |
| 外部传入的路径要做规范化校验,对路径中的.、..、../等特殊字符严格校验 |          |
| 指针变量、表示资源描述符的变量、bool变量必须赋初值                  |          |
| readParcelable获取的对象使用前需要判空                            |          |
| 分配和释放内存的函数需要成对出现                                   |          |
| 申请内存后异常退出前需要及时进行内存释放                            |          |
| 内存申请前必须对内存大小进行合法性校验                              |          |
| 内存分配后必须判断是否成功                                         |          |
| 禁止使用realloc、alloca函数                                       |          |
| 禁止打印文件路径、口令等敏感信息,如有需要,使用private修饰          |          |
| 禁止打印内存地址                                                  |          |
| 整数之间运算时必须严格检查,确保不会出现溢出、反转、除0               |          |
| 禁止对有符号整数进行位操作符运算                                    |          |
| 禁止对指针进行逻辑或位运算                                         |          |
| 循环次数如果收外部数据控制,需要检验其合法性                         |          |
| 禁止使用内存操作类危险函数,需要使用安全函数                         |          |
| 谨慎使用不可重入函数                                               |          |
| 必须检查安全函数的返回值,并进行正确处理                             |          |
| 禁止仅通过TokenType类型判断绕过权限校验                             |          |

**TDD Result**:
UT:
![image.png](https://raw.gitcode.com/user-images/assets/4421702/7361d745-9abc-4d82-9b1c-10c578416ad1/image.png 'image.png')
**XTS Result**:

### 是否已执行L0用例
- [ ] 已验证
- [ ] 不涉及。如不涉及,请写明理由


See merge request: openharmony/ability_ability_runtime!18687
This commit is contained in:
openharmony_ci
2026-04-29 08:54:46 +08:00
14 changed files with 228 additions and 8 deletions
@@ -108,6 +108,16 @@ public:
GetInstance().OnStartNativeChildProcessCheck(env, etsSrcEntry, ChildProcessArgs, ChildProcessOptions);
}
static bool IsArkChildProcessSupported(ani_env *env)
{
return GetInstance().OnIsArkChildProcessSupported(env);
}
static bool IsNativeChildProcessSupported(ani_env *env)
{
return GetInstance().OnIsNativeChildProcessSupported(env);
}
private:
void OnStartChildProcess(ani_env *env, ani_string etsSrcEntry, ani_enum_item etsStartMode, ani_object callback)
{
@@ -495,6 +505,26 @@ private:
}
return true;
}
bool OnIsArkChildProcessSupported(ani_env *env)
{
TAG_LOGD(AAFwkTag::PROCESSMGR, "IsArkChildProcessSupported called");
if (env == nullptr) {
TAG_LOGE(AAFwkTag::PROCESSMGR, "env is null");
return false;
}
return AbilityRuntime::ChildProcessManager::GetInstance().IsArkChildProcessSupported();
}
bool OnIsNativeChildProcessSupported(ani_env *env)
{
TAG_LOGD(AAFwkTag::PROCESSMGR, "IsNativeChildProcessSupported called");
if (env == nullptr) {
TAG_LOGE(AAFwkTag::PROCESSMGR, "env is null");
return false;
}
return AbilityRuntime::ChildProcessManager::GetInstance().IsNativeChildProcessSupported();
}
};
void EtsChildProcessManagerInit(ani_env *env)
@@ -547,7 +577,13 @@ void EtsChildProcessManagerInit(ani_env *env)
ani_native_function {"nativeStartNativeChildProcessCheck",
"C{std.core.String}C{@ohos.app.ability.ChildProcessArgs.ChildProcessArgs}"
"C{@ohos.app.ability.ChildProcessOptions.ChildProcessOptions}:",
reinterpret_cast<void *>(EtsChildProcessManager::StartNativeChildProcessCheck)}
reinterpret_cast<void *>(EtsChildProcessManager::StartNativeChildProcessCheck)},
ani_native_function {"isArkChildProcessSupported",
":z",
reinterpret_cast<void *>(EtsChildProcessManager::IsArkChildProcessSupported)},
ani_native_function {"isNativeChildProcessSupported",
":z",
reinterpret_cast<void *>(EtsChildProcessManager::IsNativeChildProcessSupported)}
};
status = env->Namespace_BindNativeFunctions(ns, kitFunctions.data(), kitFunctions.size());
if (status != ANI_OK) {
@@ -31,6 +31,8 @@ namespace childProcessManager {
export native function nativeStartArkChildProcess(srcEntry: string, args: ChildProcessArgs, options: ChildProcessOptions, callback: AsyncCallbackWrapper<int>): void;
export native function nativeStartNativeChildProcess(entryPoint: string, args: ChildProcessArgs, callback: AsyncCallbackWrapper<int>): void;
export native function nativeStartNativeChildProcess(entryPoint: string, args: ChildProcessArgs, options: ChildProcessOptions, callback: AsyncCallbackWrapper<int>): void;
export native function isArkChildProcessSupported(): boolean;
export native function isNativeChildProcessSupported(): boolean;
export native function nativeStartChildProcessCheck(srcEntry: string, startMode: StartMode): void;
export native function nativeStartArkChildProcessCheck(srcEntry: string, args: ChildProcessArgs, options?: ChildProcessOptions): void;
@@ -80,6 +80,16 @@ public:
GET_CB_INFO_AND_CALL(env, info, JsChildProcessManager, OnStartNativeChildProcess);
}
static napi_value IsArkChildProcessSupported(napi_env env, napi_callback_info info)
{
GET_CB_INFO_AND_CALL(env, info, JsChildProcessManager, OnIsArkChildProcessSupported);
}
static napi_value IsNativeChildProcessSupported(napi_env env, napi_callback_info info)
{
GET_CB_INFO_AND_CALL(env, info, JsChildProcessManager, OnIsNativeChildProcessSupported);
}
private:
napi_value OnStartChildProcess(napi_env env, size_t argc, napi_value* argv)
{
@@ -264,6 +274,22 @@ private:
return result;
}
napi_value OnIsArkChildProcessSupported(napi_env env, size_t argc, napi_value* argv)
{
TAG_LOGI(AAFwkTag::PROCESSMGR, "called");
bool isSupported = ChildProcessManager::GetInstance().IsArkChildProcessSupported();
TAG_LOGD(AAFwkTag::PROCESSMGR, "result:%{public}d", isSupported);
return CreateJsValue(env, isSupported);
}
napi_value OnIsNativeChildProcessSupported(napi_env env, size_t argc, napi_value* argv)
{
TAG_LOGI(AAFwkTag::PROCESSMGR, "called");
bool isSupported = ChildProcessManager::GetInstance().IsNativeChildProcessSupported();
TAG_LOGD(AAFwkTag::PROCESSMGR, "result:%{public}d", isSupported);
return CreateJsValue(env, isSupported);
}
bool ParseArgsAndOptions(const napi_env &env, napi_value* argv, size_t argc, AppExecFwk::ChildProcessArgs &args,
AppExecFwk::ChildProcessOptions &options)
{
@@ -338,6 +364,10 @@ napi_value JsChildProcessManagerInit(napi_env env, napi_value exportObj)
BindNativeFunction(env, exportObj, "startArkChildProcess", moduleName, JsChildProcessManager::StartArkChildProcess);
BindNativeFunction(env, exportObj, "startNativeChildProcess", moduleName,
JsChildProcessManager::StartNativeChildProcess);
BindNativeFunction(env, exportObj, "isArkChildProcessSupported", moduleName,
JsChildProcessManager::IsArkChildProcessSupported);
BindNativeFunction(env, exportObj, "isNativeChildProcessSupported", moduleName,
JsChildProcessManager::IsNativeChildProcessSupported);
return CreateJsUndefined(env);
}
} // namespace AbilityRuntime
@@ -628,5 +628,25 @@ ChildProcessManagerErrorCode ChildProcessManager::KillChildProcessByPid(int32_t
}
return ChildProcessManagerErrorCode::ERR_OK;
}
void ChildProcessManager::SetArkChildProcessSupported(bool supported)
{
isArkChildProcessSupported_ = supported;
}
void ChildProcessManager::SetNativeChildProcessSupported(bool supported)
{
isNativeChildProcessSupported_ = supported;
}
bool ChildProcessManager::IsArkChildProcessSupported()
{
return isArkChildProcessSupported_;
}
bool ChildProcessManager::IsNativeChildProcessSupported()
{
return isNativeChildProcessSupported_;
}
} // namespace AbilityRuntime
} // namespace OHOS
@@ -1865,6 +1865,10 @@ void MainThread::HandleLaunchApplication(const AppLaunchData &appLaunchData, con
AbilityRuntime::ChildProcessManager::GetInstance().SetForkProcessDebugOption(appInfo.bundleName,
appLaunchData.GetDebugApp(), appInfo.debug, appLaunchData.isNativeStart());
AbilityRuntime::ChildProcessManager::GetInstance().SetApplication(application_);
AbilityRuntime::ChildProcessManager::GetInstance().SetArkChildProcessSupported(
appLaunchData.IsArkChildProcessSupported());
AbilityRuntime::ChildProcessManager::GetInstance().SetNativeChildProcessSupported(
appLaunchData.IsNativeChildProcessSupported());
#endif // SUPPORT_CHILD_PROCESS
if (!pluginBundleInfos.empty()) {
for (auto &pluginBundleInfo : pluginBundleInfos) {
@@ -364,4 +364,11 @@ Ability_NativeChildProcess_ErrCode OH_Ability_KillChildProcess(int32_t pid)
return ChildProcessManagerErrorUtil::CvtChildProcessManagerErrCode(cpmErr);
}
return NCP_NO_ERROR;
}
bool OH_Ability_IsNativeChildProcessSupported()
{
bool result = ChildProcessManager::GetInstance().IsNativeChildProcessSupported();
TAG_LOGD(AAFwkTag::PROCESSMGR, "IsNativeChildProcessSupported: %{public}d", result);
return result;
}
@@ -368,6 +368,26 @@ public:
*/
bool GetDebugFromLocal() const;
inline void SetArkChildProcessSupported(bool supported)
{
isArkChildProcessSupported_ = supported;
}
inline bool IsArkChildProcessSupported() const
{
return isArkChildProcessSupported_;
}
inline void SetNativeChildProcessSupported(bool supported)
{
isNativeChildProcessSupported_ = supported;
}
inline bool IsNativeChildProcessSupported() const
{
return isNativeChildProcessSupported_;
}
private:
bool debugApp_ = false;
bool jitEnabled_ = false;
@@ -391,6 +411,8 @@ private:
std::string preloadModuleName_;
bool isDebugFromLocal_;
std::shared_ptr<StartupTaskData> startupTaskData_ = nullptr;
bool isArkChildProcessSupported_ = false;
bool isNativeChildProcessSupported_ = false;
};
} // namespace AppExecFwk
} // namespace OHOS
@@ -140,6 +140,14 @@ bool AppLaunchData::MarshallingExtend(Parcel &parcel) const
TAG_LOGE(AAFwkTag::APPMGR, "Marshalling, Failed to write isDebugFromLocal");
return false;
}
if (!parcel.WriteBool(isArkChildProcessSupported_)) {
TAG_LOGE(AAFwkTag::APPMGR, "Marshalling, Failed to write isArkChildProcessSupported");
return false;
}
if (!parcel.WriteBool(isNativeChildProcessSupported_)) {
TAG_LOGE(AAFwkTag::APPMGR, "Marshalling, Failed to write isNativeChildProcessSupported");
return false;
}
bool hasStartupTaskData = startupTaskData_ ? true : false;
if (!parcel.WriteBool(hasStartupTaskData)) {
TAG_LOGE(AAFwkTag::APPMGR, "Failed to write the hasStartupTaskData");
@@ -203,6 +211,8 @@ bool AppLaunchData::ReadFromParcel(Parcel &parcel)
isAllowedNWebPreload_ = parcel.ReadBool();
preloadModuleName_ = parcel.ReadString();
isDebugFromLocal_ = parcel.ReadBool();
isArkChildProcessSupported_ = parcel.ReadBool();
isNativeChildProcessSupported_ = parcel.ReadBool();
if (!ReadStartupTaskDataFromParcel(parcel)) {
return false;
}
@@ -44,6 +44,10 @@ public:
static void HandleSigChild(int32_t signo);
bool IsChildProcess();
bool IsChildProcessBySelfFork();
bool IsArkChildProcessSupported();
bool IsNativeChildProcessSupported();
void SetArkChildProcessSupported(bool supported);
void SetNativeChildProcessSupported(bool supported);
ChildProcessManagerErrorCode StartChildProcessBySelfFork(const std::string &srcEntry, pid_t &pid,
bool isStaticChildProcess = false);
ChildProcessManagerErrorCode StartChildProcessByAppSpawnFork(const std::string &srcEntry, pid_t &pid,
@@ -96,6 +100,8 @@ private:
static bool signalRegistered_;
bool isChildProcessBySelfFork_ = false;
std::atomic<int32_t> childProcessCount_ = 0;
bool isArkChildProcessSupported_ = false;
bool isNativeChildProcessSupported_ = false;
mutable std::mutex appMutex_;
std::weak_ptr<AppExecFwk::OHOSApplication> application_;
@@ -504,6 +504,7 @@ Ability_NativeChildProcess_ErrCode OH_Ability_UnregisterNativeChildProcessExitCa
*/
Ability_NativeChildProcess_ErrCode OH_Ability_KillChildProcess(int32_t pid);
bool OH_Ability_IsNativeChildProcessSupported();
#ifdef __cplusplus
} // extern "C"
#endif
@@ -1230,6 +1230,26 @@ public:
std::optional<bool> IsSupportMultiProcessDeviceFeature() const;
void SetSupportMultiProcessDeviceFeature(bool support);
inline void SetArkChildProcessSupported(bool supported)
{
isArkChildProcessSupported_ = supported;
}
inline bool IsArkChildProcessSupported() const
{
return isArkChildProcessSupported_;
}
inline void SetNativeChildProcessSupported(bool supported)
{
isNativeChildProcessSupported_ = supported;
}
inline bool IsNativeChildProcessSupported() const
{
return isNativeChildProcessSupported_;
}
inline void SetMasterProcess(bool isMasterProcess)
{
isMasterProcess_ = isMasterProcess;
@@ -1478,6 +1498,8 @@ private:
bool isContinuousTask_ = false; // Only continuesTask processes can be set to true, please choose carefully
bool isDebugApp_ = false;
bool isDebugFromLocal_ = false;
bool isArkChildProcessSupported_ = false;
bool isNativeChildProcessSupported_ = false;
bool isDependedOnArkWeb_ = false;
bool isEmptyKeepAliveApp_ = false; // Only empty resident processes can be set to true, please choose carefully
bool isErrorInfoEnhance_ = false;
@@ -2629,6 +2629,13 @@ void AppMgrServiceInner::LaunchApplicationExt(const std::shared_ptr<AppRunningRe
{
auto isPreload = IsAllowedNWebPreload(appRecord->GetProcessName());
appRecord->SetNWebPreload(isPreload);
bool isMultiProcessModel = AAFwk::AppUtils::GetInstance().IsMultiProcessModel();
bool isArkSupported = isMultiProcessModel || AllowChildProcessInMultiProcessFeatureApp(appRecord);
bool isNativeSupported = isMultiProcessModel ||
AllowNativeChildProcess(CHILD_PROCESS_TYPE_NATIVE, appRecord->GetAppIdentifier()) ||
AllowChildProcessInMultiProcessFeatureApp(appRecord);
appRecord->SetArkChildProcessSupported(isArkSupported);
appRecord->SetNativeChildProcessSupported(isNativeSupported);
LaunchApplication(appRecord);
}
@@ -11708,13 +11715,6 @@ int32_t AppMgrServiceInner::CreateNativeChildProcess(const pid_t hostPid, const
return ERR_INVALID_OPERATION;
}
if (!AAFwk::AppUtils::GetInstance().IsSupportNativeChildProcess() &&
!AllowNativeChildProcess(CHILD_PROCESS_TYPE_NATIVE, appRecord->GetAppIdentifier()) &&
!AllowChildProcessInMultiProcessFeatureApp(appRecord)) {
TAG_LOGE(AAFwkTag::APPMGR, "unSupport native child process");
return AAFwk::ERR_NOT_SUPPORT_NATIVE_CHILD_PROCESS;
}
std::lock_guard<std::mutex> lock(childProcessRecordMapMutex_);
auto childRecordMap = appRecord->GetChildProcessRecordMap();
auto count = count_if(childRecordMap.begin(), childRecordMap.end(), [] (const auto &pair) -> bool {
@@ -417,6 +417,8 @@ void AppRunningRecord::LaunchApplication(const Configuration &config)
launchData.SetNWebPreload(isAllowedNWebPreload_);
launchData.SetPreloadModuleName(preloadModuleName_);
launchData.SetDebugFromLocal(isDebugFromLocal_);
launchData.SetArkChildProcessSupported(isArkChildProcessSupported_);
launchData.SetNativeChildProcessSupported(isNativeChildProcessSupported_);
launchData.SetStartupTaskData(startupTaskData_);
launchData.SetImageProcessType(static_cast<int32_t>(imageProcessType_));
@@ -682,5 +682,63 @@ HWTEST_F(ChildProcessManagerTest, LoadFromAppRuntime_0300, TestSize.Level2)
auto ret = ChildProcessManager::GetInstance().LoadFromAppRuntime("./ets/process/FeatureProcess.ts", hapModuleInfo);
EXPECT_FALSE(ret);
}
/**
* @tc.number: IsArkChildProcessSupported_0100
* @tc.desc: Test IsArkChildProcessSupported when supported is set to true
* @tc.type: FUNC
*/
HWTEST_F(ChildProcessManagerTest, IsArkChildProcessSupported_0100, TestSize.Level1)
{
TAG_LOGD(AAFwkTag::TEST, "IsArkChildProcessSupported_0100 called.");
auto &cpm = ChildProcessManager::GetInstance();
cpm.SetArkChildProcessSupported(true);
bool result = cpm.IsArkChildProcessSupported();
EXPECT_TRUE(result);
cpm.SetArkChildProcessSupported(false);
}
/**
* @tc.number: IsArkChildProcessSupported_0200
* @tc.desc: Test IsArkChildProcessSupported when supported is set to false
* @tc.type: FUNC
*/
HWTEST_F(ChildProcessManagerTest, IsArkChildProcessSupported_0200, TestSize.Level1)
{
TAG_LOGD(AAFwkTag::TEST, "IsArkChildProcessSupported_0200 called.");
auto &cpm = ChildProcessManager::GetInstance();
cpm.SetArkChildProcessSupported(false);
bool result = cpm.IsArkChildProcessSupported();
EXPECT_FALSE(result);
}
/**
* @tc.number: IsNativeChildProcessSupported_0100
* @tc.desc: Test IsNativeChildProcessSupported when supported is set to true
* @tc.type: FUNC
*/
HWTEST_F(ChildProcessManagerTest, IsNativeChildProcessSupported_0100, TestSize.Level1)
{
TAG_LOGD(AAFwkTag::TEST, "IsNativeChildProcessSupported_0100 called.");
auto &cpm = ChildProcessManager::GetInstance();
cpm.SetNativeChildProcessSupported(true);
bool result = cpm.IsNativeChildProcessSupported();
EXPECT_TRUE(result);
cpm.SetNativeChildProcessSupported(false);
}
/**
* @tc.number: IsNativeChildProcessSupported_0200
* @tc.desc: Test IsNativeChildProcessSupported when supported is set to false
* @tc.type: FUNC
*/
HWTEST_F(ChildProcessManagerTest, IsNativeChildProcessSupported_0200, TestSize.Level1)
{
TAG_LOGD(AAFwkTag::TEST, "IsNativeChildProcessSupported_0200 called.");
auto &cpm = ChildProcessManager::GetInstance();
cpm.SetNativeChildProcessSupported(false);
bool result = cpm.IsNativeChildProcessSupported();
EXPECT_FALSE(result);
}
} // namespace AbilityRuntime
} // namespace OHOS