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