• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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