• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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