1 /*
2  * Copyright (c) 2023-2024 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 "status_receiver_host.h"
38 #include "system_ability_definition.h"
39 #include "if_system_ability_manager.h"
40 
41 namespace OHOS::FileManagement::Backup {
42 using namespace std;
43 
44 namespace {
45 enum { APP = 0, LOCAL, DISTRIBUTED, DATABASE, CACHE };
46 const string HMOS_HAP_CODE_PATH = "1";
47 const string LINUX_HAP_CODE_PATH = "2";
48 const string MEDIA_LIBRARY_HAP = "com.ohos.medialibrary.medialibrarydata";
49 const string EXTERNAL_FILE_HAP = "com.ohos.UserFile.ExternalFileManager";
50 const int E_ERR = -1;
51 const vector<string> dataDir = {"app", "local", "distributed", "database", "cache"};
52 } // namespace
53 
GetBundleManager()54 static sptr<AppExecFwk::IBundleMgr> GetBundleManager()
55 {
56     auto saMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
57     if (saMgr == nullptr) {
58         throw BError(BError::Codes::SA_BROKEN_IPC, "Failed to get system ability manager");
59     }
60 
61     auto bundleObj = saMgr->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
62     if (bundleObj == nullptr) {
63         throw BError(BError::Codes::SA_BROKEN_IPC, "Failed to get bundle manager service");
64     }
65 
66     return iface_cast<AppExecFwk::IBundleMgr>(bundleObj);
67 }
68 
GetAllowAndExtName(const vector<AppExecFwk::ExtensionAbilityInfo> & extensionInfos)69 static tuple<bool, bool, string, string, string, Json::Value> GetAllowAndExtName(
70     const vector<AppExecFwk::ExtensionAbilityInfo> &extensionInfos)
71 {
72     for (auto &&ext : extensionInfos) {
73         if (ext.type != AppExecFwk::ExtensionAbilityType::BACKUP) {
74             continue;
75         }
76         vector<string> out;
77         AppExecFwk::BundleMgrClient client;
78         if (!client.GetResConfigFile(ext, "ohos.extension.backup", out) || out.size() == 0) {
79             HILOGE("Failed to get resconfigfile of bundle, bundle name is:%{public}s", ext.bundleName.c_str());
80             continue;
81         }
82         BJsonCachedEntity<BJsonEntityExtensionConfig> cachedEntity(out[0], ext.bundleName);
83         auto cache = cachedEntity.Structuralize();
84         return {cache.GetAllowToBackupRestore(), cache.GetFullBackupOnly(), ext.name, cache.GetRestoreDeps(),
85             cache.GetSupportScene(), cache.GetExtraInfo()};
86     }
87     return {false, false, "", "", "", Json::Value()};
88 }
89 
GetBundleStats(const string & bundleName,int32_t userId)90 static int64_t GetBundleStats(const string &bundleName, int32_t userId)
91 {
92     HILOGI("Begin bundleName:%{public}s", bundleName.c_str());
93     if (bundleName == MEDIA_LIBRARY_HAP || bundleName == EXTERNAL_FILE_HAP) {
94         return StorageMgrAdapter::GetUserStorageStats(bundleName, userId);
95     }
96     auto bms = GetBundleManager();
97     vector<int64_t> bundleStats;
98     BJsonUtil::BundleDetailInfo bundleDetailInfo = BJsonUtil::ParseBundleNameIndexStr(bundleName);
99     bool res = bms->GetBundleStats(bundleDetailInfo.bundleName, userId, bundleStats, bundleDetailInfo.bundleIndex,
100                                    AppExecFwk::Constants::NoGetBundleStatsFlag::GET_BUNDLE_WITHOUT_CACHE_SIZE);
101     if (!res || bundleStats.size() != dataDir.size()) {
102         HILOGE("An error occurred in querying bundle stats. name:%{public}s", bundleName.c_str());
103         return 0;
104     }
105     for (uint i = 0; i < bundleStats.size(); i++) {
106         if (bundleStats[i] == E_ERR) {
107             HILOGE("Failed to query %{public}s data. name:%{public}s", dataDir[i].c_str(), bundleName.c_str());
108             bundleStats[i] = 0;
109         }
110     }
111     int64_t dataSize = bundleStats[LOCAL] + bundleStats[DISTRIBUTED] + bundleStats[DATABASE];
112     return dataSize;
113 }
114 
GetBundleInfos(const vector<string> & bundleNames,int32_t userId)115 vector<BJsonEntityCaps::BundleInfo> BundleMgrAdapter::GetBundleInfos(const vector<string> &bundleNames, int32_t userId)
116 {
117     vector<BJsonEntityCaps::BundleInfo> bundleInfos;
118     auto bms = GetBundleManager();
119     HILOGI("Start, bundleNames size:%{public}zu", bundleNames.size());
120     for (auto const &bundleName : bundleNames) {
121         HILOGI("Begin Get bundleName:%{public}s", bundleName.c_str());
122         if (bundleName.empty()) {
123             HILOGE("BundleName is invalid");
124             continue;
125         }
126         if (SAUtils::IsSABundleName(bundleName)) {
127             GetBundleInfoForSA(bundleName, bundleInfos);
128             continue;
129         }
130         AppExecFwk::BundleInfo installedBundle;
131         std::vector<AppExecFwk::ExtensionAbilityInfo> extensionInfos;
132         bool getBundleSuccess = GetCurBundleExtenionInfo(installedBundle, bundleName, extensionInfos, bms, userId);
133         if (!getBundleSuccess) {
134             HILOGE("Get current extension failed");
135             continue;
136         }
137         auto [allToBackup, fullBackupOnly, extName, restoreDeps, supportScene, extraInfo] =
138             GetAllowAndExtName(extensionInfos);
139         int64_t dataSize = 0;
140         if (allToBackup) {
141             dataSize = GetBundleStats(bundleName, userId);
142         }
143         bundleInfos.emplace_back(BJsonEntityCaps::BundleInfo {installedBundle.name, installedBundle.appIndex,
144                                                               installedBundle.versionCode,
145                                                               installedBundle.versionName, dataSize, 0, allToBackup,
146                                                               fullBackupOnly, extName, restoreDeps, supportScene,
147                                                               extraInfo});
148     }
149     HILOGI("End, bundleInfos size:%{public}zu", bundleInfos.size());
150     return bundleInfos;
151 }
152 
GetAppGalleryBundleName()153 string BundleMgrAdapter::GetAppGalleryBundleName()
154 {
155     auto bms = GetBundleManager();
156 
157     string bundleName = "";
158     auto ret = bms->QueryAppGalleryBundleName(bundleName);
159     if (!ret) {
160         HILOGI("Get App Gallery BundleName fail!");
161     } else {
162         HILOGI("App Gallery BundleName: %{public}s", bundleName.c_str());
163     }
164     return bundleName;
165 }
166 
GetBackupExtConfig(const vector<AppExecFwk::ExtensionAbilityInfo> & extensionInfos,BJsonEntityCaps::BundleBackupConfigPara & backupPara)167 static bool GetBackupExtConfig(const vector<AppExecFwk::ExtensionAbilityInfo> &extensionInfos,
168     BJsonEntityCaps::BundleBackupConfigPara &backupPara)
169 {
170     for (auto &&ext : extensionInfos) {
171         if (ext.type != AppExecFwk::ExtensionAbilityType::BACKUP) {
172             continue;
173         }
174         vector<string> out;
175         AppExecFwk::BundleMgrClient client;
176         if (!client.GetResConfigFile(ext, "ohos.extension.backup", out) || out.size() == 0) {
177             HILOGE("Failed to get resconfigfile of bundle, bundle name is:%{public}s", ext.bundleName.c_str());
178             continue;
179         }
180         BJsonCachedEntity<BJsonEntityExtensionConfig> cachedEntity(out[0], ext.bundleName);
181         auto cache = cachedEntity.Structuralize();
182         backupPara.allToBackup = cache.GetAllowToBackupRestore();
183         backupPara.fullBackupOnly = cache.GetFullBackupOnly();
184         backupPara.extensionName = ext.name;
185         backupPara.restoreDeps = cache.GetRestoreDeps();
186         backupPara.supportScene = cache.GetSupportScene();
187         backupPara.extraInfo = cache.GetExtraInfo();
188         backupPara.includes = cache.GetIncludes();
189         backupPara.excludes = cache.GetExcludes();
190         return true;
191     }
192     return false;
193 }
194 
CreateIPCInteractionFiles(int32_t userId,const string & bundleName,int64_t lastIncrementalTime,const vector<string> & includes,const vector<string> & excludes)195 static bool CreateIPCInteractionFiles(int32_t userId, const string &bundleName, int64_t lastIncrementalTime,
196     const vector<string> &includes, const vector<string> &excludes)
197 {
198     // backup_sa bundle path
199     BJsonUtil::BundleDetailInfo bundleDetail = BJsonUtil::ParseBundleNameIndexStr(bundleName);
200     string backupSaBundleDir;
201     if (bundleDetail.bundleIndex > 0) {
202         std::string bundleNameIndex  = "+clone-" + std::to_string(bundleDetail.bundleIndex) + "+" +
203             bundleDetail.bundleName;
204         backupSaBundleDir = BConstants::BACKUP_PATH_PREFIX + to_string(userId) + BConstants::BACKUP_PATH_SURFFIX +
205             bundleNameIndex + BConstants::FILE_SEPARATOR_CHAR;
206     } else {
207         backupSaBundleDir = BConstants::BACKUP_PATH_PREFIX + to_string(userId) + BConstants::BACKUP_PATH_SURFFIX +
208             bundleDetail.bundleName + BConstants::FILE_SEPARATOR_CHAR;
209     }
210     HILOGI("bundleInteraction dir is:%{public}s", backupSaBundleDir.c_str());
211     if (access(backupSaBundleDir.data(), F_OK) != 0) {
212         int32_t err = mkdir(backupSaBundleDir.data(), S_IRWXU | S_IRWXG);
213         if (err != 0 && errno != EEXIST) {
214             HILOGE("Failed to create folder in backup_sa bundleName:%{public}s, sys err:%{public}d",
215                 bundleName.c_str(), errno);
216             return false;
217         }
218     }
219     // backup_sa include/exclude
220     string incExFilePath = backupSaBundleDir + BConstants::BACKUP_INCEXC_SYMBOL + to_string(lastIncrementalTime);
221     ofstream incExcFile;
222     incExcFile.open(incExFilePath.data(), ios::out | ios::trunc);
223     if (!incExcFile.is_open()) {
224         HILOGE("Cannot create incexc file, err = %{public}d", errno);
225         return false;
226     }
227     incExcFile << BConstants::BACKUP_INCLUDE << endl;
228     for (const auto &include : includes) {
229         incExcFile << include << endl;
230     }
231     incExcFile << BConstants::BACKUP_EXCLUDE << endl;
232     for (const auto &exclude : excludes) {
233         incExcFile << exclude << endl;
234     }
235     incExcFile.close();
236 
237     // backup_sa stat
238     string statFilePath = backupSaBundleDir + BConstants::BACKUP_STAT_SYMBOL + to_string(lastIncrementalTime);
239     ofstream statFile;
240     statFile.open(statFilePath.data(), ios::out | ios::trunc);
241     if (!statFile.is_open()) {
242         HILOGE("Cannot create stat file");
243         return false;
244     }
245     statFile.close();
246 
247     return true;
248 }
249 
GenerateBundleStatsIncrease(int32_t userId,const vector<string> & bundleNames,const vector<int64_t> & lastBackTimes,vector<BJsonEntityCaps::BundleInfo> & bundleInfos,vector<BJsonEntityCaps::BundleInfo> & newBundleInfos)250 static bool GenerateBundleStatsIncrease(int32_t userId, const vector<string> &bundleNames,
251     const vector<int64_t> &lastBackTimes, vector<BJsonEntityCaps::BundleInfo> &bundleInfos,
252     vector<BJsonEntityCaps::BundleInfo> &newBundleInfos)
253 {
254     vector<int64_t> pkgFileSizes {};
255     vector<int64_t> incPkgFileSizes {};
256     int32_t err = StorageMgrAdapter::GetBundleStatsForIncrease(userId, bundleNames, lastBackTimes,
257         pkgFileSizes, incPkgFileSizes);
258     if (err != 0) {
259         HILOGE("Failed to get bundleStats result from storage, err = %{public}d", err);
260         return false;
261     }
262     HILOGI("bundleNames size:%{public}zu, pkgFileSizes size:%{public}zu, bundleInfos size:%{public}zu",
263         bundleNames.size(), pkgFileSizes.size(), bundleInfos.size());
264     if (bundleInfos.size() != pkgFileSizes.size()) {
265         HILOGE("The number of bundle is not equal to the number of data records");
266         return false;
267     }
268     for (size_t i = 0; i < bundleInfos.size(); i++) {
269         std::string curBundleName = bundleInfos[i].name;
270         HILOGD("BundleMgrAdapter name for %{public}s", curBundleName.c_str());
271         BJsonEntityCaps::BundleInfo newBundleInfo = {.name = curBundleName,
272                                                      .appIndex = bundleInfos[i].appIndex,
273                                                      .versionCode = bundleInfos[i].versionCode,
274                                                      .versionName = bundleInfos[i].versionName,
275                                                      .spaceOccupied = pkgFileSizes[i],
276                                                      .increSpaceOccupied = incPkgFileSizes[i],
277                                                      .allToBackup = bundleInfos[i].allToBackup,
278                                                      .fullBackupOnly = bundleInfos[i].fullBackupOnly,
279                                                      .extensionName = bundleInfos[i].extensionName,
280                                                      .restoreDeps = bundleInfos[i].restoreDeps,
281                                                      .supportScene = bundleInfos[i].supportScene,
282                                                      .extraInfo = bundleInfos[i].extraInfo};
283         newBundleInfos.emplace_back(newBundleInfo);
284     }
285     return true;
286 }
287 
GetBundleInfosForIncremental(const vector<BIncrementalData> & incrementalDataList,int32_t userId)288 vector<BJsonEntityCaps::BundleInfo> BundleMgrAdapter::GetBundleInfosForIncremental(
289     const vector<BIncrementalData> &incrementalDataList, int32_t userId)
290 {
291     vector<std::string> bundleNames;
292     vector<int64_t> incrementalBackTimes;
293     vector<BJsonEntityCaps::BundleInfo> bundleInfos;
294     auto bms = GetBundleManager();
295     for (auto const &bundleNameTime : incrementalDataList) {
296         auto bundleName = bundleNameTime.bundleName;
297         AppExecFwk::BundleInfo installedBundle;
298         std::vector<AppExecFwk::ExtensionAbilityInfo> extensionInfos;
299         bool getBundleSuccess = GetCurBundleExtenionInfo(installedBundle, bundleName, extensionInfos, bms, userId);
300         if (!getBundleSuccess) {
301             HILOGE("Failed to get bundle info from bms, bundleName:%{public}s", bundleName.c_str());
302             continue;
303         }
304         struct BJsonEntityCaps::BundleBackupConfigPara backupPara;
305         if (!GetBackupExtConfig(extensionInfos, backupPara)) {
306             HILOGE("No backup extension ability found, bundleName:%{public}s", bundleName.c_str());
307             continue;
308         }
309         if (!CreateIPCInteractionFiles(userId, bundleName, bundleNameTime.lastIncrementalTime, backupPara.includes,
310             backupPara.excludes)) {
311             HILOGE("Create bundleInteraction dir failed, bundleName:%{public}s", bundleName.c_str());
312             continue;
313         }
314         bundleInfos.emplace_back(BJsonEntityCaps::BundleInfo {installedBundle.name, installedBundle.appIndex,
315                                                               installedBundle.versionCode,
316                                                               installedBundle.versionName, 0, 0,
317                                                               backupPara.allToBackup, backupPara.fullBackupOnly,
318                                                               backupPara.extensionName,
319                                                               backupPara.restoreDeps, backupPara.supportScene,
320                                                               backupPara.extraInfo});
321         if (installedBundle.appIndex > 0) {
322             std::string bundleNameIndex  = "+clone-" + std::to_string(installedBundle.appIndex) + "+" +
323                 installedBundle.name;
324             bundleNames.emplace_back(bundleNameIndex);
325         } else {
326             bundleNames.emplace_back(bundleName);
327         }
328         incrementalBackTimes.emplace_back(bundleNameTime.lastIncrementalTime);
329     }
330     vector<BJsonEntityCaps::BundleInfo> newBundleInfos {};
331     if (!GenerateBundleStatsIncrease(userId, bundleNames, incrementalBackTimes, bundleInfos, newBundleInfos)) {
332         HILOGE("Failed to get bundleStats result");
333         return {};
334     }
335     HILOGI("BundleMgrAdapter GetBundleInfosForIncremental end ");
336     return newBundleInfos;
337 }
338 
GetBundleInfosForIncremental(int32_t userId,const std::vector<BIncrementalData> & extraIncreData)339 vector<BJsonEntityCaps::BundleInfo> BundleMgrAdapter::GetBundleInfosForIncremental(int32_t userId,
340     const std::vector<BIncrementalData> &extraIncreData)
341 {
342     vector<AppExecFwk::BundleInfo> installedBundles;
343     HILOGI("Begin get bundle infos");
344     auto bms = GetBundleManager();
345     if (!bms->GetBundleInfos(AppExecFwk::GET_BUNDLE_WITH_EXTENSION_INFO, installedBundles, userId)) {
346         throw BError(BError::Codes::SA_BROKEN_IPC, "Failed to get bundle infos");
347     }
348 
349     vector<BIncrementalData> bundleNames;
350     vector<BJsonEntityCaps::BundleInfo> bundleInfos;
351     HILOGI("Begin get bundle infos");
352     for (auto const &installedBundle : installedBundles) {
353         if (installedBundle.applicationInfo.codePath == HMOS_HAP_CODE_PATH ||
354             installedBundle.applicationInfo.codePath == LINUX_HAP_CODE_PATH) {
355             HILOGI("Unsupported applications, name : %{public}s", installedBundle.name.data());
356             continue;
357         }
358         auto [allToBackup, fullBackupOnly, extName, restoreDeps, supportScene, extraInfo] =
359             GetAllowAndExtName(installedBundle.extensionInfos);
360         if (!allToBackup) {
361             bundleInfos.emplace_back(BJsonEntityCaps::BundleInfo {installedBundle.name, installedBundle.appIndex,
362                 installedBundle.versionCode, installedBundle.versionName, 0, 0, allToBackup, fullBackupOnly,
363                 extName, restoreDeps, supportScene, extraInfo});
364             continue;
365         }
366         auto it = std::find_if(extraIncreData.begin(), extraIncreData.end(),
367             [installedBundle](const BIncrementalData &info)->bool {
368                 return installedBundle.name == info.bundleName;
369             });
370         if (it == extraIncreData.end()) {
371             bundleNames.emplace_back(BIncrementalData {installedBundle.name, 0});
372         } else {
373             bundleNames.emplace_back(*it);
374         }
375     }
376     auto bundleInfosNew = BundleMgrAdapter::GetBundleInfosForIncremental(bundleNames, userId);
377     auto bundleInfosSA = BundleMgrAdapter::GetBundleInfosForSA();
378     copy(bundleInfosNew.begin(), bundleInfosNew.end(), back_inserter(bundleInfos));
379     copy(bundleInfosSA.begin(), bundleInfosSA.end(), back_inserter(bundleInfos));
380     HILOGI("End get bundle infos, bundleInfos size: %{public}zu", bundleInfos.size());
381     return bundleInfos;
382 }
383 
GetFullBundleInfos(int32_t userId)384 vector<BJsonEntityCaps::BundleInfo> BundleMgrAdapter::GetFullBundleInfos(int32_t userId)
385 {
386     vector<AppExecFwk::BundleInfo> installedBundles;
387     HILOGI("Begin GetFullBundleInfos");
388     auto bms = GetBundleManager();
389     if (!bms->GetBundleInfos(AppExecFwk::GET_BUNDLE_WITH_EXTENSION_INFO, installedBundles, userId)) {
390         throw BError(BError::Codes::SA_BROKEN_IPC, "Failed to get bundle infos");
391     }
392     vector<string> bundleNames;
393     vector<BJsonEntityCaps::BundleInfo> bundleInfos;
394     for (auto const &installedBundle : installedBundles) {
395         HILOGI("Begin get bundle infos, bundleName = %{public}s", installedBundle.name.data());
396         if (installedBundle.applicationInfo.codePath == HMOS_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             std::string bundleNameIndexInfo = BJsonUtil::BuildBundleNameIndexInfo(installedBundle.name,
403                 installedBundle.appIndex);
404             bundleNames.emplace_back(bundleNameIndexInfo);
405             continue;
406         }
407         auto [allToBackup, fullBackupOnly, extName, restoreDeps, supportScene, extraInfo] =
408             GetAllowAndExtName(installedBundle.extensionInfos);
409         if (!allToBackup) {
410             HILOGI("Not allToBackup, bundleName = %{public}s", installedBundle.name.data());
411             bundleInfos.emplace_back(BJsonEntityCaps::BundleInfo {installedBundle.name, installedBundle.appIndex,
412                 installedBundle.versionCode, installedBundle.versionName, 0, 0, allToBackup, fullBackupOnly, extName,
413                 restoreDeps, supportScene, extraInfo});
414             continue;
415         }
416         bundleNames.emplace_back(installedBundle.name);
417     }
418     auto bundleInfosNew = BundleMgrAdapter::GetBundleInfos(bundleNames, userId);
419     auto bundleInfosSA = BundleMgrAdapter::GetBundleInfosForSA();
420     copy(bundleInfosNew.begin(), bundleInfosNew.end(), back_inserter(bundleInfos));
421     copy(bundleInfosSA.begin(), bundleInfosSA.end(), back_inserter(bundleInfos));
422     HILOGI("End GetFullBundleInfos, bundleInfos size: %{public}zu", bundleInfos.size());
423     return bundleInfos;
424 }
425 
GetExtName(string bundleName,int32_t userId)426 string BundleMgrAdapter::GetExtName(string bundleName, int32_t userId)
427 {
428     vector<AppExecFwk::BundleInfo> installedBundles;
429     auto bms = GetBundleManager();
430     if (!bms->GetBundleInfos(AppExecFwk::GET_BUNDLE_WITH_EXTENSION_INFO, installedBundles, userId)) {
431         throw BError(BError::Codes::SA_BROKEN_IPC, "Failed to get bundle infos");
432     }
433     for (auto const &installedBundle : installedBundles) {
434         if (installedBundle.applicationInfo.codePath == HMOS_HAP_CODE_PATH ||
435             installedBundle.applicationInfo.codePath == LINUX_HAP_CODE_PATH) {
436             HILOGI("Unsupported applications, name : %{public}s", installedBundle.name.data());
437             continue;
438         }
439         for (auto ext : installedBundle.extensionInfos) {
440             if (ext.bundleName != bundleName) {
441                 continue;
442             }
443             if (ext.type != AppExecFwk::ExtensionAbilityType::BACKUP) {
444                 continue;
445             }
446             HILOGI("bundleName: %{public}s, find extName: %{public}s", bundleName.c_str(), ext.name.c_str());
447             return ext.name;
448         }
449     }
450     HILOGI("bundleName: %{public}s , find extName failed", bundleName.c_str());
451     return "BackupExtensionAbility";
452 }
453 
GetBundleInfosForSA()454 std::vector<BJsonEntityCaps::BundleInfo> BundleMgrAdapter::GetBundleInfosForSA()
455 {
456     std::vector<int32_t> saIds;
457     vector<BJsonEntityCaps::BundleInfo> saBundleInfos;
458     sptr<ISystemAbilityManager> samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
459     if (!samgrProxy) {
460         HILOGE("SamgrProxy is nullptr");
461         return saBundleInfos;
462     }
463     int32_t ret = samgrProxy->GetExtensionSaIds(BConstants::EXTENSION_BACKUP, saIds);
464     HILOGI("GetExtensionSaIds ret: %{public}d", ret);
465     for (auto saId : saIds) {
466         saBundleInfos.emplace_back(BJsonEntityCaps::BundleInfo {std::to_string(saId), 0, 0, "", 0, 0, true, false,
467             "", "", "", ""});
468     }
469     return saBundleInfos;
470 }
471 
GetBundleInfoForSA(std::string bundleName,std::vector<BJsonEntityCaps::BundleInfo> & bundleInfos)472 void BundleMgrAdapter::GetBundleInfoForSA(std::string bundleName, std::vector<BJsonEntityCaps::BundleInfo>& bundleInfos)
473 {
474     HILOGI("SA %{public}s GetBundleInfo begin.", bundleName.c_str());
475     std::vector<int32_t> saIds;
476     vector<BJsonEntityCaps::BundleInfo> saBundleInfos;
477     sptr<ISystemAbilityManager> samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
478     if (!samgrProxy) {
479         HILOGE("SamgrProxy is nullptr");
480         return;
481     }
482     int32_t ret = samgrProxy->GetExtensionSaIds(BConstants::EXTENSION_BACKUP, saIds);
483     if (ret != ERR_OK) {
484         HILOGE("GetExtensionSaIds err,ret %{public}d", ret);
485         return;
486     }
487     if (saIds.empty()) {
488         HILOGE("GetExtensionSaIds result is empty");
489         return;
490     }
491     int32_t saId = std::atoi(bundleName.c_str());
492     if (std::find(saIds.begin(), saIds.end(), saId) == saIds.end()) {
493         HILOGE("SA %{public}d is not surport backup.", saId);
494         return;
495     }
496     bundleInfos.emplace_back(BJsonEntityCaps::BundleInfo {bundleName, 0, 0, "", 0, 0, true, false, "", "", "", ""});
497     HILOGI("SA %{public}s GetBundleInfo end.", bundleName.c_str());
498 }
499 
GetCurBundleExtenionInfo(AppExecFwk::BundleInfo & installedBundle,const std::string & bundleName,std::vector<AppExecFwk::ExtensionAbilityInfo> & extensionInfos,sptr<AppExecFwk::IBundleMgr> bms,int32_t userId)500 bool BundleMgrAdapter::GetCurBundleExtenionInfo(AppExecFwk::BundleInfo &installedBundle,
501     const std::string &bundleName, std::vector<AppExecFwk::ExtensionAbilityInfo> &extensionInfos,
502     sptr<AppExecFwk::IBundleMgr> bms, int32_t userId)
503 {
504     BJsonUtil::BundleDetailInfo bundleDetailInfo = BJsonUtil::ParseBundleNameIndexStr(bundleName);
505     int32_t flags = static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE) |
506         static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_EXTENSION_ABILITY) |
507         static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_METADATA);
508     ErrCode ret = bms->GetCloneBundleInfo(bundleDetailInfo.bundleName, flags, bundleDetailInfo.bundleIndex,
509         installedBundle, userId);
510     if (ret != ERR_OK) {
511         HILOGE("bundleName:%{public}s, ret:%{public}d, current bundle info for backup/restore is empty",
512             bundleName.c_str(), ret);
513         return false;
514     }
515     if (installedBundle.applicationInfo.codePath == HMOS_HAP_CODE_PATH ||
516         installedBundle.applicationInfo.codePath == LINUX_HAP_CODE_PATH) {
517         HILOGE("Unsupported applications, name : %{public}s", installedBundle.name.data());
518         return false;
519     }
520     std::vector<AppExecFwk::HapModuleInfo> hapModuleInfos = installedBundle.hapModuleInfos;
521     for (auto &hapModuleInfo : hapModuleInfos) {
522         extensionInfos.insert(extensionInfos.end(), hapModuleInfo.extensionInfos.begin(),
523             hapModuleInfo.extensionInfos.end());
524     }
525     HILOGI("bundleName:%{public}s, extensionInfos size:%{public}zu", bundleName.c_str(), extensionInfos.size());
526     return true;
527 }
528 
IsUser0BundleName(std::string bundleName,int32_t userId)529 bool BundleMgrAdapter::IsUser0BundleName(std::string bundleName, int32_t userId)
530 {
531     auto bms = GetBundleManager();
532     AppExecFwk::BundleInfo installedBundle;
533     BJsonUtil::BundleDetailInfo bundleDetailInfo = BJsonUtil::ParseBundleNameIndexStr(bundleName);
534     int32_t flags = static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE) |
535         static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_EXTENSION_ABILITY) |
536         static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_METADATA) |
537         static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION);
538     ErrCode ret = bms->GetCloneBundleInfo(bundleDetailInfo.bundleName, flags, bundleDetailInfo.bundleIndex,
539         installedBundle, userId);
540     if (ret != ERR_OK) {
541         HILOGE("bundleName:%{public}s, ret:%{public}d, GetBundle Failed from BMS", bundleName.c_str(), ret);
542         return false;
543     }
544     if (installedBundle.applicationInfo.singleton == true) {
545         HILOGI("bundleName:%{public}s is zero user bundle", bundleName.c_str());
546         return true;
547     }
548     HILOGI("bundleName:%{public}s is not zero user bundle", bundleName.c_str());
549     return false;
550 }
551 
GetBundleInfosForAppend(const std::vector<BIncrementalData> & list,int32_t userId)552 vector<BJsonEntityCaps::BundleInfo> BundleMgrAdapter::GetBundleInfosForAppend(const std::vector<BIncrementalData> &list,
553     int32_t userId)
554 {
555     auto bundleInfos = BundleMgrAdapter::GetBundleInfosForIncremental(list, userId);
556     for (auto const &info : list) {
557         if (SAUtils::IsSABundleName(info.bundleName)) {
558             GetBundleInfoForSA(info.bundleName, bundleInfos);
559         }
560     }
561     return bundleInfos;
562 }
563 } // namespace OHOS::FileManagement::Backup
564