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 "module_ipc/svc_restore_deps_manager.h"
17
18 #include "b_jsonutil/b_jsonutil.h"
19 #include "filemgmt_libhilog.h"
20
21 namespace OHOS::FileManagement::Backup {
22 using namespace std;
23
GetRestoreBundleNames(const vector<BJsonEntityCaps::BundleInfo> & bundleInfos,RestoreTypeEnum restoreType)24 vector<string> SvcRestoreDepsManager::GetRestoreBundleNames(const vector<BJsonEntityCaps::BundleInfo> &bundleInfos,
25 RestoreTypeEnum restoreType)
26 {
27 unique_lock<shared_mutex> lock(lock_);
28 vector<string> restoreBundleNames {}; // 需要恢复的应用列表
29 BuildDepsMap(bundleInfos); // 构建依赖Map
30
31 for (auto &bundleInfo : bundleInfos) {
32 std::string bundleNameIndexInfo = BJsonUtil::BuildBundleNameIndexInfo(bundleInfo.name, bundleInfo.appIndex);
33 restoreBundleNames.emplace_back(bundleNameIndexInfo);
34 string restoreDeps = bundleInfo.restoreDeps;
35 if (!restoreDeps.empty()) {
36 HILOGI("RestoreDeps is not empty, bundleName=%{public}s", bundleInfo.name.c_str());
37 if (IsAllDepsRestored(bundleNameIndexInfo)) {
38 HILOGI("RestoreDeps is all restored, bundleName=%{public}s", bundleInfo.name.c_str());
39 }
40 }
41 }
42 return restoreBundleNames;
43 }
44
GetRestoreBundleMap()45 map<string, SvcRestoreDepsManager::RestoreInfo> SvcRestoreDepsManager::GetRestoreBundleMap()
46 {
47 unique_lock<shared_mutex> lock(lock_);
48 map<string, RestoreInfo> restoreBundleMap {}; // 需要恢复的应用列表
49 for (auto it = toRestoreBundleMap_.begin(); it != toRestoreBundleMap_.end();) { // 所有有依赖的应用
50 // 如果该应用的依赖项已经完成备份,也需要加到 restoreBundleNames
51 string bundleName = it->first;
52 if (IsAllDepsRestored(bundleName)) {
53 RestoreInfo restoreInfo = it->second;
54 restoreBundleMap.insert(make_pair(bundleName, restoreInfo));
55 toRestoreBundleMap_.erase(it++);
56 } else {
57 it++;
58 }
59 }
60 return restoreBundleMap;
61 }
62
IsAllDepsRestored(const string & bundle)63 bool SvcRestoreDepsManager::IsAllDepsRestored(const string &bundle)
64 {
65 if (depsMap_.find(bundle) == depsMap_.end()) {
66 return false;
67 }
68 bool isAllDepsRestored = true;
69 vector<string> depList = depsMap_[bundle];
70 for (auto &dep : depList) {
71 if (find(restoredBundles_.begin(), restoredBundles_.end(), dep) == restoredBundles_.end()) {
72 isAllDepsRestored = false;
73 break;
74 }
75 }
76 return isAllDepsRestored;
77 }
78
BuildDepsMap(const vector<BJsonEntityCaps::BundleInfo> & bundleInfos)79 void SvcRestoreDepsManager::BuildDepsMap(const vector<BJsonEntityCaps::BundleInfo> &bundleInfos)
80 {
81 for (auto &bundleInfo : bundleInfos) {
82 std::string bundleNameIndexInfo = BJsonUtil::BuildBundleNameIndexInfo(bundleInfo.name, bundleInfo.appIndex);
83 if (depsMap_.find(bundleNameIndexInfo) != depsMap_.end()) {
84 continue;
85 }
86 allBundles_.emplace_back(bundleInfo);
87
88 vector<string> depsList {};
89 string restoreDeps = bundleInfo.restoreDeps;
90 if (restoreDeps.find(",") != string::npos) {
91 depsList = SplitString(restoreDeps, ",");
92 } else {
93 if (!restoreDeps.empty()) {
94 depsList.emplace_back(restoreDeps);
95 }
96 }
97
98 depsMap_.insert(make_pair(bundleNameIndexInfo, depsList));
99 }
100 }
101
SplitString(const string & srcStr,const string & separator)102 vector<string> SvcRestoreDepsManager::SplitString(const string &srcStr, const string &separator)
103 {
104 HILOGI("srcStr:%{public}s, separator:%{public}s", srcStr.c_str(), separator.c_str());
105 vector<string> dst;
106 if (srcStr.empty() || separator.empty()) {
107 return dst;
108 }
109 size_t start = 0;
110 size_t index = srcStr.find_first_of(separator, 0);
111 while (index != srcStr.npos) {
112 if (start != index) {
113 string tempStr = srcStr.substr(start, index - start);
114 tempStr.erase(0, tempStr.find_first_not_of(" "));
115 tempStr.erase(tempStr.find_last_not_of(" ") + 1);
116 tempStr.erase(tempStr.find_last_not_of("\r") + 1);
117 dst.push_back(tempStr);
118 }
119 start = index + 1;
120 index = srcStr.find_first_of(separator, start);
121 }
122
123 if (!srcStr.substr(start).empty()) {
124 string tempStr = srcStr.substr(start);
125 tempStr.erase(0, tempStr.find_first_not_of(" "));
126 tempStr.erase(tempStr.find_last_not_of(" ") + 1);
127 tempStr.erase(tempStr.find_last_not_of("\r") + 1);
128 dst.push_back(tempStr);
129 }
130 return dst;
131 }
132
AddRestoredBundles(const string & bundleName)133 void SvcRestoreDepsManager::AddRestoredBundles(const string &bundleName)
134 {
135 unique_lock<shared_mutex> lock(lock_);
136 restoredBundles_.insert(bundleName);
137 }
138
GetAllBundles() const139 vector<BJsonEntityCaps::BundleInfo> SvcRestoreDepsManager::GetAllBundles() const
140 {
141 return allBundles_;
142 }
143
IsAllBundlesRestored() const144 bool SvcRestoreDepsManager::IsAllBundlesRestored() const
145 {
146 return toRestoreBundleMap_.empty();
147 }
148
UpdateToRestoreBundleMap(const string & bundleName,const string & fileName)149 bool SvcRestoreDepsManager::UpdateToRestoreBundleMap(const string &bundleName, const string &fileName)
150 {
151 unique_lock<shared_mutex> lock(lock_);
152 auto it = toRestoreBundleMap_.find(bundleName);
153 if (it != toRestoreBundleMap_.end()) {
154 it->second.fileNames_.insert(fileName);
155 return true;
156 }
157 return false;
158 }
159
160 } // namespace OHOS::FileManagement::Backup