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