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