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