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