• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 (const auto &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, bundleName:%{public}s", bundleName.c_str());
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 (const auto &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         HILOGE("Failed to get bundle infos from bms");
347         return {};
348     }
349 
350     vector<BIncrementalData> bundleNames;
351     vector<BJsonEntityCaps::BundleInfo> bundleInfos;
352     HILOGI("End get installedBundles count is:%{public}zu", installedBundles.size());
353     for (const auto &installedBundle : installedBundles) {
354         if (installedBundle.applicationInfo.codePath == HMOS_HAP_CODE_PATH ||
355             installedBundle.applicationInfo.codePath == LINUX_HAP_CODE_PATH) {
356             HILOGI("Unsupported applications, name : %{public}s", installedBundle.name.data());
357             continue;
358         }
359         auto [allToBackup, fullBackupOnly, extName, restoreDeps, supportScene, extraInfo] =
360             GetAllowAndExtName(installedBundle.extensionInfos);
361         if (!allToBackup) {
362             bundleInfos.emplace_back(BJsonEntityCaps::BundleInfo {installedBundle.name, installedBundle.appIndex,
363                 installedBundle.versionCode, installedBundle.versionName, 0, 0, allToBackup, fullBackupOnly,
364                 extName, restoreDeps, supportScene, extraInfo});
365             continue;
366         }
367         auto it = std::find_if(extraIncreData.begin(), extraIncreData.end(),
368             [installedBundle](const BIncrementalData &info)->bool {
369                 return installedBundle.name == info.bundleName;
370             });
371         if (it == extraIncreData.end()) {
372             bundleNames.emplace_back(BIncrementalData {installedBundle.name, 0});
373         } else {
374             bundleNames.emplace_back(*it);
375         }
376     }
377     auto bundleInfosNew = BundleMgrAdapter::GetBundleInfosForIncremental(bundleNames, userId);
378     auto bundleInfosSA = BundleMgrAdapter::GetBundleInfosForSA();
379     copy(bundleInfosNew.begin(), bundleInfosNew.end(), back_inserter(bundleInfos));
380     copy(bundleInfosSA.begin(), bundleInfosSA.end(), back_inserter(bundleInfos));
381     HILOGI("End get bundle infos, bundleInfos size: %{public}zu", bundleInfos.size());
382     return bundleInfos;
383 }
384 
GetFullBundleInfos(int32_t userId)385 vector<BJsonEntityCaps::BundleInfo> BundleMgrAdapter::GetFullBundleInfos(int32_t userId)
386 {
387     vector<AppExecFwk::BundleInfo> installedBundles;
388     HILOGI("Begin GetFullBundleInfos");
389     auto bms = GetBundleManager();
390     if (!bms->GetBundleInfos(AppExecFwk::GET_BUNDLE_WITH_EXTENSION_INFO, installedBundles, userId)) {
391         HILOGE("Failed to get bundle infos from bms");
392         return {};
393     }
394     vector<string> bundleNames;
395     vector<BJsonEntityCaps::BundleInfo> bundleInfos;
396     HILOGI("End get installedBundles count is:%{public}zu", installedBundles.size());
397     for (const auto &installedBundle : installedBundles) {
398         if (installedBundle.name.empty()) {
399             HILOGE("Current bundle name is invalid");
400             continue;
401         }
402         if (installedBundle.applicationInfo.codePath == HMOS_HAP_CODE_PATH ||
403             installedBundle.applicationInfo.codePath == LINUX_HAP_CODE_PATH) {
404             HILOGI("Unsupported applications, name : %{public}s", installedBundle.name.data());
405             continue;
406         }
407         if (installedBundle.appIndex > 0) {
408             HILOGI("Current bundle %{public}s is a twin application", installedBundle.name.c_str());
409             std::string bundleNameIndexInfo = BJsonUtil::BuildBundleNameIndexInfo(installedBundle.name,
410                 installedBundle.appIndex);
411             bundleNames.emplace_back(bundleNameIndexInfo);
412             continue;
413         }
414         auto [allToBackup, fullBackupOnly, extName, restoreDeps, supportScene, extraInfo] =
415             GetAllowAndExtName(installedBundle.extensionInfos);
416         if (!allToBackup) {
417             HILOGI("Not allToBackup, bundleName = %{public}s", installedBundle.name.data());
418             bundleInfos.emplace_back(BJsonEntityCaps::BundleInfo {installedBundle.name, installedBundle.appIndex,
419                 installedBundle.versionCode, installedBundle.versionName, 0, 0, allToBackup, fullBackupOnly, extName,
420                 restoreDeps, supportScene, extraInfo});
421             continue;
422         }
423         bundleNames.emplace_back(installedBundle.name);
424     }
425     auto bundleInfosNew = BundleMgrAdapter::GetBundleInfos(bundleNames, userId);
426     auto bundleInfosSA = BundleMgrAdapter::GetBundleInfosForSA();
427     copy(bundleInfosNew.begin(), bundleInfosNew.end(), back_inserter(bundleInfos));
428     copy(bundleInfosSA.begin(), bundleInfosSA.end(), back_inserter(bundleInfos));
429     HILOGI("End GetFullBundleInfos, bundleInfos size: %{public}zu", bundleInfos.size());
430     return bundleInfos;
431 }
432 
GetExtName(string bundleName,int32_t userId)433 string BundleMgrAdapter::GetExtName(string bundleName, int32_t userId)
434 {
435     vector<AppExecFwk::BundleInfo> installedBundles;
436     auto bms = GetBundleManager();
437     if (!bms->GetBundleInfos(AppExecFwk::GET_BUNDLE_WITH_EXTENSION_INFO, installedBundles, userId)) {
438         throw BError(BError::Codes::SA_BROKEN_IPC, "Failed to get bundle infos");
439     }
440     for (const auto &installedBundle : installedBundles) {
441         if (installedBundle.applicationInfo.codePath == HMOS_HAP_CODE_PATH ||
442             installedBundle.applicationInfo.codePath == LINUX_HAP_CODE_PATH) {
443             HILOGI("Unsupported applications, name : %{public}s", installedBundle.name.data());
444             continue;
445         }
446         for (const auto &ext : installedBundle.extensionInfos) {
447             if (ext.bundleName != bundleName) {
448                 continue;
449             }
450             if (ext.type != AppExecFwk::ExtensionAbilityType::BACKUP) {
451                 continue;
452             }
453             HILOGI("bundleName: %{public}s, find extName: %{public}s", bundleName.c_str(), ext.name.c_str());
454             return ext.name;
455         }
456     }
457     HILOGI("bundleName: %{public}s , find extName failed", bundleName.c_str());
458     return "BackupExtensionAbility";
459 }
460 
GetBundleInfosForSA()461 std::vector<BJsonEntityCaps::BundleInfo> BundleMgrAdapter::GetBundleInfosForSA()
462 {
463     std::vector<int32_t> saIds;
464     vector<BJsonEntityCaps::BundleInfo> saBundleInfos;
465     sptr<ISystemAbilityManager> samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
466     if (!samgrProxy) {
467         HILOGE("SamgrProxy is nullptr");
468         return saBundleInfos;
469     }
470     int32_t ret = samgrProxy->GetExtensionSaIds(BConstants::EXTENSION_BACKUP, saIds);
471     HILOGI("GetExtensionSaIds ret: %{public}d", ret);
472     for (const auto &saId : saIds) {
473         saBundleInfos.emplace_back(BJsonEntityCaps::BundleInfo {std::to_string(saId), 0, 0, "", 0, 0, true, false,
474             "", "", "", ""});
475     }
476     return saBundleInfos;
477 }
478 
GetBundleInfoForSA(std::string bundleName,std::vector<BJsonEntityCaps::BundleInfo> & bundleInfos)479 void BundleMgrAdapter::GetBundleInfoForSA(std::string bundleName, std::vector<BJsonEntityCaps::BundleInfo>& bundleInfos)
480 {
481     HILOGI("SA %{public}s GetBundleInfo begin.", bundleName.c_str());
482     std::vector<int32_t> saIds;
483     vector<BJsonEntityCaps::BundleInfo> saBundleInfos;
484     sptr<ISystemAbilityManager> samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
485     if (!samgrProxy) {
486         HILOGE("SamgrProxy is nullptr");
487         return;
488     }
489     int32_t ret = samgrProxy->GetExtensionSaIds(BConstants::EXTENSION_BACKUP, saIds);
490     if (ret != ERR_OK) {
491         HILOGE("GetExtensionSaIds err,ret %{public}d", ret);
492         return;
493     }
494     if (saIds.empty()) {
495         HILOGE("GetExtensionSaIds result is empty");
496         return;
497     }
498     int32_t saId = std::atoi(bundleName.c_str());
499     if (std::find(saIds.begin(), saIds.end(), saId) == saIds.end()) {
500         HILOGE("SA %{public}d is not surport backup.", saId);
501         return;
502     }
503     bundleInfos.emplace_back(BJsonEntityCaps::BundleInfo {bundleName, 0, 0, "", 0, 0, true, false, "", "", "", ""});
504     HILOGI("SA %{public}s GetBundleInfo end.", bundleName.c_str());
505 }
506 
GetCurBundleExtenionInfo(AppExecFwk::BundleInfo & installedBundle,const std::string & bundleName,std::vector<AppExecFwk::ExtensionAbilityInfo> & extensionInfos,sptr<AppExecFwk::IBundleMgr> bms,int32_t userId)507 bool BundleMgrAdapter::GetCurBundleExtenionInfo(AppExecFwk::BundleInfo &installedBundle,
508     const std::string &bundleName, std::vector<AppExecFwk::ExtensionAbilityInfo> &extensionInfos,
509     sptr<AppExecFwk::IBundleMgr> bms, int32_t userId)
510 {
511     BJsonUtil::BundleDetailInfo bundleDetailInfo = BJsonUtil::ParseBundleNameIndexStr(bundleName);
512     int32_t flags = static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE) |
513         static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_EXTENSION_ABILITY) |
514         static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_METADATA);
515     ErrCode ret = bms->GetCloneBundleInfo(bundleDetailInfo.bundleName, flags, bundleDetailInfo.bundleIndex,
516         installedBundle, userId);
517     if (ret != ERR_OK) {
518         HILOGE("bundleName:%{public}s, ret:%{public}d, current bundle info for backup/restore is empty",
519             bundleName.c_str(), ret);
520         return false;
521     }
522     if (installedBundle.applicationInfo.codePath == HMOS_HAP_CODE_PATH ||
523         installedBundle.applicationInfo.codePath == LINUX_HAP_CODE_PATH) {
524         HILOGE("Unsupported applications, name : %{public}s", installedBundle.name.data());
525         return false;
526     }
527     std::vector<AppExecFwk::HapModuleInfo> hapModuleInfos = installedBundle.hapModuleInfos;
528     for (const auto &hapModuleInfo : hapModuleInfos) {
529         extensionInfos.insert(extensionInfos.end(), hapModuleInfo.extensionInfos.begin(),
530             hapModuleInfo.extensionInfos.end());
531     }
532     HILOGI("bundleName:%{public}s, extensionInfos size:%{public}zu", bundleName.c_str(), extensionInfos.size());
533     return true;
534 }
535 
IsUser0BundleName(std::string bundleName,int32_t userId)536 bool BundleMgrAdapter::IsUser0BundleName(std::string bundleName, int32_t userId)
537 {
538     auto bms = GetBundleManager();
539     AppExecFwk::BundleInfo installedBundle;
540     BJsonUtil::BundleDetailInfo bundleDetailInfo = BJsonUtil::ParseBundleNameIndexStr(bundleName);
541     int32_t flags = static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE) |
542         static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_EXTENSION_ABILITY) |
543         static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_METADATA) |
544         static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION);
545     ErrCode ret = bms->GetCloneBundleInfo(bundleDetailInfo.bundleName, flags, bundleDetailInfo.bundleIndex,
546         installedBundle, userId);
547     if (ret != ERR_OK) {
548         HILOGE("bundleName:%{public}s, ret:%{public}d, GetBundle Failed from BMS", bundleName.c_str(), ret);
549         return false;
550     }
551     if (installedBundle.applicationInfo.singleton == true) {
552         HILOGI("bundleName:%{public}s is zero user bundle", bundleName.c_str());
553         return true;
554     }
555     HILOGI("bundleName:%{public}s is not zero user bundle", bundleName.c_str());
556     return false;
557 }
558 
GetBundleInfosForAppend(const std::vector<BIncrementalData> & list,int32_t userId)559 vector<BJsonEntityCaps::BundleInfo> BundleMgrAdapter::GetBundleInfosForAppend(const std::vector<BIncrementalData> &list,
560     int32_t userId)
561 {
562     auto bundleInfos = BundleMgrAdapter::GetBundleInfosForIncremental(list, userId);
563     for (const auto &info : list) {
564         if (SAUtils::IsSABundleName(info.bundleName)) {
565             GetBundleInfoForSA(info.bundleName, bundleInfos);
566         }
567     }
568     return bundleInfos;
569 }
570 
GetBundleInfosForLocalCapabilities(int32_t userId)571 std::vector<BJsonEntityCaps::BundleInfo> BundleMgrAdapter::GetBundleInfosForLocalCapabilities(int32_t userId)
572 {
573     HILOGI("start GetBundleInfosForLocalCapabilities");
574     vector<AppExecFwk::BundleInfo> installedBundles;
575     auto bms = GetBundleManager();
576     if (!bms->GetBundleInfos(AppExecFwk::GET_BUNDLE_WITH_EXTENSION_INFO, installedBundles, userId)) {
577         HILOGI("Failed to get bundle infos");
578         return {};
579     }
580     vector<string> bundleNames;
581     vector<BJsonEntityCaps::BundleInfo> bundleInfos;
582     HILOGI("End get installedBundles count is:%{public}zu", installedBundles.size());
583     for (auto const &installedBundle : installedBundles) {
584         if (installedBundle.applicationInfo.codePath == HMOS_HAP_CODE_PATH ||
585             installedBundle.applicationInfo.codePath == LINUX_HAP_CODE_PATH) {
586             HILOGI("Unsupported applications, name : %{public}s", installedBundle.name.data());
587             continue;
588         }
589         if (installedBundle.appIndex > 0) {
590             HILOGI("Current bundle %{public}s is a twin application, index = %{public}d",
591                 installedBundle.name.c_str(), installedBundle.appIndex);
592             std::string bundleNameIndexInfo = BJsonUtil::BuildBundleNameIndexInfo(installedBundle.name,
593                 installedBundle.appIndex);
594             bundleNames.emplace_back(bundleNameIndexInfo);
595             continue;
596         }
597         auto [allToBackup, fullBackupOnly, extName, restoreDeps, supportScene, extraInfo] =
598             GetAllowAndExtName(installedBundle.extensionInfos);
599         if (!allToBackup) {
600             HILOGI("Not allToBackup, bundleName = %{public}s, appIndex = %{public}d",
601                 installedBundle.name.c_str(), installedBundle.appIndex);
602             continue;
603         }
604         bundleInfos.emplace_back(BJsonEntityCaps::BundleInfo {
605                                  installedBundle.name, installedBundle.appIndex,
606                                  installedBundle.versionCode, installedBundle.versionName,
607                                  0, 0, allToBackup, fullBackupOnly,
608                                  extName, restoreDeps, supportScene, extraInfo});
609     }
610     auto bundleInfosIndex = GetBundleInfosForIndex(bundleNames, userId);
611     auto bundleInfosSA = BundleMgrAdapter::GetBundleInfosForSA();
612     copy(bundleInfosIndex.begin(), bundleInfosIndex.end(), back_inserter(bundleInfos));
613     copy(bundleInfosSA.begin(), bundleInfosSA.end(), back_inserter(bundleInfos));
614     HILOGI("End GetBundleInfosForLocalCapabilities, allow to backup bundle count is : %{public}zu", bundleInfos.size());
615     return bundleInfos;
616 }
617 
GetBundleInfosForIndex(const vector<string> & bundleNames,int32_t userId)618 std::vector<BJsonEntityCaps::BundleInfo> BundleMgrAdapter::GetBundleInfosForIndex(
619     const vector<string> &bundleNames, int32_t userId)
620 {
621     HILOGI("start GetFullBundleInfosForIndex");
622     vector<BJsonEntityCaps::BundleInfo> bundleInfos;
623     auto bms = GetBundleManager();
624     for (auto const &bundleName : bundleNames) {
625         AppExecFwk::BundleInfo installedBundle;
626         std::vector<AppExecFwk::ExtensionAbilityInfo> extensionInfos;
627         bool getBundleSuccess = GetCurBundleExtenionInfo(installedBundle, bundleName, extensionInfos, bms, userId);
628         if (!getBundleSuccess) {
629             HILOGE("Get current extension failed, bundleName:%{public}s", bundleName.c_str());
630             continue;
631         }
632         auto [allToBackup, fullBackupOnly, extName, restoreDeps, supportScene, extraInfo] =
633             GetAllowAndExtName(extensionInfos);
634         if (!allToBackup) {
635             HILOGI("Not allToBackup, bundleName = %{public}s, appIndex = %{public}d",
636                 installedBundle.name.c_str(), installedBundle.appIndex);
637             continue;
638         }
639         bundleInfos.emplace_back(BJsonEntityCaps::BundleInfo {
640             installedBundle.name, installedBundle.appIndex,
641             installedBundle.versionCode, installedBundle.versionName,
642             0, 0, allToBackup, fullBackupOnly,
643             extName, restoreDeps, supportScene, extraInfo});
644     }
645     HILOGI("End, bundleInfos size:%{public}zu", bundleInfos.size());
646     return bundleInfos;
647 }
648 
GetBundleDataSize(const std::string & bundleName,int32_t userId)649 int64_t BundleMgrAdapter::GetBundleDataSize(const std::string &bundleName, int32_t userId)
650 {
651     return GetBundleStats(bundleName, userId);
652 }
653 
CreatBackupEnv(const std::vector<BIncrementalData> & bundleNameList,int32_t userId)654 void BundleMgrAdapter::CreatBackupEnv(const std::vector<BIncrementalData> &bundleNameList, int32_t userId)
655 {
656     HILOGI("CreatBackupEnv start");
657     auto bms = GetBundleManager();
658     for (auto const &bundleNameTime : bundleNameList) {
659         auto bundleName = bundleNameTime.bundleName;
660         if (SAUtils::IsSABundleName(bundleName)) {
661             HILOGI("SA don't need creat env");
662             continue;
663         }
664         AppExecFwk::BundleInfo installedBundle;
665         std::vector<AppExecFwk::ExtensionAbilityInfo> extensionInfos;
666         bool getBundleSuccess = GetCurBundleExtenionInfo(installedBundle, bundleName, extensionInfos, bms, userId);
667         if (!getBundleSuccess) {
668             HILOGE("Failed to get bundle info from bms, bundleName:%{public}s", bundleName.c_str());
669             continue;
670         }
671         struct BJsonEntityCaps::BundleBackupConfigPara backupPara;
672         if (!GetBackupExtConfig(extensionInfos, backupPara)) {
673             HILOGE("No backup extension ability found, bundleName:%{public}s", bundleName.c_str());
674             continue;
675         }
676         if (!CreateIPCInteractionFiles(userId, bundleName, bundleNameTime.lastIncrementalTime, backupPara.includes,
677             backupPara.excludes)) {
678             HILOGE("Create bundleInteraction dir failed, bundleName:%{public}s", bundleName.c_str());
679             continue;
680         }
681     }
682     HILOGI("CreatBackupEnv end");
683 }
684 
GetBundleInfosForAppendBundles(const std::vector<BIncrementalData> & incrementalDataList,int32_t userId)685 std::vector<BJsonEntityCaps::BundleInfo> BundleMgrAdapter::GetBundleInfosForAppendBundles(
686     const std::vector<BIncrementalData> &incrementalDataList, int32_t userId)
687 {
688     vector<BJsonEntityCaps::BundleInfo> bundleInfos;
689     auto bms = GetBundleManager();
690     for (const auto &bundleIncData : incrementalDataList) {
691         auto bundleName = bundleIncData.bundleName;
692         HILOGE("Current bundle name is:%{public}s", bundleName.c_str());
693         AppExecFwk::BundleInfo installedBundle;
694         std::vector<AppExecFwk::ExtensionAbilityInfo> extensionInfos;
695         bool getBundleSuccess = GetCurBundleExtenionInfo(installedBundle, bundleName, extensionInfos, bms, userId);
696         if (!getBundleSuccess) {
697             HILOGE("Failed to get bundle info from bms, bundleName:%{public}s", bundleName.c_str());
698             continue;
699         }
700         struct BJsonEntityCaps::BundleBackupConfigPara backupPara;
701         if (!GetBackupExtConfig(extensionInfos, backupPara)) {
702             HILOGE("No backup extension ability found, bundleName:%{public}s", bundleName.c_str());
703             continue;
704         }
705         bundleInfos.emplace_back(BJsonEntityCaps::BundleInfo {installedBundle.name, installedBundle.appIndex,
706                                                               installedBundle.versionCode,
707                                                               installedBundle.versionName, 0, 0,
708                                                               backupPara.allToBackup, backupPara.fullBackupOnly,
709                                                               backupPara.extensionName,
710                                                               backupPara.restoreDeps, backupPara.supportScene,
711                                                               backupPara.extraInfo});
712     }
713     for (const auto &info : incrementalDataList) {
714         if (SAUtils::IsSABundleName(info.bundleName)) {
715             HILOGE("Current SA name is:%{public}s", info.bundleName.c_str());
716             GetBundleInfoForSA(info.bundleName, bundleInfos);
717         }
718     }
719     return bundleInfos;
720 }
721 } // namespace OHOS::FileManagement::Backup