1 /*
2 * Copyright (c) 2023 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 "bundle_overlay_data_manager.h"
17
18 #include "bundle_common_event_mgr.h"
19 #include "bundle_mgr_service.h"
20 #include "ipc_skeleton.h"
21 #include "scope_guard.h"
22 #include "string_ex.h"
23
24 namespace OHOS {
25 namespace AppExecFwk {
UpdateOverlayInfo(const InnerBundleInfo & newInfo,InnerBundleInfo & oldInfo,InnerBundleInfo & targetInnerBundleInfo)26 ErrCode OverlayDataMgr::UpdateOverlayInfo(const InnerBundleInfo &newInfo, InnerBundleInfo &oldInfo,
27 InnerBundleInfo &targetInnerBundleInfo)
28 {
29 // 1. update internal overlay info
30 if (newInfo.GetOverlayType() == OVERLAY_INTERNAL_BUNDLE) {
31 return UpdateInternalOverlayInfo(newInfo, oldInfo);
32 }
33 // 2. update external overlay info
34 if (newInfo.GetOverlayType() == OVERLAY_EXTERNAL_BUNDLE) {
35 return UpdateExternalOverlayInfo(newInfo, oldInfo, targetInnerBundleInfo);
36 }
37 // 3. update overlay connection
38 if (newInfo.GetOverlayType() == NON_OVERLAY_TYPE) {
39 return BuildOverlayConnection(newInfo, oldInfo);
40 }
41 return ERR_OK;
42 }
43
IsExistedNonOverlayHap(const std::string & bundleName)44 bool OverlayDataMgr::IsExistedNonOverlayHap(const std::string &bundleName)
45 {
46 if (bundleName.empty()) {
47 APP_LOGE("bundle name %{public}s is invalid", bundleName.c_str());
48 return false;
49 }
50
51 if (GetBundleDataMgr() != ERR_OK) {
52 return false;
53 }
54 InnerBundleInfo innerBundleInfo;
55 if (!dataMgr_->QueryOverlayInnerBundleInfo(bundleName, innerBundleInfo)) {
56 APP_LOGE("no bundle with bundleName %{public}s installed", bundleName.c_str());
57 return false;
58 }
59 const auto &innerModuleInfos = innerBundleInfo.GetInnerModuleInfos();
60 if (innerModuleInfos.empty()) {
61 APP_LOGE("innerModuleInfo in innerBundleInfo is empty");
62 return false;
63 }
64 for (const auto &innerModuleInfo : innerModuleInfos) {
65 if (innerModuleInfo.second.targetModuleName.empty()) {
66 return true;
67 }
68 }
69 APP_LOGW("only overlay hap existed");
70 return false;
71 }
72
UpdateInternalOverlayInfo(const InnerBundleInfo & newInfo,InnerBundleInfo & oldInfo)73 ErrCode OverlayDataMgr::UpdateInternalOverlayInfo(const InnerBundleInfo &newInfo, InnerBundleInfo &oldInfo)
74 {
75 APP_LOGD("start to update internal overlay info");
76 auto &innerModuleInfos = newInfo.GetInnerModuleInfos();
77 if (innerModuleInfos.empty()) {
78 APP_LOGE("innerModuleInfos is empty");
79 return ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_INTERNAL_ERROR;
80 }
81 // build module overlay info
82 OverlayModuleInfo overlayModuleInfo;
83 overlayModuleInfo.bundleName = newInfo.GetBundleName();
84 overlayModuleInfo.moduleName = (innerModuleInfos.begin()->second).moduleName;
85 overlayModuleInfo.targetModuleName = (innerModuleInfos.begin()->second).targetModuleName;
86 overlayModuleInfo.hapPath = newInfo.GetModuleHapPath(newInfo.GetCurrentModulePackage());
87 overlayModuleInfo.priority = (innerModuleInfos.begin()->second).targetPriority;
88 oldInfo.AddOverlayModuleInfo(overlayModuleInfo);
89 SaveInternalOverlayModuleState(overlayModuleInfo, oldInfo);
90 return ERR_OK;
91 }
92
UpdateExternalOverlayInfo(const InnerBundleInfo & newInfo,InnerBundleInfo & oldInfo,InnerBundleInfo & targetInnerBundleInfo)93 ErrCode OverlayDataMgr::UpdateExternalOverlayInfo(const InnerBundleInfo &newInfo, InnerBundleInfo &oldInfo,
94 InnerBundleInfo &targetInnerBundleInfo)
95 {
96 APP_LOGD("start to update external overlay info");
97 if (GetBundleDataMgr() != ERR_OK) {
98 return ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_INTERNAL_ERROR;
99 }
100 if (targetInnerBundleInfo.GetBundleName().empty()) {
101 APP_LOGD("no need to update external overlay info");
102 return ERR_OK;
103 }
104 const auto &innerModuleInfos = newInfo.GetInnerModuleInfos();
105 if (innerModuleInfos.empty()) {
106 APP_LOGE("innerModuleInfos is empty");
107 return ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_INTERNAL_ERROR;
108 }
109 OverlayModuleInfo overlayModuleInfo;
110 overlayModuleInfo.bundleName = newInfo.GetBundleName();
111 overlayModuleInfo.moduleName = (innerModuleInfos.begin()->second).moduleName;
112 overlayModuleInfo.targetModuleName = (innerModuleInfos.begin()->second).targetModuleName;
113 overlayModuleInfo.hapPath = newInfo.GetModuleHapPath(newInfo.GetCurrentModulePackage());
114 overlayModuleInfo.priority = (innerModuleInfos.begin()->second).targetPriority;
115
116 if (SaveExternalOverlayModuleState(
117 overlayModuleInfo, targetInnerBundleInfo, newInfo.GetUserId(), oldInfo) != ERR_OK) {
118 APP_LOGE("save external overlay module state failed");
119 return ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_INTERNAL_ERROR;
120 }
121
122 // build bundle overlay info
123 std::string bundleDir;
124 const std::string &moduleHapPath = newInfo.GetModuleHapPath(newInfo.GetCurrentModulePackage());
125 GetBundleDir(moduleHapPath, bundleDir);
126 OverlayBundleInfo overlayBundleInfo;
127 overlayBundleInfo.bundleName = newInfo.GetBundleName();
128 overlayBundleInfo.bundleDir = bundleDir;
129 overlayBundleInfo.state = newInfo.GetOverlayState();
130 overlayBundleInfo.priority = newInfo.GetTargetPriority();
131 targetInnerBundleInfo.AddOverlayBundleInfo(overlayBundleInfo);
132 targetInnerBundleInfo.AddOverlayModuleInfo(overlayModuleInfo);
133 return ERR_OK;
134 }
135
BuildOverlayConnection(const InnerBundleInfo & newInfo,InnerBundleInfo & oldInfo)136 ErrCode OverlayDataMgr::BuildOverlayConnection(const InnerBundleInfo &newInfo, InnerBundleInfo &oldInfo)
137 {
138 APP_LOGD("start to update overlay connection");
139 #ifdef BUNDLE_FRAMEWORK_OVERLAY_INSTALLATION
140 // 1. build overlay connection for internal overlay
141 const auto &moduleInfos = newInfo.GetInnerModuleInfos();
142 std::string moduleName = (moduleInfos.begin()->second).moduleName;
143 BuildInternalOverlayConnection(moduleName, oldInfo, newInfo.GetUserId());
144 #endif
145 return ERR_OK;
146 }
147
BuildInternalOverlayConnection(const std::string & moduleName,InnerBundleInfo & oldInfo,int32_t userId)148 void OverlayDataMgr::BuildInternalOverlayConnection(const std::string &moduleName, InnerBundleInfo &oldInfo,
149 int32_t userId)
150 {
151 APP_LOGD("start to update internal overlay connection of module %{public}s under user %{public}d",
152 moduleName.c_str(), userId);
153 if (oldInfo.GetOverlayType() != OVERLAY_INTERNAL_BUNDLE) {
154 APP_LOGW("the old bundle is not internal overlay");
155 return;
156 }
157 auto &oldInnerModuleInfos = oldInfo.FetchInnerModuleInfos();
158 std::vector<std::string> overlayModuleVec;
159 for (auto &moduleInfo : oldInnerModuleInfos) {
160 if (moduleInfo.second.targetModuleName == moduleName) {
161 OverlayModuleInfo overlayModuleInfo;
162 overlayModuleInfo.bundleName = oldInfo.GetBundleName();
163 overlayModuleInfo.moduleName = moduleInfo.second.moduleName;
164 overlayModuleInfo.targetModuleName = moduleInfo.second.targetModuleName;
165 overlayModuleInfo.hapPath = oldInfo.GetModuleHapPath(moduleInfo.second.moduleName);
166 overlayModuleInfo.priority = moduleInfo.second.targetPriority;
167 oldInfo.AddOverlayModuleInfo(overlayModuleInfo);
168 overlayModuleVec.emplace_back(moduleInfo.second.moduleName);
169 }
170 }
171 if (GetBundleDataMgr() != ERR_OK) {
172 return;
173 }
174 auto userSet = dataMgr_->GetAllUser();
175 for (const auto &innerUserId : userSet) {
176 InnerBundleUserInfo userInfo;
177 if (!oldInfo.GetInnerBundleUserInfo(innerUserId, userInfo)) {
178 APP_LOGW("no userInfo of bundleName %{public}s under userId %{public}d", oldInfo.GetBundleName().c_str(),
179 innerUserId);
180 continue;
181 }
182 for (const auto &overlayModule : overlayModuleVec) {
183 int32_t state = OVERLAY_INVALID;
184 oldInfo.GetOverlayModuleState(overlayModule, innerUserId, state);
185 if (state == OVERLAY_INVALID) {
186 oldInfo.SetOverlayModuleState(overlayModule, OVERLAY_ENABLE, innerUserId);
187 }
188 }
189 }
190 }
191
GetBundleDir(const std::string & moduleHapPath,std::string & bundleDir) const192 ErrCode OverlayDataMgr::GetBundleDir(const std::string &moduleHapPath, std::string &bundleDir) const
193 {
194 bundleDir = moduleHapPath;
195 if (moduleHapPath.back() == Constants::FILE_SEPARATOR_CHAR) {
196 bundleDir = moduleHapPath.substr(0, moduleHapPath.length() - 1);
197 }
198 size_t pos = bundleDir.find_last_of(Constants::PATH_SEPARATOR);
199 if (pos == std::string::npos) {
200 APP_LOGE("bundleDir is invalid");
201 return ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_INVALID_BUNDLE_DIR;
202 }
203 bundleDir = bundleDir.substr(0, pos);
204 APP_LOGD("bundleDir is %{public}s", bundleDir.c_str());
205 return ERR_OK;
206 }
207
RemoveOverlayModuleConnection(const InnerBundleInfo & newInfo,InnerBundleInfo & oldInfo)208 ErrCode OverlayDataMgr::RemoveOverlayModuleConnection(const InnerBundleInfo &newInfo, InnerBundleInfo &oldInfo)
209 {
210 APP_LOGD("start to remove overlay connection before update");
211 const auto &innerModuleInfos = newInfo.GetInnerModuleInfos();
212 if (innerModuleInfos.empty()) {
213 APP_LOGE("innerModuleInfos is empty");
214 return ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_INTERNAL_ERROR;
215 }
216 std::string moduleName = (innerModuleInfos.begin()->second).moduleName;
217 const auto &oldInnerModuleInfos = oldInfo.GetInnerModuleInfos();
218 if (oldInnerModuleInfos.find(moduleName) == oldInnerModuleInfos.end()) {
219 APP_LOGE("module %{public}s is not existed", moduleName.c_str());
220 return ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_INTERNAL_ERROR;
221 }
222 if (newInfo.GetOverlayType() == OVERLAY_INTERNAL_BUNDLE) {
223 APP_LOGD("start to remove internal overlay connection before update");
224 oldInfo.RemoveOverlayModuleInfo(oldInnerModuleInfos.at(moduleName).targetModuleName, newInfo.GetBundleName(),
225 moduleName);
226 return ERR_OK;
227 }
228 if (newInfo.GetOverlayType() == OVERLAY_EXTERNAL_BUNDLE) {
229 APP_LOGD("start to remove external overlay connection before update");
230 if (GetBundleDataMgr() != ERR_OK) {
231 return ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_INTERNAL_ERROR;
232 }
233 InnerBundleInfo targetInnerBundleInfo;
234 const auto &targetBundleName = oldInfo.GetTargetBundleName();
235 if (!dataMgr_->QueryOverlayInnerBundleInfo(targetBundleName, targetInnerBundleInfo)) {
236 APP_LOGE("no bundle with bundleName %{public}s installed", targetBundleName.c_str());
237 return ERR_OK;
238 }
239 // external overlay bundle change target bundle name
240 if (newInfo.GetTargetBundleName() != oldInfo.GetTargetBundleName()) {
241 // remove all module connection in old targetBundle
242 targetInnerBundleInfo.RemoveAllOverlayModuleInfo(newInfo.GetBundleName());
243 targetInnerBundleInfo.RemoveOverLayBundleInfo(newInfo.GetBundleName());
244 } else {
245 targetInnerBundleInfo.RemoveOverlayModuleInfo(oldInnerModuleInfos.at(moduleName).targetModuleName,
246 newInfo.GetBundleName(), moduleName);
247 }
248 // save target innerBundleInfo
249 dataMgr_->SaveOverlayInfo(targetBundleName, targetInnerBundleInfo);
250 }
251 return ERR_OK;
252 }
253
RemoveOverlayBundleInfo(const std::string & bundleName,InnerBundleInfo & targetInnerBundleInfo)254 void OverlayDataMgr::RemoveOverlayBundleInfo(const std::string &bundleName, InnerBundleInfo &targetInnerBundleInfo)
255 {
256 APP_LOGD("start to remove overlay bundleInfo under uninstalling external overlay");
257 if (GetBundleDataMgr() != ERR_OK) {
258 return;
259 }
260 targetInnerBundleInfo.RemoveOverLayBundleInfo(bundleName);
261 targetInnerBundleInfo.RemoveAllOverlayModuleInfo(bundleName);
262 APP_LOGD("finish to remove overlay bundleInfo");
263 }
264
RemoveOverlayModuleInfo(const std::string & bundleName,const std::string & modulePackage,InnerBundleInfo & oldInfo,InnerBundleInfo & targetInnerBundleInfo)265 void OverlayDataMgr::RemoveOverlayModuleInfo(const std::string &bundleName, const std::string &modulePackage,
266 InnerBundleInfo &oldInfo, InnerBundleInfo &targetInnerBundleInfo)
267 {
268 APP_LOGD("start to remove overlay moduleInfo under uninstalling overlay module");
269 if (!oldInfo.FindModule(modulePackage)) {
270 return;
271 }
272 auto &innerModuleInfos = oldInfo.FetchInnerModuleInfos();
273 std::string targetModuleName = innerModuleInfos.at(modulePackage).targetModuleName;
274 // remove internal overlay info from target module
275 if (oldInfo.GetOverlayType() == OVERLAY_INTERNAL_BUNDLE) {
276 // uninstall non-overlay module and state of overlay module will be OVERLAY_INVALID
277 if (targetModuleName.empty()) {
278 ResetInternalOverlayModuleState(innerModuleInfos, modulePackage, oldInfo);
279 return;
280 }
281 // uninstall overlay module, remove state info from innerUserInfo
282 oldInfo.RemoveOverlayModuleInfo(targetModuleName, bundleName, modulePackage);
283 oldInfo.ClearOverlayModuleStates(modulePackage);
284 return;
285 }
286
287 // remove external overlay info from target bundle
288 if (oldInfo.GetOverlayType() == OVERLAY_EXTERNAL_BUNDLE) {
289 if (targetInnerBundleInfo.GetBundleName().empty()) {
290 APP_LOGD("target bundle %{public}s is not installed", targetInnerBundleInfo.GetBundleName().c_str());
291 return;
292 }
293 targetInnerBundleInfo.RemoveOverlayModuleInfo(targetModuleName, bundleName, modulePackage);
294 // uninstall overlay module, remove state info from innerUserInfo
295 oldInfo.ClearOverlayModuleStates(modulePackage);
296 }
297 APP_LOGD("finish to remove overlay moduleInfo");
298 }
299
ResetInternalOverlayModuleState(const std::map<std::string,InnerModuleInfo> & innerModuleInfos,const std::string & modulePackage,InnerBundleInfo & oldInfo)300 void OverlayDataMgr::ResetInternalOverlayModuleState(const std::map<std::string, InnerModuleInfo> &innerModuleInfos,
301 const std::string &modulePackage, InnerBundleInfo &oldInfo)
302 {
303 for (const auto &moduleInfo : innerModuleInfos) {
304 if (moduleInfo.second.targetModuleName == modulePackage) {
305 oldInfo.SetOverlayModuleState(moduleInfo.second.moduleName, OVERLAY_INVALID);
306 return;
307 }
308 }
309 }
310
QueryOverlayInnerBundleInfo(const std::string & bundleName,InnerBundleInfo & info)311 bool OverlayDataMgr::QueryOverlayInnerBundleInfo(const std::string &bundleName, InnerBundleInfo &info)
312 {
313 if (GetBundleDataMgr() != ERR_OK) {
314 return false;
315 }
316 if (!dataMgr_->QueryOverlayInnerBundleInfo(bundleName, info)) {
317 APP_LOGE("target bundle %{public}s is not installed", bundleName.c_str());
318 return false;
319 }
320 return true;
321 }
322
GetBundleDataMgr()323 ErrCode OverlayDataMgr::GetBundleDataMgr()
324 {
325 if (dataMgr_ == nullptr) {
326 dataMgr_ = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
327 if (dataMgr_ == nullptr) {
328 APP_LOGE("overlayDataMgr gets data mgr ptr failed");
329 return ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_SERVICE_EXCEPTION;
330 }
331 }
332 return ERR_OK;
333 }
334
SaveInternalOverlayModuleState(const OverlayModuleInfo & overlayModuleInfo,InnerBundleInfo & innerBundleInfo)335 ErrCode OverlayDataMgr::SaveInternalOverlayModuleState(const OverlayModuleInfo &overlayModuleInfo,
336 InnerBundleInfo &innerBundleInfo)
337 {
338 if (GetBundleDataMgr() != ERR_OK) {
339 return ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_SERVICE_EXCEPTION;
340 }
341 auto userSet = dataMgr_->GetAllUser();
342 for (const auto &userId : userSet) {
343 APP_LOGD("start to save internal overlay module state under %{public}d", userId);
344 InnerBundleUserInfo userInfo;
345 if (!innerBundleInfo.GetInnerBundleUserInfo(userId, userInfo)) {
346 APP_LOGW("no userInfo of bundleName %{public}s under userId %{public}d",
347 innerBundleInfo.GetBundleName().c_str(), userId);
348 continue;
349 }
350
351 int32_t state = OVERLAY_INVALID;
352 if (innerBundleInfo.FindModule(overlayModuleInfo.targetModuleName)) {
353 state = OVERLAY_ENABLE;
354 }
355 auto &overlayStates = userInfo.bundleUserInfo.overlayModulesState;
356 auto iter = std::find_if(overlayStates.begin(), overlayStates.end(), [&overlayModuleInfo](const auto &item) {
357 if (item.find(overlayModuleInfo.moduleName + Constants::FILE_UNDERLINE) != std::string::npos) {
358 return true;
359 }
360 return false;
361 });
362 if (iter != overlayStates.end()) {
363 overlayStates.erase(iter);
364 }
365 std::string overlayModuleState =
366 overlayModuleInfo.moduleName + Constants::FILE_UNDERLINE + std::to_string(state);
367 overlayStates.emplace_back(overlayModuleState);
368 innerBundleInfo.AddInnerBundleUserInfo(userInfo);
369 }
370 return ERR_OK;
371 }
372
SaveExternalOverlayModuleState(const OverlayModuleInfo & overlayModuleInfo,const InnerBundleInfo & targetInnerBundleInfo,int32_t userId,InnerBundleInfo & innerBundleInfo)373 ErrCode OverlayDataMgr::SaveExternalOverlayModuleState(const OverlayModuleInfo &overlayModuleInfo,
374 const InnerBundleInfo &targetInnerBundleInfo, int32_t userId, InnerBundleInfo &innerBundleInfo)
375 {
376 APP_LOGD("start to save external overlay module state under %{public}d", userId);
377 if (GetBundleDataMgr() != ERR_OK) {
378 return ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_INTERNAL_ERROR;
379 }
380 int32_t state = OVERLAY_INVALID;
381 if (targetInnerBundleInfo.FindModule(overlayModuleInfo.targetModuleName)) {
382 state = OVERLAY_ENABLE;
383 }
384 InnerBundleUserInfo userInfo;
385 if (!innerBundleInfo.GetInnerBundleUserInfo(userId, userInfo)) {
386 APP_LOGE("no userInfo of bundleName %{public}s under userId %{public}d",
387 innerBundleInfo.GetBundleName().c_str(), userId);
388 return ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_INTERNAL_ERROR;
389 }
390 auto &overlayStates = userInfo.bundleUserInfo.overlayModulesState;
391 auto iter = std::find_if(overlayStates.begin(), overlayStates.end(), [&overlayModuleInfo](const auto &item) {
392 if (item.find(overlayModuleInfo.moduleName + Constants::FILE_UNDERLINE) != std::string::npos) {
393 return true;
394 }
395 return false;
396 });
397 if (iter != overlayStates.end()) {
398 overlayStates.erase(iter);
399 }
400 std::string overlayModuleState = overlayModuleInfo.moduleName + Constants::FILE_UNDERLINE + std::to_string(state);
401 overlayStates.emplace_back(overlayModuleState);
402 innerBundleInfo.AddInnerBundleUserInfo(userInfo);
403 return ERR_OK;
404 }
405
GetAllOverlayModuleInfo(const std::string & bundleName,std::vector<OverlayModuleInfo> & overlayModuleInfos,int32_t userId)406 ErrCode OverlayDataMgr::GetAllOverlayModuleInfo(const std::string &bundleName,
407 std::vector<OverlayModuleInfo> &overlayModuleInfos, int32_t userId)
408 {
409 APP_LOGD("start to get all overlay moduleInfo");
410 if (GetBundleDataMgr() != ERR_OK) {
411 return ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_INTERNAL_ERROR;
412 }
413 InnerBundleInfo info;
414 if (!dataMgr_->QueryOverlayInnerBundleInfo(bundleName, info)) {
415 APP_LOGW("overlay bundle is not existed %{public}s", bundleName.c_str());
416 return ERR_BUNDLEMANAGER_OVERLAY_QUERY_FAILED_MISSING_OVERLAY_BUNDLE;
417 }
418 InnerBundleUserInfo userInfo;
419 if (!info.GetInnerBundleUserInfo(userId, userInfo)) {
420 APP_LOGW("the bundle %{public}s is not installed at user %{public}d", bundleName.c_str(), userId);
421 return ERR_BUNDLEMANAGER_OVERLAY_QUERY_FAILED_BUNDLE_NOT_INSTALLED_AT_SPECIFIED_USERID;
422 }
423
424 if (info.GetOverlayType() == NON_OVERLAY_TYPE) {
425 APP_LOGW("bundle %{public}s is non-overlay bundle", bundleName.c_str());
426 return ERR_BUNDLEMANAGER_OVERLAY_QUERY_FAILED_NON_OVERLAY_BUNDLE;
427 }
428 auto overlayModulesStateMap = GetModulesStateFromUserInfo(userInfo);
429 const auto &InnerModuleInfos = info.GetInnerModuleInfos();
430 for (const auto &moduleInfo : InnerModuleInfos) {
431 if (!moduleInfo.second.targetModuleName.empty()) {
432 OverlayModuleInfo overlayModuleInfo;
433 overlayModuleInfo.bundleName = bundleName;
434 overlayModuleInfo.moduleName = moduleInfo.second.moduleName;
435 overlayModuleInfo.targetModuleName = moduleInfo.second.targetModuleName;
436 overlayModuleInfo.hapPath = info.GetModuleHapPath(moduleInfo.second.moduleName);
437 overlayModuleInfo.priority = moduleInfo.second.targetPriority;
438 if (overlayModulesStateMap.find(moduleInfo.second.moduleName) != overlayModulesStateMap.end()) {
439 overlayModuleInfo.state = overlayModulesStateMap[moduleInfo.second.moduleName];
440 } else {
441 overlayModuleInfo.state = OVERLAY_INVALID;
442 }
443 overlayModuleInfos.emplace_back(overlayModuleInfo);
444 }
445 }
446
447 if (overlayModuleInfos.empty()) {
448 APP_LOGW("no overlay moduleInfo can be queried of bundleName %{public}s", bundleName.c_str());
449 }
450 return ERR_OK;
451 }
452
GetOverlayModuleInfo(const std::string & bundleName,const std::string & moduleName,OverlayModuleInfo & overlayModuleInfo,int32_t userId)453 ErrCode OverlayDataMgr::GetOverlayModuleInfo(const std::string &bundleName, const std::string &moduleName,
454 OverlayModuleInfo &overlayModuleInfo, int32_t userId)
455 {
456 APP_LOGD("start to get specific overlay moduleInfo");
457 if (GetBundleDataMgr() != ERR_OK) {
458 return ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_INTERNAL_ERROR;
459 }
460 InnerBundleInfo info;
461 if (!dataMgr_->QueryOverlayInnerBundleInfo(bundleName, info)) {
462 APP_LOGW("overlay bundle is not existed %{public}s", bundleName.c_str());
463 return ERR_BUNDLEMANAGER_OVERLAY_QUERY_FAILED_MISSING_OVERLAY_BUNDLE;
464 }
465 InnerBundleUserInfo userInfo;
466 if (!info.GetInnerBundleUserInfo(userId, userInfo)) {
467 APP_LOGW("the bundle %{public}s is not installed at user %{public}d", bundleName.c_str(), userId);
468 return ERR_BUNDLEMANAGER_OVERLAY_QUERY_FAILED_BUNDLE_NOT_INSTALLED_AT_SPECIFIED_USERID;
469 }
470
471 if (info.GetOverlayType() == NON_OVERLAY_TYPE) {
472 APP_LOGW("bundle %{public}s is non-overlay bundle", bundleName.c_str());
473 return ERR_BUNDLEMANAGER_OVERLAY_QUERY_FAILED_NON_OVERLAY_BUNDLE;
474 }
475
476 if (!info.FindModule(moduleName)) {
477 APP_LOGW("overlay bundle %{public}s does not contain module %{public}s", bundleName.c_str(),
478 moduleName.c_str());
479 return ERR_BUNDLEMANAGER_OVERLAY_QUERY_FAILED_MISSING_OVERLAY_MODULE;
480 }
481
482 if (!info.isOverlayModule(moduleName)) {
483 APP_LOGW("module %{public}s is non-overlay module", moduleName.c_str());
484 return ERR_BUNDLEMANAGER_OVERLAY_QUERY_FAILED_NON_OVERLAY_MODULE;
485 }
486
487 auto innerModuleInfo = info.GetInnerModuleInfoByModuleName(moduleName);
488 if (innerModuleInfo == std::nullopt) {
489 return ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_INTERNAL_ERROR;
490 }
491
492 const auto &moduleInfo = innerModuleInfo.value();
493 overlayModuleInfo.bundleName = bundleName;
494 overlayModuleInfo.moduleName = moduleName;
495 overlayModuleInfo.targetModuleName = moduleInfo.targetModuleName;
496 overlayModuleInfo.hapPath = info.GetModuleHapPath(moduleInfo.moduleName);
497 overlayModuleInfo.priority = moduleInfo.targetPriority;
498 if (!info.GetOverlayModuleState(moduleName, userId, overlayModuleInfo.state)) {
499 APP_LOGW("GetOverlayModuleState failed of bundleName %{public}s and moduleName %{public}s",
500 bundleName.c_str(), moduleName.c_str());
501 }
502 return ERR_OK;
503 }
504
GetOverlayBundleInfoForTarget(const std::string & targetBundleName,std::vector<OverlayBundleInfo> & overlayBundleInfo,int32_t userId)505 ErrCode OverlayDataMgr::GetOverlayBundleInfoForTarget(const std::string &targetBundleName,
506 std::vector<OverlayBundleInfo> &overlayBundleInfo, int32_t userId)
507 {
508 APP_LOGD("start to get target overlay bundle info");
509 if (GetBundleDataMgr() != ERR_OK) {
510 return ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_INTERNAL_ERROR;
511 }
512 InnerBundleInfo targetInnerBundleInfo;
513 if (!dataMgr_->QueryOverlayInnerBundleInfo(targetBundleName, targetInnerBundleInfo)) {
514 APP_LOGW("target bundle is not existed %{public}s", targetBundleName.c_str());
515 return ERR_BUNDLEMANAGER_OVERLAY_QUERY_FAILED_TARGET_BUNDLE_NOT_EXISTED;
516 }
517 InnerBundleUserInfo userInfo;
518 if (!targetInnerBundleInfo.GetInnerBundleUserInfo(userId, userInfo)) {
519 APP_LOGW("the bundle %{public}s is not installed at user %{public}d", targetBundleName.c_str(), userId);
520 return ERR_BUNDLEMANAGER_OVERLAY_QUERY_FAILED_BUNDLE_NOT_INSTALLED_AT_SPECIFIED_USERID;
521 }
522
523 overlayBundleInfo = targetInnerBundleInfo.GetOverlayBundleInfo();
524 if (overlayBundleInfo.empty()) {
525 APP_LOGW("no overlay bundle info in data mgr");
526 }
527 return ERR_OK;
528 }
529
GetOverlayModuleInfoForTarget(const std::string & targetBundleName,const std::string & targetModuleName,std::vector<OverlayModuleInfo> & overlayModuleInfo,int32_t userId)530 ErrCode OverlayDataMgr::GetOverlayModuleInfoForTarget(const std::string &targetBundleName,
531 const std::string &targetModuleName, std::vector<OverlayModuleInfo> &overlayModuleInfo, int32_t userId)
532 {
533 APP_LOGD("start to get target overlay module infos");
534 if (GetBundleDataMgr() != ERR_OK) {
535 return ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_INTERNAL_ERROR;
536 }
537 InnerBundleInfo targetInnerBundleInfo;
538 if (!dataMgr_->QueryOverlayInnerBundleInfo(targetBundleName, targetInnerBundleInfo)) {
539 APP_LOGW("target bundle is not existed %{public}s", targetBundleName.c_str());
540 return ERR_BUNDLEMANAGER_OVERLAY_QUERY_FAILED_TARGET_BUNDLE_NOT_EXISTED;
541 }
542
543 if (targetInnerBundleInfo.GetOverlayType() == OVERLAY_EXTERNAL_BUNDLE) {
544 APP_LOGW("the bundle %{public}s is external overlay bundle", targetBundleName.c_str());
545 return ERR_BUNDLEMANAGER_OVERLAY_QUERY_FAILED_TARGET_BUNDLE_IS_OVERLAY_BUNDLE;
546 }
547 InnerBundleUserInfo userInfo;
548 if (!targetInnerBundleInfo.GetInnerBundleUserInfo(userId, userInfo)) {
549 APP_LOGW("the bundle %{public}s is not installed at user %{public}d", targetBundleName.c_str(), userId);
550 return ERR_BUNDLEMANAGER_OVERLAY_QUERY_FAILED_BUNDLE_NOT_INSTALLED_AT_SPECIFIED_USERID;
551 }
552 if (targetModuleName.empty()) {
553 APP_LOGD("to get all target overlay module infos in target bundle");
554 return GetOverlayModuleInfoForTarget(targetInnerBundleInfo, overlayModuleInfo, userId);
555 }
556
557 if (!targetInnerBundleInfo.FindModule(targetModuleName)) {
558 APP_LOGW("the target module %{public}s is not existed in bundle %{public}s", targetModuleName.c_str(),
559 targetBundleName.c_str());
560 return ERR_BUNDLEMANAGER_OVERLAY_QUERY_FAILED_TARGET_MODULE_NOT_EXISTED;
561 }
562 if (targetInnerBundleInfo.isOverlayModule(targetModuleName)) {
563 APP_LOGW("the target module %{public}s is overlay module", targetModuleName.c_str());
564 return ERR_BUNDLEMANAGER_OVERLAY_QUERY_FAILED_TARGET_MODULE_IS_OVERLAY_MODULE;
565 }
566 auto targetModuleInfo = targetInnerBundleInfo.GetInnerModuleInfoByModuleName(targetModuleName);
567 if (targetModuleInfo == std::nullopt) {
568 return ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_INTERNAL_ERROR;
569 }
570 const auto &moduleInfo = targetModuleInfo.value();
571 overlayModuleInfo = moduleInfo.overlayModuleInfo;
572 if (overlayModuleInfo.empty()) {
573 APP_LOGW("no overlay module info in target module %{public}s", targetModuleName.c_str());
574 return ERR_OK;
575 }
576
577 for (auto &overlayInfo : overlayModuleInfo) {
578 auto res = ObtainOverlayModuleState(overlayInfo, userId);
579 if (res != ERR_OK) {
580 APP_LOGW("failed to obtain the state of overlay module %{public}s", overlayInfo.moduleName.c_str());
581 return res;
582 }
583 }
584 return ERR_OK;
585 }
586
GetOverlayModuleInfoForTarget(const InnerBundleInfo & innerBundleInfo,std::vector<OverlayModuleInfo> & overlayModuleInfo,int32_t userId)587 ErrCode OverlayDataMgr::GetOverlayModuleInfoForTarget(const InnerBundleInfo &innerBundleInfo,
588 std::vector<OverlayModuleInfo> &overlayModuleInfo, int32_t userId)
589 {
590 APP_LOGD("start to get all target overlay module infos");
591 const auto &InnerModuleInfos = innerBundleInfo.GetInnerModuleInfos();
592 for (const auto &moduleInfo : InnerModuleInfos) {
593 if (!moduleInfo.second.overlayModuleInfo.empty()) {
594 for (const auto &overlayInfo : moduleInfo.second.overlayModuleInfo) {
595 OverlayModuleInfo innerOverlayModuleInfo = overlayInfo;
596 ObtainOverlayModuleState(innerOverlayModuleInfo, userId);
597 overlayModuleInfo.emplace_back(innerOverlayModuleInfo);
598 }
599 }
600 }
601
602 if (overlayModuleInfo.empty()) {
603 APP_LOGW("no overlay moduleInfo can be queried of bundleName %{public}s",
604 innerBundleInfo.GetBundleName().c_str());
605 }
606 return ERR_OK;
607 }
608
GetModulesStateFromUserInfo(const InnerBundleUserInfo & userInfo) const609 std::map<std::string, int32_t> OverlayDataMgr::GetModulesStateFromUserInfo(
610 const InnerBundleUserInfo &userInfo) const
611 {
612 std::map<std::string, int32_t> statesMap;
613 const auto &overlayStates = userInfo.bundleUserInfo.overlayModulesState;
614 if (overlayStates.empty()) {
615 APP_LOGW("no overlay states info in innerUserInfo");
616 return statesMap;
617 }
618
619 for_each(overlayStates.begin(), overlayStates.end(), [&statesMap](const auto &item) {
620 size_t pos = item.find(Constants::FILE_UNDERLINE);
621 if (pos != std::string::npos) {
622 std::string moduleName = item.substr(0, pos);
623 int32_t state = OVERLAY_INVALID;
624 OHOS::StrToInt(item.substr(pos + 1), state);
625 APP_LOGD("overlay module %{public}s is under state %{public}d", moduleName.c_str(), state);
626 if (statesMap.find(moduleName) == statesMap.end()) {
627 statesMap.emplace(moduleName, state);
628 } else {
629 statesMap[moduleName] = state;
630 }
631 }
632 });
633 return statesMap;
634 }
635
ObtainOverlayModuleState(OverlayModuleInfo & overlayModuleInfo,int32_t userId)636 ErrCode OverlayDataMgr::ObtainOverlayModuleState(OverlayModuleInfo &overlayModuleInfo, int32_t userId)
637 {
638 if (GetBundleDataMgr() != ERR_OK) {
639 return ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_INTERNAL_ERROR;
640 }
641 InnerBundleInfo innerBundleInfo;
642 if (!dataMgr_->QueryOverlayInnerBundleInfo(overlayModuleInfo.bundleName, innerBundleInfo)) {
643 APP_LOGE("target bundle is not existed %{public}s", overlayModuleInfo.bundleName.c_str());
644 return ERR_BUNDLEMANAGER_OVERLAY_QUERY_FAILED_MISSING_OVERLAY_BUNDLE;
645 }
646
647 if (!innerBundleInfo.GetOverlayModuleState(overlayModuleInfo.moduleName, userId, overlayModuleInfo.state)) {
648 APP_LOGE("GetOverlayModuleState of bundleName %{public}s failed", overlayModuleInfo.bundleName.c_str());
649 return ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_INTERNAL_ERROR;
650 }
651
652 return ERR_OK;
653 }
654
SetOverlayEnabled(const std::string & bundleName,const std::string & moduleName,bool isEnabled,int32_t userId)655 ErrCode OverlayDataMgr::SetOverlayEnabled(const std::string &bundleName, const std::string &moduleName, bool isEnabled,
656 int32_t userId)
657 {
658 if (GetBundleDataMgr() != ERR_OK) {
659 return ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_INTERNAL_ERROR;
660 }
661 InnerBundleInfo innerBundleInfo;
662 if (!dataMgr_->QueryOverlayInnerBundleInfo(bundleName, innerBundleInfo)) {
663 APP_LOGE("bundle is not existed %{public}s", bundleName.c_str());
664 return ERR_BUNDLEMANAGER_OVERLAY_QUERY_FAILED_MISSING_OVERLAY_BUNDLE;
665 }
666 // 1. whether the specified bundle is installed under the specified userid
667 InnerBundleUserInfo userInfo;
668 if (!innerBundleInfo.GetInnerBundleUserInfo(userId, userInfo)) {
669 APP_LOGE("no userInfo of bundleName %{public}s under userId %{public}d",
670 innerBundleInfo.GetBundleName().c_str(), userId);
671 return ERR_BUNDLEMANAGER_OVERLAY_QUERY_FAILED_BUNDLE_NOT_INSTALLED_AT_SPECIFIED_USERID;
672 }
673 // 2. whether bundle is overlay bundle
674 if ((GetCallingBundleName() != bundleName) && innerBundleInfo.GetOverlayType() == NON_OVERLAY_TYPE) {
675 APP_LOGE("current bundle %{public}s is non-overlay bundle", bundleName.c_str());
676 return ERR_BUNDLEMANAGER_OVERLAY_QUERY_FAILED_NON_OVERLAY_BUNDLE;
677 }
678
679 if (!innerBundleInfo.FindModule(moduleName)) {
680 APP_LOGE("overlay bundle %{public}s does not contain module %{public}s", bundleName.c_str(),
681 moduleName.c_str());
682 return ERR_BUNDLEMANAGER_OVERLAY_QUERY_FAILED_MISSING_OVERLAY_MODULE;
683 }
684
685 // 3. whether module is overlay module
686 if (!innerBundleInfo.isOverlayModule(moduleName)) {
687 APP_LOGE("module %{public}s is non-overlay module", moduleName.c_str());
688 return ERR_BUNDLEMANAGER_OVERLAY_QUERY_FAILED_NON_OVERLAY_MODULE;
689 }
690
691 // 4. set enable state
692 auto &statesVec = userInfo.bundleUserInfo.overlayModulesState;
693 for (auto &item : statesVec) {
694 if (item.find(moduleName + Constants::FILE_UNDERLINE) == std::string::npos) {
695 continue;
696 }
697 item = isEnabled ? (moduleName + Constants::FILE_UNDERLINE + std::to_string(OVERLAY_ENABLE)) :
698 (moduleName + Constants::FILE_UNDERLINE + std::to_string(OVERLAY_DISABLED));
699 break;
700 }
701
702 // 5. save to date storage
703 innerBundleInfo.AddInnerBundleUserInfo(userInfo);
704 dataMgr_->SaveOverlayInfo(bundleName, innerBundleInfo);
705
706 // 6. publish the common event "usual.event.OVERLAY_STATE_CHANGED"
707 std::shared_ptr<BundleCommonEventMgr> commonEventMgr = std::make_shared<BundleCommonEventMgr>();
708 commonEventMgr->NotifyOverlayModuleStateStatus(bundleName, moduleName, isEnabled, userId, userInfo.uid);
709 return ERR_OK;
710 }
711
GetCallingBundleName()712 std::string OverlayDataMgr::GetCallingBundleName()
713 {
714 std::string callingBundleName;
715 if (GetBundleDataMgr() != ERR_OK) {
716 return callingBundleName;
717 }
718 bool ret = dataMgr_->GetBundleNameForUid(IPCSkeleton::GetCallingUid(), callingBundleName);
719 if (!ret || callingBundleName.empty()) {
720 APP_LOGE("calling GetBundleNameForUid failed by calling uid %{public}d", IPCSkeleton::GetCallingUid());
721 }
722 return callingBundleName;
723 }
724
AddOverlayModuleStates(const InnerBundleInfo & innerBundleInfo,InnerBundleUserInfo & userInfo)725 void OverlayDataMgr::AddOverlayModuleStates(const InnerBundleInfo &innerBundleInfo, InnerBundleUserInfo &userInfo)
726 {
727 APP_LOGD("start to add overlay module state info at new userId %{public}d", userInfo.bundleUserInfo.userId);
728 if (GetBundleDataMgr() != ERR_OK) {
729 APP_LOGE("get dataMgr failed");
730 return;
731 }
732
733 auto userSet = dataMgr_->GetAllUser();
734 std::vector<std::string> overlayModuleStatesVec;
735 for (const auto &userId : userSet) {
736 if (userId == userInfo.bundleUserInfo.userId) {
737 continue;
738 }
739 InnerBundleUserInfo innerUserInfo;
740 if (!innerBundleInfo.GetInnerBundleUserInfo(userId, innerUserInfo)) {
741 APP_LOGW("no userInfo of bundleName %{public}s under userId %{public}d",
742 innerBundleInfo.GetBundleName().c_str(), userId);
743 continue;
744 }
745 overlayModuleStatesVec = innerUserInfo.bundleUserInfo.overlayModulesState;
746 if (overlayModuleStatesVec.empty()) {
747 continue;
748 }
749 break;
750 }
751 for (auto &item : overlayModuleStatesVec) {
752 size_t pos = item.find(Constants::FILE_UNDERLINE);
753 if (pos == std::string::npos) {
754 continue;
755 }
756 std::string moduleName = item.substr(0, pos);
757 auto innerModuleInfo = innerBundleInfo.GetInnerModuleInfoByModuleName(moduleName);
758 if (innerModuleInfo == std::nullopt) {
759 APP_LOGW("no innerModuleInfo in dataMgr");
760 continue;
761 }
762 const auto &moduleInfo = innerModuleInfo.value();
763 if (innerBundleInfo.GetOverlayType() == OVERLAY_INTERNAL_BUNDLE) {
764 bool isTargetModuleExisted = innerBundleInfo.FindModule(moduleInfo.targetModuleName);
765 item = isTargetModuleExisted ? (moduleName + Constants::FILE_UNDERLINE + std::to_string(OVERLAY_ENABLE)) :
766 (moduleName + Constants::FILE_UNDERLINE + std::to_string(OVERLAY_INVALID));
767 }
768 if (innerBundleInfo.GetOverlayType() == OVERLAY_EXTERNAL_BUNDLE) {
769 std::string targetBundleName = innerBundleInfo.GetTargetBundleName();
770 InnerBundleInfo targetInnerBundleInfo;
771 if (!dataMgr_->QueryOverlayInnerBundleInfo(targetBundleName, targetInnerBundleInfo)) {
772 APP_LOGD("target bundle %{public}s is not installed", targetBundleName.c_str());
773 item = moduleName + Constants::FILE_UNDERLINE + std::to_string(OVERLAY_INVALID);
774 continue;
775 }
776 bool isTargetModuleExisted = targetInnerBundleInfo.FindModule(moduleInfo.targetModuleName);
777 item = isTargetModuleExisted ? (moduleName + Constants::FILE_UNDERLINE + std::to_string(OVERLAY_ENABLE)) :
778 (moduleName + Constants::FILE_UNDERLINE + std::to_string(OVERLAY_INVALID));
779 }
780 }
781 userInfo.bundleUserInfo.overlayModulesState = overlayModuleStatesVec;
782 }
783 } // AppExecFwk
784 } // OHOS