!18555 merge lscdev0305 into master

cpp_crash场景使能APPrecover

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

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

**TDD Result**:
OK
**XTS Result**:
OK
### 是否已执行L0用例
已验证



See merge request: openharmony/ability_ability_runtime!18555
This commit is contained in:
openharmony_ci
2026-03-06 10:15:35 +08:00
24 changed files with 427 additions and 0 deletions
@@ -22,6 +22,7 @@ export default namespace appRecovery {
ALWAYS_RESTART = 0,
RESTART_WHEN_JS_CRASH = 0x0001,
RESTART_WHEN_APP_FREEZE = 0x0002,
RESTART_WHEN_CPP_CRASH = 0x0008,
NO_RESTART = 0xFFFF
}
@@ -196,6 +196,8 @@ napi_value AppRecoveryRestartFlagInit(napi_env env)
CreateJsValue(env, RestartFlag::RESTART_WHEN_JS_CRASH));
napi_set_named_property(env, objValue, "RESTART_WHEN_APP_FREEZE",
CreateJsValue(env, RestartFlag::RESTART_WHEN_APP_FREEZE));
napi_set_named_property(env, objValue, "RESTART_WHEN_CPP_CRASH",
CreateJsValue(env, RestartFlag::RESTART_WHEN_CPP_CRASH));
napi_set_named_property(env, objValue, "NO_RESTART", CreateJsValue(env, RestartFlag::NO_RESTART));
return objValue;
}
@@ -143,6 +143,8 @@ bool AppRecovery::AddAbility(std::shared_ptr<AbilityRuntime::UIAbility> ability,
abilityRecovery->EnableAbilityRecovery(useAppSettedValue_.load(), restartFlag_, saveOccasion_, saveMode_);
ability->EnableAbilityRecovery(abilityRecovery, useAppSettedValue_.load());
abilityRecoverys_.push_back(abilityRecovery);
std::shared_ptr<AAFwk::AbilityManagerClient> abilityMgr = AAFwk::AbilityManagerClient::GetInstance();
abilityMgr->SetAppRecoveryFlag(token_.promote(), restartFlag_);
return true;
}
@@ -2088,6 +2088,13 @@ public:
*/
ErrCode GetUserLockedBundleList(int32_t userId, std::unordered_set<std::string> &userLockedBundleList);
/**
* @brief UnRegister preload ui extension host client.
*
* @return Returns ERR_OK on success, others on failure.
*/
int32_t SetAppRecoveryFlag(const sptr<IRemoteObject>& token, int flag);
private:
AbilityManagerClient();
DISALLOW_COPY_AND_MOVE(AbilityManagerClient);
@@ -2588,6 +2588,17 @@ public:
{
return ERR_OK;
}
/**
* @brief Set app recovery galg.
* @param token Caller ability token.
* @param flag App recovery flag.
* @return Returns ERR_OK on success, others on failure.
*/
virtual int32_t SetAppRecoveryFlag(const sptr<IRemoteObject>& token, int flag)
{
return 0;
}
};
} // namespace AAFwk
} // namespace OHOS
@@ -711,6 +711,9 @@ enum class AbilityManagerInterfaceCode {
// get user locked bundle list
GET_USER_LOCKED_BUNDLE_LIST = 6159,
// set app recovery flag
SET_APP_RECOVERY_FLAG = 6160,
};
} // namespace AAFwk
} // namespace OHOS
@@ -44,6 +44,7 @@ enum RestartFlag {
ALWAYS_RESTART = 0,
RESTART_WHEN_JS_CRASH = 0x0001,
RESTART_WHEN_APP_FREEZE = 0x0002,
RESTART_WHEN_CPP_CRASH = 0x0008,
NO_RESTART = 0xFFFF,
};
@@ -57,6 +57,7 @@ ohos_shared_library("app_manager") {
"${ability_runtime_services_path}/appdfr/src/appfreeze_cpu_freq_manager.cpp",
"${ability_runtime_services_path}/appdfr/src/appfreeze_event_report.cpp",
"${ability_runtime_services_path}/appdfr/src/appfreeze_manager.cpp",
"${ability_runtime_services_path}/appdfr/src/app_recovery_mgr.cpp",
"${ability_runtime_services_path}/appdfr/src/appfreeze_util.cpp",
"${ability_runtime_services_path}/appdfr/src/cpu_data_processor.cpp",
"${ability_runtime_services_path}/appdfr/src/cpu_sys_config.cpp",
@@ -164,6 +165,8 @@ ohos_shared_library("app_manager") {
"hicollie:libhicollie",
"hilog:libhilog",
"hisysevent:libhisysevent",
"eventhandler:libeventhandler",
"ability_base:session_info",
"hitrace:hitrace_meter",
"hitrace:libhitracechain",
"init:libbegetutil",
@@ -45,6 +45,7 @@ enum RestartFlag {
RESTART_WHEN_JS_CRASH = 0x0001,
RESTART_WHEN_APP_FREEZE = 0x0002,
RESTART_WHEN_CJ_CRASH = 0x0004,
RESTART_WHEN_CPP_CRASH = 0x0008,
NO_RESTART = 0xFFFF,
};
@@ -2013,6 +2013,7 @@ public:
virtual int32_t GetUserLockedBundleList(int32_t userId,
std::unordered_set<std::string> &userLockedBundleList) override;
virtual int32_t SetAppRecoveryFlag(const sptr<IRemoteObject>& token, int flag)override;
private:
template <typename T>
int GetParcelableInfos(MessageParcel &reply, std::vector<T> &parcelableInfos);
@@ -3356,6 +3356,14 @@ private:
bool IsAllowAttachOrDetachAppDebug(AppExecFwk::ApplicationInfo &appInfo);
bool IsExitReasonValid(const ExitReasonCompability &reason);
void RecordRecoveryExitReason(bool isAppRecovery, int32_t callerPid, int32_t callerUid);
void SetAppDeathRecipient(const sptr<IRemoteObject>& abilityToken);
void HandleAppDiedForRecovery(const sptr<IRemoteObject>& remote, const AbilityInfo& abilityInfo,
int32_t pid, int32_t uid);
void startRecoveryMgr();
int getAppRecoveryFlag(const sptr<IRemoteObject> &token);
void HandleRecoveryRecipient(const std::shared_ptr<AbilityRecord>& abilityRecord,
const sptr<IRemoteObject>& token);
int32_t SetAppRecoveryFlag(const sptr<IRemoteObject>& token, int flag) override;
#ifdef BGTASKMGR_CONTINUOUS_TASK_ENABLE
std::shared_ptr<BackgroundTaskObserver> bgtaskObserver_;
#endif
@@ -364,6 +364,7 @@ private:
int32_t ClearAllPreloadUIExtensionAbilityInner(MessageParcel &data, MessageParcel &reply);
int32_t RegisterPreloadUIExtensionHostClientInner(MessageParcel &data, MessageParcel &reply);
int32_t UnRegisterPreloadUIExtensionHostClientInner(MessageParcel &data, MessageParcel &reply);
int32_t SetAppRecoveryFlagInner(MessageParcel &data, MessageParcel &reply);
int OnRemoteRequestInnerFirst(uint32_t code, MessageParcel &data,
MessageParcel &reply, MessageOption &option);
@@ -830,6 +830,8 @@ public:
return firstCallerBundleName_;
}
void SetAppRecoveryFlag(int flag);
int GetAppRecoveryFlag() const;
protected:
Want want_ = {}; // want to start this ability
std::unique_ptr<LifecycleDeal> lifecycleDeal_ = {}; // life manager used to schedule life
@@ -1037,6 +1039,7 @@ protected:
bool isStartingWindow_ = false;
bool isCompleteFirstFrameDrawing_ = false;
bool coldStart_ = false;
int appRecoveryFlag_ = 0xFFFF;
#endif
};
} // namespace AAFwk
@@ -2563,5 +2563,19 @@ ErrCode AbilityManagerClient::GetUserLockedBundleList(int32_t userId,
CHECK_POINTER_RETURN_NOT_CONNECTED(abms);
return abms->GetUserLockedBundleList(userId, userLockedBundleList);
}
int32_t AbilityManagerClient::SetAppRecoveryFlag(const sptr<IRemoteObject>& token, int flag)
{
if (token == nullptr) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "token is nullptr");
return ERR_INVALID_VALUE;
}
auto proxy = GetAbilityManager();
if (proxy == nullptr) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "GetAbilityManager proxy failed");
return ERR_INVALID_VALUE;
}
return proxy->SetAppRecoveryFlag(token, flag);
}
} // namespace AAFwk
} // namespace OHOS
@@ -7683,5 +7683,32 @@ int32_t AbilityManagerProxy::GetUserLockedBundleList(int32_t userId,
}
return NO_ERROR;
}
int32_t AbilityManagerProxy::SetAppRecoveryFlag(const sptr<IRemoteObject>& token, int flag)
{
MessageParcel data;
MessageParcel reply;
MessageOption option;
if (!data.WriteInterfaceToken(AbilityManagerProxy::GetDescriptor())) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "Write interface token failed");
return ERR_INVALID_VALUE;
}
if (!data.WriteRemoteObject(token)) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "Write token failed");
return ERR_INVALID_VALUE;
}
if (!data.WriteInt32(flag)) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "Write flag failed");
return ERR_INVALID_VALUE;
}
int32_t error = SendRequest(AbilityManagerInterfaceCode::SET_APP_RECOVERY_FLAG, data, reply, option);
if (error != NO_ERROR) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "SendRequest failed");
return error;
}
return reply.ReadInt32();
}
} // namespace AAFwk
} // namespace OHOS
@@ -32,6 +32,7 @@
#include "app_exit_reason_data_manager.h"
#include "app_mgr_constants.h"
#include "app_mgr_util.h"
#include "app_recovery_mgr.h"
#include "application_util.h"
#include "assert_fault_callback_death_mgr.h"
#include "collaborator_util.h"
@@ -16739,5 +16740,100 @@ bool AbilityManagerService::IsExitReasonValid(const ExitReasonCompability &reaso
}
return true;
}
int32_t AbilityManagerService::SetAppRecoveryFlag(const sptr<IRemoteObject>& token, int flag)
{
auto abilityRecord = Token::GetAbilityRecordByToken(token);
if (abilityRecord == nullptr) {
TAG_LOGE(AAFwkTag::UI_EXT,"AbilityRecord not found for given token");
return ERR_INVALID_VALUE;
}
abilityRecord->SetAppRecoveryFlag(flag);
HandleRecoveryRecipient(abilityRecord, token);
return ERR_OK;
}
void AbilityManagerService::HandleRecoveryRecipient(
const std::shared_ptr<AbilityRecord>& abilityRecord,
const sptr<IRemoteObject>& token)
{
int restartFlag = abilityRecord->GetAppRecoveryFlag();
TAG_LOGD(AAFwkTag::ABILITYMGR, "%{public}s SetAppDeathRecipient, restartFlag is %{public}d",
abilityRecord->GetAbilityInfo().bundleName.c_str(),
restartFlag);
if (restartFlag == AppExecFwk::RestartFlag::ALWAYS_RESTART ||
(restartFlag & AppExecFwk::RestartFlag::RESTART_WHEN_CPP_CRASH) != 0) {
TAG_LOGD(AAFwkTag::ABILITYMGR, "enable OnAbilityRequestDone");
SetAppDeathRecipient(token);
}
}
void AbilityManagerService::SetAppDeathRecipient(const sptr<IRemoteObject> &token)
{
auto abilityRecord = Token::GetAbilityRecordByToken(token);
const auto &abilityInfo = abilityRecord->GetAbilityInfo();
int32_t pid = abilityRecord->GetPid();
int32_t uid = abilityRecord->GetUid();
auto callback = [this,abilityInfo,pid,uid](const sptr<IRemoteObject>& remote) {
this->HandleAppDiedForRecovery(remote,abilityInfo,pid,uid);
};
AppRecoveryMgr::AppRecoveryMgr::GetInstance().SetOnRemoteDieCallback(token, callback);
}
void AbilityManagerService::HandleAppDiedForRecovery(const sptr<IRemoteObject>& remote,
const AbilityInfo& abilityInfo,
int32_t pid,
int32_t uid)
{
if (remote == nullptr) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "remote is null, cannot recover app");
return;
}
if (abilityInfo.bundleName.empty() || abilityInfo.name.empty()) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "abilityInfo is invalid: bundleName or name is empty");
return;
}
constexpr int64_t ONE_SECOND_MS = 1000;
constexpr int64_t RECOVERY_DELAY = 5000;
constexpr int64_t MIN_RECOVERY_TIME = 60;
int64_t now = time(nullptr);
auto it = appRecoveryHistory_.find(uid);
bool isSetReason = false;
int64_t stamp = 0;
bool withKillMsg = false;
AppExecFwk::RunningProcessInfo processInfo;
auto accessTokenId = abilityInfo.applicationInfo.accessTokenId;
AAFwk::ExitReason exitReason = {AAFwk::REASON_JS_ERROR, "Js Error."};
auto result = DelayedSingleton<AppExitReasonDataManager>::GetInstance()->GetAppExitReason(abilityInfo.bundleName, accessTokenId,
abilityInfo.name, isSetReason, exitReason, processInfo, stamp, withKillMsg);
if(exitReason.reason!= AAFwk::REASON_CPP_CRASH) {
TAG_LOGI(AAFwkTag::APPMGR, "app exit reason is not REASON_CPP_CRASH");
return;
}
if ((it != appRecoveryHistory_.end()) &&
(it->second + MIN_RECOVERY_TIME > now)) {
TAG_LOGW(AAFwkTag::ABILITYMGR,
"%{public}s appRecovery recover too frequently in one minute, kill app(%{public}d). "
"Last recovery: %{public}lld, Now: %{public}lld",
__func__,
pid,
static_cast<long long>(it->second),
static_cast<long long>(now));
} else if (std::abs(now*ONE_SECOND_MS-stamp)>RECOVERY_DELAY){
TAG_LOGW(AAFwkTag::ABILITYMGR,"now is %{public}lld,timestamp is %{public}lld,no recovery",static_cast<long long>(now),static_cast<long long>(stamp));
} else {
appRecoveryHistory_[uid] = now;
AAFwk::Want *newWant=new AAFwk::Want();
newWant->SetElementName(abilityInfo.bundleName, abilityInfo.name);
newWant->SetParam(AAFwk::Want::PARAM_ABILITY_RECOVERY_RESTART, true);
StartAbility(*newWant,MAIN_USER_ID);
TAG_LOGW(AAFwkTag::ABILITYMGR,"now is %{public}lld,timestamp is %{public}lld",static_cast<long long>(now),static_cast<long long>(stamp));
}
if (remote != nullptr) {
AppRecoveryMgr::AppRecoveryMgr::GetInstance().RemoveOnRemoteDieCallback(remote);
}
}
} // namespace AAFwk
} // namespace OHOS
@@ -965,6 +965,9 @@ int AbilityManagerStub::OnRemoteRequestInnerTwentySecond(uint32_t code, MessageP
if (interfaceCode == AbilityManagerInterfaceCode::GET_USER_LOCKED_BUNDLE_LIST) {
return GetUserLockedBundleListInner(data, reply);
}
if (interfaceCode == AbilityManagerInterfaceCode::SET_APP_RECOVERY_FLAG) {
return SetAppRecoveryFlagInner(data, reply);
}
return ERR_CODE_NOT_EXIST;
}
@@ -5327,5 +5330,18 @@ int32_t AbilityManagerStub::GetUserLockedBundleListInner(MessageParcel &data, Me
}
return result;
}
int32_t AbilityManagerStub::SetAppRecoveryFlagInner(MessageParcel &data, MessageParcel &reply)
{
sptr<IRemoteObject> token = data.ReadRemoteObject();
if (token == nullptr) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "Read token failed");
return ERR_INVALID_VALUE;
}
int flag = data.ReadInt32();
int32_t result = SetAppRecoveryFlag(token, flag);
reply.WriteInt32(result);
return NO_ERROR;
}
} // namespace AAFwk
} // namespace OHOS
@@ -3433,5 +3433,16 @@ void AbilityRecord::PluginCompleteTerminate()
hostAbility->GetAbilityInfo().name.c_str());
}
}
void AbilityRecord::SetAppRecoveryFlag(int flag)
{
TAG_LOGE(AAFwkTag::ABILITYMGR, "SetAppRecoveryFlag:%{public}d", flag);
appRecoveryFlag_ = flag;
}
int AbilityRecord::GetAppRecoveryFlag() const
{
return appRecoveryFlag_;
}
} // namespace AAFwk
} // namespace OHOS
@@ -0,0 +1,56 @@
/*
* Copyright (c) 2023 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_APP_RECOVERY_MGR_H
#define OHOS_ABILITY_RUNTIME_APP_RECOVERY_MGR_H
#include "cpp/mutex.h"
#include <map>
#include "iremote_object.h"
#include "refbase.h"
#include "event_handler.h"
namespace OHOS {
namespace AppRecoveryMgr {
class AppRecoveryMgr {
public:
static AppRecoveryMgr& GetInstance();
void SetOnRemoteDieCallback(const sptr<IRemoteObject>& abilityToken,
const std::function<void(const sptr<IRemoteObject>&)>& callback);
void RemoveOnRemoteDieCallback(const sptr<IRemoteObject>& abilityToken);
void HandleAppDied(const sptr<IRemoteObject>& remote);
void Init(const std::shared_ptr<AppExecFwk::EventHandler>& handler);
void Clear();
private:
AppRecoveryMgr();
~AppRecoveryMgr();
std::function<void(const sptr<IRemoteObject>&)> FindCallback(const sptr<IRemoteObject>& remote);
private:
std::mutex mutex_;
std::shared_ptr<AppExecFwk::EventHandler> handler_;
std::map<sptr<IRemoteObject>, std::function<void(const sptr<IRemoteObject>&)>> dieCallbacks_;
};
} // namespace AppRecoveryMgr
} // namespace OHOS
#endif // OHOS_ABILITY_RUNTIME_APP_RECOVERY_MGR_H
+122
View File
@@ -0,0 +1,122 @@
/*
* Copyright (c) 2023-2025 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 "app_recovery_mgr.h"
#include "hilog_tag_wrapper.h"
namespace OHOS {
namespace AppRecoveryMgr {
AppRecoveryMgr::AppRecoveryMgr()
{
}
AppRecoveryMgr::~AppRecoveryMgr()
{
}
AppRecoveryMgr& AppRecoveryMgr::GetInstance()
{
static AppRecoveryMgr instance;
return instance;
}
void AppRecoveryMgr::Init(const std::shared_ptr<AppExecFwk::EventHandler>& handler)
{
std::lock_guard<std::mutex> lock(mutex_);
handler_ = handler;
TAG_LOGI(AAFwkTag::APPDFR, "AppRecoveryMgr initialized");
}
void AppRecoveryMgr::SetOnRemoteDieCallback(const sptr<IRemoteObject>& abilityToken,
const std::function<void(const sptr<IRemoteObject>&)>& callback)
{
if (abilityToken == nullptr || callback == nullptr) {
TAG_LOGI(AAFwkTag::APPDFR, "SetOnRemoteDieCallback: invalid parameter");
return;
}
std::lock_guard<std::mutex> lock(mutex_);
auto it = dieCallbacks_.find(abilityToken);
if (it != dieCallbacks_.end()) {
TAG_LOGI(AAFwkTag::APPDFR, "SetOnRemoteDieCallback: callback already exists, updating");
dieCallbacks_.erase(it);
}
dieCallbacks_.emplace(abilityToken, callback);
TAG_LOGI(AAFwkTag::APPDFR, "SetOnRemoteDieCallback: callback set for ability token");
}
void AppRecoveryMgr::RemoveOnRemoteDieCallback(const sptr<IRemoteObject>& abilityToken)
{
if (abilityToken == nullptr) {
TAG_LOGI(AAFwkTag::APPDFR, "RemoveOnRemoteDieCallback: invalid parameter");
return;
}
std::lock_guard<std::mutex> lock(mutex_);
auto it = dieCallbacks_.find(abilityToken);
if (it != dieCallbacks_.end()) {
dieCallbacks_.erase(it);
TAG_LOGI(AAFwkTag::APPDFR, "RemoveOnRemoteDieCallback: callback removed");
}
}
std::function<void(const sptr<IRemoteObject>&)> AppRecoveryMgr::FindCallback(const sptr<IRemoteObject>& remote)
{
std::lock_guard<std::mutex> lock(mutex_);
if (remote == nullptr) {
return nullptr;
}
auto it = dieCallbacks_.find(remote);
if (it != dieCallbacks_.end()) {
return it->second;
}
return nullptr;
}
void AppRecoveryMgr::HandleAppDied(const sptr<IRemoteObject>& remote)
{
TAG_LOGI(AAFwkTag::APPDFR, "HandleAppDied: app died event received");
auto callback = FindCallback(remote);
if (callback == nullptr) {
TAG_LOGI(AAFwkTag::APPDFR, "HandleAppDied: no callback found for this remote");
return;
}
if (handler_ != nullptr) {
auto task = [callback, remote]() {
callback(remote);
};
handler_->PostTask(task);
TAG_LOGI(AAFwkTag::APPDFR, "HandleAppDied: callback posted to handler");
} else {
callback(remote);
TAG_LOGI(AAFwkTag::APPDFR, "HandleAppDied: callback executed directly no handler");
}
}
void AppRecoveryMgr::Clear()
{
std::lock_guard<std::mutex> lock(mutex_);
dieCallbacks_.clear();
handler_ = nullptr;
TAG_LOGI(AAFwkTag::APPDFR, "AppRecoveryMgr cleared");
}
} // namespace AppRecoveryMgr
} // namespace OHOS
@@ -2223,6 +2223,8 @@ private:
void RemoveUninstallOrUpgradeUidSet(int32_t uid);
bool IsUninstallingOrUpgrading(int32_t uid);
void SendProcessKillEvent(std::shared_ptr<AppRunningRecord> appRecord);
void HandleForegroundAbilityDied(const std::vector<sptr<IRemoteObject>>& abilityTokens,
ApplicationState state);
std::shared_ptr<RemoteClientManager> remoteClientManager_;
std::shared_ptr<AppRunningManager> appRunningManager_;
@@ -36,6 +36,7 @@
#include "app_mgr_service.h"
#include "app_mgr_event.h"
#include "app_process_data.h"
#include "app_recovery_mgr.h"
#include "app_state_observer_manager.h"
#include "app_utils.h"
#include "appfreeze_manager.h"
@@ -5184,6 +5185,7 @@ void AppMgrServiceInner::OnRemoteDied(const wptr<IRemoteObject> &remote, bool is
for (const auto &token : appRecord->GetAbilities()) {
abilityTokens.emplace_back(token.first);
}
HandleForegroundAbilityDied(abilityTokens,appRecord->GetState());
{
std::lock_guard lock(appStateCallbacksLock_);
for (const auto &item : appStateCallbacks_) {
@@ -11498,5 +11500,22 @@ void AppMgrServiceInner::CheckRenderAttachTimeout(std::shared_ptr<RenderRecord>
AppMgrEventUtil::SendRenderProcessStartFailedEvent(renderRecord,
ProcessStartFailedReason::ATTACH_TIMEOUT, elapsedMs);
}
void AppMgrServiceInner::HandleForegroundAbilityDied(
const std::vector<sptr<IRemoteObject>>& abilityTokens,ApplicationState state)
{
if (state != ApplicationState::APP_STATE_FOREGROUND) {
return;
}
TAG_LOGD(AAFwkTag::APPMGR, "Handling died abilities in foreground.");
for (const auto& token : abilityTokens) {
if (token == nullptr) {
continue;
}
AppRecoveryMgr::AppRecoveryMgr::GetInstance().HandleAppDied(token);
TAG_LOGI(AAFwkTag::APPMGR, "Notified AppRecoveryMgr for ability token: %{public}p",
token.GetRefPtr());
}
}
} // namespace AppExecFwk
} // namespace OHOS
@@ -1724,5 +1724,15 @@ bool AbilityRecord::PromotePriority()
{
return false;
}
void AbilityRecord::SetAppRecoveryFlag(int flag)
{
TAG_LOGE(AAFwkTag::ABILITYMGR, "SetAppRecoveryFlag%{public}d", flag);
appRecoveryFlag_ = flag;
}
int AbilityRecord::GetAppRecoveryFlag() const
{
return appRecoveryFlag_;
}
} // namespace AAFwk
} // namespace OHOS
@@ -1744,5 +1744,15 @@ bool AbilityRecord::PromotePriority()
{
return false;
}
void AbilityRecord::SetAppRecoveryFlag(int flag)
{
TAG_LOGE(AAFwkTag::ABILITYMGR, "SetAppRecoveryFlag%{public}d", flag);
appRecoveryFlag_ = flag;
}
int AbilityRecord::GetAppRecoveryFlag() const
{
return appRecoveryFlag_;
}
} // namespace AAFwk
} // namespace OHOS