• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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