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 "accesstoken_kit.h"
19 #include "app_exit_reason_data_manager.h"
20 #include "bundle_mgr_helper.h"
21 #include "os_account_manager_wrapper.h"
22 #include "scene_board_judgement.h"
23
24 namespace OHOS {
25 namespace AAFwk {
26 namespace {
27 constexpr int32_t U0_USER_ID = 0;
28 }
29
AppExitReasonHelper(std::shared_ptr<SubManagersHelper> subManagersHelper)30 AppExitReasonHelper::AppExitReasonHelper(std::shared_ptr<SubManagersHelper> subManagersHelper)
31 : subManagersHelper_(subManagersHelper) {}
32
RecordAppExitReason(const ExitReason & exitReason)33 int32_t AppExitReasonHelper::RecordAppExitReason(const ExitReason &exitReason)
34 {
35 if (!IsExitReasonValid(exitReason)) {
36 TAG_LOGE(AAFwkTag::ABILITYMGR, "Exit reason invalid.");
37 return ERR_INVALID_VALUE;
38 }
39 auto uid = IPCSkeleton::GetCallingUid();
40 std::string bundleName;
41 int32_t appIndex = 0;
42 auto ret = IN_PROCESS_CALL(AbilityUtil::GetBundleManagerHelper()->GetNameAndIndexForUid(uid, bundleName,
43 appIndex));
44 if (ret != ERR_OK) {
45 TAG_LOGE(AAFwkTag::ABILITYMGR, "GetNameAndIndexForUid failed, ret:%{public}d", ret);
46 return ret;
47 }
48 // There is a possibility that the PID cannot be obtained when the CPP
49 // process exits. The exit cause is recorded by application.
50 int32_t pid = (exitReason.reason == Reason::REASON_CPP_CRASH) ? NO_PID : IPCSkeleton::GetCallingPid();
51 int32_t resultCode = RecordProcessExtensionExitReason(pid, bundleName, exitReason);
52 if (resultCode != ERR_OK) {
53 TAG_LOGE(AAFwkTag::ABILITYMGR, "Record Process Extension Exit Reason failed.code: %{public}d", resultCode);
54 }
55 CHECK_POINTER_AND_RETURN(subManagersHelper_, ERR_NULL_OBJECT);
56 std::vector<std::string> abilityList;
57 if (Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {
58 auto uiAbilityManager = subManagersHelper_->GetUIAbilityManagerByUid(uid);
59 CHECK_POINTER_AND_RETURN(uiAbilityManager, ERR_NULL_OBJECT);
60 uiAbilityManager->GetActiveAbilityList(uid, abilityList);
61 } else {
62 auto missionListManager = subManagersHelper_->GetMissionListManagerByUid(uid);
63 CHECK_POINTER_AND_RETURN(missionListManager, ERR_NULL_OBJECT);
64 missionListManager->GetActiveAbilityList(uid, abilityList);
65 }
66
67 ret = DelayedSingleton<AppScheduler>::GetInstance()->NotifyAppMgrRecordExitReason(IPCSkeleton::GetCallingPid(),
68 exitReason.reason, exitReason.exitMsg);
69 if (ret != ERR_OK) {
70 TAG_LOGE(AAFwkTag::ABILITYMGR, "NotifyAppMgrRecordExitReason failed.code: %{public}d", ret);
71 }
72
73 if (abilityList.empty()) {
74 TAG_LOGE(AAFwkTag::ABILITYMGR, "Active abilityLists empty.");
75 return ERR_GET_ACTIVE_ABILITY_LIST_EMPTY;
76 }
77 int32_t userId;
78 if (DelayedSingleton<AppExecFwk::OsAccountManagerWrapper>::GetInstance()->
79 GetOsAccountLocalIdFromUid(uid, userId) != ERR_OK) {
80 TAG_LOGE(AAFwkTag::ABILITYMGR, "Get GetOsAccountLocalIdFromUid failed.");
81 return ERR_INVALID_VALUE;
82 }
83 uint32_t accessTokenId = Security::AccessToken::AccessTokenKit::GetHapTokenID(userId, bundleName, appIndex);
84 return DelayedSingleton<AbilityRuntime::AppExitReasonDataManager>::GetInstance()->SetAppExitReason(bundleName,
85 accessTokenId, abilityList, exitReason);
86 }
87
RecordProcessExitReason(const int32_t pid,const ExitReason & exitReason)88 int32_t AppExitReasonHelper::RecordProcessExitReason(const int32_t pid, const ExitReason &exitReason)
89 {
90 AppExecFwk::ApplicationInfo application;
91 bool debug = false;
92 auto ret = IN_PROCESS_CALL(DelayedSingleton<AppScheduler>::GetInstance()->GetApplicationInfoByProcessID(pid,
93 application, debug));
94 if (ret != ERR_OK) {
95 TAG_LOGE(AAFwkTag::ABILITYMGR, "GetApplicationInfoByProcessID failed.");
96 return ret;
97 }
98 auto bundleName = application.bundleName;
99 int32_t resultCode = RecordProcessExtensionExitReason(pid, bundleName, exitReason);
100 if (resultCode != ERR_OK) {
101 TAG_LOGE(AAFwkTag::ABILITYMGR, "Record Process Extension Exit Reason failed.code: %{public}d", resultCode);
102 }
103
104 return RecordProcessExitReason(pid, bundleName, application.uid, application.accessTokenId, exitReason);
105 }
106
RecordAppExitReason(const std::string & bundleName,int32_t uid,int32_t appIndex,const ExitReason & exitReason)107 int32_t AppExitReasonHelper::RecordAppExitReason(const std::string &bundleName, int32_t uid, int32_t appIndex,
108 const ExitReason &exitReason)
109 {
110 int32_t userId;
111 if (DelayedSingleton<AppExecFwk::OsAccountManagerWrapper>::GetInstance()->
112 GetOsAccountLocalIdFromUid(uid, userId) != ERR_OK) {
113 TAG_LOGE(AAFwkTag::ABILITYMGR, "Get GetOsAccountLocalIdFromUid failed.");
114 return ERR_INVALID_VALUE;
115 }
116 uint32_t accessTokenId = Security::AccessToken::AccessTokenKit::GetHapTokenID(userId, bundleName, appIndex);
117 return RecordProcessExitReason(NO_PID, bundleName, uid, accessTokenId, exitReason);
118 }
119
RecordProcessExitReason(const int32_t pid,const std::string bundleName,const int32_t uid,const uint32_t accessTokenId,const ExitReason & exitReason)120 int32_t AppExitReasonHelper::RecordProcessExitReason(const int32_t pid, const std::string bundleName,
121 const int32_t uid, const uint32_t accessTokenId, const ExitReason &exitReason)
122 {
123 if (!IsExitReasonValid(exitReason)) {
124 TAG_LOGE(AAFwkTag::ABILITYMGR, "Force exit reason invalid.");
125 return ERR_INVALID_VALUE;
126 }
127
128 int32_t targetUserId;
129 if (DelayedSingleton<AppExecFwk::OsAccountManagerWrapper>::GetInstance()->
130 GetOsAccountLocalIdFromUid(uid, targetUserId) != ERR_OK) {
131 TAG_LOGE(AAFwkTag::ABILITYMGR, "Get GetOsAccountLocalIdFromUid failed.");
132 return ERR_INVALID_VALUE;
133 }
134 std::vector<std::string> abilityLists;
135 if (Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {
136 GetActiveAbilityListFromUIAbilityManager(uid, abilityLists, pid);
137 } else {
138 GetActiveAbilityList(uid, abilityLists, pid);
139 }
140
141 auto ret = DelayedSingleton<AppScheduler>::GetInstance()->NotifyAppMgrRecordExitReason(pid, exitReason.reason,
142 exitReason.exitMsg);
143 if (ret != ERR_OK) {
144 TAG_LOGE(AAFwkTag::ABILITYMGR, "NotifyAppMgrRecordExitReason failed.code: %{public}d", ret);
145 }
146
147 if (abilityLists.empty()) {
148 TAG_LOGE(AAFwkTag::ABILITYMGR, "Active abilityLists empty.");
149 return ERR_GET_ACTIVE_ABILITY_LIST_EMPTY;
150 }
151 return DelayedSingleton<AbilityRuntime::AppExitReasonDataManager>::GetInstance()->SetAppExitReason(bundleName,
152 accessTokenId, abilityLists, exitReason);
153 }
154
RecordProcessExtensionExitReason(const int32_t pid,const std::string & bundleName,const ExitReason & exitReason)155 int32_t AppExitReasonHelper::RecordProcessExtensionExitReason(
156 const int32_t pid, const std::string &bundleName, const ExitReason &exitReason)
157 {
158 TAG_LOGD(AAFwkTag::ABILITYMGR, "called");
159 CHECK_POINTER_AND_RETURN(subManagersHelper_, ERR_NULL_OBJECT);
160 auto connectManager = subManagersHelper_->GetCurrentConnectManager();
161 CHECK_POINTER_AND_RETURN(connectManager, ERR_NULL_OBJECT);
162 std::vector<std::string> extensionList;
163 int32_t resultCode = ERR_OK;
164 if (pid <= NO_PID) {
165 resultCode = connectManager->GetActiveUIExtensionList(bundleName, extensionList);
166 } else {
167 resultCode = connectManager->GetActiveUIExtensionList(pid, extensionList);
168 }
169 if (resultCode != ERR_OK) {
170 TAG_LOGD(AAFwkTag::ABILITYMGR, "ResultCode: %{public}d", resultCode);
171 return ERR_GET_ACTIVE_EXTENSION_LIST_EMPTY;
172 }
173
174 if (extensionList.empty()) {
175 TAG_LOGD(AAFwkTag::ABILITYMGR, "ExtensionList is empty.");
176 return ERR_GET_ACTIVE_EXTENSION_LIST_EMPTY;
177 }
178
179 auto appExitReasonDataMgr = DelayedSingleton<AbilityRuntime::AppExitReasonDataManager>::GetInstance();
180 if (appExitReasonDataMgr == nullptr) {
181 TAG_LOGE(AAFwkTag::ABILITYMGR, "Get app exit reason data mgr instance is nullptr.");
182 return ERR_INVALID_VALUE;
183 }
184
185 return appExitReasonDataMgr->SetUIExtensionAbilityExitReason(bundleName, extensionList, exitReason);
186 }
187
GetActiveAbilityList(int32_t uid,std::vector<std::string> & abilityLists,const int32_t pid)188 void AppExitReasonHelper::GetActiveAbilityList(int32_t uid, std::vector<std::string> &abilityLists,
189 const int32_t pid)
190 {
191 int32_t targetUserId;
192 if (DelayedSingleton<AppExecFwk::OsAccountManagerWrapper>::GetInstance()->
193 GetOsAccountLocalIdFromUid(uid, targetUserId) != ERR_OK) {
194 TAG_LOGE(AAFwkTag::ABILITYMGR, "Get GetOsAccountLocalIdFromUid failed.");
195 return;
196 }
197 CHECK_POINTER(subManagersHelper_);
198 if (targetUserId == U0_USER_ID) {
199 auto missionListManagers = subManagersHelper_->GetMissionListManagers();
200 for (auto& item: missionListManagers) {
201 CHECK_POINTER_CONTINUE(item.second);
202 std::vector<std::string> abilityList;
203 item.second->GetActiveAbilityList(uid, abilityList, pid);
204 if (!abilityList.empty()) {
205 abilityLists.insert(abilityLists.end(), abilityList.begin(), abilityList.end());
206 }
207 }
208 return;
209 }
210
211 auto listManager = subManagersHelper_->GetMissionListManagerByUserId(targetUserId);
212 CHECK_POINTER(listManager);
213 listManager->GetActiveAbilityList(uid, abilityLists, pid);
214 }
215
GetActiveAbilityListFromUIAbilityManager(int32_t uid,std::vector<std::string> & abilityLists,const int32_t pid)216 void AppExitReasonHelper::GetActiveAbilityListFromUIAbilityManager(int32_t uid, std::vector<std::string> &abilityLists,
217 const int32_t pid)
218 {
219 CHECK_POINTER(subManagersHelper_);
220 int32_t targetUserId;
221 if (DelayedSingleton<AppExecFwk::OsAccountManagerWrapper>::GetInstance()->
222 GetOsAccountLocalIdFromUid(uid, targetUserId) != ERR_OK) {
223 TAG_LOGE(AAFwkTag::ABILITYMGR, "Get GetOsAccountLocalIdFromUid failed.");
224 return;
225 }
226 if (targetUserId == U0_USER_ID) {
227 auto uiAbilityManagers = subManagersHelper_->GetUIAbilityManagers();
228 for (auto& item: uiAbilityManagers) {
229 CHECK_POINTER_CONTINUE(item.second);
230 std::vector<std::string> abilityList;
231 item.second->GetActiveAbilityList(uid, abilityList, pid);
232 if (!abilityList.empty()) {
233 abilityLists.insert(abilityLists.end(), abilityList.begin(), abilityList.end());
234 }
235 }
236 return;
237 }
238
239 auto uiAbilityManager = subManagersHelper_->GetUIAbilityManagerByUserId(targetUserId);
240 CHECK_POINTER(uiAbilityManager);
241 uiAbilityManager->GetActiveAbilityList(uid, abilityLists, pid);
242 }
243
IsExitReasonValid(const ExitReason & exitReason)244 bool AppExitReasonHelper::IsExitReasonValid(const ExitReason &exitReason)
245 {
246 const Reason reason = exitReason.reason;
247 return reason >= REASON_MIN && reason <= REASON_MAX;
248 }
249 } // namespace AppExecFwk
250 } // namespace OHOS
251