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