• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024-2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "app_exit_reason_helper.h"
17 
18 #include "accesstoken_kit.h"
19 #include "app_exit_reason_data_manager.h"
20 #include "app_mgr_util.h"
21 #include "bundle_mgr_helper.h"
22 #include "exit_info_data_manager.h"
23 #include "hitrace_meter.h"
24 #include "os_account_manager_wrapper.h"
25 #include "scene_board_judgement.h"
26 
27 namespace OHOS {
28 namespace AAFwk {
29 namespace {
30 }
31 
AppExitReasonHelper(std::shared_ptr<SubManagersHelper> subManagersHelper)32 AppExitReasonHelper::AppExitReasonHelper(std::shared_ptr<SubManagersHelper> subManagersHelper)
33     : subManagersHelper_(subManagersHelper) {}
34 
RecordAppExitReason(const ExitReason & exitReason)35 int32_t AppExitReasonHelper::RecordAppExitReason(const ExitReason &exitReason)
36 {
37     if (!IsExitReasonValid(exitReason)) {
38         TAG_LOGE(AAFwkTag::ABILITYMGR, "exit reason invalid");
39         return ERR_INVALID_VALUE;
40     }
41     auto uid = IPCSkeleton::GetCallingUid();
42     std::string bundleName;
43     int32_t appIndex = 0;
44     auto ret = IN_PROCESS_CALL(AbilityUtil::GetBundleManagerHelper()->GetNameAndIndexForUid(uid, bundleName, appIndex));
45     if (ret != ERR_OK) {
46         TAG_LOGE(AAFwkTag::ABILITYMGR, "GetNameAndIndexForUid failed, ret: %{public}d", ret);
47         return ret;
48     }
49 
50     int32_t pid = exitReason.reason != Reason::REASON_CPP_CRASH ? IPCSkeleton::GetCallingPid() : NO_PID;
51     AppExecFwk::RunningProcessInfo processInfo;
52     int32_t userId = -1;
53     int32_t getOsAccountRet = DelayedSingleton<AppExecFwk::OsAccountManagerWrapper>::GetInstance()->
54         GetOsAccountLocalIdFromUid(uid, userId);
55     GetRunningProcessInfo(pid, userId, bundleName, processInfo);
56     int32_t resultCode = RecordProcessExtensionExitReason(pid, bundleName, exitReason, processInfo, false);
57     if (resultCode != ERR_OK) {
58         TAG_LOGI(AAFwkTag::ABILITYMGR, "not record extension reason: %{public}d", resultCode);
59     }
60     std::vector<std::string> abilityList;
61     int32_t getActiveAbilityListRet = GetActiveAbilityListWithPid(uid, abilityList, pid);
62     if (getActiveAbilityListRet != ERR_OK) {
63         return getActiveAbilityListRet;
64     }
65     ret = DelayedSingleton<AppScheduler>::GetInstance()->NotifyAppMgrRecordExitReason(IPCSkeleton::GetCallingPid(),
66         exitReason.reason, exitReason.exitMsg);
67     if (ret != ERR_OK) {
68         TAG_LOGI(AAFwkTag::ABILITYMGR, "notify ret: %{public}d", ret);
69     }
70     if (abilityList.empty()) {
71         TAG_LOGE(AAFwkTag::ABILITYMGR, "abilityLists empty");
72         return ERR_GET_ACTIVE_ABILITY_LIST_EMPTY;
73     }
74     if (getOsAccountRet != ERR_OK) {
75         TAG_LOGE(AAFwkTag::ABILITYMGR, "get GetOsAccountLocalIdFromUid failed. ret: %{public}d", getOsAccountRet);
76         return ERR_INVALID_VALUE;
77     }
78     TAG_LOGD(AAFwkTag::ABILITYMGR,
79         "userId: %{public}d, bundleName: %{public}s, appIndex: %{public}d", userId, bundleName.c_str(), appIndex);
80     uint32_t accessTokenId = Security::AccessToken::AccessTokenKit::GetHapTokenID(userId, bundleName, appIndex);
81     return DelayedSingleton<AbilityRuntime::AppExitReasonDataManager>::GetInstance()->SetAppExitReason(bundleName,
82         accessTokenId, abilityList, exitReason, processInfo, false);
83 }
84 
RecordProcessExitReason(const int32_t pid,const ExitReason & exitReason,bool fromKillWithReason)85 int32_t AppExitReasonHelper::RecordProcessExitReason(const int32_t pid, const ExitReason &exitReason,
86     bool fromKillWithReason)
87 {
88     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
89     AppExecFwk::ApplicationInfo application;
90     bool debug = false;
91     auto ret = IN_PROCESS_CALL(DelayedSingleton<AppScheduler>::GetInstance()->GetApplicationInfoByProcessID(pid,
92         application, debug));
93     if (ret != ERR_OK) {
94         TAG_LOGE(AAFwkTag::ABILITYMGR, "getApplicationInfoByProcessID failed");
95         return ret;
96     }
97     auto bundleName = application.bundleName;
98     AppExecFwk::RunningProcessInfo processInfo;
99     if (pid > 0) {
100         DelayedSingleton<AppScheduler>::GetInstance()->GetRunningProcessInfoByPid(
101             static_cast<pid_t>(pid), processInfo);
102     }
103     int32_t resultCode = RecordProcessExtensionExitReason(pid, bundleName, exitReason, processInfo,
104         fromKillWithReason);
105     if (resultCode != ERR_OK) {
106         TAG_LOGI(AAFwkTag::ABILITYMGR, "not record extension reason: %{public}d", resultCode);
107     }
108 
109     return RecordProcessExitReason(pid, bundleName, application.uid, application.accessTokenId, exitReason,
110         processInfo, fromKillWithReason);
111 }
112 
RecordAppExitReason(const std::string & bundleName,int32_t uid,int32_t appIndex,const ExitReason & exitReason)113 int32_t AppExitReasonHelper::RecordAppExitReason(const std::string &bundleName, int32_t uid, int32_t appIndex,
114     const ExitReason &exitReason)
115 {
116     int32_t userId;
117     int32_t getOsAccountRet = DelayedSingleton<AppExecFwk::OsAccountManagerWrapper>::GetInstance()->
118         GetOsAccountLocalIdFromUid(uid, userId);
119     if (getOsAccountRet != ERR_OK) {
120         TAG_LOGE(AAFwkTag::ABILITYMGR, "get GetOsAccountLocalIdFromUid failed. ret: %{public}d", getOsAccountRet);
121         return ERR_INVALID_VALUE;
122     }
123     TAG_LOGD(AAFwkTag::ABILITYMGR,
124         "userId: %{public}d, bundleName: %{public}s, appIndex: %{public}d", userId, bundleName.c_str(), appIndex);
125     uint32_t accessTokenId = Security::AccessToken::AccessTokenKit::GetHapTokenID(userId, bundleName, appIndex);
126     AppExecFwk::RunningProcessInfo processInfo;
127     GetRunningProcessInfo(NO_PID, userId, bundleName, processInfo);
128     return RecordProcessExitReason(NO_PID, bundleName, uid, accessTokenId, exitReason, processInfo, false);
129 }
130 
RecordProcessExitReason(int32_t pid,int32_t uid,const ExitReason & exitReason)131 int32_t AppExitReasonHelper::RecordProcessExitReason(int32_t pid, int32_t uid, const ExitReason &exitReason)
132 {
133     uint32_t accessTokenId = 0;
134     AbilityRuntime::ExitCacheInfo cacheInfo = {};
135     if (!AbilityRuntime::ExitInfoDataManager::GetInstance().GetExitInfo(pid, uid, accessTokenId, cacheInfo)) {
136         TAG_LOGE(AAFwkTag::ABILITYMGR, "not found, pid: %{public}d, uid: %{public}d", pid, uid);
137         return ERR_NO_APP_RECORD;
138     }
139     return DelayedSingleton<AbilityRuntime::AppExitReasonDataManager>::GetInstance()->SetAppExitReason(
140         cacheInfo.bundleName, accessTokenId, cacheInfo.abilityNames, exitReason, cacheInfo.exitInfo, false);
141 }
142 
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)143 int32_t AppExitReasonHelper::RecordProcessExitReason(const int32_t pid, const std::string bundleName,
144     const int32_t uid, const uint32_t accessTokenId, const ExitReason &exitReason,
145     const AppExecFwk::RunningProcessInfo &processInfo, bool fromKillWithReason)
146 {
147     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
148     if (!IsExitReasonValid(exitReason)) {
149         TAG_LOGE(AAFwkTag::ABILITYMGR, "reason invalid");
150         return ERR_INVALID_VALUE;
151     }
152 
153     int32_t targetUserId;
154     int32_t getOsAccountRet = DelayedSingleton<AppExecFwk::OsAccountManagerWrapper>::GetInstance()->
155         GetOsAccountLocalIdFromUid(uid, targetUserId);
156     if (getOsAccountRet != ERR_OK) {
157         TAG_LOGE(AAFwkTag::ABILITYMGR, "get GetOsAccountLocalIdFromUid failed. ret: %{pubilc}d", getOsAccountRet);
158         return ERR_INVALID_VALUE;
159     }
160     TAG_LOGD(AAFwkTag::ABILITYMGR, "targetUserId: %{public}d", targetUserId);
161     std::vector<std::string> abilityLists;
162     if (Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {
163         GetActiveAbilityListFromUIAbilityManager(uid, abilityLists, pid);
164     } else  {
165         GetActiveAbilityList(uid, abilityLists, pid);
166     }
167 
168     auto ret = DelayedSingleton<AppScheduler>::GetInstance()->NotifyAppMgrRecordExitReason(pid, exitReason.reason,
169         exitReason.exitMsg);
170     if (ret != ERR_OK) {
171         TAG_LOGI(AAFwkTag::ABILITYMGR, "notify ret:%{public}d", ret);
172     }
173 
174     if (abilityLists.empty()) {
175         TAG_LOGE(AAFwkTag::ABILITYMGR, "active abilityLists empty");
176         return ERR_GET_ACTIVE_ABILITY_LIST_EMPTY;
177     }
178     return DelayedSingleton<AbilityRuntime::AppExitReasonDataManager>::GetInstance()->SetAppExitReason(bundleName,
179         accessTokenId, abilityLists, exitReason, processInfo, fromKillWithReason);
180 }
181 
RecordProcessExtensionExitReason(const int32_t pid,const std::string & bundleName,const ExitReason & exitReason,const AppExecFwk::RunningProcessInfo & processInfo,bool withKillMsg)182 int32_t AppExitReasonHelper::RecordProcessExtensionExitReason(
183     const int32_t pid, const std::string &bundleName, const ExitReason &exitReason,
184     const AppExecFwk::RunningProcessInfo &processInfo, bool withKillMsg)
185 {
186     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
187     TAG_LOGD(AAFwkTag::ABILITYMGR, "called");
188     CHECK_POINTER_AND_RETURN(subManagersHelper_, ERR_NULL_OBJECT);
189     auto connectManager = subManagersHelper_->GetCurrentConnectManager();
190     CHECK_POINTER_AND_RETURN(connectManager, ERR_NULL_OBJECT);
191     std::vector<std::string> extensionList;
192     int32_t resultCode = ERR_OK;
193     if (pid <= NO_PID) {
194         resultCode = connectManager->GetActiveUIExtensionList(bundleName, extensionList);
195     } else {
196         resultCode = connectManager->GetActiveUIExtensionList(pid, extensionList);
197     }
198     if (resultCode != ERR_OK) {
199         TAG_LOGD(AAFwkTag::ABILITYMGR, "ResultCode: %{public}d", resultCode);
200         return ERR_GET_ACTIVE_EXTENSION_LIST_EMPTY;
201     }
202 
203     if (extensionList.empty()) {
204         TAG_LOGD(AAFwkTag::ABILITYMGR, "ExtensionList is empty.");
205         return ERR_GET_ACTIVE_EXTENSION_LIST_EMPTY;
206     }
207 
208     auto appExitReasonDataMgr = DelayedSingleton<AbilityRuntime::AppExitReasonDataManager>::GetInstance();
209     if (appExitReasonDataMgr == nullptr) {
210         TAG_LOGE(AAFwkTag::ABILITYMGR, "null appExitReasonDataMgr");
211         return ERR_INVALID_VALUE;
212     }
213 
214     return appExitReasonDataMgr->SetUIExtensionAbilityExitReason(bundleName, extensionList, exitReason,
215         processInfo, withKillMsg);
216 }
217 
GetActiveAbilityList(int32_t uid,std::vector<std::string> & abilityLists,const int32_t pid)218 void AppExitReasonHelper::GetActiveAbilityList(int32_t uid, std::vector<std::string> &abilityLists,
219     const int32_t pid)
220 {
221     int32_t targetUserId;
222     int32_t getOsAccountRet = DelayedSingleton<AppExecFwk::OsAccountManagerWrapper>::GetInstance()->
223         GetOsAccountLocalIdFromUid(uid, targetUserId);
224     if (getOsAccountRet != ERR_OK) {
225         TAG_LOGE(AAFwkTag::ABILITYMGR, "get GetOsAccountLocalIdFromUid failed. ret: %{public}d", getOsAccountRet);
226         return;
227     }
228     TAG_LOGD(AAFwkTag::ABILITYMGR, "targetUserId: %{public}d", targetUserId);
229     CHECK_POINTER(subManagersHelper_);
230     if (targetUserId == U0_USER_ID) {
231         auto missionListManagers = subManagersHelper_->GetMissionListManagers();
232         for (auto& item: missionListManagers) {
233             CHECK_POINTER_CONTINUE(item.second);
234             std::vector<std::string> abilityList;
235             item.second->GetActiveAbilityList(uid, abilityList, pid);
236             if (!abilityList.empty()) {
237                 abilityLists.insert(abilityLists.end(), abilityList.begin(), abilityList.end());
238             }
239         }
240         return;
241     }
242 
243     auto listManager = subManagersHelper_->GetMissionListManagerByUserId(targetUserId);
244     CHECK_POINTER(listManager);
245     listManager->GetActiveAbilityList(uid, abilityLists, pid);
246 }
247 
GetActiveAbilityListFromUIAbilityManager(int32_t uid,std::vector<std::string> & abilityLists,const int32_t pid)248 void AppExitReasonHelper::GetActiveAbilityListFromUIAbilityManager(int32_t uid, std::vector<std::string> &abilityLists,
249     const int32_t pid)
250 {
251     CHECK_POINTER(subManagersHelper_);
252     int32_t targetUserId;
253     int32_t getOsAccountRet = DelayedSingleton<AppExecFwk::OsAccountManagerWrapper>::GetInstance()->
254         GetOsAccountLocalIdFromUid(uid, targetUserId);
255     if (getOsAccountRet != ERR_OK) {
256         TAG_LOGE(AAFwkTag::ABILITYMGR, "get GetOsAccountLocalIdFromUid failed. ret: %{public}d", getOsAccountRet);
257         return;
258     }
259     TAG_LOGD(AAFwkTag::ABILITYMGR, "targetUserId: %{public}d", targetUserId);
260     if (targetUserId == U0_USER_ID) {
261         auto uiAbilityManagers = subManagersHelper_->GetUIAbilityManagers();
262         for (auto& item: uiAbilityManagers) {
263             CHECK_POINTER_CONTINUE(item.second);
264             std::vector<std::string> abilityList;
265             item.second->GetActiveAbilityList(uid, abilityList, pid);
266             if (!abilityList.empty()) {
267                 abilityLists.insert(abilityLists.end(), abilityList.begin(), abilityList.end());
268             }
269         }
270         return;
271     }
272 
273     auto uiAbilityManager = subManagersHelper_->GetUIAbilityManagerByUserId(targetUserId);
274     CHECK_POINTER(uiAbilityManager);
275     uiAbilityManager->GetActiveAbilityList(uid, abilityLists, pid);
276 }
277 
IsExitReasonValid(const ExitReason & exitReason)278 bool AppExitReasonHelper::IsExitReasonValid(const ExitReason &exitReason)
279 {
280     const Reason reason = exitReason.reason;
281     return reason >= REASON_MIN && reason <= REASON_MAX;
282 }
283 
GetActiveAbilityListWithPid(int32_t uid,std::vector<std::string> & abilityList,int32_t pid)284 int32_t AppExitReasonHelper::GetActiveAbilityListWithPid(int32_t uid, std::vector<std::string> &abilityList,
285     int32_t pid)
286 {
287     CHECK_POINTER_AND_RETURN(subManagersHelper_, ERR_NULL_OBJECT);
288     if (Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {
289         auto uiAbilityManager = subManagersHelper_->GetUIAbilityManagerByUid(uid);
290         CHECK_POINTER_AND_RETURN(uiAbilityManager, ERR_NULL_OBJECT);
291         uiAbilityManager->GetActiveAbilityList(uid, abilityList, pid);
292     } else {
293         auto missionListManager = subManagersHelper_->GetMissionListManagerByUid(uid);
294         CHECK_POINTER_AND_RETURN(missionListManager, ERR_NULL_OBJECT);
295         missionListManager->GetActiveAbilityList(uid, abilityList, pid);
296     }
297     return ERR_OK;
298 }
299 
RecordUIAbilityExitReason(const pid_t pid,const std::string & abilityName,const ExitReason & exitReason)300 int32_t AppExitReasonHelper::RecordUIAbilityExitReason(const pid_t pid, const std::string &abilityName,
301     const ExitReason &exitReason)
302 {
303     AppExecFwk::ApplicationInfo application;
304     bool debug = false;
305     auto ret = IN_PROCESS_CALL(DelayedSingleton<AppScheduler>::GetInstance()->GetApplicationInfoByProcessID(pid,
306         application, debug));
307     if (ret != ERR_OK) {
308         TAG_LOGE(AAFwkTag::ABILITYMGR, "getApplicationInfoByProcessID failed");
309         return ret;
310     }
311     auto bundleName = application.bundleName;
312     AppExecFwk::RunningProcessInfo processInfo;
313     if (pid > 0) {
314         DelayedSingleton<AppScheduler>::GetInstance()->GetRunningProcessInfoByPid(pid, processInfo);
315     }
316     std::vector<std::string> abilityLists = {};
317     DelayedSingleton<AbilityRuntime::AppExitReasonDataManager>::GetInstance()->
318         GetRecordAppAbilityNames(application.accessTokenId, abilityLists);
319     bool isAbilityListsEmpty = abilityLists.empty();
320     abilityLists.emplace_back(abilityName);
321     if (isAbilityListsEmpty) {
322         return DelayedSingleton<AbilityRuntime::AppExitReasonDataManager>::GetInstance()->SetAppExitReason(bundleName,
323             application.accessTokenId, abilityLists, exitReason, processInfo, false);
324     } else {
325         DelayedSingleton<AbilityRuntime::AppExitReasonDataManager>::GetInstance()->
326             UpdateAppExitReason(application.accessTokenId, abilityLists, exitReason, processInfo, false);
327     }
328     return ERR_OK;
329 }
330 
GetRunningProcessInfo(int32_t pid,int32_t userId,const std::string & bundleName,AppExecFwk::RunningProcessInfo & processInfo)331 void AppExitReasonHelper::GetRunningProcessInfo(int32_t pid, int32_t userId, const std::string &bundleName,
332     AppExecFwk::RunningProcessInfo &processInfo)
333 {
334     if (pid != NO_PID) {
335         DelayedSingleton<AppScheduler>::GetInstance()->GetRunningProcessInfoByPid(static_cast<pid_t>(pid),
336             processInfo);
337         return;
338     }
339     if (userId == -1 || bundleName.empty()) {
340         return;
341     }
342     auto appMgr = AppMgrUtil::GetAppMgr();
343     if (appMgr == nullptr) {
344         TAG_LOGE(AAFwkTag::ABILITYMGR, "appMgr null");
345         return;
346     }
347     std::vector<AppExecFwk::RunningProcessInfo> infoList;
348     IN_PROCESS_CALL(appMgr->GetRunningProcessInformation(bundleName, userId, infoList));
349     if (infoList.size() == 1) {
350         processInfo = infoList.front();
351     }
352 }
353 }  // namespace AppExecFwk
354 }  // namespace OHOS
355