* Copyright (c) 2024-2026 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_exit_reason_helper.h"
#include "accesstoken_kit.h"
#include "app_exit_reason_data_manager.h"
#include "app_mgr_util.h"
#include "bundle_mgr_helper.h"
#include "exit_info_data_manager.h"
#include "hitrace_meter.h"
#include "os_account_manager_wrapper.h"
#include "scene_board_judgement.h"
namespace OHOS {
namespace AAFwk {
namespace {
constexpr int32_t INVALID_KILLID = -2;
constexpr int32_t DEFAULT_KILL_ID = -1;
constexpr int32_t DEFAULT_PROCESS_RUNNING_INFO_PID = 0;
}
AppExitReasonHelper::AppExitReasonHelper(std::shared_ptr<SubManagersHelper> subManagersHelper)
: subManagersHelper_(subManagersHelper) {}
int32_t AppExitReasonHelper::RecordAppWithReason(int32_t pid, int32_t uid, const ExitReasonCompability &exitReason)
{
std::string bundleName;
int32_t userId = DEFAULT_INVAL_VALUE;
int32_t appIndex = DEFAULT_INVAL_VALUE;
if (pid == NO_PID) {
auto ret = IN_PROCESS_CALL(AbilityUtil::GetBundleManagerHelper()->GetNameAndIndexForUid(
uid, bundleName, appIndex));
if (ret != ERR_OK) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "GetNameAndIndexForUid failed, ret: %{public}d", ret);
return ret;
}
int32_t getOsAccountRet = AppExecFwk::OsAccountManagerWrapper::
GetOsAccountLocalIdFromUid(uid, userId);
if (getOsAccountRet != ERR_OK) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "get GetOsAccountLocalIdFromUid failed. ret: %{public}d", getOsAccountRet);
return getOsAccountRet;
}
}
AppExecFwk::RunningProcessInfo processInfo;
GetRunningProcessInfo(pid, userId, bundleName, processInfo, appIndex);
TAG_LOGD(AAFwkTag::ABILITYMGR, "RecordAppWithReason inputPid: %{public}d, processPid: %{public}d",
pid, processInfo.pid_);
return RecordAppWithReasonInner(exitReason, processInfo);
}
int32_t AppExitReasonHelper::RecordAppWithReasonInner(const ExitReasonCompability &exitReasonCompability,
const AppExecFwk::RunningProcessInfo &processInfo)
{
if (processInfo.pid_ <= 0 || processInfo.uid_ <= 0 || processInfo.bundleNames.empty()) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "processInfo is invalid, pid: %{public}d, uid: %{public}d, "
"bundleNames empty: %{public}d", processInfo.pid_, processInfo.uid_, processInfo.bundleNames.empty());
return ERR_INVALID_VALUE;
}
std::string bundleName = processInfo.bundleNames.front();
ExitReason exitReason(exitReasonCompability.reason, exitReasonCompability.subReason,
exitReasonCompability.exitMsg);
exitReason.killId = exitReasonCompability.killId;
int32_t extensionResultCode = RecordProcessExtensionExitReason(
processInfo.pid_, bundleName, exitReason, processInfo, false);
if (extensionResultCode != ERR_OK) {
TAG_LOGW(AAFwkTag::ABILITYMGR, "record extension reason failed. bundleName: %{public}s, ret: %{public}d",
bundleName.c_str(), extensionResultCode);
}
int32_t ret = DelayedSingleton<AppScheduler>::GetInstance()->NotifyAppMgrRecordExitReasonCompability(
processInfo.pid_, exitReasonCompability.killId, exitReasonCompability.killMsg,
exitReasonCompability.innerMsg);
if (ret != ERR_OK) {
TAG_LOGW(AAFwkTag::ABILITYMGR, "notify failed: %{public}d", ret);
}
std::vector<std::string> abilityList;
int32_t getActiveAbilityListRet = GetActiveAbilityListWithPid(processInfo.uid_, abilityList, processInfo.pid_);
if (getActiveAbilityListRet != ERR_OK) {
return getActiveAbilityListRet;
}
if (abilityList.empty()) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "abilityLists empty");
return ERR_GET_ACTIVE_ABILITY_LIST_EMPTY;
}
uint32_t accessTokenId = processInfo.accessTokenId_;
TAG_LOGD(AAFwkTag::ABILITYMGR,
"bundleName: %{public}s, accessTokenId: %{public}u", bundleName.c_str(), accessTokenId);
return DelayedSingleton<AbilityRuntime::AppExitReasonDataManager>::GetInstance()->SetAppExitReason(
bundleName, accessTokenId, abilityList, exitReason, processInfo, false);
}
void AppExitReasonHelper::RecordAppsWithReasonByProcessInfoList(const ExitReasonCompability &exitReason,
const std::vector<AppExecFwk::RunningProcessInfo> &processInfoList)
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
int32_t innerResult = ERR_OK;
for (const auto &processInfo : processInfoList) {
TAG_LOGD(AAFwkTag::ABILITYMGR, "RecordAppsWithReasonByProcessInfoList uid: %{public}d, pid: %{public}d",
processInfo.uid_, processInfo.pid_);
innerResult = RecordAppWithReasonInner(exitReason, processInfo);
if (innerResult != ERR_OK) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "RecordAppWithReasonInner failed for uid:%{public}d, ret: %{public}d",
processInfo.uid_, innerResult);
continue;
}
}
}
int32_t AppExitReasonHelper::RecordAppExitReason(const ExitReason &exitReason)
{
if (!IsExitReasonValid(exitReason)) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "exit reason invalid");
return ERR_INVALID_VALUE;
}
auto uid = IPCSkeleton::GetCallingUid();
std::string bundleName;
int32_t appIndex = 0;
auto ret = IN_PROCESS_CALL(AbilityUtil::GetBundleManagerHelper()->GetNameAndIndexForUid(uid, bundleName, appIndex));
if (ret != ERR_OK) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "GetNameAndIndexForUid failed, ret: %{public}d", ret);
return ret;
}
int32_t pid = exitReason.reason != Reason::REASON_CPP_CRASH ? IPCSkeleton::GetCallingPid() : NO_PID;
AppExecFwk::RunningProcessInfo processInfo;
int32_t userId = -1;
int32_t getOsAccountRet = AppExecFwk::OsAccountManagerWrapper::
GetOsAccountLocalIdFromUid(uid, userId);
if (getOsAccountRet != ERR_OK) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "get GetOsAccountLocalIdFromUid failed. ret: %{public}d", getOsAccountRet);
return getOsAccountRet;
}
GetRunningProcessInfo(pid, userId, bundleName, processInfo);
int32_t resultCode = RecordProcessExtensionExitReason(pid, bundleName, exitReason, processInfo, false);
if (resultCode != ERR_OK) {
TAG_LOGI(AAFwkTag::ABILITYMGR, "not record extension reason: %{public}d", resultCode);
}
std::vector<std::string> abilityList;
int32_t getActiveAbilityListRet = GetActiveAbilityListWithPid(uid, abilityList, pid);
if (getActiveAbilityListRet != ERR_OK) {
return getActiveAbilityListRet;
}
ret = DelayedSingleton<AppScheduler>::GetInstance()->NotifyAppMgrRecordExitReason(IPCSkeleton::GetCallingPid(),
exitReason.reason, exitReason.exitMsg);
if (ret != ERR_OK) {
TAG_LOGI(AAFwkTag::ABILITYMGR, "notify ret: %{public}d", ret);
}
if (abilityList.empty()) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "abilityLists empty");
return ERR_GET_ACTIVE_ABILITY_LIST_EMPTY;
}
TAG_LOGD(AAFwkTag::ABILITYMGR,
"userId: %{public}d, bundleName: %{public}s, appIndex: %{public}d", userId, bundleName.c_str(), appIndex);
uint32_t accessTokenId = Security::AccessToken::AccessTokenKit::GetHapTokenID(userId, bundleName, appIndex);
return DelayedSingleton<AbilityRuntime::AppExitReasonDataManager>::GetInstance()->SetAppExitReason(bundleName,
accessTokenId, abilityList, exitReason, processInfo, false);
}
int32_t AppExitReasonHelper::RecordProcessExitReasonForTimeout(const AppExecFwk::AbilityInfo &abilityInfo,
const ExitReason &exitReason, const std::vector<std::string> &abilityList,
const AppExecFwk::RunningProcessInfo &processInfo)
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
auto pid = processInfo.pid_;
if (!IsExitReasonValid(exitReason) || pid <= 0) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "invalid params");
return ERR_INVALID_VALUE;
}
std::string bundleName = abilityInfo.bundleName;
auto uid = abilityInfo.applicationInfo.uid;
auto accessTokenId = abilityInfo.applicationInfo.accessTokenId;
int32_t resultCode = RecordProcessExtensionExitReason(pid, bundleName, exitReason, processInfo, false);
if (resultCode != ERR_OK) {
TAG_LOGI(AAFwkTag::ABILITYMGR, "not record extension reason: %{public}d", resultCode);
}
int32_t targetUserId;
int32_t getOsAccountRet = AppExecFwk::OsAccountManagerWrapper::
GetOsAccountLocalIdFromUid(uid, targetUserId);
if (getOsAccountRet != ERR_OK) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "get GetOsAccountLocalIdFromUid failed. ret: %{public}d", getOsAccountRet);
return ERR_INVALID_VALUE;
}
TAG_LOGD(AAFwkTag::ABILITYMGR, "targetUserId: %{public}d", targetUserId);
auto ret = DelayedSingleton<AppScheduler>::GetInstance()->NotifyAppMgrRecordExitReason(pid, exitReason.reason,
exitReason.exitMsg);
if (ret != ERR_OK) {
TAG_LOGI(AAFwkTag::ABILITYMGR, "notify ret:%{public}d", ret);
}
if (abilityList.empty()) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "active abilityList empty");
return ERR_GET_ACTIVE_ABILITY_LIST_EMPTY;
}
return DelayedSingleton<AbilityRuntime::AppExitReasonDataManager>::GetInstance()->SetAppExitReason(bundleName,
accessTokenId, abilityList, exitReason, processInfo, false);
}
int32_t AppExitReasonHelper::RecordProcessExitReason(const int32_t pid, const ExitReason &exitReason,
bool fromKillWithReason)
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
AppExecFwk::ApplicationInfo application;
bool debug = false;
auto ret = IN_PROCESS_CALL(DelayedSingleton<AppScheduler>::GetInstance()->GetApplicationInfoByProcessID(pid,
application, debug));
if (ret != ERR_OK) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "getApplicationInfoByProcessID failed: %{public}d", ret);
return ret;
}
auto bundleName = application.bundleName;
AppExecFwk::RunningProcessInfo processInfo;
if (pid > 0) {
DelayedSingleton<AppScheduler>::GetInstance()->GetRunningProcessInfoByPid(
static_cast<pid_t>(pid), processInfo);
}
int32_t resultCode = RecordProcessExtensionExitReason(pid, bundleName, exitReason, processInfo,
fromKillWithReason);
if (resultCode != ERR_OK) {
TAG_LOGI(AAFwkTag::ABILITYMGR, "not record extension reason: %{public}d", resultCode);
}
return RecordProcessExitReason(pid, bundleName, application.uid, application.accessTokenId, exitReason,
processInfo, fromKillWithReason);
}
int32_t AppExitReasonHelper::RecordAppExitReason(const std::string &bundleName, int32_t uid, int32_t appIndex,
const ExitReason &exitReason)
{
int32_t userId;
int32_t getOsAccountRet = AppExecFwk::OsAccountManagerWrapper::
GetOsAccountLocalIdFromUid(uid, userId);
if (getOsAccountRet != ERR_OK) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "get GetOsAccountLocalIdFromUid failed. ret: %{public}d", getOsAccountRet);
return ERR_INVALID_VALUE;
}
TAG_LOGD(AAFwkTag::ABILITYMGR,
"userId: %{public}d, bundleName: %{public}s, appIndex: %{public}d", userId, bundleName.c_str(), appIndex);
uint32_t accessTokenId = Security::AccessToken::AccessTokenKit::GetHapTokenID(userId, bundleName, appIndex);
AppExecFwk::RunningProcessInfo processInfo;
GetRunningProcessInfo(NO_PID, userId, bundleName, processInfo, appIndex);
int32_t pid = processInfo.pid_ == DEFAULT_PROCESS_RUNNING_INFO_PID ? NO_PID : processInfo.pid_;
return RecordProcessExitReason(pid, bundleName, uid, accessTokenId, exitReason, processInfo, false);
}
int32_t AppExitReasonHelper::RecordProcessExitReason(int32_t pid, int32_t uid, const ExitReason &exitReason)
{
uint32_t accessTokenId = 0;
AbilityRuntime::ExitCacheInfo cacheInfo = {};
if (!AbilityRuntime::ExitInfoDataManager::GetInstance().GetExitInfo(pid, uid, accessTokenId, cacheInfo)) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "not found, pid: %{public}d, uid: %{public}d", pid, uid);
return ERR_NO_APP_RECORD;
}
return DelayedSingleton<AbilityRuntime::AppExitReasonDataManager>::GetInstance()->SetAppExitReason(
cacheInfo.bundleName, accessTokenId, cacheInfo.abilityNames, exitReason, cacheInfo.exitInfo, false);
}
int32_t AppExitReasonHelper::RecordProcessExitReason(const int32_t pid, const std::string bundleName,
const int32_t uid, const uint32_t accessTokenId, const ExitReason &exitReason,
const AppExecFwk::RunningProcessInfo &processInfo, bool fromKillWithReason)
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
if (!IsExitReasonValid(exitReason)) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "reason invalid");
return ERR_INVALID_VALUE;
}
int32_t targetUserId;
int32_t getOsAccountRet = AppExecFwk::OsAccountManagerWrapper::
GetOsAccountLocalIdFromUid(uid, targetUserId);
if (getOsAccountRet != ERR_OK) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "get GetOsAccountLocalIdFromUid failed. ret: %{public}d", getOsAccountRet);
return ERR_INVALID_VALUE;
}
TAG_LOGD(AAFwkTag::ABILITYMGR, "targetUserId: %{public}d", targetUserId);
std::vector<std::string> abilityLists;
if (Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {
GetActiveAbilityListFromUIAbilityManager(uid, abilityLists, pid);
} else {
GetActiveAbilityList(uid, abilityLists, pid);
}
if (exitReason.killId != DEFAULT_KILL_ID) {
ExitReasonCompability exitReasonCompability(exitReason);
int32_t ret = DelayedSingleton<AppScheduler>::GetInstance()->NotifyAppMgrRecordExitReasonCompability(
pid, exitReasonCompability.killId, exitReasonCompability.killMsg, exitReasonCompability.innerMsg);
if (ret != ERR_OK) {
TAG_LOGW(AAFwkTag::ABILITYMGR, "notify compability failed: %{public}d", ret);
}
}
auto ret = DelayedSingleton<AppScheduler>::GetInstance()->NotifyAppMgrRecordExitReason(pid, exitReason.reason,
exitReason.exitMsg);
if (ret != ERR_OK) {
TAG_LOGI(AAFwkTag::ABILITYMGR, "notify ret:%{public}d", ret);
}
if (abilityLists.empty()) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "active abilityLists empty");
return ERR_GET_ACTIVE_ABILITY_LIST_EMPTY;
}
return DelayedSingleton<AbilityRuntime::AppExitReasonDataManager>::GetInstance()->SetAppExitReason(bundleName,
accessTokenId, abilityLists, exitReason, processInfo, fromKillWithReason);
}
int32_t AppExitReasonHelper::RecordProcessExtensionExitReason(
const int32_t pid, const std::string &bundleName, const ExitReason &exitReason,
const AppExecFwk::RunningProcessInfo &processInfo, bool withKillMsg)
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
TAG_LOGD(AAFwkTag::ABILITYMGR, "called");
CHECK_POINTER_AND_RETURN(subManagersHelper_, ERR_NULL_OBJECT);
auto connectManager = subManagersHelper_->GetCurrentUIExtensionAbilityManager();
CHECK_POINTER_AND_RETURN(connectManager, ERR_NULL_OBJECT);
std::vector<std::string> extensionList;
int32_t resultCode = ERR_OK;
if (pid <= NO_PID) {
resultCode = connectManager->GetActiveUIExtensionList(bundleName, extensionList);
} else {
resultCode = connectManager->GetActiveUIExtensionList(pid, extensionList);
}
if (resultCode != ERR_OK) {
TAG_LOGD(AAFwkTag::ABILITYMGR, "ResultCode: %{public}d", resultCode);
return ERR_GET_ACTIVE_EXTENSION_LIST_EMPTY;
}
if (extensionList.empty()) {
TAG_LOGD(AAFwkTag::ABILITYMGR, "ExtensionList is empty.");
return ERR_GET_ACTIVE_EXTENSION_LIST_EMPTY;
}
auto appExitReasonDataMgr = DelayedSingleton<AbilityRuntime::AppExitReasonDataManager>::GetInstance();
if (appExitReasonDataMgr == nullptr) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "null appExitReasonDataMgr");
return ERR_INVALID_VALUE;
}
return appExitReasonDataMgr->SetUIExtensionAbilityExitReason(bundleName, extensionList, exitReason,
processInfo, withKillMsg);
}
int32_t AppExitReasonHelper::AddAppExitReason(const std::string &bundleName, int32_t pid, int32_t uid, int32_t appIndex,
const ExitReasonCompability &exitReason)
{
int32_t userId = -1;
int32_t getOsAccountRet = AppExecFwk::OsAccountManagerWrapper::
GetOsAccountLocalIdFromUid(uid, userId);
if (getOsAccountRet != ERR_OK) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "get GetOsAccountLocalIdFromUid failed. ret: %{public}d", getOsAccountRet);
return getOsAccountRet;
}
TAG_LOGD(AAFwkTag::ABILITYMGR,
"userId: %{public}d, bundleName: %{public}s, appIndex: %{public}d", userId, bundleName.c_str(), appIndex);
uint32_t accessTokenId = Security::AccessToken::AccessTokenKit::GetHapTokenID(userId, bundleName, appIndex);
AppExecFwk::RunningProcessInfo processInfo;
GetRunningProcessInfo(pid, userId, bundleName, processInfo, appIndex);
RecordExitReasonParams params;
params.pid = pid;
params.uid = uid;
params.bundleName = bundleName;
params.accessTokenId = accessTokenId;
params.exitReason = exitReason;
params.processInfo = processInfo;
return AddProcessExitReason(params);
}
int32_t AppExitReasonHelper::AddBundleExitReason(
const std::string &bundleName, int32_t userId, int32_t appIndex, const ExitReasonCompability &exitReason)
{
TAG_LOGD(AAFwkTag::ABILITYMGR,
"userId: %{public}d, bundleName: %{public}s, appIndex: %{public}d", userId, bundleName.c_str(), appIndex);
uint32_t accessTokenId = Security::AccessToken::AccessTokenKit::GetHapTokenID(userId, bundleName, appIndex);
auto bms = AbilityUtil::GetBundleManagerHelper();
CHECK_POINTER_AND_RETURN(bms, ERR_INVALID_VALUE);
AppExecFwk::BundleInfo bundleInfo;
auto ret = IN_PROCESS_CALL(bms->GetCloneBundleInfo(
bundleName, static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION),
appIndex, bundleInfo, userId));
if (ret != ERR_OK) {
TAG_LOGE(AAFwkTag::WANTAGENT, "failed get bundle info for %{public}s", bundleName.c_str());
return ret;
}
AppExecFwk::RunningProcessInfo processInfo;
auto processInfos = GetRunningProcessInfos(userId, bundleName);
for (const auto& info : processInfos) {
if (info.appCloneIndex == appIndex || info.appCloneIndex == -1) {
processInfo = info;
break;
}
}
RecordExitReasonParams params;
params.pid = processInfo.pid_;
params.uid = bundleInfo.uid;
params.bundleName = bundleName;
params.accessTokenId = accessTokenId;
params.exitReason = exitReason;
params.processInfo = processInfo;
return AddProcessExitReason(params);
}
void AppExitReasonHelper::GetActiveAbilityList(int32_t uid, std::vector<std::string> &abilityLists,
const int32_t pid)
{
int32_t targetUserId;
int32_t getOsAccountRet = AppExecFwk::OsAccountManagerWrapper::
GetOsAccountLocalIdFromUid(uid, targetUserId);
if (getOsAccountRet != ERR_OK) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "get GetOsAccountLocalIdFromUid failed. ret: %{public}d", getOsAccountRet);
return;
}
TAG_LOGD(AAFwkTag::ABILITYMGR, "targetUserId: %{public}d", targetUserId);
CHECK_POINTER(subManagersHelper_);
if (targetUserId == U0_USER_ID) {
auto missionListManagers = subManagersHelper_->GetMissionListManagers();
for (auto& item: missionListManagers) {
CHECK_POINTER_CONTINUE(item.second);
std::vector<std::string> abilityList;
item.second->GetActiveAbilityList(uid, abilityList, pid);
if (!abilityList.empty()) {
abilityLists.insert(abilityLists.end(), abilityList.begin(), abilityList.end());
}
}
return;
}
auto listManager = subManagersHelper_->GetMissionListManagerByUserId(targetUserId);
CHECK_POINTER(listManager);
listManager->GetActiveAbilityList(uid, abilityLists, pid);
}
void AppExitReasonHelper::GetActiveAbilityListFromUIAbilityManager(int32_t uid, std::vector<std::string> &abilityLists,
const int32_t pid)
{
CHECK_POINTER(subManagersHelper_);
int32_t targetUserId;
int32_t getOsAccountRet = AppExecFwk::OsAccountManagerWrapper::
GetOsAccountLocalIdFromUid(uid, targetUserId);
if (getOsAccountRet != ERR_OK) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "get GetOsAccountLocalIdFromUid failed. ret: %{public}d", getOsAccountRet);
return;
}
TAG_LOGD(AAFwkTag::ABILITYMGR, "targetUserId: %{public}d", targetUserId);
if (targetUserId == U0_USER_ID) {
auto uiAbilityManagers = subManagersHelper_->GetUIAbilityManagers();
for (auto& item: uiAbilityManagers) {
CHECK_POINTER_CONTINUE(item.second);
std::vector<std::string> abilityList;
item.second->GetActiveAbilityList(uid, abilityList, pid);
if (!abilityList.empty()) {
abilityLists.insert(abilityLists.end(), abilityList.begin(), abilityList.end());
}
}
return;
}
auto uiAbilityManager = subManagersHelper_->GetUIAbilityManagerByUserId(targetUserId);
CHECK_POINTER(uiAbilityManager);
uiAbilityManager->GetActiveAbilityList(uid, abilityLists, pid);
}
bool AppExitReasonHelper::IsExitReasonValid(const ExitReason &exitReason)
{
const Reason reason = exitReason.reason;
return reason >= REASON_MIN && reason <= REASON_MAX;
}
int32_t AppExitReasonHelper::GetActiveAbilityListWithPid(int32_t uid, std::vector<std::string> &abilityList,
int32_t pid)
{
CHECK_POINTER_AND_RETURN(subManagersHelper_, ERR_NULL_OBJECT);
if (Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {
auto uiAbilityManager = subManagersHelper_->GetUIAbilityManagerByUid(uid);
CHECK_POINTER_AND_RETURN(uiAbilityManager, ERR_NULL_OBJECT);
uiAbilityManager->GetActiveAbilityList(uid, abilityList, pid);
} else {
auto missionListManager = subManagersHelper_->GetMissionListManagerByUid(uid);
CHECK_POINTER_AND_RETURN(missionListManager, ERR_NULL_OBJECT);
missionListManager->GetActiveAbilityList(uid, abilityList, pid);
}
return ERR_OK;
}
int32_t AppExitReasonHelper::RecordUIAbilityExitReason(const pid_t pid, const std::string &abilityName,
const ExitReason &exitReason)
{
AppExecFwk::ApplicationInfo application;
bool debug = false;
auto ret = IN_PROCESS_CALL(DelayedSingleton<AppScheduler>::GetInstance()->GetApplicationInfoByProcessID(pid,
application, debug));
if (ret != ERR_OK) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "getApplicationInfoByProcessID failed: %{public}d", ret);
return ret;
}
auto bundleName = application.bundleName;
AppExecFwk::RunningProcessInfo processInfo;
if (pid > 0) {
DelayedSingleton<AppScheduler>::GetInstance()->GetRunningProcessInfoByPid(pid, processInfo);
}
std::vector<std::string> abilityLists = {};
DelayedSingleton<AbilityRuntime::AppExitReasonDataManager>::GetInstance()->
GetRecordAppAbilityNames(application.accessTokenId, abilityLists);
bool isAbilityListsEmpty = abilityLists.empty();
abilityLists.emplace_back(abilityName);
ExitReasonCompability exitReasonCompability(exitReason);
ret = DelayedSingleton<AppScheduler>::GetInstance()->NotifyAppMgrRecordExitReasonCompability(
pid, exitReasonCompability.killId, exitReasonCompability.killMsg, exitReasonCompability.innerMsg);
if (ret != ERR_OK) {
TAG_LOGW(AAFwkTag::ABILITYMGR, "notify failed: %{public}d", ret);
}
if (isAbilityListsEmpty) {
return DelayedSingleton<AbilityRuntime::AppExitReasonDataManager>::GetInstance()->SetAppExitReason(bundleName,
application.accessTokenId, abilityLists, exitReason, processInfo, false);
} else {
DelayedSingleton<AbilityRuntime::AppExitReasonDataManager>::GetInstance()->
UpdateAppExitReason(application.accessTokenId, abilityLists, exitReason, processInfo, false);
}
return ERR_OK;
}
void AppExitReasonHelper::GetRunningProcessInfo(int32_t pid, int32_t userId, const std::string &bundleName,
AppExecFwk::RunningProcessInfo &processInfo, int32_t appIndex)
{
if (pid != NO_PID) {
DelayedSingleton<AppScheduler>::GetInstance()->GetRunningProcessInfoByPid(static_cast<pid_t>(pid),
processInfo);
return;
}
std::vector<AppExecFwk::RunningProcessInfo> infoList = GetRunningProcessInfos(userId, bundleName);
if (infoList.size() == 1) {
processInfo = infoList.front();
} else if (infoList.size() > 1 && appIndex != DEFAULT_INVAL_VALUE) {
for (const auto &info : infoList) {
if (info.appCloneIndex == appIndex) {
processInfo = info;
return;
}
}
}
}
std::vector<AppExecFwk::RunningProcessInfo> AppExitReasonHelper::GetRunningProcessInfos(
int32_t userId, const std::string &bundleName)
{
std::vector<AppExecFwk::RunningProcessInfo> infoList;
if (userId == -1 || bundleName.empty()) {
return infoList;
}
auto appMgr = AppMgrUtil::GetAppMgr();
if (appMgr == nullptr) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "appMgr null");
return infoList;
}
IN_PROCESS_CALL(appMgr->GetRunningProcessInformation(bundleName, userId, infoList));
return infoList;
}
int32_t AppExitReasonHelper::AddProcessExitReason(const RecordExitReasonParams ¶ms)
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
std::vector<std::string> abilityLists;
if (Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {
GetActiveAbilityListFromUIAbilityManager(params.uid, abilityLists, params.pid);
} else {
GetActiveAbilityList(params.uid, abilityLists, params.pid);
}
ExitReasonCompability exitReason = params.exitReason;
auto ret = DelayedSingleton<AppScheduler>::GetInstance()->NotifyAppMgrRecordExitReasonCompability(
params.pid, exitReason.killId, exitReason.killMsg, exitReason.innerMsg);
if (ret != ERR_OK) {
TAG_LOGW(AAFwkTag::ABILITYMGR, "notify failed:%{public}d", ret);
}
ExitReason tmpReason(exitReason.reason, exitReason.subReason, exitReason.exitMsg);
tmpReason.killId = exitReason.killId;
if (abilityLists.empty()) {
TAG_LOGD(AAFwkTag::ABILITYMGR, "ui abilityLists empty");
return RecordProcessExtensionExitReason(params.pid, params.bundleName, tmpReason, params.processInfo, false);
}
return DelayedSingleton<AbilityRuntime::AppExitReasonDataManager>::GetInstance()->SetAppExitReason(
params.bundleName, params.accessTokenId, abilityLists, tmpReason, params.processInfo,
params.fromKillWithReason);
}
void AppExitReasonHelper::RecordInvalidKillId(int32_t pid, const ExitReasonCompability ¶ms,
const std::string &bundleName, int32_t userId)
{
if (pid == NO_PID) {
AppExecFwk::RunningProcessInfo processInfo;
GetRunningProcessInfo(NO_PID, userId, bundleName, processInfo);
pid = processInfo.pid_;
}
DelayedSingleton<AppScheduler>::GetInstance()->NotifyAppMgrRecordExitReasonCompability(
pid, INVALID_KILLID, params.killMsg, params.innerMsg);
}
}
}