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