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