mirror of
https://gitee.com/openharmony/filemanagement_app_file_service
synced 2024-11-23 16:10:07 +00:00
PublishFile rebuild
issue: https://gitee.com/openharmony/filemanagement_app_file_service/issues/I9EIIW Signed-off-by: hunili <lihucheng2@huawei.com>
This commit is contained in:
parent
78224ccbb3
commit
cfd68acc03
@ -24,6 +24,7 @@
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "b_json/b_json_entity_extension_config.h"
|
||||
#include "b_json/b_json_entity_ext_manage.h"
|
||||
#include "b_json/b_report_entity.h"
|
||||
#include "ext_backup_js.h"
|
||||
#include "ext_extension_stub.h"
|
||||
@ -83,9 +84,8 @@ private:
|
||||
/**
|
||||
* @brief incremental restore
|
||||
*
|
||||
* @param fileName name of the file that to be untar
|
||||
*/
|
||||
int DoIncrementalRestore(const string &fileName);
|
||||
int DoIncrementalRestore();
|
||||
|
||||
/** @brief clear backup restore data */
|
||||
void DoClear();
|
||||
@ -117,7 +117,7 @@ private:
|
||||
* @brief Executing Restoration Tasks Asynchronously
|
||||
*
|
||||
*/
|
||||
void AsyncTaskRestore();
|
||||
void AsyncTaskRestore(std::set<std::string> fileSet, const std::vector<ExtManageInfo> extManageInfo);
|
||||
|
||||
/**
|
||||
* @brief Executing Incremental Restoration Tasks Asynchronously
|
||||
@ -178,7 +178,6 @@ private:
|
||||
private:
|
||||
std::shared_mutex lock_;
|
||||
std::shared_ptr<ExtBackup> extension_;
|
||||
std::vector<std::string> tars_;
|
||||
std::string backupInfo_;
|
||||
OHOS::ThreadPool threadPool_;
|
||||
};
|
||||
|
@ -44,8 +44,6 @@
|
||||
#include "b_filesystem/b_file.h"
|
||||
#include "b_filesystem/b_file_hash.h"
|
||||
#include "b_json/b_json_cached_entity.h"
|
||||
#include "b_json/b_json_entity_ext_manage.h"
|
||||
#include "b_json/b_report_entity.h"
|
||||
#include "b_tarball/b_tarball_factory.h"
|
||||
#include "filemgmt_libhilog.h"
|
||||
#include "hitrace_meter.h"
|
||||
@ -71,6 +69,31 @@ const int64_t DEFAULT_SLICE_SIZE = 100 * 1024 * 1024; // 分片文件大小为10
|
||||
const uint32_t MAX_FILE_COUNT = 6000; // 单个tar包最多包含6000个文件
|
||||
} // namespace
|
||||
|
||||
static std::set<std::string> GetIdxFileData()
|
||||
{
|
||||
UniqueFd idxFd(open(INDEX_FILE_RESTORE.data(), O_RDONLY));
|
||||
if (idxFd < 0) {
|
||||
HILOGE("Failed to open idxFile = %{private}s, err = %{public}d", INDEX_FILE_RESTORE.c_str(), errno);
|
||||
return std::set<std::string>();
|
||||
}
|
||||
BJsonCachedEntity<BJsonEntityExtManage> cachedEntity(std::move(idxFd));
|
||||
auto cache = cachedEntity.Structuralize();
|
||||
return cache.GetExtManage();
|
||||
}
|
||||
|
||||
static std::vector<ExtManageInfo> GetExtManageInfo()
|
||||
{
|
||||
string filePath = BExcepUltils::Canonicalize(INDEX_FILE_RESTORE);
|
||||
UniqueFd idxFd(open(filePath.data(), O_RDONLY));
|
||||
if (idxFd < 0) {
|
||||
HILOGE("Failed to open cano_idxFile = %{private}s, err = %{public}d", filePath.c_str(), errno);
|
||||
return {};
|
||||
}
|
||||
BJsonCachedEntity<BJsonEntityExtManage> cachedEntity(std::move(idxFd));
|
||||
auto cache = cachedEntity.Structuralize();
|
||||
return cache.GetExtManageInfo();
|
||||
}
|
||||
|
||||
void BackupExtExtension::VerifyCaller()
|
||||
{
|
||||
uint32_t tokenCaller = IPCSkeleton::GetCallingTokenID();
|
||||
@ -326,45 +349,7 @@ static ErrCode BigFileReady(sptr<IService> proxy)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool IsAllFileReceived(vector<string> tars, bool isSpeicalVersion)
|
||||
{
|
||||
HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
|
||||
// 是否已收到索引文件
|
||||
HILOGI("Start check All file is received");
|
||||
if (isSpeicalVersion) {
|
||||
HILOGI("Check if manage.json is received for SpeicalVersion.");
|
||||
string manageFileName = INDEX_FILE_RESTORE;
|
||||
if (manageFileName.front() == BConstants::FILE_SEPARATOR_CHAR) {
|
||||
manageFileName = manageFileName.substr(1);
|
||||
}
|
||||
if (find(tars.begin(), tars.end(), manageFileName) == tars.end()) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
HILOGI("Check if manage.json is received.");
|
||||
if (find(tars.begin(), tars.end(), string(BConstants::EXT_BACKUP_MANAGE)) == tars.end()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 获取索引文件内容
|
||||
HILOGI("Start Parse manage.json file");
|
||||
BJsonCachedEntity<BJsonEntityExtManage> cachedEntity(UniqueFd(open(INDEX_FILE_RESTORE.data(), O_RDONLY)));
|
||||
auto cache = cachedEntity.Structuralize();
|
||||
set<string> info = cache.GetExtManage();
|
||||
|
||||
// 从数量上判断是否已经全部收到
|
||||
if (tars.size() <= info.size()) {
|
||||
HILOGE("tars count is not equals info count");
|
||||
return false;
|
||||
}
|
||||
HILOGI("compare tars and info, tars size:%zu, info size:%zu", tars.size(), info.size());
|
||||
// 逐个判断是否收到
|
||||
sort(tars.begin(), tars.end());
|
||||
return includes(tars.begin(), tars.end(), info.begin(), info.end());
|
||||
}
|
||||
|
||||
ErrCode BackupExtExtension::PublishFile(const string &fileName)
|
||||
ErrCode BackupExtExtension::PublishFile(const std::string &fileName)
|
||||
{
|
||||
HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
|
||||
HILOGI("Begin publish file. fileName is %{public}s", fileName.data());
|
||||
@ -373,26 +358,9 @@ ErrCode BackupExtExtension::PublishFile(const string &fileName)
|
||||
throw BError(BError::Codes::EXT_INVAL_ARG, "Action is invalid");
|
||||
}
|
||||
VerifyCaller();
|
||||
// 是否指定克隆模式
|
||||
bool isSpeicalVersion = extension_->SpeicalVersionForCloneAndCloud();
|
||||
|
||||
string path = string(BConstants::PATH_BUNDLE_BACKUP_HOME).append(BConstants::SA_BUNDLE_BACKUP_RESTORE);
|
||||
string tarName = isSpeicalVersion ? fileName : path + fileName;
|
||||
{
|
||||
BExcepUltils::VerifyPath(tarName, !isSpeicalVersion);
|
||||
unique_lock<shared_mutex> lock(lock_);
|
||||
if (find(tars_.begin(), tars_.end(), fileName) != tars_.end() || access(tarName.data(), F_OK) != 0) {
|
||||
throw BError(BError::Codes::EXT_INVAL_ARG, "The file does not exist");
|
||||
}
|
||||
tars_.push_back(fileName);
|
||||
if (!IsAllFileReceived(tars_, isSpeicalVersion)) {
|
||||
HILOGE("Check all file is received failed");
|
||||
return ERR_OK;
|
||||
}
|
||||
}
|
||||
// 异步执行解压操作
|
||||
if (extension_->AllowToBackupRestore()) {
|
||||
AsyncTaskRestore();
|
||||
AsyncTaskRestore(GetIdxFileData(), GetExtManageInfo());
|
||||
}
|
||||
HILOGE("End publish file");
|
||||
return ERR_OK;
|
||||
@ -419,27 +387,9 @@ ErrCode BackupExtExtension::PublishIncrementalFile(const string &fileName)
|
||||
throw BError(BError::Codes::EXT_INVAL_ARG, "Action is invalid");
|
||||
}
|
||||
VerifyCaller();
|
||||
|
||||
bool isSpeicalVersion = extension_->SpeicalVersionForCloneAndCloud();
|
||||
|
||||
string path = string(BConstants::PATH_BUNDLE_BACKUP_HOME).append(BConstants::SA_BUNDLE_BACKUP_RESTORE);
|
||||
string tarName = isSpeicalVersion ? fileName : path + fileName;
|
||||
{
|
||||
BExcepUltils::VerifyPath(tarName, !isSpeicalVersion);
|
||||
unique_lock<shared_mutex> lock(lock_);
|
||||
if (find(tars_.begin(), tars_.end(), fileName) != tars_.end() || access(tarName.data(), F_OK) != 0) {
|
||||
throw BError(BError::Codes::EXT_INVAL_ARG, "The file does not exist");
|
||||
}
|
||||
tars_.push_back(fileName);
|
||||
if (!IsAllFileReceived(tars_, isSpeicalVersion)) {
|
||||
HILOGE("Check all files received failed");
|
||||
return ERR_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// 异步执行解压操作
|
||||
if (extension_->AllowToBackupRestore()) {
|
||||
if (isSpeicalVersion) {
|
||||
if (extension_->SpeicalVersionForCloneAndCloud()) {
|
||||
HILOGI("Create task for Incremental SpecialVersion");
|
||||
AsyncTaskIncreRestoreSpecialVersion();
|
||||
} else {
|
||||
@ -478,18 +428,15 @@ ErrCode BackupExtExtension::HandleBackup()
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool IsUserTar(const string &tarFile, const string &indexFile)
|
||||
static bool IsUserTar(const string &tarFile, const std::vector<ExtManageInfo> &extManageInfo)
|
||||
{
|
||||
HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
|
||||
if (tarFile.empty()) {
|
||||
return false;
|
||||
}
|
||||
string filePath = BExcepUltils::Canonicalize(indexFile);
|
||||
BJsonCachedEntity<BJsonEntityExtManage> cachedEntity(UniqueFd(open(filePath.data(), O_RDONLY)));
|
||||
auto cache = cachedEntity.Structuralize();
|
||||
auto info = cache.GetExtManageInfo();
|
||||
auto iter = find_if(info.begin(), info.end(), [&tarFile](const auto &item) { return item.hashName == tarFile; });
|
||||
if (iter != info.end()) {
|
||||
auto iter = find_if(extManageInfo.begin(), extManageInfo.end(),
|
||||
[&tarFile](const auto &item) { return item.hashName == tarFile; });
|
||||
if (iter != extManageInfo.end()) {
|
||||
HILOGI("tarFile:%{public}s isUserTar:%{public}d", tarFile.data(), iter->isUserTar);
|
||||
return iter->isUserTar;
|
||||
}
|
||||
@ -611,25 +558,30 @@ static unordered_map<string, struct ReportFileInfo> GetTarIncludes(const string
|
||||
return rp.GetReportInfos();
|
||||
}
|
||||
|
||||
int BackupExtExtension::DoIncrementalRestore(const string &fileName)
|
||||
int BackupExtExtension::DoIncrementalRestore()
|
||||
{
|
||||
HILOGI("Do incremental restore");
|
||||
if (extension_->GetExtensionAction() != BConstants::ExtensionAction::RESTORE) {
|
||||
return EPERM;
|
||||
}
|
||||
// REM: 给定version
|
||||
// REM: 解压启动Extension时即挂载好的备份目录中的数据
|
||||
string path = string(BConstants::PATH_BUNDLE_BACKUP_HOME).append(BConstants::SA_BUNDLE_BACKUP_RESTORE);
|
||||
string tarName = path + fileName;
|
||||
auto fileSet = GetIdxFileData();
|
||||
auto extManageInfo = GetExtManageInfo();
|
||||
for (auto item : fileSet) { // 处理要解压的tar文件
|
||||
if (ExtractFileExt(item) == "tar" && !IsUserTar(item, extManageInfo)) {
|
||||
if (extension_->GetExtensionAction() != BConstants::ExtensionAction::RESTORE) {
|
||||
return EPERM;
|
||||
}
|
||||
// REM: 给定version
|
||||
// REM: 解压启动Extension时即挂载好的备份目录中的数据
|
||||
string path = string(BConstants::PATH_BUNDLE_BACKUP_HOME).append(BConstants::SA_BUNDLE_BACKUP_RESTORE);
|
||||
string tarName = path + item;
|
||||
|
||||
// 当用户指定fullBackupOnly字段或指定版本的恢复,解压目录当前在/backup/restore
|
||||
if (extension_->SpeicalVersionForCloneAndCloud() || extension_->UseFullBackupOnly()) {
|
||||
UntarFile::GetInstance().IncrementalUnPacket(tarName, path, GetTarIncludes(tarName));
|
||||
} else {
|
||||
UntarFile::GetInstance().IncrementalUnPacket(tarName, "/", GetTarIncludes(tarName));
|
||||
// 当用户指定fullBackupOnly字段或指定版本的恢复,解压目录当前在/backup/restore
|
||||
if (extension_->SpeicalVersionForCloneAndCloud() || extension_->UseFullBackupOnly()) {
|
||||
UntarFile::GetInstance().IncrementalUnPacket(tarName, path, GetTarIncludes(tarName));
|
||||
} else {
|
||||
UntarFile::GetInstance().IncrementalUnPacket(tarName, "/", GetTarIncludes(tarName));
|
||||
}
|
||||
HILOGI("Application recovered successfully, package path is %{public}s", tarName.c_str());
|
||||
}
|
||||
}
|
||||
HILOGI("Application recovered successfully, package path is %{public}s", tarName.c_str());
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
@ -833,8 +785,9 @@ static void DeleteBackupTars()
|
||||
auto cache = cachedEntity.Structuralize();
|
||||
auto info = cache.GetExtManage();
|
||||
auto path = string(BConstants::PATH_BUNDLE_BACKUP_HOME).append(BConstants::SA_BUNDLE_BACKUP_RESTORE);
|
||||
auto extManageInfo = GetExtManageInfo();
|
||||
for (auto &item : info) {
|
||||
if (ExtractFileExt(item) != "tar" || IsUserTar(item, INDEX_FILE_RESTORE)) {
|
||||
if (ExtractFileExt(item) != "tar" || IsUserTar(item, extManageInfo)) {
|
||||
continue;
|
||||
}
|
||||
string tarPath = path + item;
|
||||
@ -855,8 +808,9 @@ static void DeleteBackupIncrementalTars()
|
||||
auto cache = cachedEntity.Structuralize();
|
||||
auto info = cache.GetExtManage();
|
||||
auto path = string(BConstants::PATH_BUNDLE_BACKUP_HOME).append(BConstants::SA_BUNDLE_BACKUP_RESTORE);
|
||||
auto extManageInfo = GetExtManageInfo();
|
||||
for (auto &item : info) {
|
||||
if (ExtractFileExt(item) != "tar" || IsUserTar(item, INDEX_FILE_RESTORE)) {
|
||||
if (ExtractFileExt(item) != "tar" || IsUserTar(item, extManageInfo)) {
|
||||
continue;
|
||||
}
|
||||
string tarPath = path + item;
|
||||
@ -878,9 +832,10 @@ static void DeleteBackupIncrementalTars()
|
||||
}
|
||||
}
|
||||
|
||||
void BackupExtExtension::AsyncTaskRestore()
|
||||
void BackupExtExtension::AsyncTaskRestore(std::set<std::string> fileSet,
|
||||
const std::vector<ExtManageInfo> extManageInfo)
|
||||
{
|
||||
auto task = [obj {wptr<BackupExtExtension>(this)}, tars {tars_}]() {
|
||||
auto task = [obj {wptr<BackupExtExtension>(this)}, fileSet {fileSet}, extManageInfo {extManageInfo}]() {
|
||||
auto ptr = obj.promote();
|
||||
BExcepUltils::BAssert(ptr, BError::Codes::EXT_BROKEN_FRAMEWORK, "Ext extension handle have already released");
|
||||
try {
|
||||
@ -895,8 +850,9 @@ void BackupExtExtension::AsyncTaskRestore()
|
||||
}
|
||||
return;
|
||||
}
|
||||
for (auto item : tars) { // 处理要解压的tar文件
|
||||
if (ExtractFileExt(item) == "tar" && !IsUserTar(item, INDEX_FILE_RESTORE)) {
|
||||
// 解压
|
||||
for (auto item : fileSet) { // 处理要解压的tar文件
|
||||
if (ExtractFileExt(item) == "tar" && !IsUserTar(item, extManageInfo)) {
|
||||
ret = ptr->DoRestore(item);
|
||||
}
|
||||
}
|
||||
@ -937,7 +893,7 @@ void BackupExtExtension::AsyncTaskRestore()
|
||||
|
||||
void BackupExtExtension::AsyncTaskIncrementalRestore()
|
||||
{
|
||||
auto task = [obj {wptr<BackupExtExtension>(this)}, tars {tars_}]() {
|
||||
auto task = [obj {wptr<BackupExtExtension>(this)}]() {
|
||||
auto ptr = obj.promote();
|
||||
BExcepUltils::BAssert(ptr, BError::Codes::EXT_BROKEN_FRAMEWORK,
|
||||
"Ext extension handle have been already released");
|
||||
@ -945,12 +901,7 @@ void BackupExtExtension::AsyncTaskIncrementalRestore()
|
||||
"extension handle have been already released");
|
||||
try {
|
||||
// 解压
|
||||
int ret = ERR_OK;
|
||||
for (auto item : tars) { // 处理要解压的tar文件
|
||||
if (ExtractFileExt(item) == "tar" && !IsUserTar(item, INDEX_FILE_RESTORE)) {
|
||||
ret = ptr->DoIncrementalRestore(item);
|
||||
}
|
||||
}
|
||||
int ret = ptr->DoIncrementalRestore();
|
||||
// 恢复用户tar包以及大文件
|
||||
// 目的地址是否需要拼接path(临时目录),FullBackupOnly为true并且非特殊场景
|
||||
bool appendTargetPath =
|
||||
@ -992,7 +943,7 @@ void BackupExtExtension::AsyncTaskIncrementalRestore()
|
||||
|
||||
void BackupExtExtension::AsyncTaskIncreRestoreSpecialVersion()
|
||||
{
|
||||
auto task = [obj {wptr<BackupExtExtension>(this)}, tars {tars_}]() {
|
||||
auto task = [obj {wptr<BackupExtExtension>(this)}]() {
|
||||
auto ptr = obj.promote();
|
||||
BExcepUltils::BAssert(ptr, BError::Codes::EXT_BROKEN_FRAMEWORK,
|
||||
"Ext extension handle have been already released");
|
||||
@ -1147,7 +1098,6 @@ void BackupExtExtension::DoClear()
|
||||
ForceRemoveDirectory(
|
||||
string(BConstants::PATH_BUNDLE_BACKUP_HOME_EL1).append(BConstants::SA_BUNDLE_BACKUP_RESTORE));
|
||||
unique_lock<shared_mutex> lock(lock_);
|
||||
tars_.clear();
|
||||
} catch (...) {
|
||||
HILOGI("Failed to clear");
|
||||
}
|
||||
|
@ -482,7 +482,10 @@ ErrCode Service::PublishFile(const BFileInfo &fileInfo)
|
||||
HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
|
||||
try {
|
||||
VerifyCaller(IServiceReverse::Scenario::RESTORE);
|
||||
|
||||
if (!fileInfo.fileName.empty()) {
|
||||
HILOGE("Forbit to use publishFile with fileName for App");
|
||||
return EPERM;
|
||||
}
|
||||
auto backUpConnection = session_->GetExtConnection(fileInfo.owner);
|
||||
|
||||
auto proxy = backUpConnection->GetBackupExtProxy();
|
||||
|
@ -181,6 +181,10 @@ ErrCode Service::PublishIncrementalFile(const BFileInfo &fileInfo)
|
||||
try {
|
||||
VerifyCaller(IServiceReverse::Scenario::RESTORE);
|
||||
HILOGI("Start get ExtConnection, bundleName:%{public}s", fileInfo.owner.c_str());
|
||||
if (!fileInfo.fileName.empty()) {
|
||||
HILOGE("Forbit to use PublishIncrementalFile with fileName for App");
|
||||
return EPERM;
|
||||
}
|
||||
auto backUpConnection = session_->GetExtConnection(fileInfo.owner);
|
||||
auto proxy = backUpConnection->GetBackupExtProxy();
|
||||
if (!proxy) {
|
||||
|
@ -494,11 +494,11 @@ HWTEST_F(ServiceProxyTest, SUB_Service_proxy_PublishIncrementalFile_0100, testin
|
||||
.WillOnce(Return(EPERM));
|
||||
|
||||
string bundleName = "com.example.app2backup";
|
||||
string fileName = "1.tar";
|
||||
string fileName = "";
|
||||
BFileInfo fileInfo(bundleName, fileName, -1);
|
||||
int32_t result = proxy_->PublishIncrementalFile(fileInfo);
|
||||
EXPECT_EQ(result, BError(BError::Codes::OK));
|
||||
|
||||
fileName = "test";
|
||||
result = proxy_->PublishIncrementalFile(fileInfo);
|
||||
EXPECT_NE(result, BError(BError::Codes::OK));
|
||||
GTEST_LOG_(INFO) << "ServiceProxyTest-end SUB_Service_proxy_PublishIncrementalFile_0100";
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022-2023 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2022-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
|
||||
@ -189,7 +189,7 @@ HWTEST_F(ServiceTest, SUB_Service_PublishFile_0100, testing::ext::TestSize.Level
|
||||
try {
|
||||
ErrCode ret = Init(IServiceReverse::Scenario::RESTORE);
|
||||
EXPECT_EQ(ret, BError(BError::Codes::OK));
|
||||
BFileInfo fileInfo {BUNDLE_NAME, FILE_NAME, 0};
|
||||
BFileInfo fileInfo {BUNDLE_NAME, "", 0};
|
||||
ret = servicePtr_->PublishFile(fileInfo);
|
||||
EXPECT_EQ(ret, BError(BError::Codes::OK));
|
||||
GTEST_LOG_(INFO) << "ServiceTest-PublishFile Branches";
|
||||
@ -218,13 +218,13 @@ HWTEST_F(ServiceTest, SUB_Service_PublishFile_0101, testing::ext::TestSize.Level
|
||||
try {
|
||||
ErrCode ret = Init(IServiceReverse::Scenario::RESTORE);
|
||||
EXPECT_EQ(ret, BError(BError::Codes::OK));
|
||||
BFileInfo fileInfo {BUNDLE_NAME, FILE_NAME, 0};
|
||||
BFileInfo fileInfo {BUNDLE_NAME, "", 0};
|
||||
ret = servicePtr_->PublishFile(fileInfo);
|
||||
EXPECT_EQ(ret, BError(BError::Codes::OK));
|
||||
GTEST_LOG_(INFO) << "ServiceTest-PublishFile Branches";
|
||||
fileInfo.fileName = "/data/storage/el2/restore/bundle.hap";
|
||||
ret = servicePtr_->PublishFile(fileInfo);
|
||||
EXPECT_EQ(ret, BError(BError::Codes::OK));
|
||||
EXPECT_NE(ret, BError(BError::Codes::OK));
|
||||
} catch (...) {
|
||||
EXPECT_TRUE(false);
|
||||
GTEST_LOG_(INFO) << "ServiceTest-an exception occurred by PublishFile.";
|
||||
@ -247,13 +247,12 @@ HWTEST_F(ServiceTest, SUB_Service_PublishFile_0102, testing::ext::TestSize.Level
|
||||
try {
|
||||
ErrCode ret = Init(IServiceReverse::Scenario::RESTORE);
|
||||
EXPECT_EQ(ret, BError(BError::Codes::OK));
|
||||
BFileInfo fileInfo {BUNDLE_NAME, FILE_NAME, 0};
|
||||
BFileInfo fileInfo {BUNDLE_NAME, "", 0};
|
||||
ret = servicePtr_->PublishFile(fileInfo);
|
||||
EXPECT_EQ(ret, BError(BError::Codes::OK));
|
||||
GTEST_LOG_(INFO) << "ServiceTest-PublishFile Branches";
|
||||
string bundleName = "";
|
||||
ret = servicePtr_->PublishFile(fileInfo);
|
||||
EXPECT_EQ(ret, BError(BError::Codes::OK));
|
||||
EXPECT_NE(ret, BError(BError::Codes::OK));
|
||||
} catch (...) {
|
||||
EXPECT_TRUE(false);
|
||||
GTEST_LOG_(INFO) << "ServiceTest-an exception occurred by PublishFile.";
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022-2023 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2022-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
|
||||
@ -19,6 +19,8 @@
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "b_resources/b_constants.h"
|
||||
#include "directory_ex.h"
|
||||
#include "tools_op.h"
|
||||
|
||||
namespace OHOS::FileManagement::Backup {
|
||||
@ -149,4 +151,55 @@ HWTEST_F(ToolsOpTest, SUB_backup_tools_op_0400, testing::ext::TestSize.Level1)
|
||||
}
|
||||
GTEST_LOG_(INFO) << "ToolsOpTest-end SUB_backup_tools_op_0400";
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.number: SUB_backup_tools_op_0500
|
||||
* @tc.name: SUB_backup_tools_op_0500
|
||||
* @tc.desc: 测试Execute分支
|
||||
* @tc.size: MEDIUM
|
||||
* @tc.type: FUNC
|
||||
* @tc.level Level 1
|
||||
* @tc.require: I6F3GV
|
||||
*/
|
||||
HWTEST_F(ToolsOpTest, SUB_backup_tools_op_0500, testing::ext::TestSize.Level1)
|
||||
{
|
||||
GTEST_LOG_(INFO) << "ToolsOpTest-begin SUB_backup_tools_op_0500";
|
||||
try {
|
||||
std::string bundleName = "test";
|
||||
std::string wholePath = string(BConstants::BACKUP_TOOL_RECEIVE_DIR) + bundleName;
|
||||
std::string incrementalpath = string(BConstants::BACKUP_TOOL_INCREMENTAL_RECEIVE_DIR) + bundleName;
|
||||
if (access(incrementalpath.c_str(), F_OK) == 0) {
|
||||
ForceRemoveDirectory(incrementalpath.data());
|
||||
}
|
||||
int result = ToolsOp::GetFIleNums(bundleName, false);
|
||||
EXPECT_TRUE(result == DEFAULT_ERR_NUMBER);
|
||||
if (access(wholePath.c_str(), F_OK) == 0) {
|
||||
ForceRemoveDirectory(wholePath.data());
|
||||
}
|
||||
result = ToolsOp::GetFIleNums(bundleName, true);
|
||||
EXPECT_TRUE(result == DEFAULT_ERR_NUMBER);
|
||||
|
||||
|
||||
if (access(incrementalpath.c_str(), F_OK) != 0) {
|
||||
ForceCreateDirectory(incrementalpath.data());
|
||||
}
|
||||
result = ToolsOp::GetFIleNums(bundleName, false);
|
||||
EXPECT_TRUE(result == 0);
|
||||
if (access(wholePath.c_str(), F_OK) != 0) {
|
||||
ForceCreateDirectory(wholePath.data());
|
||||
}
|
||||
result = ToolsOp::GetFIleNums(bundleName, true);
|
||||
EXPECT_TRUE(result == 0);
|
||||
if (access(incrementalpath.c_str(), F_OK) == 0) {
|
||||
ForceRemoveDirectory(incrementalpath.data());
|
||||
}
|
||||
if (access(wholePath.c_str(), F_OK) != 0) {
|
||||
ForceCreateDirectory(wholePath.data());
|
||||
}
|
||||
} catch (...) {
|
||||
EXPECT_TRUE(false);
|
||||
GTEST_LOG_(INFO) << "ToolsOpTest-an exception occurred by construction.";
|
||||
}
|
||||
GTEST_LOG_(INFO) << "ToolsOpTest-end SUB_backup_tools_op_0500";
|
||||
}
|
||||
} // namespace OHOS::FileManagement::Backup
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022-2023 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2022-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
|
||||
@ -16,6 +16,7 @@
|
||||
#ifndef OHOS_FILEMGMT_BACKUP_TOOLS_OP_H
|
||||
#define OHOS_FILEMGMT_BACKUP_TOOLS_OP_H
|
||||
|
||||
#include <dirent.h>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <string>
|
||||
@ -23,6 +24,7 @@
|
||||
#include <vector>
|
||||
|
||||
namespace OHOS::FileManagement::Backup {
|
||||
const int DEFAULT_ERR_NUMBER = -1;
|
||||
class ToolsOp {
|
||||
public:
|
||||
using CRefVStrView = const std::vector<std::string_view> &;
|
||||
@ -112,6 +114,12 @@ public:
|
||||
*/
|
||||
int Execute(std::map<std::string, std::vector<std::string>> mapArg) const;
|
||||
|
||||
/**
|
||||
* @brief 获取dir下文件个数,用于publishfile触发时机
|
||||
*
|
||||
* @return int 错误码(0 表示成功,非零表示失败)
|
||||
*/
|
||||
static int GetFIleNums(const std::string &bundleName, bool isWholeRestore = true);
|
||||
private:
|
||||
Descriptor desc_;
|
||||
static inline std::vector<ToolsOp> opsAvailable_;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022-2023 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2022-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
|
||||
@ -13,6 +13,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "b_resources/b_constants.h"
|
||||
#include "tools_op.h"
|
||||
|
||||
#include <regex>
|
||||
@ -84,4 +85,31 @@ int ToolsOp::Execute(map<string, vector<string>> args) const
|
||||
}
|
||||
return desc_.funcExec(args);
|
||||
}
|
||||
|
||||
int ToolsOp::GetFIleNums(const std::string &bundleName, bool isWholeRestore)
|
||||
{
|
||||
std::string path = "";
|
||||
path = string(isWholeRestore? BConstants::BACKUP_TOOL_RECEIVE_DIR :
|
||||
BConstants::BACKUP_TOOL_INCREMENTAL_RECEIVE_DIR) + bundleName;
|
||||
struct dirent *entry;
|
||||
printf("bundle path = %s\n", path.c_str());
|
||||
DIR *dir = opendir(path.c_str());
|
||||
if (dir == nullptr) {
|
||||
fprintf(stderr, "Open path error %s\n", path.c_str());
|
||||
return DEFAULT_ERR_NUMBER;
|
||||
}
|
||||
int num = 0;
|
||||
while ((entry = readdir(dir)) != nullptr) {
|
||||
if (entry->d_type != DT_DIR || (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0)) {
|
||||
++num;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (num == 0) {
|
||||
fprintf(stderr, "The path dir is empty!\n");
|
||||
}
|
||||
closedir(dir);
|
||||
return num;
|
||||
}
|
||||
} // namespace OHOS::FileManagement::Backup
|
||||
|
@ -105,7 +105,10 @@ private:
|
||||
|
||||
public:
|
||||
std::atomic<bool> isAllBundelsFinished {false};
|
||||
mutex fileCountLock_;
|
||||
vector<BIncrementalData> lastIncrementalData {};
|
||||
map<string, int> fileCount_;
|
||||
map<string, int> fileNums_;
|
||||
};
|
||||
|
||||
static string GenHelpMsg()
|
||||
@ -150,10 +153,21 @@ static void OnFileReady(shared_ptr<SessionRestore> ctx, const BFileInfo &fileInf
|
||||
}
|
||||
BFile::SendFile(manifestFd, fdManifest);
|
||||
}
|
||||
// 文件准备完成
|
||||
int ret = ctx->session_->PublishFile(fileInfo);
|
||||
if (ret != 0) {
|
||||
throw BError(BError::Codes::TOOL_INVAL_ARG, "PublishFile error");
|
||||
std::string bundleName = fileInfo.owner;
|
||||
{
|
||||
unique_lock<mutex> fileLock(ctx->fileCountLock_);
|
||||
++ctx->fileCount_[bundleName];
|
||||
// 文件准备完成
|
||||
printf("FileReady count/num = %d/%d\n", ctx->fileCount_[bundleName], ctx->fileNums_[bundleName]);
|
||||
if (ctx->fileCount_[bundleName] == ctx->fileNums_[bundleName]) {
|
||||
printf("PublishFile start.\n");
|
||||
BFileInfo fileInfoTemp = fileInfo;
|
||||
fileInfoTemp.fileName = "";
|
||||
int ret = ctx->session_->PublishFile(fileInfoTemp);
|
||||
if (ret != 0) {
|
||||
throw BError(BError::Codes::TOOL_INVAL_ARG, "PublishFile error");
|
||||
}
|
||||
}
|
||||
}
|
||||
ctx->TryNotify();
|
||||
}
|
||||
@ -287,6 +301,10 @@ static int32_t Init(const string &pathCapFile, vector<string> bundleNames, bool
|
||||
|
||||
UniqueFd fd(open(realPath.data(), O_RDWR, S_IRWXU));
|
||||
auto ctx = make_shared<SessionRestore>();
|
||||
int len = bundleNames.size();
|
||||
for (int i = 0; i < len; ++i) {
|
||||
ctx->fileNums_[bundleNames[i]] = ToolsOp::GetFIleNums(bundleNames[i], false);
|
||||
}
|
||||
int32_t ret = InitRestoreSession(ctx, bundleNames, times);
|
||||
if (ret != 0) {
|
||||
printf("Failed to init restore session error:%d\n", ret);
|
||||
|
@ -75,6 +75,9 @@ public:
|
||||
}
|
||||
|
||||
shared_ptr<BIncrementalSessionRestoreAsync> session_ = {};
|
||||
map<string, int> fileCount_;
|
||||
map<string, int> fileNums_;
|
||||
mutex fileCountLock_;
|
||||
|
||||
private:
|
||||
mutable condition_variable cv_;
|
||||
@ -120,9 +123,21 @@ static void OnFileReady(shared_ptr<InrementalSessionAsync> ctx, const BFileInfo
|
||||
throw BError(BError::Codes::TOOL_INVAL_ARG, generic_category().message(errno));
|
||||
}
|
||||
BFile::SendFile(fd, fdLocal);
|
||||
int ret = ctx->session_->PublishFile(fileInfo);
|
||||
if (ret != 0) {
|
||||
throw BError(BError::Codes::TOOL_INVAL_ARG, "PublishFile error");
|
||||
std::string bundleName = fileInfo.owner;
|
||||
{
|
||||
unique_lock<mutex> fileLock(ctx->fileCountLock_);
|
||||
++ctx->fileCount_[bundleName];
|
||||
// 文件准备完成
|
||||
printf("FileReady count/num = %d/%d\n", ctx->fileCount_[bundleName], ctx->fileNums_[bundleName]);
|
||||
if (ctx->fileCount_[bundleName] == ctx->fileNums_[bundleName]) {
|
||||
printf("PublishFile start.\n");
|
||||
BFileInfo fileInfoTemp = fileInfo;
|
||||
fileInfoTemp.fileName = "";
|
||||
int ret = ctx->session_->PublishFile(fileInfoTemp);
|
||||
if (ret != 0) {
|
||||
throw BError(BError::Codes::TOOL_INVAL_ARG, "PublishFile error");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -355,6 +370,10 @@ static int32_t InitArg(const string &pathCapFile,
|
||||
}
|
||||
|
||||
auto ctx = make_shared<InrementalSessionAsync>();
|
||||
int len = bundleNames.size();
|
||||
for (int i = 0; i < len; ++i) {
|
||||
ctx->fileNums_[bundleNames[i]] = ToolsOp::GetFIleNums(bundleNames[i], false);
|
||||
}
|
||||
ctx->session_ = BIncrementalSessionRestoreAsync::Init(BIncrementalSessionRestoreAsync::Callbacks {
|
||||
.onFileReady = bind(OnFileReady, ctx, placeholders::_1, placeholders::_2, placeholders::_3),
|
||||
.onBundleStarted = bind(OnBundleStarted, ctx, placeholders::_1, placeholders::_2),
|
||||
|
@ -104,6 +104,9 @@ private:
|
||||
|
||||
public:
|
||||
std::atomic<bool> isAllBundelsFinished {false};
|
||||
map<string, int> fileCount_;
|
||||
map<string, int> fileNums_;
|
||||
mutex fileCountLock_;
|
||||
};
|
||||
|
||||
static string GenHelpMsg()
|
||||
@ -129,9 +132,21 @@ static void OnFileReady(shared_ptr<Session> ctx, const BFileInfo &fileInfo, Uniq
|
||||
throw BError(BError::Codes::TOOL_INVAL_ARG, generic_category().message(errno));
|
||||
}
|
||||
BFile::SendFile(fd, fdLocal);
|
||||
int ret = ctx->session_->PublishFile(fileInfo);
|
||||
if (ret != 0) {
|
||||
throw BError(BError::Codes::TOOL_INVAL_ARG, "PublishFile error");
|
||||
std::string bundleName = fileInfo.owner;
|
||||
{
|
||||
unique_lock<mutex> fileLock(ctx->fileCountLock_);
|
||||
++ctx->fileCount_[bundleName];
|
||||
// 文件准备完成
|
||||
printf("FileReady count/num = %d/%d\n", ctx->fileCount_[bundleName], ctx->fileNums_[bundleName]);
|
||||
if (ctx->fileCount_[bundleName] == ctx->fileNums_[bundleName]) {
|
||||
printf("PublishFile start.\n");
|
||||
BFileInfo fileInfoTemp = fileInfo;
|
||||
fileInfoTemp.fileName = "";
|
||||
int ret = ctx->session_->PublishFile(fileInfoTemp);
|
||||
if (ret != 0) {
|
||||
throw BError(BError::Codes::TOOL_INVAL_ARG, "PublishFile error");
|
||||
}
|
||||
}
|
||||
}
|
||||
ctx->TryNotify();
|
||||
}
|
||||
@ -263,6 +278,10 @@ static int32_t InitPathCapFile(const string &pathCapFile, vector<string> bundleN
|
||||
|
||||
UniqueFd fd(open(realPath.data(), O_RDWR, S_IRWXU));
|
||||
auto ctx = make_shared<Session>();
|
||||
int len = bundleNames.size();
|
||||
for (int i = 0; i < len; ++i) {
|
||||
ctx->fileNums_[bundleNames[i]] = ToolsOp::GetFIleNums(bundleNames[i]);
|
||||
}
|
||||
int32_t ret = InitRestoreSession(ctx);
|
||||
if (ret != 0) {
|
||||
printf("Failed to init restore session error:%d\n", ret);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 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
|
||||
@ -75,6 +75,9 @@ public:
|
||||
}
|
||||
|
||||
shared_ptr<BSessionRestoreAsync> session_ = {};
|
||||
map<string, int> fileCount_;
|
||||
map<string, int> fileNums_;
|
||||
mutex fileCountLock_;
|
||||
|
||||
private:
|
||||
mutable condition_variable cv_;
|
||||
@ -114,9 +117,21 @@ static void OnFileReady(shared_ptr<SessionAsync> ctx, const BFileInfo &fileInfo,
|
||||
throw BError(BError::Codes::TOOL_INVAL_ARG, generic_category().message(errno));
|
||||
}
|
||||
BFile::SendFile(fd, fdLocal);
|
||||
int ret = ctx->session_->PublishFile(fileInfo);
|
||||
if (ret != 0) {
|
||||
throw BError(BError::Codes::TOOL_INVAL_ARG, "PublishFile error");
|
||||
std::string bundleName = fileInfo.owner;
|
||||
{
|
||||
unique_lock<mutex> fileLock(ctx->fileCountLock_);
|
||||
++ctx->fileCount_[bundleName];
|
||||
// 文件准备完成
|
||||
printf("FileReady count/num = %d/%d\n", ctx->fileCount_[bundleName], ctx->fileNums_[bundleName]);
|
||||
if (ctx->fileCount_[bundleName] == ctx->fileNums_[bundleName]) {
|
||||
printf("PublishFile start.\n");
|
||||
BFileInfo fileInfoTemp = fileInfo;
|
||||
fileInfoTemp.fileName = "";
|
||||
int ret = ctx->session_->PublishFile(fileInfoTemp);
|
||||
if (ret != 0) {
|
||||
throw BError(BError::Codes::TOOL_INVAL_ARG, "PublishFile error");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -339,6 +354,10 @@ static int32_t InitArg(const string &pathCapFile,
|
||||
}
|
||||
|
||||
auto ctx = make_shared<SessionAsync>();
|
||||
int len = bundleNames.size();
|
||||
for (int i = 0; i < len; ++i) {
|
||||
ctx->fileNums_[bundleNames[i]] = ToolsOp::GetFIleNums(bundleNames[i]);
|
||||
}
|
||||
ctx->session_ = BSessionRestoreAsync::Init(BSessionRestoreAsync::Callbacks {
|
||||
.onFileReady = bind(OnFileReady, ctx, placeholders::_1, placeholders::_2),
|
||||
.onBundleStarted = bind(OnBundleStarted, ctx, placeholders::_1, placeholders::_2),
|
||||
|
Loading…
Reference in New Issue
Block a user