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