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 (SAUtils::IsSABundleName(bundleName)) {
123 GetBundleInfoForSA(bundleName, bundleInfos);
124 continue;
125 }
126 AppExecFwk::BundleInfo installedBundle;
127 std::vector<AppExecFwk::ExtensionAbilityInfo> extensionInfos;
128 bool getBundleSuccess = GetCurBundleExtenionInfo(installedBundle, bundleName, extensionInfos, bms, userId);
129 if (!getBundleSuccess) {
130 HILOGE("Get current extension failed");
131 continue;
132 }
133 auto [allToBackup, fullBackupOnly, extName, restoreDeps, supportScene, extraInfo] =
134 GetAllowAndExtName(extensionInfos);
135 int64_t dataSize = 0;
136 if (allToBackup) {
137 dataSize = GetBundleStats(bundleName, userId);
138 }
139 bundleInfos.emplace_back(BJsonEntityCaps::BundleInfo {installedBundle.name, installedBundle.appIndex,
140 installedBundle.versionCode,
141 installedBundle.versionName, dataSize, 0, allToBackup,
142 fullBackupOnly, extName, restoreDeps, supportScene,
143 extraInfo});
144 }
145 HILOGI("End, bundleInfos size:%{public}zu", bundleInfos.size());
146 return bundleInfos;
147 }
148
GetAppGalleryBundleName()149 string BundleMgrAdapter::GetAppGalleryBundleName()
150 {
151 auto bms = GetBundleManager();
152
153 string bundleName = "";
154 auto ret = bms->QueryAppGalleryBundleName(bundleName);
155 if (!ret) {
156 HILOGI("Get App Gallery BundleName fail!");
157 } else {
158 HILOGI("App Gallery BundleName: %{public}s", bundleName.c_str());
159 }
160 return bundleName;
161 }
162
GetBackupExtConfig(const vector<AppExecFwk::ExtensionAbilityInfo> & extensionInfos,BJsonEntityCaps::BundleBackupConfigPara & backupPara)163 static bool GetBackupExtConfig(const vector<AppExecFwk::ExtensionAbilityInfo> &extensionInfos,
164 BJsonEntityCaps::BundleBackupConfigPara &backupPara)
165 {
166 for (auto &&ext : extensionInfos) {
167 if (ext.type != AppExecFwk::ExtensionAbilityType::BACKUP) {
168 continue;
169 }
170 vector<string> out;
171 AppExecFwk::BundleMgrClient client;
172 if (!client.GetResConfigFile(ext, "ohos.extension.backup", out) || out.size() == 0) {
173 HILOGE("Failed to get resconfigfile of bundle, bundle name is:%{public}s", ext.bundleName.c_str());
174 continue;
175 }
176 BJsonCachedEntity<BJsonEntityExtensionConfig> cachedEntity(out[0], ext.bundleName);
177 auto cache = cachedEntity.Structuralize();
178 backupPara.allToBackup = cache.GetAllowToBackupRestore();
179 backupPara.fullBackupOnly = cache.GetFullBackupOnly();
180 backupPara.extensionName = ext.name;
181 backupPara.restoreDeps = cache.GetRestoreDeps();
182 backupPara.supportScene = cache.GetSupportScene();
183 backupPara.extraInfo = cache.GetExtraInfo();
184 backupPara.includes = cache.GetIncludes();
185 backupPara.excludes = cache.GetExcludes();
186 return true;
187 }
188 return false;
189 }
190
CreateIPCInteractionFiles(int32_t userId,const string & bundleName,int64_t lastIncrementalTime,const vector<string> & includes,const vector<string> & excludes)191 static bool CreateIPCInteractionFiles(int32_t userId, const string &bundleName, int64_t lastIncrementalTime,
192 const vector<string> &includes, const vector<string> &excludes)
193 {
194 // backup_sa bundle path
195 BJsonUtil::BundleDetailInfo bundleDetail = BJsonUtil::ParseBundleNameIndexStr(bundleName);
196 string backupSaBundleDir;
197 if (bundleDetail.bundleIndex > 0) {
198 std::string bundleNameIndex = "+clone-" + std::to_string(bundleDetail.bundleIndex) + "+" +
199 bundleDetail.bundleName;
200 backupSaBundleDir = BConstants::BACKUP_PATH_PREFIX + to_string(userId) + BConstants::BACKUP_PATH_SURFFIX +
201 bundleNameIndex + BConstants::FILE_SEPARATOR_CHAR;
202 } else {
203 backupSaBundleDir = BConstants::BACKUP_PATH_PREFIX + to_string(userId) + BConstants::BACKUP_PATH_SURFFIX +
204 bundleDetail.bundleName + BConstants::FILE_SEPARATOR_CHAR;
205 }
206 HILOGI("bundleInteraction dir is:%{public}s", backupSaBundleDir.c_str());
207 if (access(backupSaBundleDir.data(), F_OK) != 0) {
208 int32_t err = mkdir(backupSaBundleDir.data(), S_IRWXU | S_IRWXG);
209 if (err != 0 && errno != EEXIST) {
210 HILOGE("Failed to create folder in backup_sa bundleName:%{public}s, sys err:%{public}d",
211 bundleName.c_str(), errno);
212 return false;
213 }
214 }
215 // backup_sa include/exclude
216 string incExFilePath = backupSaBundleDir + BConstants::BACKUP_INCEXC_SYMBOL + to_string(lastIncrementalTime);
217 ofstream incExcFile;
218 incExcFile.open(incExFilePath.data(), ios::out | ios::trunc);
219 if (!incExcFile.is_open()) {
220 HILOGE("Cannot create incexc file, err = %{public}d", errno);
221 return false;
222 }
223 incExcFile << BConstants::BACKUP_INCLUDE << endl;
224 for (const auto &include : includes) {
225 incExcFile << include << endl;
226 }
227 incExcFile << BConstants::BACKUP_EXCLUDE << endl;
228 for (const auto &exclude : excludes) {
229 incExcFile << exclude << endl;
230 }
231 incExcFile.close();
232
233 // backup_sa stat
234 string statFilePath = backupSaBundleDir + BConstants::BACKUP_STAT_SYMBOL + to_string(lastIncrementalTime);
235 ofstream statFile;
236 statFile.open(statFilePath.data(), ios::out | ios::trunc);
237 if (!statFile.is_open()) {
238 HILOGE("Cannot create stat file");
239 return false;
240 }
241 statFile.close();
242
243 return true;
244 }
245
GenerateBundleStatsIncrease(int32_t userId,const vector<string> & bundleNames,const vector<int64_t> & lastBackTimes,vector<BJsonEntityCaps::BundleInfo> & bundleInfos,vector<BJsonEntityCaps::BundleInfo> & newBundleInfos)246 static bool GenerateBundleStatsIncrease(int32_t userId, const vector<string> &bundleNames,
247 const vector<int64_t> &lastBackTimes, vector<BJsonEntityCaps::BundleInfo> &bundleInfos,
248 vector<BJsonEntityCaps::BundleInfo> &newBundleInfos)
249 {
250 vector<int64_t> pkgFileSizes {};
251 vector<int64_t> incPkgFileSizes {};
252 int32_t err = StorageMgrAdapter::GetBundleStatsForIncrease(userId, bundleNames, lastBackTimes,
253 pkgFileSizes, incPkgFileSizes);
254 if (err != 0) {
255 HILOGE("Failed to get bundleStats result from storage, err = %{public}d", err);
256 return false;
257 }
258 HILOGI("bundleNames size:%{public}zu, pkgFileSizes size:%{public}zu, bundleInfos size:%{public}zu",
259 bundleNames.size(), pkgFileSizes.size(), bundleInfos.size());
260 if (bundleInfos.size() != pkgFileSizes.size()) {
261 HILOGE("The number of bundle is not equal to the number of data records");
262 return false;
263 }
264 for (size_t i = 0; i < bundleInfos.size(); i++) {
265 std::string curBundleName = bundleInfos[i].name;
266 HILOGD("BundleMgrAdapter name for %{public}s", curBundleName.c_str());
267 BJsonEntityCaps::BundleInfo newBundleInfo = {.name = curBundleName,
268 .appIndex = bundleInfos[i].appIndex,
269 .versionCode = bundleInfos[i].versionCode,
270 .versionName = bundleInfos[i].versionName,
271 .spaceOccupied = pkgFileSizes[i],
272 .increSpaceOccupied = incPkgFileSizes[i],
273 .allToBackup = bundleInfos[i].allToBackup,
274 .fullBackupOnly = bundleInfos[i].fullBackupOnly,
275 .extensionName = bundleInfos[i].extensionName,
276 .restoreDeps = bundleInfos[i].restoreDeps,
277 .supportScene = bundleInfos[i].supportScene,
278 .extraInfo = bundleInfos[i].extraInfo};
279 newBundleInfos.emplace_back(newBundleInfo);
280 }
281 return true;
282 }
283
GetBundleInfosForIncremental(const vector<BIncrementalData> & incrementalDataList,int32_t userId)284 vector<BJsonEntityCaps::BundleInfo> BundleMgrAdapter::GetBundleInfosForIncremental(
285 const vector<BIncrementalData> &incrementalDataList, int32_t userId)
286 {
287 vector<std::string> bundleNames;
288 vector<int64_t> incrementalBackTimes;
289 vector<BJsonEntityCaps::BundleInfo> bundleInfos;
290 auto bms = GetBundleManager();
291 for (auto const &bundleNameTime : incrementalDataList) {
292 auto bundleName = bundleNameTime.bundleName;
293 AppExecFwk::BundleInfo installedBundle;
294 std::vector<AppExecFwk::ExtensionAbilityInfo> extensionInfos;
295 bool getBundleSuccess = GetCurBundleExtenionInfo(installedBundle, bundleName, extensionInfos, 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(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 continue;
308 }
309 bundleInfos.emplace_back(BJsonEntityCaps::BundleInfo {installedBundle.name, installedBundle.appIndex,
310 installedBundle.versionCode,
311 installedBundle.versionName, 0, 0,
312 backupPara.allToBackup, backupPara.fullBackupOnly,
313 backupPara.extensionName,
314 backupPara.restoreDeps, backupPara.supportScene,
315 backupPara.extraInfo});
316 if (installedBundle.appIndex > 0) {
317 std::string bundleNameIndex = "+clone-" + std::to_string(installedBundle.appIndex) + "+" +
318 installedBundle.name;
319 bundleNames.emplace_back(bundleNameIndex);
320 } else {
321 bundleNames.emplace_back(bundleName);
322 }
323 incrementalBackTimes.emplace_back(bundleNameTime.lastIncrementalTime);
324 }
325 vector<BJsonEntityCaps::BundleInfo> newBundleInfos {};
326 if (!GenerateBundleStatsIncrease(userId, bundleNames, incrementalBackTimes, bundleInfos, newBundleInfos)) {
327 HILOGE("Failed to get bundleStats result");
328 return {};
329 }
330 HILOGI("BundleMgrAdapter GetBundleInfosForIncremental end ");
331 return newBundleInfos;
332 }
333
GetBundleInfosForIncremental(int32_t userId,const std::vector<BIncrementalData> & extraIncreData)334 vector<BJsonEntityCaps::BundleInfo> BundleMgrAdapter::GetBundleInfosForIncremental(int32_t userId,
335 const std::vector<BIncrementalData> &extraIncreData)
336 {
337 vector<AppExecFwk::BundleInfo> installedBundles;
338 HILOGI("Begin get bundle infos");
339 auto bms = GetBundleManager();
340 if (!bms->GetBundleInfos(AppExecFwk::GET_BUNDLE_WITH_EXTENSION_INFO, installedBundles, userId)) {
341 throw BError(BError::Codes::SA_BROKEN_IPC, "Failed to get bundle infos");
342 }
343
344 vector<BIncrementalData> bundleNames;
345 vector<BJsonEntityCaps::BundleInfo> bundleInfos;
346 HILOGI("Begin get bundle infos");
347 for (auto const &installedBundle : installedBundles) {
348 if (installedBundle.applicationInfo.codePath == HMOS_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] =
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 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 throw BError(BError::Codes::SA_BROKEN_IPC, "Failed to get bundle infos");
386 }
387 vector<string> bundleNames;
388 vector<BJsonEntityCaps::BundleInfo> bundleInfos;
389 for (auto const &installedBundle : installedBundles) {
390 HILOGI("Begin get bundle infos, bundleName = %{public}s", installedBundle.name.data());
391 if (installedBundle.applicationInfo.codePath == HMOS_HAP_CODE_PATH ||
392 installedBundle.applicationInfo.codePath == LINUX_HAP_CODE_PATH) {
393 HILOGI("Unsupported applications, name : %{public}s", installedBundle.name.data());
394 continue;
395 }
396 if (installedBundle.appIndex > 0) {
397 std::string bundleNameIndexInfo = BJsonUtil::BuildBundleNameIndexInfo(installedBundle.name,
398 installedBundle.appIndex);
399 bundleNames.emplace_back(bundleNameIndexInfo);
400 continue;
401 }
402 auto [allToBackup, fullBackupOnly, extName, restoreDeps, supportScene, extraInfo] =
403 GetAllowAndExtName(installedBundle.extensionInfos);
404 if (!allToBackup) {
405 HILOGI("Not allToBackup, bundleName = %{public}s", installedBundle.name.data());
406 bundleInfos.emplace_back(BJsonEntityCaps::BundleInfo {installedBundle.name, installedBundle.appIndex,
407 installedBundle.versionCode, installedBundle.versionName, 0, 0, allToBackup, fullBackupOnly, extName,
408 restoreDeps, supportScene, extraInfo});
409 continue;
410 }
411 bundleNames.emplace_back(installedBundle.name);
412 }
413 auto bundleInfosNew = BundleMgrAdapter::GetBundleInfos(bundleNames, userId);
414 auto bundleInfosSA = BundleMgrAdapter::GetBundleInfosForSA();
415 copy(bundleInfosNew.begin(), bundleInfosNew.end(), back_inserter(bundleInfos));
416 copy(bundleInfosSA.begin(), bundleInfosSA.end(), back_inserter(bundleInfos));
417 HILOGI("End GetFullBundleInfos, bundleInfos size: %{public}zu", bundleInfos.size());
418 return bundleInfos;
419 }
420
GetExtName(string bundleName,int32_t userId)421 string BundleMgrAdapter::GetExtName(string bundleName, int32_t userId)
422 {
423 vector<AppExecFwk::BundleInfo> installedBundles;
424 auto bms = GetBundleManager();
425 if (!bms->GetBundleInfos(AppExecFwk::GET_BUNDLE_WITH_EXTENSION_INFO, installedBundles, userId)) {
426 throw BError(BError::Codes::SA_BROKEN_IPC, "Failed to get bundle infos");
427 }
428 for (auto const &installedBundle : installedBundles) {
429 if (installedBundle.applicationInfo.codePath == HMOS_HAP_CODE_PATH ||
430 installedBundle.applicationInfo.codePath == LINUX_HAP_CODE_PATH) {
431 HILOGI("Unsupported applications, name : %{public}s", installedBundle.name.data());
432 continue;
433 }
434 for (auto ext : installedBundle.extensionInfos) {
435 if (ext.bundleName != bundleName) {
436 continue;
437 }
438 if (ext.type != AppExecFwk::ExtensionAbilityType::BACKUP) {
439 continue;
440 }
441 HILOGI("bundleName: %{public}s, find extName: %{public}s", bundleName.c_str(), ext.name.c_str());
442 return ext.name;
443 }
444 }
445 HILOGI("bundleName: %{public}s , find extName failed", bundleName.c_str());
446 return "BackupExtensionAbility";
447 }
448
GetBundleInfosForSA()449 std::vector<BJsonEntityCaps::BundleInfo> BundleMgrAdapter::GetBundleInfosForSA()
450 {
451 std::vector<int32_t> saIds;
452 vector<BJsonEntityCaps::BundleInfo> saBundleInfos;
453 sptr<ISystemAbilityManager> samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
454 if (!samgrProxy) {
455 HILOGE("SamgrProxy is nullptr");
456 return saBundleInfos;
457 }
458 int32_t ret = samgrProxy->GetExtensionSaIds(BConstants::EXTENSION_BACKUP, saIds);
459 HILOGI("GetExtensionSaIds ret: %{public}d", ret);
460 for (auto saId : saIds) {
461 saBundleInfos.emplace_back(BJsonEntityCaps::BundleInfo {std::to_string(saId), 0, 0, "", 0, 0, true, false,
462 "", "", "", ""});
463 }
464 return saBundleInfos;
465 }
466
GetBundleInfoForSA(std::string bundleName,std::vector<BJsonEntityCaps::BundleInfo> & bundleInfos)467 void BundleMgrAdapter::GetBundleInfoForSA(std::string bundleName, std::vector<BJsonEntityCaps::BundleInfo>& bundleInfos)
468 {
469 HILOGI("SA %{public}s GetBundleInfo begin.", bundleName.c_str());
470 std::vector<int32_t> saIds;
471 vector<BJsonEntityCaps::BundleInfo> saBundleInfos;
472 sptr<ISystemAbilityManager> samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
473 if (!samgrProxy) {
474 HILOGE("SamgrProxy is nullptr");
475 return;
476 }
477 int32_t ret = samgrProxy->GetExtensionSaIds(BConstants::EXTENSION_BACKUP, saIds);
478 if (ret != ERR_OK) {
479 HILOGE("GetExtensionSaIds err,ret %{public}d", ret);
480 return;
481 }
482 if (saIds.empty()) {
483 HILOGE("GetExtensionSaIds result is empty");
484 return;
485 }
486 int32_t saId = std::atoi(bundleName.c_str());
487 if (std::find(saIds.begin(), saIds.end(), saId) == saIds.end()) {
488 HILOGE("SA %{public}d is not surport backup.", saId);
489 return;
490 }
491 bundleInfos.emplace_back(BJsonEntityCaps::BundleInfo {bundleName, 0, 0, "", 0, 0, true, false, "", "", "", ""});
492 HILOGI("SA %{public}s GetBundleInfo end.", bundleName.c_str());
493 }
494
GetCurBundleExtenionInfo(AppExecFwk::BundleInfo & installedBundle,const std::string & bundleName,std::vector<AppExecFwk::ExtensionAbilityInfo> & extensionInfos,sptr<AppExecFwk::IBundleMgr> bms,int32_t userId)495 bool BundleMgrAdapter::GetCurBundleExtenionInfo(AppExecFwk::BundleInfo &installedBundle,
496 const std::string &bundleName, std::vector<AppExecFwk::ExtensionAbilityInfo> &extensionInfos,
497 sptr<AppExecFwk::IBundleMgr> bms, int32_t userId)
498 {
499 BJsonUtil::BundleDetailInfo bundleDetailInfo = BJsonUtil::ParseBundleNameIndexStr(bundleName);
500 int32_t flags = static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE) |
501 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_EXTENSION_ABILITY) |
502 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_METADATA);
503 ErrCode ret = bms->GetCloneBundleInfo(bundleDetailInfo.bundleName, flags, bundleDetailInfo.bundleIndex,
504 installedBundle, userId);
505 if (ret != ERR_OK) {
506 HILOGE("bundleName:%{public}s, ret:%{public}d, current bundle info for backup/restore is empty",
507 bundleName.c_str(), ret);
508 return false;
509 }
510 if (installedBundle.applicationInfo.codePath == HMOS_HAP_CODE_PATH ||
511 installedBundle.applicationInfo.codePath == LINUX_HAP_CODE_PATH) {
512 HILOGE("Unsupported applications, name : %{public}s", installedBundle.name.data());
513 return false;
514 }
515 std::vector<AppExecFwk::HapModuleInfo> hapModuleInfos = installedBundle.hapModuleInfos;
516 for (auto &hapModuleInfo : hapModuleInfos) {
517 extensionInfos.insert(extensionInfos.end(), hapModuleInfo.extensionInfos.begin(),
518 hapModuleInfo.extensionInfos.end());
519 }
520 HILOGI("bundleName:%{public}s, extensionInfos size:%{public}zu", bundleName.c_str(), extensionInfos.size());
521 return true;
522 }
523
IsUser0BundleName(std::string bundleName,int32_t userId)524 bool BundleMgrAdapter::IsUser0BundleName(std::string bundleName, int32_t userId)
525 {
526 auto bms = GetBundleManager();
527 AppExecFwk::BundleInfo installedBundle;
528 BJsonUtil::BundleDetailInfo bundleDetailInfo = BJsonUtil::ParseBundleNameIndexStr(bundleName);
529 int32_t flags = static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE) |
530 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_EXTENSION_ABILITY) |
531 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_METADATA) |
532 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION);
533 ErrCode ret = bms->GetCloneBundleInfo(bundleDetailInfo.bundleName, flags, bundleDetailInfo.bundleIndex,
534 installedBundle, userId);
535 if (ret != ERR_OK) {
536 HILOGE("bundleName:%{public}s, ret:%{public}d, GetBundle Failed from BMS", bundleName.c_str(), ret);
537 return false;
538 }
539 if (installedBundle.applicationInfo.singleton == true) {
540 HILOGI("bundleName:%{public}s is zero user bundle", bundleName.c_str());
541 return true;
542 }
543 HILOGI("bundleName:%{public}s is not zero user bundle", bundleName.c_str());
544 return false;
545 }
546
GetBundleInfosForAppend(const std::vector<BIncrementalData> & list,int32_t userId)547 vector<BJsonEntityCaps::BundleInfo> BundleMgrAdapter::GetBundleInfosForAppend(const std::vector<BIncrementalData> &list,
548 int32_t userId)
549 {
550 auto bundleInfos = BundleMgrAdapter::GetBundleInfosForIncremental(list, userId);
551 for (auto const &info : list) {
552 if (SAUtils::IsSABundleName(info.bundleName)) {
553 GetBundleInfoForSA(info.bundleName, bundleInfos);
554 }
555 }
556 return bundleInfos;
557 }
558 } // namespace OHOS::FileManagement::Backup
559