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