1 /*
2 * Copyright (c) 2024 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 "ability_record_death_manager.h"
19 #include "accesstoken_kit.h"
20 #include "app_exit_reason_data_manager.h"
21 #include "app_mgr_util.h"
22 #include "bundle_mgr_helper.h"
23 #include "os_account_manager_wrapper.h"
24 #include "scene_board_judgement.h"
25
26 namespace OHOS {
27 namespace AAFwk {
28 namespace {
29 constexpr int32_t U0_USER_ID = 0;
AppendAbilities(const std::list<std::shared_ptr<AbilityRecord>> & abilityRecords,std::vector<std::string> & abilities)30 void AppendAbilities(const std::list<std::shared_ptr<AbilityRecord>> &abilityRecords,
31 std::vector<std::string> &abilities)
32 {
33 for (const auto &abilityRecord : abilityRecords) {
34 if (abilityRecord == nullptr) {
35 continue;
36 }
37
38 const auto &abilityInfo = abilityRecord->GetAbilityInfo();
39 if (!abilityInfo.name.empty()) {
40 std::string abilityName = abilityInfo.name;
41 if (abilityInfo.launchMode == AppExecFwk::LaunchMode::STANDARD &&
42 abilityRecord->GetSessionInfo() != nullptr) {
43 abilityName += std::to_string(abilityRecord->GetSessionInfo()->persistentId);
44 }
45 TAG_LOGD(AAFwkTag::ABILITYMGR, "find ability name is %{public}s.", abilityName.c_str());
46 abilities.emplace_back(std::move(abilityName));
47 }
48 }
49 }
50 }
51
AppExitReasonHelper(std::shared_ptr<SubManagersHelper> subManagersHelper)52 AppExitReasonHelper::AppExitReasonHelper(std::shared_ptr<SubManagersHelper> subManagersHelper)
53 : subManagersHelper_(subManagersHelper) {}
54
RecordAppExitReason(const ExitReason & exitReason)55 int32_t AppExitReasonHelper::RecordAppExitReason(const ExitReason &exitReason)
56 {
57 if (!IsExitReasonValid(exitReason)) {
58 TAG_LOGE(AAFwkTag::ABILITYMGR, "exit reason invalid");
59 return ERR_INVALID_VALUE;
60 }
61 auto uid = IPCSkeleton::GetCallingUid();
62 std::string bundleName;
63 int32_t appIndex = 0;
64 auto ret = IN_PROCESS_CALL(AbilityUtil::GetBundleManagerHelper()->GetNameAndIndexForUid(uid, bundleName, appIndex));
65 if (ret != ERR_OK) {
66 TAG_LOGE(AAFwkTag::ABILITYMGR, "GetNameAndIndexForUid failed, ret: %{public}d", ret);
67 return ret;
68 }
69
70 int32_t pid = NO_PID;
71 AppExecFwk::RunningProcessInfo processInfo;
72 if (exitReason.reason != Reason::REASON_CPP_CRASH) {
73 pid = IPCSkeleton::GetCallingPid();
74 DelayedSingleton<AppScheduler>::GetInstance()->GetRunningProcessInfoByPid(static_cast<pid_t>(pid),
75 processInfo);
76 }
77 int32_t resultCode = RecordProcessExtensionExitReason(pid, bundleName, exitReason, processInfo, false);
78 if (resultCode != ERR_OK) {
79 TAG_LOGE(AAFwkTag::ABILITYMGR, "record reason failed, code: %{public}d", resultCode);
80 }
81 CHECK_POINTER_AND_RETURN(subManagersHelper_, ERR_NULL_OBJECT);
82 std::vector<std::string> abilityList;
83 int32_t getActiveAbilityListRet = GetActiveAbilityListWithPid(uid, abilityList, pid);
84 if (getActiveAbilityListRet != ERR_OK) {
85 return getActiveAbilityListRet;
86 }
87 ret = DelayedSingleton<AppScheduler>::GetInstance()->NotifyAppMgrRecordExitReason(IPCSkeleton::GetCallingPid(),
88 exitReason.reason, exitReason.exitMsg);
89 if (ret != ERR_OK) {
90 TAG_LOGE(AAFwkTag::ABILITYMGR, "failed,code: %{public}d", ret);
91 }
92 if (abilityList.empty()) {
93 TAG_LOGE(AAFwkTag::ABILITYMGR, "abilityLists empty");
94 return ERR_GET_ACTIVE_ABILITY_LIST_EMPTY;
95 }
96 int32_t userId;
97 int32_t getOsAccountRet = DelayedSingleton<AppExecFwk::OsAccountManagerWrapper>::GetInstance()->
98 GetOsAccountLocalIdFromUid(uid, userId);
99 if (getOsAccountRet != ERR_OK) {
100 TAG_LOGE(AAFwkTag::ABILITYMGR, "get GetOsAccountLocalIdFromUid failed. ret: %{public}d", getOsAccountRet);
101 return ERR_INVALID_VALUE;
102 }
103 TAG_LOGD(AAFwkTag::ABILITYMGR,
104 "userId: %{public}d, bundleName: %{public}s, appIndex: %{public}d", userId, bundleName.c_str(), appIndex);
105 uint32_t accessTokenId = Security::AccessToken::AccessTokenKit::GetHapTokenID(userId, bundleName, appIndex);
106 return DelayedSingleton<AbilityRuntime::AppExitReasonDataManager>::GetInstance()->SetAppExitReason(bundleName,
107 accessTokenId, abilityList, exitReason, processInfo, false);
108 }
109
RecordProcessExitReason(const int32_t pid,const ExitReason & exitReason,bool fromKillWithReason)110 int32_t AppExitReasonHelper::RecordProcessExitReason(const int32_t pid, const ExitReason &exitReason,
111 bool fromKillWithReason)
112 {
113 AppExecFwk::ApplicationInfo application;
114 bool debug = false;
115 auto ret = IN_PROCESS_CALL(DelayedSingleton<AppScheduler>::GetInstance()->GetApplicationInfoByProcessID(pid,
116 application, debug));
117 if (ret != ERR_OK) {
118 TAG_LOGE(AAFwkTag::ABILITYMGR, "getApplicationInfoByProcessID failed");
119 return ret;
120 }
121 auto bundleName = application.bundleName;
122 AppExecFwk::RunningProcessInfo processInfo;
123 if (pid > 0) {
124 DelayedSingleton<AppScheduler>::GetInstance()->GetRunningProcessInfoByPid(
125 static_cast<pid_t>(pid), processInfo);
126 }
127 int32_t resultCode = RecordProcessExtensionExitReason(pid, bundleName, exitReason, processInfo,
128 fromKillWithReason);
129 if (resultCode != ERR_OK) {
130 TAG_LOGE(AAFwkTag::ABILITYMGR, "record Reason failed, code: %{public}d", resultCode);
131 }
132
133 return RecordProcessExitReason(pid, bundleName, application.uid, application.accessTokenId, exitReason,
134 processInfo, fromKillWithReason, false);
135 }
136
RecordAppExitReason(const std::string & bundleName,int32_t uid,int32_t appIndex,const ExitReason & exitReason)137 int32_t AppExitReasonHelper::RecordAppExitReason(const std::string &bundleName, int32_t uid, int32_t appIndex,
138 const ExitReason &exitReason)
139 {
140 int32_t userId;
141 int32_t getOsAccountRet = DelayedSingleton<AppExecFwk::OsAccountManagerWrapper>::GetInstance()->
142 GetOsAccountLocalIdFromUid(uid, userId);
143 if (getOsAccountRet != ERR_OK) {
144 TAG_LOGE(AAFwkTag::ABILITYMGR, "get GetOsAccountLocalIdFromUid failed. ret: %{public}d", getOsAccountRet);
145 return ERR_INVALID_VALUE;
146 }
147 TAG_LOGD(AAFwkTag::ABILITYMGR,
148 "userId: %{public}d, bundleName: %{public}s, appIndex: %{public}d", userId, bundleName.c_str(), appIndex);
149 uint32_t accessTokenId = Security::AccessToken::AccessTokenKit::GetHapTokenID(userId, bundleName, appIndex);
150 AppExecFwk::RunningProcessInfo processInfo;
151 return RecordProcessExitReason(NO_PID, bundleName, uid, accessTokenId, exitReason, processInfo, false, false);
152 }
153
RecordProcessExitReason(int32_t pid,int32_t uid,const ExitReason & exitReason)154 int32_t AppExitReasonHelper::RecordProcessExitReason(int32_t pid, int32_t uid, const ExitReason &exitReason)
155 {
156 auto appMgr = AppMgrUtil::GetAppMgr();
157 if (appMgr == nullptr) {
158 TAG_LOGE(AAFwkTag::ABILITYMGR, "appMgr null");
159 return ERR_NULL_APP_MGR_PROXY;
160 }
161 AppExecFwk::KilledProcessInfo appInfo;
162 auto ret = IN_PROCESS_CALL(appMgr->GetKilledProcessInfo(pid, uid, appInfo));
163 if (ret != ERR_OK) {
164 TAG_LOGW(AAFwkTag::ABILITYMGR, "GetKilledProcessInfo failed");
165 return ret;
166 }
167
168 AppExecFwk::RunningProcessInfo processInfo;
169 processInfo.pid_ = pid;
170 processInfo.uid_ = uid;
171 processInfo.processName_ = appInfo.processName;
172 return RecordProcessExitReason(pid, appInfo.bundleName, uid, appInfo.accessTokenId, exitReason,
173 processInfo, false, true);
174 }
175
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,bool searchDead)176 int32_t AppExitReasonHelper::RecordProcessExitReason(const int32_t pid, const std::string bundleName,
177 const int32_t uid, const uint32_t accessTokenId, const ExitReason &exitReason,
178 const AppExecFwk::RunningProcessInfo &processInfo, bool fromKillWithReason, bool searchDead)
179 {
180 if (!IsExitReasonValid(exitReason)) {
181 TAG_LOGE(AAFwkTag::ABILITYMGR, "reason invalid");
182 return ERR_INVALID_VALUE;
183 }
184
185 int32_t targetUserId;
186 int32_t getOsAccountRet = DelayedSingleton<AppExecFwk::OsAccountManagerWrapper>::GetInstance()->
187 GetOsAccountLocalIdFromUid(uid, targetUserId);
188 if (getOsAccountRet != ERR_OK) {
189 TAG_LOGE(AAFwkTag::ABILITYMGR, "get GetOsAccountLocalIdFromUid failed. ret: %{pubilc}d", getOsAccountRet);
190 return ERR_INVALID_VALUE;
191 }
192 TAG_LOGD(AAFwkTag::ABILITYMGR, "targetUserId: %{public}d", targetUserId);
193 std::vector<std::string> abilityLists;
194 if (Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {
195 GetActiveAbilityListFromUIAbilityManager(uid, abilityLists, pid);
196 if (searchDead) {
197 AppendAbilities(AbilityRecordDeathManager::GetInstance().QueryDeadAbilityRecord(pid, uid), abilityLists);
198 }
199 } else {
200 GetActiveAbilityList(uid, abilityLists, pid);
201 }
202
203 auto ret = DelayedSingleton<AppScheduler>::GetInstance()->NotifyAppMgrRecordExitReason(pid, exitReason.reason,
204 exitReason.exitMsg);
205 if (ret != ERR_OK) {
206 TAG_LOGE(AAFwkTag::ABILITYMGR, "failed:%{public}d", ret);
207 }
208
209 if (abilityLists.empty()) {
210 TAG_LOGE(AAFwkTag::ABILITYMGR, "active abilityLists empty");
211 return ERR_GET_ACTIVE_ABILITY_LIST_EMPTY;
212 }
213 return DelayedSingleton<AbilityRuntime::AppExitReasonDataManager>::GetInstance()->SetAppExitReason(bundleName,
214 accessTokenId, abilityLists, exitReason, processInfo, fromKillWithReason);
215 }
216
RecordProcessExtensionExitReason(const int32_t pid,const std::string & bundleName,const ExitReason & exitReason,const AppExecFwk::RunningProcessInfo & processInfo,bool withKillMsg)217 int32_t AppExitReasonHelper::RecordProcessExtensionExitReason(
218 const int32_t pid, const std::string &bundleName, const ExitReason &exitReason,
219 const AppExecFwk::RunningProcessInfo &processInfo, bool withKillMsg)
220 {
221 TAG_LOGD(AAFwkTag::ABILITYMGR, "called");
222 CHECK_POINTER_AND_RETURN(subManagersHelper_, ERR_NULL_OBJECT);
223 auto connectManager = subManagersHelper_->GetCurrentConnectManager();
224 CHECK_POINTER_AND_RETURN(connectManager, ERR_NULL_OBJECT);
225 std::vector<std::string> extensionList;
226 int32_t resultCode = ERR_OK;
227 if (pid <= NO_PID) {
228 resultCode = connectManager->GetActiveUIExtensionList(bundleName, extensionList);
229 } else {
230 resultCode = connectManager->GetActiveUIExtensionList(pid, extensionList);
231 }
232 if (resultCode != ERR_OK) {
233 TAG_LOGD(AAFwkTag::ABILITYMGR, "ResultCode: %{public}d", resultCode);
234 return ERR_GET_ACTIVE_EXTENSION_LIST_EMPTY;
235 }
236
237 if (extensionList.empty()) {
238 TAG_LOGD(AAFwkTag::ABILITYMGR, "ExtensionList is empty.");
239 return ERR_GET_ACTIVE_EXTENSION_LIST_EMPTY;
240 }
241
242 auto appExitReasonDataMgr = DelayedSingleton<AbilityRuntime::AppExitReasonDataManager>::GetInstance();
243 if (appExitReasonDataMgr == nullptr) {
244 TAG_LOGE(AAFwkTag::ABILITYMGR, "null appExitReasonDataMgr");
245 return ERR_INVALID_VALUE;
246 }
247
248 return appExitReasonDataMgr->SetUIExtensionAbilityExitReason(bundleName, extensionList, exitReason,
249 processInfo, withKillMsg);
250 }
251
GetActiveAbilityList(int32_t uid,std::vector<std::string> & abilityLists,const int32_t pid)252 void AppExitReasonHelper::GetActiveAbilityList(int32_t uid, std::vector<std::string> &abilityLists,
253 const int32_t pid)
254 {
255 int32_t targetUserId;
256 int32_t getOsAccountRet = DelayedSingleton<AppExecFwk::OsAccountManagerWrapper>::GetInstance()->
257 GetOsAccountLocalIdFromUid(uid, targetUserId);
258 if (getOsAccountRet != ERR_OK) {
259 TAG_LOGE(AAFwkTag::ABILITYMGR, "get GetOsAccountLocalIdFromUid failed. ret: %{public}d", getOsAccountRet);
260 return;
261 }
262 TAG_LOGD(AAFwkTag::ABILITYMGR, "targetUserId: %{public}d", targetUserId);
263 CHECK_POINTER(subManagersHelper_);
264 if (targetUserId == U0_USER_ID) {
265 auto missionListManagers = subManagersHelper_->GetMissionListManagers();
266 for (auto& item: missionListManagers) {
267 CHECK_POINTER_CONTINUE(item.second);
268 std::vector<std::string> abilityList;
269 item.second->GetActiveAbilityList(uid, abilityList, pid);
270 if (!abilityList.empty()) {
271 abilityLists.insert(abilityLists.end(), abilityList.begin(), abilityList.end());
272 }
273 }
274 return;
275 }
276
277 auto listManager = subManagersHelper_->GetMissionListManagerByUserId(targetUserId);
278 CHECK_POINTER(listManager);
279 listManager->GetActiveAbilityList(uid, abilityLists, pid);
280 }
281
GetActiveAbilityListFromUIAbilityManager(int32_t uid,std::vector<std::string> & abilityLists,const int32_t pid)282 void AppExitReasonHelper::GetActiveAbilityListFromUIAbilityManager(int32_t uid, std::vector<std::string> &abilityLists,
283 const int32_t pid)
284 {
285 CHECK_POINTER(subManagersHelper_);
286 int32_t targetUserId;
287 int32_t getOsAccountRet = DelayedSingleton<AppExecFwk::OsAccountManagerWrapper>::GetInstance()->
288 GetOsAccountLocalIdFromUid(uid, targetUserId);
289 if (getOsAccountRet != ERR_OK) {
290 TAG_LOGE(AAFwkTag::ABILITYMGR, "get GetOsAccountLocalIdFromUid failed. ret: %{public}d", getOsAccountRet);
291 return;
292 }
293 TAG_LOGD(AAFwkTag::ABILITYMGR, "targetUserId: %{public}d", targetUserId);
294 if (targetUserId == U0_USER_ID) {
295 auto uiAbilityManagers = subManagersHelper_->GetUIAbilityManagers();
296 for (auto& item: uiAbilityManagers) {
297 CHECK_POINTER_CONTINUE(item.second);
298 std::vector<std::string> abilityList;
299 item.second->GetActiveAbilityList(uid, abilityList, pid);
300 if (!abilityList.empty()) {
301 abilityLists.insert(abilityLists.end(), abilityList.begin(), abilityList.end());
302 }
303 }
304 return;
305 }
306
307 auto uiAbilityManager = subManagersHelper_->GetUIAbilityManagerByUserId(targetUserId);
308 CHECK_POINTER(uiAbilityManager);
309 uiAbilityManager->GetActiveAbilityList(uid, abilityLists, pid);
310 }
311
IsExitReasonValid(const ExitReason & exitReason)312 bool AppExitReasonHelper::IsExitReasonValid(const ExitReason &exitReason)
313 {
314 const Reason reason = exitReason.reason;
315 return reason >= REASON_MIN && reason <= REASON_MAX;
316 }
317
GetActiveAbilityList(int32_t uid,std::vector<std::string> & abilityList)318 int32_t AppExitReasonHelper::GetActiveAbilityList(int32_t uid, std::vector<std::string> &abilityList)
319 {
320 if (Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {
321 auto uiAbilityManager = subManagersHelper_->GetUIAbilityManagerByUid(uid);
322 CHECK_POINTER_AND_RETURN(uiAbilityManager, ERR_NULL_OBJECT);
323 uiAbilityManager->GetActiveAbilityList(uid, abilityList);
324 } else {
325 auto missionListManager = subManagersHelper_->GetMissionListManagerByUid(uid);
326 CHECK_POINTER_AND_RETURN(missionListManager, ERR_NULL_OBJECT);
327 missionListManager->GetActiveAbilityList(uid, abilityList);
328 }
329 return ERR_OK;
330 }
331
GetActiveAbilityListWithPid(int32_t uid,std::vector<std::string> & abilityList,int32_t pid)332 int32_t AppExitReasonHelper::GetActiveAbilityListWithPid(int32_t uid, std::vector<std::string> &abilityList,
333 int32_t pid)
334 {
335 if (Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {
336 auto uiAbilityManager = subManagersHelper_->GetUIAbilityManagerByUid(uid);
337 CHECK_POINTER_AND_RETURN(uiAbilityManager, ERR_NULL_OBJECT);
338 uiAbilityManager->GetActiveAbilityList(uid, abilityList, pid);
339 } else {
340 auto missionListManager = subManagersHelper_->GetMissionListManagerByUid(uid);
341 CHECK_POINTER_AND_RETURN(missionListManager, ERR_NULL_OBJECT);
342 missionListManager->GetActiveAbilityList(uid, abilityList, pid);
343 }
344 return ERR_OK;
345 }
346
RecordUIAbilityExitReason(const pid_t pid,const std::string & abilityName,const ExitReason & exitReason)347 int32_t AppExitReasonHelper::RecordUIAbilityExitReason(const pid_t pid, const std::string &abilityName,
348 const ExitReason &exitReason)
349 {
350 AppExecFwk::ApplicationInfo application;
351 bool debug = false;
352 auto ret = IN_PROCESS_CALL(DelayedSingleton<AppScheduler>::GetInstance()->GetApplicationInfoByProcessID(pid,
353 application, debug));
354 if (ret != ERR_OK) {
355 TAG_LOGE(AAFwkTag::ABILITYMGR, "getApplicationInfoByProcessID failed");
356 return ret;
357 }
358 auto bundleName = application.bundleName;
359 AppExecFwk::RunningProcessInfo processInfo;
360 if (pid > 0) {
361 DelayedSingleton<AppScheduler>::GetInstance()->GetRunningProcessInfoByPid(pid, processInfo);
362 }
363 std::vector<std::string> abilityLists = {};
364 DelayedSingleton<AbilityRuntime::AppExitReasonDataManager>::GetInstance()->
365 GetRecordAppAbilityNames(application.accessTokenId, abilityLists);
366 bool isAbilityListsEmpty = abilityLists.empty();
367 abilityLists.emplace_back(abilityName);
368 if (isAbilityListsEmpty) {
369 return DelayedSingleton<AbilityRuntime::AppExitReasonDataManager>::GetInstance()->SetAppExitReason(bundleName,
370 application.accessTokenId, abilityLists, exitReason, processInfo, false);
371 } else {
372 DelayedSingleton<AbilityRuntime::AppExitReasonDataManager>::GetInstance()->
373 UpdateAppExitReason(application.accessTokenId, abilityLists, exitReason, processInfo, false);
374 }
375 return ERR_OK;
376 }
377 } // namespace AppExecFwk
378 } // namespace OHOS
379