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