1 /*
2 * Copyright (c) 2022-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 "resident_process_manager.h"
17
18 #include "ability_manager_service.h"
19 #include "ability_resident_process_rdb.h"
20 #include "ability_util.h"
21 #include "app_utils.h"
22 #include "ffrt.h"
23 #include "keep_alive_utils.h"
24 #include "main_element_utils.h"
25
26 namespace OHOS {
27 namespace AAFwk {
ResidentAbilityInfoGuard(const std::string & bundleName,const std::string & abilityName,int32_t userId)28 ResidentAbilityInfoGuard::ResidentAbilityInfoGuard(const std::string &bundleName,
29 const std::string &abilityName, int32_t userId)
30 {
31 residentId_ = DelayedSingleton<ResidentProcessManager>::GetInstance()->PutResidentAbility(bundleName,
32 abilityName, userId);
33 }
34
~ResidentAbilityInfoGuard()35 ResidentAbilityInfoGuard::~ResidentAbilityInfoGuard()
36 {
37 if (residentId_ != -1) {
38 DelayedSingleton<ResidentProcessManager>::GetInstance()->RemoveResidentAbility(residentId_);
39 }
40 }
41
SetResidentAbilityInfo(const std::string & bundleName,const std::string & abilityName,int32_t userId)42 void ResidentAbilityInfoGuard::SetResidentAbilityInfo(const std::string &bundleName,
43 const std::string &abilityName, int32_t userId)
44 {
45 if (residentId_ != -1) {
46 return;
47 }
48 residentId_ = DelayedSingleton<ResidentProcessManager>::GetInstance()->PutResidentAbility(bundleName,
49 abilityName, userId);
50 }
51
ResidentProcessManager()52 ResidentProcessManager::ResidentProcessManager()
53 {}
54
~ResidentProcessManager()55 ResidentProcessManager::~ResidentProcessManager()
56 {}
57
Init()58 void ResidentProcessManager::Init()
59 {
60 auto &amsRdb = AmsResidentProcessRdb::GetInstance();
61 amsRdb.Init();
62 }
63
StartResidentProcess(const std::vector<AppExecFwk::BundleInfo> & bundleInfos)64 void ResidentProcessManager::StartResidentProcess(const std::vector<AppExecFwk::BundleInfo> &bundleInfos)
65 {
66 DelayedSingleton<AppScheduler>::GetInstance()->StartupResidentProcess(bundleInfos);
67 }
68
StartResidentProcessWithMainElement(std::vector<AppExecFwk::BundleInfo> & bundleInfos,int32_t userId)69 void ResidentProcessManager::StartResidentProcessWithMainElement(std::vector<AppExecFwk::BundleInfo> &bundleInfos,
70 int32_t userId)
71 {
72 std::set<uint32_t> needEraseIndexSet;
73
74 for (size_t i = 0; i < bundleInfos.size(); i++) {
75 StartResidentProcessWithMainElementPerBundle(bundleInfos[i], i, needEraseIndexSet, userId);
76 }
77
78 // delete item which process has been started.
79 for (auto iter = needEraseIndexSet.rbegin(); iter != needEraseIndexSet.rend(); iter++) {
80 bundleInfos.erase(bundleInfos.begin() + *iter);
81 }
82 }
83
StartResidentProcessWithMainElementPerBundle(const AppExecFwk::BundleInfo & bundleInfo,size_t index,std::set<uint32_t> & needEraseIndexSet,int32_t userId)84 void ResidentProcessManager::StartResidentProcessWithMainElementPerBundle(const AppExecFwk::BundleInfo &bundleInfo,
85 size_t index, std::set<uint32_t> &needEraseIndexSet, int32_t userId)
86 {
87 if (userId != 0 && !AppUtils::GetInstance().InResidentWhiteList(bundleInfo.name)) {
88 TAG_LOGW(AAFwkTag::ABILITYMGR, "not in resident allow list");
89 needEraseIndexSet.insert(index);
90 return;
91 }
92 std::string processName = bundleInfo.applicationInfo.process;
93 bool keepAliveEnable = bundleInfo.isKeepAlive;
94 // Check startup permissions
95 AmsResidentProcessRdb::GetInstance().GetResidentProcessEnable(bundleInfo.name, keepAliveEnable);
96 if (!bundleInfo.isKeepAlive && keepAliveEnable) {
97 auto &bundleName = bundleInfo.name;
98 TAG_LOGI(AAFwkTag::ABILITYMGR, "keepAliveBundle changed, bundle:%{public}s", bundleName.c_str());
99 AmsResidentProcessRdb::GetInstance().RemoveData(bundleName);
100 keepAliveEnable = false;
101 }
102 TAG_LOGI(AAFwkTag::ABILITYMGR,
103 "Precheck,bundle:%{public}s, process:%{public}s, keepAlive:%{public}d, enable:%{public}d",
104 bundleInfo.name.c_str(), processName.c_str(), bundleInfo.isKeepAlive, keepAliveEnable);
105 if (!keepAliveEnable || processName.empty()) {
106 needEraseIndexSet.insert(index);
107 return;
108 }
109 for (auto hapModuleInfo : bundleInfo.hapModuleInfos) {
110 StartResidentProcessWithMainElementPerBundleHap(hapModuleInfo, processName, index, needEraseIndexSet, userId);
111 }
112 }
113
StartResidentProcessWithMainElementPerBundleHap(const AppExecFwk::HapModuleInfo & hapModuleInfo,const std::string & processName,size_t index,std::set<uint32_t> & needEraseIndexSet,int32_t userId)114 void ResidentProcessManager::StartResidentProcessWithMainElementPerBundleHap(
115 const AppExecFwk::HapModuleInfo &hapModuleInfo, const std::string &processName,
116 size_t index, std::set<uint32_t> &needEraseIndexSet, int32_t userId)
117 {
118 std::string mainElement;
119 bool isDataAbility = false;
120 std::string uriStr;
121 if (!MainElementUtils::CheckMainElement(hapModuleInfo,
122 processName, mainElement, isDataAbility, uriStr, userId)) {
123 if (isDataAbility) {
124 // dataability, need use AcquireDataAbility
125 needEraseIndexSet.insert(index);
126 TAG_LOGI(AAFwkTag::ABILITYMGR, "call, mainElement: %{public}s, uri: %{public}s",
127 mainElement.c_str(), uriStr.c_str());
128 Uri uri(uriStr);
129 DelayedSingleton<AbilityManagerService>::GetInstance()->AcquireDataAbility(uri, true, nullptr);
130 }
131 return;
132 }
133
134 needEraseIndexSet.insert(index);
135 // startAbility
136 Want want;
137 want.SetElementName(hapModuleInfo.bundleName, mainElement);
138 ResidentAbilityInfoGuard residentAbilityInfoGuard(hapModuleInfo.bundleName, mainElement, userId);
139 TAG_LOGI(AAFwkTag::ABILITYMGR, "StartResidentAbility, bundleName: %{public}s, mainElement: %{public}s",
140 hapModuleInfo.bundleName.c_str(), mainElement.c_str());
141 auto ret = DelayedSingleton<AbilityManagerService>::GetInstance()->StartAbility(want, userId,
142 DEFAULT_INVAL_VALUE);
143 MainElementUtils::UpdateMainElement(hapModuleInfo.bundleName,
144 hapModuleInfo.name, mainElement, true, userId);
145 if (ret != ERR_OK) {
146 AddFailedResidentAbility(hapModuleInfo.bundleName, mainElement, userId);
147 }
148 }
149
SetResidentProcessEnabled(const std::string & bundleName,const std::string & callerName,bool updateEnable)150 int32_t ResidentProcessManager::SetResidentProcessEnabled(
151 const std::string &bundleName, const std::string &callerName, bool updateEnable)
152 {
153 TAG_LOGI(AAFwkTag::ABILITYMGR, "SetResidentProcessEnabled,bundle:%{public}s,caller:%{public}s,enable:%{public}d",
154 bundleName.c_str(), callerName.c_str(), updateEnable);
155 if (bundleName.empty() || callerName.empty()) {
156 TAG_LOGE(AAFwkTag::ABILITYMGR, "input parameter error");
157 return INVALID_PARAMETERS_ERR;
158 }
159 auto &rdb = AmsResidentProcessRdb::GetInstance();
160 auto rdbResult = rdb.VerifyConfigurationPermissions(bundleName, callerName);
161 auto configResult = rdb.GetResidentProcessRawData(bundleName, callerName);
162 if (rdbResult != Rdb_OK && configResult != Rdb_OK) {
163 TAG_LOGE(AAFwkTag::ABILITYMGR, "obtain permissions failed. result: %{public}d, configResult: %{public}d",
164 rdbResult, configResult);
165 return ERR_NO_RESIDENT_PERMISSION;
166 }
167
168 bool localEnable = false;
169 rdbResult = rdb.GetResidentProcessEnable(bundleName, localEnable);
170 if (rdbResult != Rdb_OK) {
171 TAG_LOGE(AAFwkTag::ABILITYMGR, "GetResidentProcess failed:%{public}d", rdbResult);
172 return INNER_ERR;
173 }
174
175 if (updateEnable == localEnable) {
176 TAG_LOGE(AAFwkTag::ABILITYMGR, "no change to the resident process setting properties");
177 return ERR_OK;
178 }
179
180 rdbResult = rdb.UpdateResidentProcessEnable(bundleName, updateEnable);
181 if (rdbResult != Rdb_OK) {
182 TAG_LOGE(AAFwkTag::ABILITYMGR, "resident process attribute update failed");
183 return INNER_ERR;
184 }
185
186 auto appMgrClient = DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance();
187 if (appMgrClient != nullptr) {
188 TAG_LOGD(AAFwkTag::ABILITYMGR, "Set keep alive enable state.");
189 IN_PROCESS_CALL_WITHOUT_RET(appMgrClient->SetKeepAliveEnableState(bundleName, updateEnable, 0));
190 }
191
192 ffrt::submit([self = shared_from_this(), bundleName, localEnable, updateEnable]() {
193 self->UpdateResidentProcessesStatus(bundleName, localEnable, updateEnable);
194 });
195 return ERR_OK;
196 }
197
UpdateResidentProcessesStatus(const std::string & bundleName,bool localEnable,bool updateEnable)198 void ResidentProcessManager::UpdateResidentProcessesStatus(
199 const std::string &bundleName, bool localEnable, bool updateEnable)
200 {
201 TAG_LOGD(AAFwkTag::ABILITYMGR, "called");
202 if (bundleName.empty()) {
203 TAG_LOGE(AAFwkTag::ABILITYMGR, "bundle name empty");
204 return;
205 }
206
207 auto bms = AbilityUtil::GetBundleManagerHelper();
208 if (bms == nullptr) {
209 TAG_LOGE(AAFwkTag::ABILITYMGR, "obtain bms handle failed");
210 return;
211 }
212
213 AppExecFwk::BundleInfo bundleInfo;
214 auto currentUser = DelayedSingleton<AbilityManagerService>::GetInstance()->GetUserId();
215 std::set<int32_t> users{0, currentUser};
216
217 for (const auto &userId: users) {
218 if (!IN_PROCESS_CALL(bms->GetBundleInfo(
219 bundleName, AppExecFwk::BundleFlag::GET_BUNDLE_DEFAULT, bundleInfo, userId))) {
220 TAG_LOGW(AAFwkTag::ABILITYMGR, "get bundle info failed, userId:%{public}d", userId);
221 continue;
222 }
223
224 if (updateEnable && !localEnable) {
225 // need start
226 std::vector<AppExecFwk::BundleInfo> bundleInfos{ bundleInfo };
227 StartResidentProcessWithMainElement(bundleInfos, userId);
228 if (!bundleInfos.empty()) {
229 StartResidentProcess(bundleInfos);
230 }
231 } else if (!updateEnable && localEnable) {
232 // just update
233 std::vector<AppExecFwk::BundleInfo> bundleInfos{ bundleInfo };
234 KeepAliveUtils::NotifyDisableKeepAliveProcesses(bundleInfos, userId);
235 }
236 }
237 }
238
OnAppStateChanged(const AppInfo & info)239 void ResidentProcessManager::OnAppStateChanged(const AppInfo &info)
240 {
241 TAG_LOGD(AAFwkTag::ABILITYMGR, "Called");
242 if (info.state != AppState::BEGIN) {
243 TAG_LOGD(AAFwkTag::ABILITYMGR, "Not a state of concern. state: %{public}d", info.state);
244 return;
245 }
246
247 if (info.pid <= 0) {
248 TAG_LOGD(AAFwkTag::ABILITYMGR, "The obtained application pid is incorrect. state: %{public}d", info.pid);
249 return;
250 }
251
252 std::string bundleName;
253 // user 0
254 int32_t uid = 0;
255 auto appScheduler = DelayedSingleton<AppScheduler>::GetInstance();
256 if (appScheduler == nullptr) {
257 TAG_LOGE(AAFwkTag::ABILITYMGR, "app scheduler error");
258 return;
259 }
260 appScheduler->GetBundleNameByPid(info.pid, bundleName, uid);
261 if (bundleName.empty()) {
262 TAG_LOGE(AAFwkTag::ABILITYMGR, "get bundle name by pid failed");
263 return;
264 }
265
266 bool localEnable = false;
267 auto rdbResult = AmsResidentProcessRdb::GetInstance().GetResidentProcessEnable(bundleName, localEnable);
268 if (rdbResult != Rdb_OK) {
269 TAG_LOGE(AAFwkTag::ABILITYMGR, "rdbResult: %{public}d", rdbResult);
270 return;
271 }
272
273 auto appMgrClient = DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance();
274 if (appMgrClient == nullptr) {
275 TAG_LOGE(AAFwkTag::ABILITYMGR, "set keep alive enable state error");
276 return;
277 }
278 IN_PROCESS_CALL_WITHOUT_RET(appMgrClient->SetKeepAliveEnableState(bundleName, localEnable, 0));
279 }
280
PutResidentAbility(const std::string & bundleName,const std::string & abilityName,int32_t userId)281 int32_t ResidentProcessManager::PutResidentAbility(const std::string &bundleName,
282 const std::string &abilityName, int32_t userId)
283 {
284 std::lock_guard lock(residentAbilityInfoMutex_);
285 auto residentId = residentId_++;
286 residentAbilityInfos_.push_back(ResidentAbilityInfo {
287 .bundleName = bundleName,
288 .abilityName = abilityName,
289 .userId = userId,
290 .residentId = residentId
291 });
292 return residentId;
293 }
294
IsResidentAbility(const std::string & bundleName,const std::string & abilityName,int32_t userId)295 bool ResidentProcessManager::IsResidentAbility(const std::string &bundleName,
296 const std::string &abilityName, int32_t userId)
297 {
298 std::lock_guard lock(residentAbilityInfoMutex_);
299 for (const auto &item: residentAbilityInfos_) {
300 if (item.bundleName == bundleName && item.abilityName == abilityName && item.userId == userId) {
301 return true;
302 }
303 }
304 return false;
305 }
306
RemoveResidentAbility(int32_t residentId)307 void ResidentProcessManager::RemoveResidentAbility(int32_t residentId)
308 {
309 std::lock_guard lock(residentAbilityInfoMutex_);
310 for (auto it = residentAbilityInfos_.begin(); it != residentAbilityInfos_.end(); ++it) {
311 if (it->residentId == residentId) {
312 residentAbilityInfos_.erase(it);
313 return;
314 }
315 }
316 }
317
GetResidentBundleInfosForUser(std::vector<AppExecFwk::BundleInfo> & bundleInfos,int32_t userId)318 bool ResidentProcessManager::GetResidentBundleInfosForUser(std::vector<AppExecFwk::BundleInfo> &bundleInfos,
319 int32_t userId)
320 {
321 auto bundleMgrHelper = DelayedSingleton<AppExecFwk::BundleMgrHelper>::GetInstance();
322 CHECK_POINTER_AND_RETURN(bundleMgrHelper, false);
323
324 const auto &residentWhiteList = AppUtils::GetInstance().GetResidentWhiteList();
325 if (userId == 0 || residentWhiteList.empty()) {
326 TAG_LOGD(AAFwkTag::ABILITYMGR, "userId: %{public}d", userId);
327 return IN_PROCESS_CALL(bundleMgrHelper->GetBundleInfos(OHOS::AppExecFwk::GET_BUNDLE_DEFAULT,
328 bundleInfos, userId));
329 }
330
331 for (const auto &bundleName: residentWhiteList) {
332 AppExecFwk::BundleInfo bundleInfo;
333 if (!IN_PROCESS_CALL(bundleMgrHelper->GetBundleInfo(bundleName,
334 AppExecFwk::BundleFlag::GET_BUNDLE_WITH_ABILITIES, bundleInfo, userId))) {
335 TAG_LOGW(AAFwkTag::ABILITYMGR, "failed get bundle info: %{public}s", bundleName.c_str());
336 continue;
337 }
338 bundleInfos.push_back(bundleInfo);
339 }
340
341 return !bundleInfos.empty();
342 }
343
StartFailedResidentAbilities()344 void ResidentProcessManager::StartFailedResidentAbilities()
345 {
346 unlockedAfterBoot_ = true;
347 std::list<ResidentAbilityInfo> tmpList;
348 {
349 std::lock_guard lock(failedResidentAbilityInfoMutex_);
350 if (failedResidentAbilityInfos_.empty()) {
351 TAG_LOGI(AAFwkTag::ABILITYMGR, "no failed abilities");
352 return;
353 }
354 tmpList = std::move(failedResidentAbilityInfos_);
355 }
356 for (const auto &item: tmpList) {
357 ResidentAbilityInfoGuard residentAbilityInfoGuard(item.bundleName, item.abilityName, item.userId);
358 Want want;
359 want.SetElementName(item.bundleName, item.abilityName);
360 TAG_LOGI(AAFwkTag::ABILITYMGR, "call, bundleName: %{public}s, mainElement: %{public}s",
361 item.bundleName.c_str(), item.abilityName.c_str());
362 DelayedSingleton<AbilityManagerService>::GetInstance()->StartAbility(want, item.userId,
363 DEFAULT_INVAL_VALUE);
364 }
365 }
366
AddFailedResidentAbility(const std::string & bundleName,const std::string & abilityName,int32_t userId)367 void ResidentProcessManager::AddFailedResidentAbility(const std::string &bundleName,
368 const std::string &abilityName, int32_t userId)
369 {
370 TAG_LOGI(AAFwkTag::ABILITYMGR, "failed bundleName: %{public}s, mainElement: %{public}s",
371 bundleName.c_str(), abilityName.c_str());
372 if (unlockedAfterBoot_) {
373 TAG_LOGI(AAFwkTag::ABILITYMGR, "already unlocked");
374 return;
375 }
376
377 std::lock_guard lock(failedResidentAbilityInfoMutex_);
378 failedResidentAbilityInfos_.push_back(ResidentAbilityInfo {
379 .bundleName = bundleName,
380 .abilityName = abilityName,
381 .userId = userId,
382 });
383 }
384 } // namespace AAFwk
385 } // namespace OHOS
386