From ce1f3c7e4dce7a572a48003de523d11b55fde2c2 Mon Sep 17 00:00:00 2001 From: yang-jingbo1985 Date: Fri, 26 Jan 2024 18:38:22 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E9=87=8FGetLocalCapa=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E6=8E=A5=E5=8F=A3=20Signed-off-by:=20yangjingbo10=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I04eebf406c2b3857da42d244c32f932e85dec744 --- .../include/module_external/bms_adapter.h | 14 +- .../include/module_external/sms_adapter.h | 15 +- .../src/module_external/bms_adapter.cpp | 145 ++++++++++++++++++ .../src/module_external/sms_adapter.cpp | 10 ++ .../src/module_ipc/service_incremental.cpp | 42 ++++- .../mock/module_external/bms_adapter_mock.cpp | 9 ++ .../mock/module_external/sms_adapter_mock.cpp | 6 + utils/include/b_json/b_json_entity_caps.h | 9 +- 8 files changed, 246 insertions(+), 4 deletions(-) diff --git a/services/backup_sa/include/module_external/bms_adapter.h b/services/backup_sa/include/module_external/bms_adapter.h index 7af9bedff..af1c849e4 100644 --- a/services/backup_sa/include/module_external/bms_adapter.h +++ b/services/backup_sa/include/module_external/bms_adapter.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Huawei Device Co., Ltd. + * Copyright (c) 2023-2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -21,6 +21,8 @@ #include "b_json/b_json_entity_caps.h" #include "bundlemgr/bundle_mgr_interface.h" +#include "b_incremental_data.h" +#include "istorage_manager.h" namespace OHOS::FileManagement::Backup { class InnerReceiverImpl; @@ -49,6 +51,16 @@ public: * @brief Get app gallery bundle name */ static std::string GetAppGalleryBundleName(); + + /** + * @brief Get the bundle infos object for incremental backup + * + * @param incrementalDataList bundle Name and time list + * @param userId User ID + * @return std::vector + */ + static std::vector GetBundleInfosForIncremental( + const std::vector &incrementalDataList, int32_t userId); }; } // namespace OHOS::FileManagement::Backup #endif // OHOS_FILEMGMT_BACKUP_BUNDLE_MGR_ADAPTER_H diff --git a/services/backup_sa/include/module_external/sms_adapter.h b/services/backup_sa/include/module_external/sms_adapter.h index 0e3b51e78..30b44abd1 100644 --- a/services/backup_sa/include/module_external/sms_adapter.h +++ b/services/backup_sa/include/module_external/sms_adapter.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Huawei Device Co., Ltd. + * Copyright (c) 2023-2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -17,6 +17,8 @@ #define OHOS_FILEMGMT_BACKUP_STORAGE_MGR_ADAPTER_H #include +#include +#include #include "istorage_manager.h" @@ -44,6 +46,17 @@ public: * @param size para data */ static int32_t UpdateMemPara(int32_t size); + + /** + * @brief Get the user storage stats object + * + * @param userId user id + * @param bundleNames + * @param incrementalBackTimes + * @param pkgFileSizes bundle backup file size + */ + static int32_t GetBundleStatsForIncrease(uint32_t userId, const std::vector &bundleNames, + const std::vector &incrementalBackTimes, std::vector &pkgFileSizes); }; } // namespace OHOS::FileManagement::Backup #endif // OHOS_FILEMGMT_BACKUP_STORAGE_MGR_ADAPTER_H \ No newline at end of file diff --git a/services/backup_sa/src/module_external/bms_adapter.cpp b/services/backup_sa/src/module_external/bms_adapter.cpp index a8038634b..067ae0ee6 100644 --- a/services/backup_sa/src/module_external/bms_adapter.cpp +++ b/services/backup_sa/src/module_external/bms_adapter.cpp @@ -14,7 +14,10 @@ */ #include "module_external/bms_adapter.h" +#include "module_external/sms_adapter.h" +#include +#include #include #include "b_error/b_error.h" @@ -169,4 +172,146 @@ string BundleMgrAdapter::GetAppGalleryBundleName() } return bundleName; } + +static bool GetBackupExtConfig(const vector &extensionInfos, + BJsonEntityCaps::BundleBackupConfigPara &backupPara) +{ + for (auto &&ext : extensionInfos) { + if (ext.type != AppExecFwk::ExtensionAbilityType::BACKUP) { + continue; + } + vector out; + AppExecFwk::BundleMgrClient client; + if (!client.GetResConfigFile(ext, "ohos.extension.backup", out) || out.size() == 0) { + throw BError(BError::Codes::SA_INVAL_ARG, "Failed to get resconfigfile of bundle " + ext.bundleName); + } + BJsonCachedEntity cachedEntity(out[0], ext.bundleName); + auto cache = cachedEntity.Structuralize(); + backupPara.allToBackup = cache.GetAllowToBackupRestore(); + backupPara.extensionName = ext.name; + backupPara.restoreDeps = cache.GetRestoreDeps(); + backupPara.supportScene = cache.GetSupportScene(); + backupPara.includes = cache.GetIncludes(); + backupPara.excludes = cache.GetExcludes(); + return true; + } + return false; +} + +static bool CreateIPCInteractionFiles(int32_t userId, const string &bundleName, int64_t lastIncrementalTime, + const vector &includes, const vector &excludes) +{ + // backup_sa bundle path + string backupSaBundleDir = BConstants::BACKUP_PATH_PREFIX + to_string(userId) + BConstants::BACKUP_PATH_SURFFIX + + bundleName + BConstants::FILE_SEPARATOR_CHAR; + if (access(backupSaBundleDir.data(), F_OK) != 0) { + int32_t err = mkdir(backupSaBundleDir.data(), S_IRWXU | S_IRWXG); + if (err != 0) { + HILOGE("Failed to create folder in backup_sa, err = %{public}d", err); + return false; + } + } + // backup_sa include/exclude + string incExFilePath = backupSaBundleDir + BConstants::BACKUP_INCEXC_SYMBOL + to_string(lastIncrementalTime); + ofstream incExcFile; + incExcFile.open(incExFilePath.data(), ios::out | ios::trunc); + if (!incExcFile.is_open()) { + HILOGE("Cannot create incexc file, err = %{public}d", errno); + return false; + } + incExcFile << BConstants::BACKUP_INCLUDE << endl; + for (auto &include : includes) { + incExcFile << include << endl; + } + incExcFile << BConstants::BACKUP_EXCLUDE << endl; + for (auto &exclude : excludes) { + incExcFile << exclude << endl; + } + incExcFile.close(); + + // backup_sa stat + string statFilePath = backupSaBundleDir + BConstants::BACKUP_STAT_SYMBOL + to_string(lastIncrementalTime); + ofstream statFile; + statFile.open(statFilePath.data(), ios::out | ios::trunc); + if (!statFile.is_open()) { + HILOGE("Cannot create stat file"); + return false; + } + statFile.close(); + + return true; +} + +static bool GenerateBundleStatsIncrease(int32_t userId, const vector &bundleNames, + const vector &lastBackTimes, vector &bundleInfos, + vector &newBundleInfos) +{ + vector pkgFileSizes {}; + int32_t err = StorageMgrAdapter::GetBundleStatsForIncrease(userId, bundleNames, lastBackTimes, pkgFileSizes); + if (err != 0) { + HILOGE("Failed to get bundleStats result from storage, err = %{public}d", err); + return false; + } + + for (size_t i = 0; i < bundleInfos.size(); i++) { + HILOGI("BundleMgrAdapter name for %{private}s", bundleInfos[i].name.c_str()); + BJsonEntityCaps::BundleInfo newBundleInfo = {.name = bundleInfos[i].name, + .versionCode = bundleInfos[i].versionCode, + .versionName = bundleInfos[i].versionName, + .spaceOccupied = pkgFileSizes[i], + .allToBackup = bundleInfos[i].allToBackup, + .extensionName = bundleInfos[i].extensionName, + .restoreDeps = bundleInfos[i].restoreDeps, + .supportScene = bundleInfos[i].supportScene}; + newBundleInfos.emplace_back(newBundleInfo); + } + return true; +} + +vector BundleMgrAdapter::GetBundleInfosForIncremental( + const vector &incrementalDataList, int32_t userId) +{ + vector bundleNames; + vector incrementalBackTimes; + vector bundleInfos; + auto bms = GetBundleManager(); + for (auto const &bundleNameTime : incrementalDataList) { + auto bundleName = bundleNameTime.bundleName; + HILOGI("Begin Get bundleName:%{public}s", bundleName.c_str()); + AppExecFwk::BundleInfo installedBundle; + if (!bms->GetBundleInfo(bundleName, AppExecFwk::GET_BUNDLE_WITH_EXTENSION_INFO, installedBundle, userId)) { + throw BError(BError::Codes::SA_BROKEN_IPC, "Failed to get bundle info"); + } + if (installedBundle.applicationInfo.codePath == HMOS_HAP_CODE_PATH || + installedBundle.applicationInfo.codePath == LINUX_HAP_CODE_PATH) { + HILOGI("Unsupported applications, name : %{public}s", installedBundle.name.data()); + continue; + } + struct BJsonEntityCaps::BundleBackupConfigPara backupPara; + if (!GetBackupExtConfig(installedBundle.extensionInfos, backupPara)) { + HILOGE("No backup extension ability found"); + continue; + } + bundleInfos.emplace_back(BJsonEntityCaps::BundleInfo {installedBundle.name, installedBundle.versionCode, + installedBundle.versionName, 0, backupPara.allToBackup, + backupPara.extensionName, backupPara.restoreDeps, + backupPara.supportScene}); + if (!CreateIPCInteractionFiles(userId, bundleName, bundleNameTime.lastIncrementalTime, backupPara.includes, + backupPara.excludes)) { + HILOGE("Failed to write include/exclude files, name : %{public}s", installedBundle.name.data()); + continue; + } + bundleNames.emplace_back(bundleName); + incrementalBackTimes.emplace_back(bundleNameTime.lastIncrementalTime); + } + + vector newBundleInfos {}; + if (!GenerateBundleStatsIncrease(userId, bundleNames, incrementalBackTimes, bundleInfos, newBundleInfos)) { + HILOGE("Failed to get bundleStats result"); + return {}; + } + + HILOGI("BundleMgrAdapter GetBundleInfosForIncremental end "); + return newBundleInfos; +} } // namespace OHOS::FileManagement::Backup diff --git a/services/backup_sa/src/module_external/sms_adapter.cpp b/services/backup_sa/src/module_external/sms_adapter.cpp index a46e870f8..83a23f557 100644 --- a/services/backup_sa/src/module_external/sms_adapter.cpp +++ b/services/backup_sa/src/module_external/sms_adapter.cpp @@ -86,4 +86,14 @@ int32_t StorageMgrAdapter::UpdateMemPara(int32_t size) } return oldSize; } + +int32_t StorageMgrAdapter::GetBundleStatsForIncrease(uint32_t userId, const std::vector &bundleNames, + const std::vector &incrementalBackTimes, std::vector &pkgFileSizes) +{ + auto storageMgr = GetStorageManager(); + if (storageMgr->GetBundleStatsForIncrease(userId, bundleNames, incrementalBackTimes, pkgFileSizes)) { + throw BError(BError::Codes::SA_BROKEN_IPC, "Failed to get user storage stats"); + } + return 0; +} } // namespace OHOS::FileManagement::Backup diff --git a/services/backup_sa/src/module_ipc/service_incremental.cpp b/services/backup_sa/src/module_ipc/service_incremental.cpp index 1d76a877f..ecac75077 100644 --- a/services/backup_sa/src/module_ipc/service_incremental.cpp +++ b/services/backup_sa/src/module_ipc/service_incremental.cpp @@ -74,7 +74,47 @@ ErrCode Service::Release() UniqueFd Service::GetLocalCapabilitiesIncremental(const std::vector &bundleNames) { - return UniqueFd(-EPERM); + try { + HILOGI("Begin"); + /* + Only called by restore app before InitBackupSession, + so there must be set init userId. + */ + session_->IncreaseSessionCnt(); + session_->SetSessionUserId(GetUserIdDefault()); + VerifyCaller(); + string path = BConstants::GetSaBundleBackupRootDir(session_->GetSessionUserId()); + BExcepUltils::VerifyPath(path, false); + UniqueFd fd(open(path.data(), O_TMPFILE | O_RDWR, S_IRUSR | S_IWUSR)); + if (fd < 0) { + HILOGE("GetLocalCapabilitiesIncremental: open file failed, err = %{public}d", errno); + session_->DecreaseSessionCnt(); + return UniqueFd(-ENOENT); + } + BJsonCachedEntity cachedEntity(move(fd)); + auto cache = cachedEntity.Structuralize(); + + cache.SetSystemFullName(GetOSFullName()); + cache.SetDeviceType(GetDeviceType()); + auto bundleInfos = BundleMgrAdapter::GetBundleInfosForIncremental(bundleNames, session_->GetSessionUserId()); + cache.SetBundleInfos(bundleInfos); + cachedEntity.Persist(); + HILOGI("Service GetLocalCapabilitiesIncremental persist"); + session_->DecreaseSessionCnt(); + return move(cachedEntity.GetFd()); + } catch (const BError &e) { + session_->DecreaseSessionCnt(); + HILOGE("GetLocalCapabilitiesIncremental failed, errCode = %{public}d", e.GetCode()); + return UniqueFd(-e.GetCode()); + } catch (const exception &e) { + session_->DecreaseSessionCnt(); + HILOGI("Catched an unexpected low-level exception %{public}s", e.what()); + return UniqueFd(-EPERM); + } catch (...) { + session_->DecreaseSessionCnt(); + HILOGI("Unexpected exception"); + return UniqueFd(-EPERM); + } } ErrCode Service::InitIncrementalBackupSession(sptr remote) diff --git a/tests/mock/module_external/bms_adapter_mock.cpp b/tests/mock/module_external/bms_adapter_mock.cpp index 5b9b776fa..01fa1b898 100644 --- a/tests/mock/module_external/bms_adapter_mock.cpp +++ b/tests/mock/module_external/bms_adapter_mock.cpp @@ -48,4 +48,13 @@ string BundleMgrAdapter::GetAppGalleryBundleName() { return ""; } + +vector BundleMgrAdapter::GetBundleInfosForIncremental( + const vector &incrementalDataList, int32_t userId) +{ + vector bundleInfos; + bundleInfos.emplace_back( + BJsonEntityCaps::BundleInfo {"com.example.app2backup", {}, {}, 0, true, "com.example.app2backup"}); + return bundleInfos; +} } // namespace OHOS::FileManagement::Backup diff --git a/tests/mock/module_external/sms_adapter_mock.cpp b/tests/mock/module_external/sms_adapter_mock.cpp index cafd6c621..a9f503746 100644 --- a/tests/mock/module_external/sms_adapter_mock.cpp +++ b/tests/mock/module_external/sms_adapter_mock.cpp @@ -29,4 +29,10 @@ int32_t StorageMgrAdapter::UpdateMemPara(int32_t size) { return 0; } + +int32_t StorageMgrAdapter::GetBundleStatsForIncrease(uint32_t userId, const std::vector &bundleNames, + const std::vector &incrementalBackTimes, std::vector &pkgFileSizes) +{ + return 0; +} } // namespace OHOS::FileManagement::Backup diff --git a/utils/include/b_json/b_json_entity_caps.h b/utils/include/b_json/b_json_entity_caps.h index f8e86a7d0..ef7ce2309 100644 --- a/utils/include/b_json/b_json_entity_caps.h +++ b/utils/include/b_json/b_json_entity_caps.h @@ -32,7 +32,14 @@ public: std::string restoreDeps; std::string supportScene; }; - + struct BundleBackupConfigPara { + bool allToBackup; + std::string extensionName; + std::string restoreDeps; + std::string supportScene; + std::vector includes; + std::vector excludes; + }; public: void SetSystemFullName(std::string systemFullName) { -- Gitee