1 /*
2 * Copyright (c) 2023-2025 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_external/bms_adapter.h"
17 #include "module_external/sms_adapter.h"
18
19 #include <fstream>
20 #include <iostream>
21 #include <refbase.h>
22
23 #include "b_error/b_error.h"
24 #include "b_file_info.h"
25 #include "b_jsonutil/b_jsonutil.h"
26 #include "b_json/b_json_entity_extension_config.h"
27 #include "b_resources/b_constants.h"
28 #include "b_sa/b_sa_utils.h"
29 #include "bundle_mgr_client.h"
30 #include "filemgmt_libhilog.h"
31 #include "install_param.h"
32 #include "iservice_registry.h"
33 #include "module_external/sms_adapter.h"
34 #include "module_ipc/service.h"
35 #include "module_ipc/svc_session_manager.h"
36 #include "module_sched/sched_scheduler.h"
37 #include "parameters.h"
38 #include "status_receiver_host.h"
39 #include "system_ability_definition.h"
40 #include "if_system_ability_manager.h"
41
42 namespace OHOS::FileManagement::Backup {
43 using namespace std;
44
45 namespace {
46 enum { APP = 0, LOCAL, DISTRIBUTED, DATABASE, CACHE };
47 const string HAP_CODE_PATH = "1";
48 const string LINUX_HAP_CODE_PATH = "2";
49 const string MEDIA_LIBRARY_HAP = "com.ohos.medialibrary.medialibrarydata";
50 const string EXTERNAL_FILE_HAP = "com.ohos.UserFile.ExternalFileManager";
51 const string APP_GALLERY_BUNDLE_NAME = "const.appgallery.shaderowner.bundlename";
52 const int E_ERR = -1;
53 const vector<string> dataDir = {"app", "local", "distributed", "database", "cache"};
54 } // namespace
55
GetBundleManager()56 static sptr<AppExecFwk::IBundleMgr> GetBundleManager()
57 {
58 auto saMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
59 if (saMgr == nullptr) {
60 throw BError(BError::Codes::SA_BROKEN_IPC, "Failed to get system ability manager");
61 }
62
63 auto bundleObj = saMgr->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
64 if (bundleObj == nullptr) {
65 throw BError(BError::Codes::SA_BROKEN_IPC, "Failed to get bundle manager service");
66 }
67
68 return iface_cast<AppExecFwk::IBundleMgr>(bundleObj);
69 }
70
GetAllowAndExtName(const vector<AppExecFwk::ExtensionAbilityInfo> & extensionInfos)71 static tuple<bool, bool, string, string, string, Json::Value, bool> GetAllowAndExtName(
72 const vector<AppExecFwk::ExtensionAbilityInfo> &extensionInfos)
73 {
74 for (auto &&ext : extensionInfos) {
75 if (ext.type != AppExecFwk::ExtensionAbilityType::BACKUP) {
76 continue;
77 }
78 vector<string> out;
79 AppExecFwk::BundleMgrClient client;
80 if (!client.GetResConfigFile(ext, "ohos.extension.backup", out) || out.size() == 0) {
81 HILOGE("Failed to get resconfigfile of bundle, bundle name is:%{public}s", ext.bundleName.c_str());
82 continue;
83 }
84 BJsonCachedEntity<BJsonEntityExtensionConfig> cachedEntity(out[0], ext.bundleName);
85 auto cache = cachedEntity.Structuralize();
86 return {cache.GetAllowToBackupRestore(), cache.GetFullBackupOnly(), ext.name, cache.GetRestoreDeps(),
87 cache.GetSupportScene(), cache.GetExtraInfo(), cache.GetRequireCompatibility()};
88 }
89 return {false, false, "", "", "", Json::Value(), false};
90 }
91
GetBundleStats(const string & bundleName,int32_t userId)92 static int64_t GetBundleStats(const string &bundleName, int32_t userId)
93 {
94 HILOGI("Begin bundleName:%{public}s", bundleName.c_str());
95 if (bundleName == MEDIA_LIBRARY_HAP || bundleName == EXTERNAL_FILE_HAP) {
96 return StorageMgrAdapter::GetUserStorageStats(bundleName, userId);
97 }
98 auto bms = GetBundleManager();
99 vector<int64_t> bundleStats;
100 BJsonUtil::BundleDetailInfo bundleDetailInfo = BJsonUtil::ParseBundleNameIndexStr(bundleName);
101 bool res = bms->GetBundleStats(bundleDetailInfo.bundleName, userId, bundleStats, bundleDetailInfo.bundleIndex,
102 AppExecFwk::Constants::NoGetBundleStatsFlag::GET_BUNDLE_WITHOUT_CACHE_SIZE);
103 if (!res || bundleStats.size() != dataDir.size()) {
104 HILOGE("An error occurred in querying bundle stats. name:%{public}s", bundleName.c_str());
105 return 0;
106 }
107 for (uint i = 0; i < bundleStats.size(); i++) {
108 if (bundleStats[i] == E_ERR) {
109 HILOGE("Failed to query %{public}s data. name:%{public}s", dataDir[i].c_str(), bundleName.c_str());
110 bundleStats[i] = 0;
111 }
112 }
113 int64_t dataSize = bundleStats[LOCAL] + bundleStats[DISTRIBUTED] + bundleStats[DATABASE];
114 return dataSize;
115 }
116
GetBundleInfos(const vector<string> & bundleNames,int32_t userId)117 vector<BJsonEntityCaps::BundleInfo> BundleMgrAdapter::GetBundleInfos(const vector<string> &bundleNames, int32_t userId)
118 {
119 vector<BJsonEntityCaps::BundleInfo> bundleInfos;
120 auto bms = GetBundleManager();
121 HILOGI("Start, bundleNames size:%{public}zu", bundleNames.size());
122 for (const auto &bundleName : bundleNames) {
123 HILOGI("Begin Get bundleName:%{public}s", bundleName.c_str());
124 if (bundleName.empty()) {
125 HILOGE("BundleName is invalid");
126 continue;
127 }
128 if (SAUtils::IsSABundleName(bundleName)) {
129 GetBundleInfoForSA(bundleName, bundleInfos);
130 continue;
131 }
132 BundleExtInfo bundleExtInfo(bundleName);
133 bool getBundleSuccess = GetCurBundleExtenionInfo(bundleExtInfo, bms, userId);
134 if (!getBundleSuccess) {
135 HILOGE("Get current extension failed, bundleName:%{public}s", bundleName.c_str());
136 continue;
137 }
138 auto [allToBackup, fullBackupOnly, extName, restoreDeps, supportScene, extraInfo, requireCompatibility] =
139 GetAllowAndExtName(bundleExtInfo.extensionInfos_);
140 int64_t dataSize = 0;
141 if (allToBackup) {
142 dataSize = GetBundleStats(bundleName, userId);
143 }
144 bundleInfos.emplace_back(BJsonEntityCaps::BundleInfo {bundleExtInfo.bundleInfo_.name,
145 bundleExtInfo.bundleInfo_.appIndex, bundleExtInfo.bundleInfo_.versionCode,
146 bundleExtInfo.bundleInfo_.versionName, dataSize, 0, allToBackup, fullBackupOnly, requireCompatibility,
147 extName, restoreDeps, supportScene, extraInfo});
148 }
149 HILOGI("End, bundleInfos size:%{public}zu", bundleInfos.size());
150 return bundleInfos;
151 }
152
GetAppGalleryBundleName()153 string BundleMgrAdapter::GetAppGalleryBundleName()
154 {
155 string bundleName = OHOS::system::GetParameter(APP_GALLERY_BUNDLE_NAME, "");
156 if (bundleName.empty()) {
157 HILOGI("Get App Gallery BundleName fail!");
158 } else {
159 HILOGI("App Gallery BundleName: %{public}s", bundleName.c_str());
160 }
161 return bundleName;
162 }
163
GetBackupExtConfig(const vector<AppExecFwk::ExtensionAbilityInfo> & extensionInfos,BJsonEntityCaps::BundleBackupConfigPara & backupPara)164 static bool GetBackupExtConfig(const vector<AppExecFwk::ExtensionAbilityInfo> &extensionInfos,
165 BJsonEntityCaps::BundleBackupConfigPara &backupPara)
166 {
167 for (auto &&ext : extensionInfos) {
168 if (ext.type != AppExecFwk::ExtensionAbilityType::BACKUP) {
169 continue;
170 }
171 vector<string> out;
172 AppExecFwk::BundleMgrClient client;
173 if (!client.GetResConfigFile(ext, "ohos.extension.backup", out) || out.size() == 0) {
174 HILOGE("Failed to get resconfigfile of bundle, bundle name is:%{public}s", ext.bundleName.c_str());
175 continue;
176 }
177 BJsonCachedEntity<BJsonEntityExtensionConfig> cachedEntity(out[0], ext.bundleName);
178 auto cache = cachedEntity.Structuralize();
179 backupPara.allToBackup = cache.GetAllowToBackupRestore();
180 backupPara.fullBackupOnly = cache.GetFullBackupOnly();
181 backupPara.extensionName = ext.name;
182 backupPara.restoreDeps = cache.GetRestoreDeps();
183 backupPara.supportScene = cache.GetSupportScene();
184 backupPara.extraInfo = cache.GetExtraInfo();
185 backupPara.includes = cache.GetIncludes();
186 backupPara.excludes = cache.GetExcludes();
187 backupPara.requireCompatibility = cache.GetRequireCompatibility();
188 return true;
189 }
190 return false;
191 }
192
CreateIPCInteractionFiles(int32_t userId,const string & bundleName,int64_t lastIncrementalTime,const vector<string> & includes,const vector<string> & excludes)193 static bool CreateIPCInteractionFiles(int32_t userId, const string &bundleName, int64_t lastIncrementalTime,
194 const vector<string> &includes, const vector<string> &excludes)
195 {
196 // backup_sa bundle path
197 BJsonUtil::BundleDetailInfo bundleDetail = BJsonUtil::ParseBundleNameIndexStr(bundleName);
198 string backupSaBundleDir;
199 if (bundleDetail.bundleIndex > 0) {
200 std::string bundleNameIndex = "+clone-" + std::to_string(bundleDetail.bundleIndex) + "+" +
201 bundleDetail.bundleName;
202 backupSaBundleDir = BConstants::BACKUP_PATH_PREFIX + to_string(userId) + BConstants::BACKUP_PATH_SURFFIX +
203 bundleNameIndex + BConstants::FILE_SEPARATOR_CHAR;
204 } else {
205 backupSaBundleDir = BConstants::BACKUP_PATH_PREFIX + to_string(userId) + BConstants::BACKUP_PATH_SURFFIX +
206 bundleDetail.bundleName + BConstants::FILE_SEPARATOR_CHAR;
207 }
208 if (access(backupSaBundleDir.data(), F_OK) != 0) {
209 int32_t err = mkdir(backupSaBundleDir.data(), S_IRWXU | S_IRWXG);
210 if (err != 0 && errno != EEXIST) {
211 HILOGE("Failed to create folder in backup_sa bundleName:%{public}s, sys err:%{public}d",
212 bundleName.c_str(), errno);
213 return false;
214 }
215 }
216 // backup_sa include/exclude
217 string incExFilePath = backupSaBundleDir + BConstants::BACKUP_INCEXC_SYMBOL + to_string(lastIncrementalTime);
218 ofstream incExcFile;
219 incExcFile.open(incExFilePath.data(), ios::out | ios::trunc);
220 if (!incExcFile.is_open()) {
221 HILOGE("Cannot create incexc file, err = %{public}d", errno);
222 return false;
223 }
224 incExcFile << BConstants::BACKUP_INCLUDE << endl;
225 for (const auto &include : includes) {
226 incExcFile << include << endl;
227 }
228 incExcFile << BConstants::BACKUP_EXCLUDE << endl;
229 for (const auto &exclude : excludes) {
230 incExcFile << exclude << endl;
231 }
232 incExcFile.close();
233
234 // backup_sa stat
235 string statFilePath = backupSaBundleDir + BConstants::BACKUP_STAT_SYMBOL + to_string(lastIncrementalTime);
236 ofstream statFile;
237 statFile.open(statFilePath.data(), ios::out | ios::trunc);
238 if (!statFile.is_open()) {
239 HILOGE("Cannot create stat file");
240 return false;
241 }
242 statFile.close();
243
244 return true;
245 }
246
GenerateBundleStatsIncrease(int32_t userId,const vector<string> & bundleNames,const vector<int64_t> & lastBackTimes,vector<BJsonEntityCaps::BundleInfo> & bundleInfos,vector<BJsonEntityCaps::BundleInfo> & newBundleInfos)247 static bool GenerateBundleStatsIncrease(int32_t userId, const vector<string> &bundleNames,
248 const vector<int64_t> &lastBackTimes, vector<BJsonEntityCaps::BundleInfo> &bundleInfos,
249 vector<BJsonEntityCaps::BundleInfo> &newBundleInfos)
250 {
251 vector<int64_t> pkgFileSizes {};
252 vector<int64_t> incPkgFileSizes {};
253 int32_t err = StorageMgrAdapter::GetBundleStatsForIncrease(userId, bundleNames, lastBackTimes,
254 pkgFileSizes, incPkgFileSizes);
255 if (err != 0) {
256 HILOGE("Failed to get bundleStats result from storage, err = %{public}d", err);
257 return false;
258 }
259 HILOGI("bundleNames size:%{public}zu, pkgFileSizes size:%{public}zu, bundleInfos size:%{public}zu",
260 bundleNames.size(), pkgFileSizes.size(), bundleInfos.size());
261 if (bundleInfos.size() != pkgFileSizes.size()) {
262 HILOGE("The number of bundle is not equal to the number of data records");
263 return false;
264 }
265 for (size_t i = 0; i < bundleInfos.size(); i++) {
266 std::string curBundleName = bundleInfos[i].name;
267 HILOGD("BundleMgrAdapter name for %{public}s", curBundleName.c_str());
268 BJsonEntityCaps::BundleInfo newBundleInfo = {.name = curBundleName,
269 .appIndex = bundleInfos[i].appIndex,
270 .versionCode = bundleInfos[i].versionCode,
271 .versionName = bundleInfos[i].versionName,
272 .spaceOccupied = pkgFileSizes[i],
273 .increSpaceOccupied = incPkgFileSizes[i],
274 .allToBackup = bundleInfos[i].allToBackup,
275 .fullBackupOnly = bundleInfos[i].fullBackupOnly,
276 .extensionName = bundleInfos[i].extensionName,
277 .restoreDeps = bundleInfos[i].restoreDeps,
278 .supportScene = bundleInfos[i].supportScene,
279 .extraInfo = bundleInfos[i].extraInfo};
280 newBundleInfos.emplace_back(newBundleInfo);
281 }
282 return true;
283 }
284
GetBundleInfosForIncremental(const vector<BIncrementalData> & incrementalDataList,int32_t userId)285 vector<BJsonEntityCaps::BundleInfo> BundleMgrAdapter::GetBundleInfosForIncremental(
286 const vector<BIncrementalData> &incrementalDataList, int32_t userId)
287 {
288 vector<std::string> bundleNames;
289 vector<int64_t> incrementalBackTimes;
290 vector<BJsonEntityCaps::BundleInfo> bundleInfos;
291 auto bms = GetBundleManager();
292 for (const auto &bundleNameTime : incrementalDataList) {
293 auto bundleName = bundleNameTime.bundleName;
294 BundleExtInfo bundleExtInfo(bundleName);
295 bool getBundleSuccess = GetCurBundleExtenionInfo(bundleExtInfo, bms, userId);
296 if (!getBundleSuccess) {
297 HILOGE("Failed to get bundle info from bms, bundleName:%{public}s", bundleName.c_str());
298 continue;
299 }
300 struct BJsonEntityCaps::BundleBackupConfigPara backupPara;
301 if (!GetBackupExtConfig(bundleExtInfo.extensionInfos_, backupPara)) {
302 HILOGE("No backup extension ability found, bundleName:%{public}s", bundleName.c_str());
303 continue;
304 }
305 if (!CreateIPCInteractionFiles(userId, bundleName, bundleNameTime.lastIncrementalTime, backupPara.includes,
306 backupPara.excludes)) {
307 HILOGE("Create bundleInteraction dir failed, bundleName:%{public}s", bundleName.c_str());
308 continue;
309 }
310 bundleInfos.emplace_back(BJsonEntityCaps::BundleInfo {bundleExtInfo.bundleInfo_.name,
311 bundleExtInfo.bundleInfo_.appIndex, bundleExtInfo.bundleInfo_.versionCode,
312 bundleExtInfo.bundleInfo_.versionName, 0, 0, backupPara.allToBackup, backupPara.fullBackupOnly,
313 backupPara.requireCompatibility, backupPara.extensionName, backupPara.restoreDeps, backupPara.supportScene,
314 backupPara.extraInfo});
315 if (bundleExtInfo.bundleInfo_.appIndex > 0) {
316 std::string bundleNameIndex = "+clone-" + std::to_string(bundleExtInfo.bundleInfo_.appIndex) + "+" +
317 bundleExtInfo.bundleInfo_.name;
318 bundleNames.emplace_back(bundleNameIndex);
319 } else {
320 bundleNames.emplace_back(bundleName);
321 }
322 incrementalBackTimes.emplace_back(bundleNameTime.lastIncrementalTime);
323 }
324 vector<BJsonEntityCaps::BundleInfo> newBundleInfos {};
325 if (!GenerateBundleStatsIncrease(userId, bundleNames, incrementalBackTimes, bundleInfos, newBundleInfos)) {
326 HILOGE("Failed to get bundleStats result");
327 return {};
328 }
329 HILOGI("BundleMgrAdapter GetBundleInfosForIncremental end ");
330 return newBundleInfos;
331 }
332
GetBundleInfosForIncremental(int32_t userId,const std::vector<BIncrementalData> & extraIncreData)333 vector<BJsonEntityCaps::BundleInfo> BundleMgrAdapter::GetBundleInfosForIncremental(int32_t userId,
334 const std::vector<BIncrementalData> &extraIncreData)
335 {
336 vector<AppExecFwk::BundleInfo> installedBundles;
337 HILOGI("Begin get bundle infos");
338 auto bms = GetBundleManager();
339 if (!bms->GetBundleInfos(AppExecFwk::GET_BUNDLE_WITH_EXTENSION_INFO, installedBundles, userId)) {
340 HILOGE("Failed to get bundle infos from bms");
341 return {};
342 }
343
344 vector<BIncrementalData> bundleNames;
345 vector<BJsonEntityCaps::BundleInfo> bundleInfos;
346 HILOGI("End get installedBundles count is:%{public}zu", installedBundles.size());
347 for (const auto &installedBundle : installedBundles) {
348 if (installedBundle.applicationInfo.codePath == HAP_CODE_PATH ||
349 installedBundle.applicationInfo.codePath == LINUX_HAP_CODE_PATH) {
350 HILOGI("Unsupported applications, name : %{public}s", installedBundle.name.data());
351 continue;
352 }
353 auto [allToBackup, fullBackupOnly, extName, restoreDeps, supportScene, extraInfo, requireCompatibility] =
354 GetAllowAndExtName(installedBundle.extensionInfos);
355 if (!allToBackup) {
356 bundleInfos.emplace_back(BJsonEntityCaps::BundleInfo {installedBundle.name, installedBundle.appIndex,
357 installedBundle.versionCode, installedBundle.versionName, 0, 0, allToBackup, fullBackupOnly,
358 requireCompatibility, extName, restoreDeps, supportScene, extraInfo});
359 continue;
360 }
361 auto it = std::find_if(extraIncreData.begin(), extraIncreData.end(),
362 [installedBundle](const BIncrementalData &info)->bool {
363 return installedBundle.name == info.bundleName;
364 });
365 if (it == extraIncreData.end()) {
366 bundleNames.emplace_back(BIncrementalData {installedBundle.name, 0});
367 } else {
368 bundleNames.emplace_back(*it);
369 }
370 }
371 auto bundleInfosNew = BundleMgrAdapter::GetBundleInfosForIncremental(bundleNames, userId);
372 auto bundleInfosSA = BundleMgrAdapter::GetBundleInfosForSA();
373 copy(bundleInfosNew.begin(), bundleInfosNew.end(), back_inserter(bundleInfos));
374 copy(bundleInfosSA.begin(), bundleInfosSA.end(), back_inserter(bundleInfos));
375 HILOGI("End get bundle infos, bundleInfos size: %{public}zu", bundleInfos.size());
376 return bundleInfos;
377 }
378
GetFullBundleInfos(int32_t userId)379 vector<BJsonEntityCaps::BundleInfo> BundleMgrAdapter::GetFullBundleInfos(int32_t userId)
380 {
381 vector<AppExecFwk::BundleInfo> installedBundles;
382 HILOGI("Begin GetFullBundleInfos");
383 auto bms = GetBundleManager();
384 if (!bms->GetBundleInfos(AppExecFwk::GET_BUNDLE_WITH_EXTENSION_INFO, installedBundles, userId)) {
385 HILOGE("Failed to get bundle infos from bms");
386 return {};
387 }
388 vector<string> bundleNames;
389 vector<BJsonEntityCaps::BundleInfo> bundleInfos;
390 HILOGI("End get installedBundles count is:%{public}zu", installedBundles.size());
391 for (const auto &installedBundle : installedBundles) {
392 if (installedBundle.name.empty()) {
393 HILOGE("Current bundle name is invalid");
394 continue;
395 }
396 if (installedBundle.applicationInfo.codePath == HAP_CODE_PATH ||
397 installedBundle.applicationInfo.codePath == LINUX_HAP_CODE_PATH) {
398 HILOGI("Unsupported applications, name : %{public}s", installedBundle.name.data());
399 continue;
400 }
401 if (installedBundle.appIndex > 0) {
402 HILOGI("Current bundle %{public}s is a twin application", installedBundle.name.c_str());
403 std::string bundleNameIndexInfo = BJsonUtil::BuildBundleNameIndexInfo(installedBundle.name,
404 installedBundle.appIndex);
405 bundleNames.emplace_back(bundleNameIndexInfo);
406 continue;
407 }
408 auto [allToBackup, fullBackupOnly, extName, restoreDeps, supportScene, extraInfo, requireCompatibility] =
409 GetAllowAndExtName(installedBundle.extensionInfos);
410 if (!allToBackup) {
411 HILOGI("Not allToBackup, bundleName = %{public}s", installedBundle.name.data());
412 bundleInfos.emplace_back(BJsonEntityCaps::BundleInfo {installedBundle.name, installedBundle.appIndex,
413 installedBundle.versionCode, installedBundle.versionName, 0, 0, allToBackup, fullBackupOnly,
414 requireCompatibility, extName, restoreDeps, supportScene, extraInfo});
415 continue;
416 }
417 bundleNames.emplace_back(installedBundle.name);
418 }
419 auto bundleInfosNew = BundleMgrAdapter::GetBundleInfos(bundleNames, userId);
420 auto bundleInfosSA = BundleMgrAdapter::GetBundleInfosForSA();
421 copy(bundleInfosNew.begin(), bundleInfosNew.end(), back_inserter(bundleInfos));
422 copy(bundleInfosSA.begin(), bundleInfosSA.end(), back_inserter(bundleInfos));
423 HILOGI("End GetFullBundleInfos, bundleInfos size: %{public}zu", bundleInfos.size());
424 return bundleInfos;
425 }
426
GetExtName(string bundleName,int32_t userId)427 string BundleMgrAdapter::GetExtName(string bundleName, int32_t userId)
428 {
429 vector<AppExecFwk::BundleInfo> installedBundles;
430 auto bms = GetBundleManager();
431 if (!bms->GetBundleInfos(AppExecFwk::GET_BUNDLE_WITH_EXTENSION_INFO, installedBundles, userId)) {
432 throw BError(BError::Codes::SA_BROKEN_IPC, "Failed to get bundle infos");
433 }
434 for (const auto &installedBundle : installedBundles) {
435 if (installedBundle.applicationInfo.codePath == HAP_CODE_PATH ||
436 installedBundle.applicationInfo.codePath == LINUX_HAP_CODE_PATH) {
437 HILOGI("Unsupported applications, name : %{public}s", installedBundle.name.data());
438 continue;
439 }
440 for (const auto &ext : installedBundle.extensionInfos) {
441 if (ext.bundleName != bundleName) {
442 continue;
443 }
444 if (ext.type != AppExecFwk::ExtensionAbilityType::BACKUP) {
445 continue;
446 }
447 HILOGI("bundleName: %{public}s, find extName: %{public}s", bundleName.c_str(), ext.name.c_str());
448 return ext.name;
449 }
450 }
451 HILOGI("bundleName: %{public}s , find extName failed", bundleName.c_str());
452 return "BackupExtensionAbility";
453 }
454
GetBundleInfosForSA()455 std::vector<BJsonEntityCaps::BundleInfo> BundleMgrAdapter::GetBundleInfosForSA()
456 {
457 std::vector<int32_t> saIds;
458 vector<BJsonEntityCaps::BundleInfo> saBundleInfos;
459 sptr<ISystemAbilityManager> samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
460 if (!samgrProxy) {
461 HILOGE("SamgrProxy is nullptr");
462 return saBundleInfos;
463 }
464 int32_t ret = samgrProxy->GetExtensionSaIds(BConstants::EXTENSION_BACKUP, saIds);
465 HILOGI("GetExtensionSaIds ret: %{public}d", ret);
466 for (const auto &saId : saIds) {
467 saBundleInfos.emplace_back(BJsonEntityCaps::BundleInfo {std::to_string(saId), 0, 0, "", 0, 0, true, false,
468 false, "", "", "", ""});
469 }
470 return saBundleInfos;
471 }
472
GetBundleInfoForSA(std::string bundleName,std::vector<BJsonEntityCaps::BundleInfo> & bundleInfos)473 void BundleMgrAdapter::GetBundleInfoForSA(std::string bundleName, std::vector<BJsonEntityCaps::BundleInfo>& bundleInfos)
474 {
475 HILOGI("SA %{public}s GetBundleInfo begin.", bundleName.c_str());
476 std::vector<int32_t> saIds;
477 vector<BJsonEntityCaps::BundleInfo> saBundleInfos;
478 sptr<ISystemAbilityManager> samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
479 if (!samgrProxy) {
480 HILOGE("SamgrProxy is nullptr");
481 return;
482 }
483 int32_t ret = samgrProxy->GetExtensionSaIds(BConstants::EXTENSION_BACKUP, saIds);
484 if (ret != ERR_OK) {
485 HILOGE("GetExtensionSaIds err,ret %{public}d", ret);
486 return;
487 }
488 if (saIds.empty()) {
489 HILOGE("GetExtensionSaIds result is empty");
490 return;
491 }
492 int32_t saId = std::atoi(bundleName.c_str());
493 if (std::find(saIds.begin(), saIds.end(), saId) == saIds.end()) {
494 HILOGE("SA %{public}d is not surport backup.", saId);
495 return;
496 }
497 bundleInfos.emplace_back(BJsonEntityCaps::BundleInfo {bundleName, 0, 0, "", 0, 0, true, false, false,
498 "", "", "", ""});
499 HILOGI("SA %{public}s GetBundleInfo end.", bundleName.c_str());
500 }
501
GetCurBundleExtenionInfo(BundleExtInfo & bundleExtInfo,sptr<AppExecFwk::IBundleMgr> bms,int32_t userId)502 bool BundleMgrAdapter::GetCurBundleExtenionInfo(BundleExtInfo &bundleExtInfo, sptr<AppExecFwk::IBundleMgr> bms,
503 int32_t userId)
504 {
505 BJsonUtil::BundleDetailInfo bundleDetailInfo = BJsonUtil::ParseBundleNameIndexStr(bundleExtInfo.bundleName_);
506 int32_t flags = static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE) |
507 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_EXTENSION_ABILITY) |
508 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_METADATA);
509 int64_t getExtStart = TimeUtils::GetTimeMS();
510 ErrCode ret = bms->GetCloneBundleInfo(bundleDetailInfo.bundleName, flags, bundleDetailInfo.bundleIndex,
511 bundleExtInfo.bundleInfo_, userId);
512 bundleExtInfo.getExtSpend_ = TimeUtils::GetSpendMS(getExtStart);
513 if (ret != ERR_OK) {
514 HILOGE("bundleName:%{public}s, ret:%{public}d, current bundle info for backup/restore is empty",
515 bundleExtInfo.bundleName_.c_str(), ret);
516 bundleExtInfo.error_ = RadarError(MODULE_HAP, BError(BError::Codes::SA_BUNDLE_INFO_EMPTY));
517 return false;
518 }
519 if (bundleExtInfo.bundleInfo_.applicationInfo.codePath == HAP_CODE_PATH ||
520 bundleExtInfo.bundleInfo_.applicationInfo.codePath == LINUX_HAP_CODE_PATH) {
521 HILOGE("Unsupported applications, name : %{public}s", bundleExtInfo.bundleInfo_.name.data());
522 bundleExtInfo.error_ = RadarError(MODULE_HAP, BError(BError::Codes::SA_FORBID_BACKUP_RESTORE));
523 return false;
524 }
525 std::vector<AppExecFwk::HapModuleInfo> hapModuleInfos = bundleExtInfo.bundleInfo_.hapModuleInfos;
526 for (const auto &hapModuleInfo : hapModuleInfos) {
527 bundleExtInfo.extensionInfos_.insert(bundleExtInfo.extensionInfos_.end(), hapModuleInfo.extensionInfos.begin(),
528 hapModuleInfo.extensionInfos.end());
529 }
530 HILOGI("bundleName:%{public}s, extensionInfos size:%{public}zu", bundleExtInfo.bundleName_.c_str(),
531 bundleExtInfo.extensionInfos_.size());
532 return true;
533 }
534
IsUser0BundleName(std::string bundleName,int32_t userId)535 bool BundleMgrAdapter::IsUser0BundleName(std::string bundleName, int32_t userId)
536 {
537 auto bms = GetBundleManager();
538 AppExecFwk::BundleInfo installedBundle;
539 BJsonUtil::BundleDetailInfo bundleDetailInfo = BJsonUtil::ParseBundleNameIndexStr(bundleName);
540 int32_t flags = static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE) |
541 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_EXTENSION_ABILITY) |
542 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_METADATA) |
543 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION);
544 ErrCode ret = bms->GetCloneBundleInfo(bundleDetailInfo.bundleName, flags, bundleDetailInfo.bundleIndex,
545 installedBundle, userId);
546 if (ret != ERR_OK) {
547 HILOGE("bundleName:%{public}s, ret:%{public}d, GetBundle Failed from BMS", bundleName.c_str(), ret);
548 return false;
549 }
550 if (installedBundle.applicationInfo.singleton == true) {
551 HILOGI("bundleName:%{public}s is zero user bundle", bundleName.c_str());
552 return true;
553 }
554 HILOGI("bundleName:%{public}s is not zero user bundle", bundleName.c_str());
555 return false;
556 }
557
GetBundleInfosForAppend(const std::vector<BIncrementalData> & list,int32_t userId)558 vector<BJsonEntityCaps::BundleInfo> BundleMgrAdapter::GetBundleInfosForAppend(const std::vector<BIncrementalData> &list,
559 int32_t userId)
560 {
561 auto bundleInfos = BundleMgrAdapter::GetBundleInfosForIncremental(list, userId);
562 for (const auto &info : list) {
563 if (SAUtils::IsSABundleName(info.bundleName)) {
564 GetBundleInfoForSA(info.bundleName, bundleInfos);
565 }
566 }
567 return bundleInfos;
568 }
569
GetBundleInfosForLocalCapabilities(int32_t userId)570 std::vector<BJsonEntityCaps::BundleInfo> BundleMgrAdapter::GetBundleInfosForLocalCapabilities(int32_t userId)
571 {
572 HILOGI("start GetBundleInfosForLocalCapabilities");
573 vector<AppExecFwk::BundleInfo> installedBundles;
574 auto bms = GetBundleManager();
575 if (!bms->GetBundleInfos(AppExecFwk::GET_BUNDLE_WITH_EXTENSION_INFO, installedBundles, userId)) {
576 HILOGI("Failed to get bundle infos");
577 return {};
578 }
579 vector<string> bundleNames;
580 vector<BJsonEntityCaps::BundleInfo> bundleInfos;
581 HILOGI("End get installedBundles count is:%{public}zu", installedBundles.size());
582 for (auto const &installedBundle : installedBundles) {
583 if (installedBundle.applicationInfo.codePath == HAP_CODE_PATH ||
584 installedBundle.applicationInfo.codePath == LINUX_HAP_CODE_PATH) {
585 HILOGI("Unsupported applications, name : %{public}s", installedBundle.name.data());
586 continue;
587 }
588 if (installedBundle.appIndex > 0) {
589 HILOGI("Current bundle %{public}s is a twin application, index = %{public}d",
590 installedBundle.name.c_str(), installedBundle.appIndex);
591 std::string bundleNameIndexInfo = BJsonUtil::BuildBundleNameIndexInfo(installedBundle.name,
592 installedBundle.appIndex);
593 bundleNames.emplace_back(bundleNameIndexInfo);
594 continue;
595 }
596 auto [allToBackup, fullBackupOnly, extName, restoreDeps, supportScene, extraInfo, requireCompatibility] =
597 GetAllowAndExtName(installedBundle.extensionInfos);
598 if (!allToBackup) {
599 HILOGI("Not allToBackup, bundleName = %{public}s, appIndex = %{public}d",
600 installedBundle.name.c_str(), installedBundle.appIndex);
601 continue;
602 }
603 bundleInfos.emplace_back(BJsonEntityCaps::BundleInfo {
604 installedBundle.name, installedBundle.appIndex,
605 installedBundle.versionCode, installedBundle.versionName,
606 0, 0, allToBackup, fullBackupOnly, requireCompatibility,
607 extName, restoreDeps, supportScene, extraInfo});
608 }
609 auto bundleInfosIndex = GetBundleInfosForIndex(bundleNames, userId);
610 auto bundleInfosSA = BundleMgrAdapter::GetBundleInfosForSA();
611 copy(bundleInfosIndex.begin(), bundleInfosIndex.end(), back_inserter(bundleInfos));
612 copy(bundleInfosSA.begin(), bundleInfosSA.end(), back_inserter(bundleInfos));
613 HILOGI("End GetBundleInfosForLocalCapabilities, allow to backup bundle count is : %{public}zu", bundleInfos.size());
614 return bundleInfos;
615 }
616
GetBundleInfosForIndex(const vector<string> & bundleNames,int32_t userId)617 std::vector<BJsonEntityCaps::BundleInfo> BundleMgrAdapter::GetBundleInfosForIndex(
618 const vector<string> &bundleNames, int32_t userId)
619 {
620 HILOGI("start GetFullBundleInfosForIndex");
621 vector<BJsonEntityCaps::BundleInfo> bundleInfos;
622 auto bms = GetBundleManager();
623 for (auto const &bundleName : bundleNames) {
624 BundleExtInfo bundleExtInfo(bundleName);
625 bool getBundleSuccess = GetCurBundleExtenionInfo(bundleExtInfo, bms, userId);
626 if (!getBundleSuccess) {
627 HILOGE("Get current extension failed, bundleName:%{public}s", bundleName.c_str());
628 continue;
629 }
630 auto [allToBackup, fullBackupOnly, extName, restoreDeps, supportScene, extraInfo, requireCompatibility] =
631 GetAllowAndExtName(bundleExtInfo.extensionInfos_);
632 if (!allToBackup) {
633 HILOGI("Not allToBackup, bundleName = %{public}s, appIndex = %{public}d",
634 bundleExtInfo.bundleInfo_.name.c_str(), bundleExtInfo.bundleInfo_.appIndex);
635 continue;
636 }
637 bundleInfos.emplace_back(BJsonEntityCaps::BundleInfo {
638 bundleExtInfo.bundleInfo_.name, bundleExtInfo.bundleInfo_.appIndex,
639 bundleExtInfo.bundleInfo_.versionCode, bundleExtInfo.bundleInfo_.versionName,
640 0, 0, allToBackup, fullBackupOnly, requireCompatibility,
641 extName, restoreDeps, supportScene, extraInfo});
642 }
643 HILOGI("End, bundleInfos size:%{public}zu", bundleInfos.size());
644 return bundleInfos;
645 }
646
GetBundleDataSize(const std::string & bundleName,int32_t userId)647 int64_t BundleMgrAdapter::GetBundleDataSize(const std::string &bundleName, int32_t userId)
648 {
649 return GetBundleStats(bundleName, userId);
650 }
651
CreatBackupEnv(const std::vector<BIncrementalData> & bundleNameList,int32_t userId)652 void BundleMgrAdapter::CreatBackupEnv(const std::vector<BIncrementalData> &bundleNameList, int32_t userId)
653 {
654 HILOGI("CreatBackupEnv start");
655 auto bms = GetBundleManager();
656 for (auto const &bundleNameTime : bundleNameList) {
657 auto bundleName = bundleNameTime.bundleName;
658 if (SAUtils::IsSABundleName(bundleName)) {
659 HILOGI("SA don't need creat env");
660 continue;
661 }
662 BundleExtInfo bundleExtInfo(bundleName);
663 bool getBundleSuccess = GetCurBundleExtenionInfo(bundleExtInfo, bms, userId);
664 if (!getBundleSuccess) {
665 HILOGE("Failed to get bundle info from bms, bundleName:%{public}s", bundleName.c_str());
666 continue;
667 }
668 struct BJsonEntityCaps::BundleBackupConfigPara backupPara;
669 if (!GetBackupExtConfig(bundleExtInfo.extensionInfos_, backupPara)) {
670 HILOGE("No backup extension ability found, bundleName:%{public}s", bundleName.c_str());
671 continue;
672 }
673 if (!CreateIPCInteractionFiles(userId, bundleName, bundleNameTime.lastIncrementalTime, backupPara.includes,
674 backupPara.excludes)) {
675 HILOGE("Create bundleInteraction dir failed, bundleName:%{public}s", bundleName.c_str());
676 continue;
677 }
678 }
679 HILOGI("CreatBackupEnv end");
680 }
681
GetBundleInfosForAppendBundles(const std::vector<BIncrementalData> & incrementalDataList,int32_t userId)682 std::vector<BJsonEntityCaps::BundleInfo> BundleMgrAdapter::GetBundleInfosForAppendBundles(
683 const std::vector<BIncrementalData> &incrementalDataList, int32_t userId)
684 {
685 vector<BJsonEntityCaps::BundleInfo> bundleInfos;
686 auto bms = GetBundleManager();
687 for (const auto &bundleIncData : incrementalDataList) {
688 auto bundleName = bundleIncData.bundleName;
689 HILOGE("Current bundle name is:%{public}s", bundleName.c_str());
690 BundleExtInfo bundleExtInfo(bundleName);
691 bool getBundleSuccess = GetCurBundleExtenionInfo(bundleExtInfo, bms, userId);
692 if (!getBundleSuccess) {
693 HILOGE("Failed to get bundle info from bms, bundleName:%{public}s", bundleName.c_str());
694 continue;
695 }
696 struct BJsonEntityCaps::BundleBackupConfigPara backupPara;
697 if (!GetBackupExtConfig(bundleExtInfo.extensionInfos_, backupPara)) {
698 HILOGE("No backup extension ability found, bundleName:%{public}s", bundleName.c_str());
699 continue;
700 }
701 bundleInfos.emplace_back(BJsonEntityCaps::BundleInfo {bundleExtInfo.bundleInfo_.name,
702 bundleExtInfo.bundleInfo_.appIndex, bundleExtInfo.bundleInfo_.versionCode,
703 bundleExtInfo.bundleInfo_.versionName, 0, 0, backupPara.allToBackup, backupPara.fullBackupOnly,
704 backupPara.requireCompatibility, backupPara.extensionName, backupPara.restoreDeps, backupPara.supportScene,
705 backupPara.extraInfo});
706 }
707 for (const auto &info : incrementalDataList) {
708 if (SAUtils::IsSABundleName(info.bundleName)) {
709 HILOGE("Current SA name is:%{public}s", info.bundleName.c_str());
710 GetBundleInfoForSA(info.bundleName, bundleInfos);
711 }
712 }
713 return bundleInfos;
714 }
715 } // namespace OHOS::FileManagement::Backup