From 7a17bb9c12a235a3bf66f13be9daf98e4e19a3b4 Mon Sep 17 00:00:00 2001 From: huaqingsimeng <1004904143@qq.com> Date: Tue, 26 Dec 2023 23:32:11 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E5=A2=9E=E9=87=8F=E5=A4=87=E4=BB=BD?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E8=81=94=E8=B0=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: huaqingsimeng --- bundle.json | 3 + .../native/backup_ext/include/ext_extension.h | 3 + .../backup_ext/include/ext_extension_stub.h | 3 + .../native/backup_ext/src/ext_extension.cpp | 19 ++ .../backup_ext/src/ext_extension_stub.cpp | 52 +++ .../include/service_reverse.h | 16 + .../include/service_reverse_stub.h | 10 + .../src/b_incremental_backup_session.cpp | 107 ++++++ .../src/b_incremental_data.cpp | 65 ++++ .../src/b_incremental_restore_session.cpp | 125 +++++++ .../backup_kit_inner/src/b_session_backup.cpp | 10 + .../src/b_session_restore.cpp | 10 + .../src/b_session_restore_async.cpp | 10 + .../src/service_incremental_proxy.cpp | 263 ++++++++++++++ .../src/service_incremental_reverse.cpp | 115 +++++++ .../src/service_reverse_stub.cpp | 90 +++++ .../native/backup_kit_inner/BUILD.gn | 5 + .../backup_kit_inner/backup_kit_inner.h | 2 + .../impl/b_incremental_backup_session.h | 79 +++++ .../impl/b_incremental_data.h | 47 +++ .../impl/b_incremental_restore_session.h | 97 ++++++ .../backup_kit_inner/impl/b_session_backup.h | 7 + .../backup_kit_inner/impl/b_session_restore.h | 7 + .../impl/b_session_restore_async.h | 25 +- .../backup_kit_inner/impl/i_extension.h | 3 + .../impl/i_extension_ipc_interface_code.h | 3 + .../native/backup_kit_inner/impl/i_service.h | 10 + .../impl/i_service_ipc_interface_code.h | 8 + .../backup_kit_inner/impl/i_service_reverse.h | 13 + .../i_service_reverse_ipc_interface_code.h | 8 + .../backup_kit_inner/impl/service_proxy.h | 11 + services/backup.para | 5 +- services/backup_sa/BUILD.gn | 2 + .../backup_sa/include/module_ipc/service.h | 19 ++ .../module_ipc/service_reverse_proxy.h | 10 + .../include/module_ipc/service_stub.h | 12 + .../include/module_ipc/svc_extension_proxy.h | 4 + .../include/module_ipc/svc_session_manager.h | 29 ++ .../include/module_sched/sched_scheduler.h | 6 +- services/backup_sa/src/module_ipc/service.cpp | 31 +- .../src/module_ipc/service_incremental.cpp | 321 ++++++++++++++++++ .../service_incremental_reverse_proxy.cpp | 183 ++++++++++ .../backup_sa/src/module_ipc/service_stub.cpp | 175 ++++++++++ .../src/module_ipc/svc_extension_proxy.cpp | 73 ++++ .../src/module_ipc/svc_session_manager.cpp | 37 ++ .../src/module_sched/sched_scheduler.cpp | 9 + .../b_session_backup_mock.cpp | 5 + .../b_session_restore_async_mock.cpp | 5 + .../b_session_restore_mock.cpp | 5 + .../backup_kit_inner/service_proxy_mock.cpp | 40 +++ tests/mock/module_ipc/service_mock.cpp | 40 +++ .../module_ipc/service_reverse_proxy_mock.cpp | 16 + tests/mock/module_ipc/service_stub_mock.cpp | 52 +++ .../module_ipc/svc_extension_proxy_mock.cpp | 15 + .../module_ipc/svc_session_manager_mock.cpp | 12 + .../module_sched/sched_scheduler_mock.cpp | 2 + tests/moduletests/backup_kit_inner/BUILD.gn | 1 + .../backup_impl/include/ext_extension_mock.h | 15 + .../backup_impl/include/i_service_mock.h | 40 +++ .../include/service_reverse_mock.h | 10 + .../backup_impl/service_reverse_stub_test.cpp | 8 + tests/unittests/backup_sa/module_ipc/BUILD.gn | 2 + .../module_ipc/service_stub_test.cpp | 39 +++ tools/backup_tool/src/tools_op_backup.cpp | 1 + tools/backup_tool/src/tools_op_restore.cpp | 3 +- utils/include/b_ohos/startup/backup_para.h | 14 + utils/include/b_resources/b_constants.h | 7 + utils/src/b_ohos/startup/backup_para.cpp | 20 ++ 68 files changed, 2465 insertions(+), 29 deletions(-) create mode 100644 frameworks/native/backup_kit_inner/src/b_incremental_backup_session.cpp create mode 100644 frameworks/native/backup_kit_inner/src/b_incremental_data.cpp create mode 100644 frameworks/native/backup_kit_inner/src/b_incremental_restore_session.cpp create mode 100644 frameworks/native/backup_kit_inner/src/service_incremental_proxy.cpp create mode 100644 frameworks/native/backup_kit_inner/src/service_incremental_reverse.cpp create mode 100644 interfaces/inner_api/native/backup_kit_inner/impl/b_incremental_backup_session.h create mode 100644 interfaces/inner_api/native/backup_kit_inner/impl/b_incremental_data.h create mode 100644 interfaces/inner_api/native/backup_kit_inner/impl/b_incremental_restore_session.h create mode 100644 services/backup_sa/src/module_ipc/service_incremental.cpp create mode 100644 services/backup_sa/src/module_ipc/service_incremental_reverse_proxy.cpp diff --git a/bundle.json b/bundle.json index 0d0c382c7..db8920b9d 100644 --- a/bundle.json +++ b/bundle.json @@ -108,6 +108,9 @@ "header_base": "//foundation/filemanagement/app_file_service/interfaces/inner_api/native/backup_kit_inner", "header_files": [ "backup_kit_inner.h", + "impl/b_incremental_backup_session.h", + "impl/b_incremental_data.h", + "impl/b_incremental_restore_session.h", "impl/b_session_restore.h", "impl/b_session_restore_async.h", "impl/b_file_info.h", diff --git a/frameworks/native/backup_ext/include/ext_extension.h b/frameworks/native/backup_ext/include/ext_extension.h index c39e05fcd..a1683f9e1 100644 --- a/frameworks/native/backup_ext/include/ext_extension.h +++ b/frameworks/native/backup_ext/include/ext_extension.h @@ -34,6 +34,9 @@ public: ErrCode PublishFile(const std::string &fileName) override; ErrCode HandleBackup() override; ErrCode HandleRestore() override; + ErrCode GetIncrementalFileHandle(const std::string &fileName) override; + ErrCode PublishIncrementalFile(const std::string &fileName) override; + ErrCode HandleIncrementalBackup(UniqueFd incrementalFd, UniqueFd manifestFd) override; void AsyncTaskRestoreForUpgrade(void); diff --git a/frameworks/native/backup_ext/include/ext_extension_stub.h b/frameworks/native/backup_ext/include/ext_extension_stub.h index 806bf8595..08ccc2a88 100644 --- a/frameworks/native/backup_ext/include/ext_extension_stub.h +++ b/frameworks/native/backup_ext/include/ext_extension_stub.h @@ -36,6 +36,9 @@ private: ErrCode CmdHandleBackup(MessageParcel &data, MessageParcel &reply); ErrCode CmdPublishFile(MessageParcel &data, MessageParcel &reply); ErrCode CmdHandleRestore(MessageParcel &data, MessageParcel &reply); + ErrCode CmdGetIncrementalFileHandle(MessageParcel &data, MessageParcel &reply); + ErrCode CmdPublishIncrementalFile(MessageParcel &data, MessageParcel &reply); + ErrCode CmdHandleIncrementalBackup(MessageParcel &data, MessageParcel &reply); private: using ExtensionInterface = int32_t (ExtExtensionStub::*)(MessageParcel &data, MessageParcel &reply); diff --git a/frameworks/native/backup_ext/src/ext_extension.cpp b/frameworks/native/backup_ext/src/ext_extension.cpp index 083e4d7d4..e200f06ca 100644 --- a/frameworks/native/backup_ext/src/ext_extension.cpp +++ b/frameworks/native/backup_ext/src/ext_extension.cpp @@ -805,4 +805,23 @@ ErrCode BackupExtExtension::HandleRestore() return 0; } + +ErrCode BackupExtExtension::GetIncrementalFileHandle(const string &fileName) +{ + HILOGI("begin"); + return BError(BError::Codes::OK); +} + +ErrCode BackupExtExtension::PublishIncrementalFile(const string &fileName) +{ + HILOGI("begin"); + return BError(BError::Codes::OK); +} + +ErrCode BackupExtExtension::HandleIncrementalBackup(UniqueFd incrementalFd, UniqueFd manifestFd) +{ + HILOGI("begin"); + return BError(BError::Codes::OK); +} + } // namespace OHOS::FileManagement::Backup diff --git a/frameworks/native/backup_ext/src/ext_extension_stub.cpp b/frameworks/native/backup_ext/src/ext_extension_stub.cpp index c98380a37..373caeefa 100644 --- a/frameworks/native/backup_ext/src/ext_extension_stub.cpp +++ b/frameworks/native/backup_ext/src/ext_extension_stub.cpp @@ -37,6 +37,12 @@ ExtExtensionStub::ExtExtensionStub() &ExtExtensionStub::CmdPublishFile; opToInterfaceMap_[static_cast(IExtensionInterfaceCode::CMD_HANDLE_RESTORE)] = &ExtExtensionStub::CmdHandleRestore; + opToInterfaceMap_[static_cast(IExtensionInterfaceCode::CMD_GET_INCREMENTAL_FILE_HANDLE)] = + &ExtExtensionStub::CmdGetIncrementalFileHandle; + opToInterfaceMap_[static_cast(IExtensionInterfaceCode::CMD_PUBLISH_INCREMENTAL_FILE)] = + &ExtExtensionStub::CmdPublishIncrementalFile; + opToInterfaceMap_[static_cast(IExtensionInterfaceCode::CMD_HANDLE_INCREMENTAL_BACKUP)] = + &ExtExtensionStub::CmdHandleIncrementalBackup; } int32_t ExtExtensionStub::OnRemoteRequest(uint32_t code, @@ -128,4 +134,50 @@ ErrCode ExtExtensionStub::CmdHandleRestore(MessageParcel &data, MessageParcel &r } return BError(BError::Codes::OK); } + +ErrCode ExtExtensionStub::CmdGetIncrementalFileHandle(MessageParcel &data, MessageParcel &reply) +{ + HILOGI("Begin"); + string fileName; + if (!data.ReadString(fileName)) { + return BError(BError::Codes::EXT_INVAL_ARG, "Failed to receive fileName").GetCode(); + } + + ErrCode res = GetIncrementalFileHandle(fileName); + if (!reply.WriteInt32(res)) { + return BError(BError::Codes::EXT_BROKEN_IPC, "Failed to send out the file").GetCode(); + } + return BError(BError::Codes::OK); +} + +ErrCode ExtExtensionStub::CmdPublishIncrementalFile(MessageParcel &data, MessageParcel &reply) +{ + HILOGI("Begin"); + string fileName; + if (!data.ReadString(fileName)) { + return BError(BError::Codes::EXT_INVAL_ARG, "Failed to receive fileName"); + } + + ErrCode res = PublishIncrementalFile(fileName); + if (!reply.WriteInt32(res)) { + stringstream ss; + ss << "Failed to send the result " << res; + return BError(BError::Codes::EXT_BROKEN_IPC, ss.str()).GetCode(); + } + return BError(BError::Codes::OK); +} + +ErrCode ExtExtensionStub::CmdHandleIncrementalBackup(MessageParcel &data, MessageParcel &reply) +{ + HILOGI("Begin"); + UniqueFd incrementalFd(data.ReadFileDescriptor()); + UniqueFd manifestFd(data.ReadFileDescriptor()); + ErrCode res = HandleIncrementalBackup(move(incrementalFd), move(manifestFd)); + if (!reply.WriteInt32(res)) { + stringstream ss; + ss << "Failed to send the result " << res; + return BError(BError::Codes::EXT_BROKEN_IPC, ss.str()).GetCode(); + } + return BError(BError::Codes::OK); +} } // namespace OHOS::FileManagement::Backup \ No newline at end of file diff --git a/frameworks/native/backup_kit_inner/include/service_reverse.h b/frameworks/native/backup_kit_inner/include/service_reverse.h index f0810e14a..92b22c47e 100644 --- a/frameworks/native/backup_kit_inner/include/service_reverse.h +++ b/frameworks/native/backup_kit_inner/include/service_reverse.h @@ -18,6 +18,8 @@ #include "b_session_backup.h" #include "b_session_restore.h" +#include "b_incremental_backup_session.h" +#include "b_incremental_restore_session.h" #include "service_reverse_stub.h" namespace OHOS::FileManagement::Backup { @@ -33,16 +35,30 @@ public: void RestoreOnAllBundlesFinished(int32_t errCode) override; void RestoreOnFileReady(std::string bundleName, std::string fileName, int fd) override; + void IncrementalBackupOnFileReady(std::string bundleName, std::string fileName, int fd, int manifestFd) override; + void IncrementalBackupOnBundleStarted(int32_t errCode, std::string bundleName) override; + void IncrementalBackupOnBundleFinished(int32_t errCode, std::string bundleName) override; + void IncrementalBackupOnAllBundlesFinished(int32_t errCode) override; + + void IncrementalRestoreOnBundleStarted(int32_t errCode, std::string bundleName) override; + void IncrementalRestoreOnBundleFinished(int32_t errCode, std::string bundleName) override; + void IncrementalRestoreOnAllBundlesFinished(int32_t errCode) override; + void IncrementalRestoreOnFileReady(std::string bundleName, std::string fileName, int fd, int manifestFd) override; + public: ServiceReverse() = delete; explicit ServiceReverse(BSessionRestore::Callbacks callbacks); explicit ServiceReverse(BSessionBackup::Callbacks callbacks); + explicit ServiceReverse(BIncrementalBackupSession::Callbacks callbacks); + explicit ServiceReverse(BIncrementalRestoreSession::Callbacks callbacks); ~ServiceReverse() override = default; private: Scenario scenario_ {Scenario::UNDEFINED}; BSessionBackup::Callbacks callbacksBackup_; BSessionRestore::Callbacks callbacksRestore_; + BIncrementalBackupSession::Callbacks callbacksIncrementalBackup_; + BIncrementalRestoreSession::Callbacks callbacksIncrementalRestore_; }; } // namespace OHOS::FileManagement::Backup diff --git a/frameworks/native/backup_kit_inner/include/service_reverse_stub.h b/frameworks/native/backup_kit_inner/include/service_reverse_stub.h index 5c46907b2..ea1e5f8be 100644 --- a/frameworks/native/backup_kit_inner/include/service_reverse_stub.h +++ b/frameworks/native/backup_kit_inner/include/service_reverse_stub.h @@ -43,6 +43,16 @@ private: int32_t CmdRestoreOnBundleFinished(MessageParcel &data, MessageParcel &reply); int32_t CmdRestoreOnAllBundlesFinished(MessageParcel &data, MessageParcel &reply); int32_t CmdRestoreOnFileReady(MessageParcel &data, MessageParcel &reply); + + int32_t CmdIncrementalBackupOnFileReady(MessageParcel &data, MessageParcel &reply); + int32_t CmdIncrementalBackupOnBundleStarted(MessageParcel &data, MessageParcel &reply); + int32_t CmdIncrementalBackupOnBundleFinished(MessageParcel &data, MessageParcel &reply); + int32_t CmdIncrementalBackupOnAllBundlesFinished(MessageParcel &data, MessageParcel &reply); + + int32_t CmdIncrementalRestoreOnBundleStarted(MessageParcel &data, MessageParcel &reply); + int32_t CmdIncrementalRestoreOnBundleFinished(MessageParcel &data, MessageParcel &reply); + int32_t CmdIncrementalRestoreOnAllBundlesFinished(MessageParcel &data, MessageParcel &reply); + int32_t CmdIncrementalRestoreOnFileReady(MessageParcel &data, MessageParcel &reply); }; } // namespace OHOS::FileManagement::Backup diff --git a/frameworks/native/backup_kit_inner/src/b_incremental_backup_session.cpp b/frameworks/native/backup_kit_inner/src/b_incremental_backup_session.cpp new file mode 100644 index 000000000..9d17428c1 --- /dev/null +++ b/frameworks/native/backup_kit_inner/src/b_incremental_backup_session.cpp @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2023 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "b_incremental_backup_session.h" + +#include "b_error/b_error.h" +#include "filemgmt_libhilog.h" +#include "service_proxy.h" +#include "service_reverse.h" + +namespace OHOS::FileManagement::Backup { +using namespace std; + +BIncrementalBackupSession::~BIncrementalBackupSession() +{ + if (!deathRecipient_) { + HILOGI("Death Recipient is nullptr"); + return; + } + auto proxy = ServiceProxy::GetInstance(); + if (proxy == nullptr) { + return; + } + auto remoteObject = proxy->AsObject(); + if (remoteObject != nullptr) { + remoteObject->RemoveDeathRecipient(deathRecipient_); + } + deathRecipient_ = nullptr; +} + +unique_ptr BIncrementalBackupSession::Init(Callbacks callbacks) +{ + try { + auto backup = make_unique(); + ServiceProxy::InvaildInstance(); + auto proxy = ServiceProxy::GetInstance(); + if (proxy == nullptr) { + HILOGI("Failed to get backup service"); + return nullptr; + } + + int32_t res = proxy->InitIncrementalBackupSession(sptr(new ServiceReverse(callbacks))); + if (res != 0) { + HILOGE("Failed to Backup because of %{public}d", res); + return nullptr; + } + + backup->RegisterBackupServiceDied(callbacks.onBackupServiceDied); + return backup; + } catch (const exception &e) { + HILOGE("Failed to Backup because of %{public}s", e.what()); + } + return nullptr; +} + +void BIncrementalBackupSession::RegisterBackupServiceDied(function functor) +{ + auto proxy = ServiceProxy::GetInstance(); + if (proxy == nullptr || !functor) { + return; + } + auto remoteObj = proxy->AsObject(); + if (!remoteObj) { + throw BError(BError::Codes::SA_BROKEN_IPC, "Proxy's remote object can't be nullptr"); + } + + auto callback = [functor](const wptr &obj) { + ServiceProxy::InvaildInstance(); + HILOGI("Backup service died"); + functor(); + }; + deathRecipient_ = sptr(new SvcDeathRecipient(callback)); + remoteObj->AddDeathRecipient(deathRecipient_); +} + +ErrCode BIncrementalBackupSession::AppendBundles(vector bundlesToBackup) +{ + auto proxy = ServiceProxy::GetInstance(); + if (proxy == nullptr) { + return BError(BError::Codes::SDK_BROKEN_IPC, "Failed to get backup service").GetCode(); + } + + return proxy->AppendBundlesIncrementalBackupSession(bundlesToBackup); +} + +ErrCode BIncrementalBackupSession::Release() +{ + auto proxy = ServiceProxy::GetInstance(); + if (proxy == nullptr) { + return BError(BError::Codes::SDK_BROKEN_IPC, "Failed to get backup service").GetCode(); + } + + return proxy->Release(); +} +} // namespace OHOS::FileManagement::Backup \ No newline at end of file diff --git a/frameworks/native/backup_kit_inner/src/b_incremental_data.cpp b/frameworks/native/backup_kit_inner/src/b_incremental_data.cpp new file mode 100644 index 000000000..bb8e8dbba --- /dev/null +++ b/frameworks/native/backup_kit_inner/src/b_incremental_data.cpp @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2023 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "b_incremental_data.h" + +#include "filemgmt_libhilog.h" +#include "message_parcel.h" + +namespace OHOS { +namespace FileManagement { +namespace Backup { +using namespace std; + +bool BIncrementalData::Marshalling(Parcel &parcel) const +{ + if (!parcel.WriteString(bundleName) || !parcel.WriteInt64(lastIncrementalTime) || + !parcel.WriteString(backupParameters) || !parcel.WriteString(backupPriority)) { + HILOGE("Failed"); + return false; + } + auto msgParcel = static_cast(&parcel); + msgParcel->WriteFileDescriptor(manifestFd); + return true; +} + +bool BIncrementalData::ReadFromParcel(Parcel &parcel) +{ + if (!parcel.ReadString(bundleName) || !parcel.ReadInt64(lastIncrementalTime) || + !parcel.ReadString(backupParameters) || !parcel.ReadString(backupPriority)) { + HILOGE("Failed"); + return false; + } + auto msgParcel = static_cast(&parcel); + manifestFd = msgParcel->ReadFileDescriptor(); + return true; +} + +BIncrementalData *BIncrementalData::Unmarshalling(Parcel &parcel) +{ + try { + auto result = make_unique(); + if (!result->ReadFromParcel(parcel)) { + return nullptr; + } + return result.release(); + } catch (const bad_alloc &e) { + HILOGE("Failed to unmarshall BIncrementalData because of %{public}s", e.what()); + } + return nullptr; +} +} // namespace Backup +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/native/backup_kit_inner/src/b_incremental_restore_session.cpp b/frameworks/native/backup_kit_inner/src/b_incremental_restore_session.cpp new file mode 100644 index 000000000..9a9fe5abc --- /dev/null +++ b/frameworks/native/backup_kit_inner/src/b_incremental_restore_session.cpp @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2023 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "b_incremental_restore_session.h" + +#include "b_error/b_error.h" +#include "filemgmt_libhilog.h" +#include "service_proxy.h" +#include "service_reverse.h" + +namespace OHOS::FileManagement::Backup { +using namespace std; + +BIncrementalRestoreSession::~BIncrementalRestoreSession() +{ + if (!deathRecipient_) { + HILOGI("Death Recipient is nullptr"); + return; + } + auto proxy = ServiceProxy::GetInstance(); + if (proxy == nullptr) { + return; + } + auto remoteObject = proxy->AsObject(); + if (remoteObject != nullptr) { + remoteObject->RemoveDeathRecipient(deathRecipient_); + } + deathRecipient_ = nullptr; +} + +unique_ptr BIncrementalRestoreSession::Init(Callbacks callbacks) +{ + try { + auto restore = make_unique(); + ServiceProxy::InvaildInstance(); + auto proxy = ServiceProxy::GetInstance(); + if (proxy == nullptr) { + HILOGI("Failed to get backup service"); + return nullptr; + } + int32_t res = proxy->InitRestoreSession(new ServiceReverse(callbacks)); + if (res != 0) { + HILOGE("Failed to Restore because of %{public}d", res); + return nullptr; + } + + restore->RegisterBackupServiceDied(callbacks.onBackupServiceDied); + return restore; + } catch (const exception &e) { + HILOGE("Failed to Restore because of %{public}s", e.what()); + } + return nullptr; +} + +ErrCode BIncrementalRestoreSession::PublishFile(BFileInfo fileInfo) +{ + auto proxy = ServiceProxy::GetInstance(); + if (proxy == nullptr) { + return BError(BError::Codes::SDK_BROKEN_IPC, "Failed to get backup service").GetCode(); + } + return proxy->PublishIncrementalFile(fileInfo); +} + +ErrCode BIncrementalRestoreSession::GetFileHandle(const string &bundleName, const string &fileName) +{ + auto proxy = ServiceProxy::GetInstance(); + if (proxy == nullptr) { + return BError(BError::Codes::SDK_BROKEN_IPC, "Failed to get backup service").GetCode(); + } + + return proxy->GetIncrementalFileHandle(bundleName, fileName); +} + +ErrCode BIncrementalRestoreSession::AppendBundles(UniqueFd remoteCap, vector bundlesToRestore) +{ + auto proxy = ServiceProxy::GetInstance(); + if (proxy == nullptr) { + return BError(BError::Codes::SDK_BROKEN_IPC, "Failed to get backup service").GetCode(); + } + + return proxy->AppendBundlesRestoreSession(move(remoteCap), bundlesToRestore); +} + +ErrCode BIncrementalRestoreSession::Release() +{ + auto proxy = ServiceProxy::GetInstance(); + if (proxy == nullptr) { + return BError(BError::Codes::SDK_BROKEN_IPC, "Failed to get backup service").GetCode(); + } + + return proxy->Release(); +} + +void BIncrementalRestoreSession::RegisterBackupServiceDied(function functor) +{ + auto proxy = ServiceProxy::GetInstance(); + if (proxy == nullptr || !functor) { + return; + } + auto remoteObj = proxy->AsObject(); + if (!remoteObj) { + throw BError(BError::Codes::SA_BROKEN_IPC, "Proxy's remote object can't be nullptr"); + } + + auto callback = [functor](const wptr &obj) { + HILOGI("Backup service died"); + ServiceProxy::InvaildInstance(); + functor(); + }; + deathRecipient_ = sptr(new SvcDeathRecipient(callback)); + remoteObj->AddDeathRecipient(deathRecipient_); +} +} // namespace OHOS::FileManagement::Backup \ No newline at end of file diff --git a/frameworks/native/backup_kit_inner/src/b_session_backup.cpp b/frameworks/native/backup_kit_inner/src/b_session_backup.cpp index e89285aba..d96ef7847 100644 --- a/frameworks/native/backup_kit_inner/src/b_session_backup.cpp +++ b/frameworks/native/backup_kit_inner/src/b_session_backup.cpp @@ -114,4 +114,14 @@ ErrCode BSessionBackup::Finish() return proxy->Finish(); } + +ErrCode BSessionBackup::Release() +{ + auto proxy = ServiceProxy::GetInstance(); + if (proxy == nullptr) { + return BError(BError::Codes::SDK_BROKEN_IPC, "Failed to get backup service").GetCode(); + } + + return proxy->Release(); +} } // namespace OHOS::FileManagement::Backup \ No newline at end of file diff --git a/frameworks/native/backup_kit_inner/src/b_session_restore.cpp b/frameworks/native/backup_kit_inner/src/b_session_restore.cpp index 59a6d67e4..f41ea469b 100644 --- a/frameworks/native/backup_kit_inner/src/b_session_restore.cpp +++ b/frameworks/native/backup_kit_inner/src/b_session_restore.cpp @@ -113,6 +113,16 @@ ErrCode BSessionRestore::Finish() return proxy->Finish(); } +ErrCode BSessionRestore::Release() +{ + auto proxy = ServiceProxy::GetInstance(); + if (proxy == nullptr) { + return BError(BError::Codes::SDK_BROKEN_IPC, "Failed to get backup service").GetCode(); + } + + return proxy->Release(); +} + void BSessionRestore::RegisterBackupServiceDied(std::function functor) { auto proxy = ServiceProxy::GetInstance(); diff --git a/frameworks/native/backup_kit_inner/src/b_session_restore_async.cpp b/frameworks/native/backup_kit_inner/src/b_session_restore_async.cpp index a0a38653c..4416e873b 100644 --- a/frameworks/native/backup_kit_inner/src/b_session_restore_async.cpp +++ b/frameworks/native/backup_kit_inner/src/b_session_restore_async.cpp @@ -104,6 +104,16 @@ ErrCode BSessionRestoreAsync::AppendBundles(UniqueFd remoteCap, return proxy->AppendBundlesRestoreSession(move(remoteCap), bundlesToRestore, restoreType, userId); } +ErrCode BSessionRestoreAsync::Release() +{ + auto proxy = ServiceProxy::GetInstance(); + if (proxy == nullptr) { + return BError(BError::Codes::SDK_BROKEN_IPC, "Failed to get backup service").GetCode(); + } + + return proxy->Release(); +} + void BSessionRestoreAsync::RegisterBackupServiceDied(std::function functor) { auto proxy = ServiceProxy::GetInstance(); diff --git a/frameworks/native/backup_kit_inner/src/service_incremental_proxy.cpp b/frameworks/native/backup_kit_inner/src/service_incremental_proxy.cpp new file mode 100644 index 000000000..ea227c5a3 --- /dev/null +++ b/frameworks/native/backup_kit_inner/src/service_incremental_proxy.cpp @@ -0,0 +1,263 @@ +/* + * Copyright (c) 2023 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "service_proxy.h" + +#include "iservice_registry.h" +#include "system_ability_definition.h" + +#include "b_error/b_error.h" +#include "b_error/b_excep_utils.h" +#include "b_resources/b_constants.h" +#include "filemgmt_libhilog.h" +#include "svc_death_recipient.h" +#include "unique_fd.h" + +namespace OHOS::FileManagement::Backup { +using namespace std; + +ErrCode ServiceProxy::Release() +{ + HILOGI("Begin"); + BExcepUltils::BAssert(Remote(), BError::Codes::SDK_INVAL_ARG, "Remote is nullptr"); + MessageParcel data; + if (!data.WriteInterfaceToken(GetDescriptor())) { + return BError(BError::Codes::SDK_INVAL_ARG, "Failed to write descriptor").GetCode(); + } + + MessageParcel reply; + MessageOption option; + int32_t ret = Remote()->SendRequest(static_cast(IServiceInterfaceCode::SERVICE_CMD_RELSEASE_SESSION), + data, reply, option); + if (ret != NO_ERROR) { + string str = "Failed to send out the request because of " + to_string(ret); + return BError(BError::Codes::SDK_INVAL_ARG, str.data()).GetCode(); + } + return reply.ReadInt32(); +} + +UniqueFd ServiceProxy::GetLocalCapabilitiesIncremental(const vector &bundleNames) +{ + HILOGI("Begin"); + BExcepUltils::BAssert(Remote(), BError::Codes::SDK_INVAL_ARG, "Remote is nullptr"); + MessageParcel data; + if (!data.WriteInterfaceToken(GetDescriptor())) { + HILOGE("Failed to write descriptor"); + return UniqueFd(-EPERM); + } + + if (!WriteParcelableVector(bundleNames, data)) { + HILOGE("Failed to send the bundleNames"); + return UniqueFd(-EPERM); + } + + MessageParcel reply; + MessageOption option; + option.SetWaitTime(BConstants::IPC_MAX_WAIT_TIME); + int32_t ret = Remote()->SendRequest( + static_cast(IServiceInterfaceCode::SERVICE_CMD_GET_LOCAL_CAPABILITIES_INCREMENTAL), data, reply, + option); + if (ret != NO_ERROR) { + HILOGE("Received error %{public}d when doing IPC", ret); + return UniqueFd(-ret); + } + UniqueFd fd(reply.ReadFileDescriptor()); + return UniqueFd(fd.Release()); +} + +ErrCode ServiceProxy::InitIncrementalBackupSession(sptr remote) +{ + HILOGI("Begin"); + BExcepUltils::BAssert(Remote(), BError::Codes::SDK_INVAL_ARG, "remote is nullptr"); + MessageParcel data; + if (!data.WriteInterfaceToken(GetDescriptor())) { + HILOGE("Failed to write descriptor"); + return BError(BError::Codes::SDK_INVAL_ARG, "Failed to write descriptor").GetCode(); + } + + MessageParcel reply; + MessageOption option; + + if (!remote) { + HILOGE("Empty reverse stub"); + return BError(BError::Codes::SDK_INVAL_ARG, "Empty reverse stub").GetCode(); + } + if (!data.WriteRemoteObject(remote->AsObject().GetRefPtr())) { + HILOGE("Failed to send the reverse stub"); + return BError(BError::Codes::SDK_INVAL_ARG, "Failed to send the reverse stub").GetCode(); + } + + int32_t ret = Remote()->SendRequest( + static_cast(IServiceInterfaceCode::SERVICE_CMD_INIT_INCREMENTAL_BACKUP_SESSION), data, reply, option); + if (ret != NO_ERROR) { + HILOGE("Received error %{public}d when doing IPC", ret); + return BError(BError::Codes::SDK_INVAL_ARG, "Received error when doing IPC").GetCode(); + } + return reply.ReadInt32(); +} + +ErrCode ServiceProxy::AppendBundlesIncrementalBackupSession(const vector &bundlesToBackup) +{ + HILOGI("Begin"); + BExcepUltils::BAssert(Remote(), BError::Codes::SDK_INVAL_ARG, "remote is nullptr"); + MessageParcel data; + if (!data.WriteInterfaceToken(GetDescriptor())) { + HILOGE("Failed to write descriptor"); + return BError(BError::Codes::SDK_INVAL_ARG, "Failed to write descriptor").GetCode(); + } + + if (!WriteParcelableVector(bundlesToBackup, data)) { + HILOGE("Failed to send the bundleNames"); + return UniqueFd(-EPERM); + } + + MessageParcel reply; + MessageOption option; + + int32_t ret = Remote()->SendRequest( + static_cast(IServiceInterfaceCode::SERVICE_CMD_APPEND_BUNDLES_INCREMENTAL_BACKUP_SESSION), data, + reply, option); + if (ret != NO_ERROR) { + HILOGE("Received error %{public}d when doing IPC", ret); + return BError(BError::Codes::SDK_INVAL_ARG, "Received error when doing IPC").GetCode(); + } + return reply.ReadInt32(); +} + +ErrCode ServiceProxy::PublishIncrementalFile(const BFileInfo &fileInfo) +{ + HILOGI("Begin"); + BExcepUltils::BAssert(Remote(), BError::Codes::SDK_INVAL_ARG, "Remote is nullptr"); + MessageParcel data; + if (!data.WriteInterfaceToken(GetDescriptor())) { + return BError(BError::Codes::SDK_INVAL_ARG, "Failed to write descriptor").GetCode(); + } + + if (!data.WriteParcelable(&fileInfo)) { + HILOGE("Failed to send the fileInfo"); + return -EPIPE; + } + + MessageParcel reply; + MessageOption option; + int32_t ret = Remote()->SendRequest( + static_cast(IServiceInterfaceCode::SERVICE_CMD_PUBLISH_INCREMENTAL_FILE), data, reply, option); + if (ret != NO_ERROR) { + string str = "Failed to send out the request because of " + to_string(ret); + return BError(BError::Codes::SDK_INVAL_ARG, str.data()).GetCode(); + } + return reply.ReadInt32(); +} + +ErrCode ServiceProxy::AppIncrementalFileReady(const std::string &fileName, UniqueFd fd, UniqueFd manifestFd) +{ + HILOGI("Begin"); + BExcepUltils::BAssert(Remote(), BError::Codes::SDK_INVAL_ARG, "Remote is nullptr"); + MessageParcel data; + if (!data.WriteInterfaceToken(GetDescriptor())) { + return BError(BError::Codes::SDK_INVAL_ARG, "Failed to write descriptor").GetCode(); + } + + if (!data.WriteString(fileName)) { + return BError(BError::Codes::SDK_INVAL_ARG, "Failed to send the filename").GetCode(); + } + if (!data.WriteFileDescriptor(fd)) { + return BError(BError::Codes::SDK_INVAL_ARG, "Failed to send the fd").GetCode(); + } + if (!data.WriteFileDescriptor(manifestFd)) { + return BError(BError::Codes::SDK_INVAL_ARG, "Failed to send the fd").GetCode(); + } + + MessageParcel reply; + MessageOption option; + int32_t ret = Remote()->SendRequest( + static_cast(IServiceInterfaceCode::SERVICE_CMD_APP_INCREMENTAL_FILE_READY), data, reply, option); + if (ret != NO_ERROR) { + string str = "Failed to send out the request because of " + to_string(ret); + return BError(BError::Codes::SDK_INVAL_ARG, str.data()).GetCode(); + } + return reply.ReadInt32(); +} + +ErrCode ServiceProxy::AppIncrementalDone(ErrCode errCode) +{ + HILOGI("Begin"); + BExcepUltils::BAssert(Remote(), BError::Codes::SDK_INVAL_ARG, "Remote is nullptr"); + MessageParcel data; + if (!data.WriteInterfaceToken(GetDescriptor())) { + return BError(BError::Codes::SDK_INVAL_ARG, "Failed to write descriptor").GetCode(); + } + + if (!data.WriteInt32(errCode)) { + return BError(BError::Codes::SDK_INVAL_ARG, "Failed to send the errCode").GetCode(); + } + + MessageParcel reply; + MessageOption option; + int32_t ret = Remote()->SendRequest(static_cast(IServiceInterfaceCode::SERVICE_CMD_APP_INCREMENTAL_DONE), + data, reply, option); + if (ret != NO_ERROR) { + string str = "Failed to send out the request because of " + to_string(ret); + return BError(BError::Codes::SDK_INVAL_ARG, str.data()).GetCode(); + } + return reply.ReadInt32(); +} + +ErrCode ServiceProxy::GetIncrementalFileHandle(const std::string &bundleName, const std::string &fileName) +{ + HILOGI("Begin"); + BExcepUltils::BAssert(Remote(), BError::Codes::SDK_INVAL_ARG, "Remote is nullptr"); + MessageParcel data; + if (!data.WriteInterfaceToken(GetDescriptor())) { + return BError(BError::Codes::SDK_INVAL_ARG, "Failed to write descriptor").GetCode(); + } + + if (!data.WriteString(bundleName)) { + return BError(BError::Codes::SDK_INVAL_ARG, "Failed to send the bundleName").GetCode(); + } + if (!data.WriteString(fileName)) { + return BError(BError::Codes::SDK_INVAL_ARG, "Failed to send the fileName").GetCode(); + } + + MessageParcel reply; + MessageOption option; + option.SetFlags(MessageOption::TF_ASYNC); + int32_t ret = Remote()->SendRequest( + static_cast(IServiceInterfaceCode::SERVICE_CMD_GET_INCREMENTAL_FILE_NAME), data, reply, option); + if (ret != NO_ERROR) { + string str = "Failed to send out the request because of " + to_string(ret); + return BError(BError::Codes::SDK_INVAL_ARG, str.data()).GetCode(); + } + return ret; +} + +template +bool ServiceProxy::WriteParcelableVector(const std::vector &parcelableVector, Parcel &data) +{ + if (!data.WriteUint32(parcelableVector.size())) { + HILOGE("failed to WriteInt32 for parcelableVector.size()"); + return false; + } + + for (const auto &parcelable : parcelableVector) { + if (!data.WriteParcelable(&parcelable)) { + HILOGE("failed to WriteParcelable for parcelable"); + return false; + } + } + + return true; +} +} // namespace OHOS::FileManagement::Backup \ No newline at end of file diff --git a/frameworks/native/backup_kit_inner/src/service_incremental_reverse.cpp b/frameworks/native/backup_kit_inner/src/service_incremental_reverse.cpp new file mode 100644 index 000000000..5378ac946 --- /dev/null +++ b/frameworks/native/backup_kit_inner/src/service_incremental_reverse.cpp @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2023 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "service_reverse.h" + +#include "b_error/b_error.h" +#include "filemgmt_libhilog.h" + +namespace OHOS::FileManagement::Backup { +using namespace std; + +void ServiceReverse::IncrementalBackupOnFileReady(string bundleName, string fileName, int fd, int manifestFd) +{ + HILOGI("begin"); + if (scenario_ != Scenario::BACKUP || !callbacksIncrementalBackup_.onFileReady) { + HILOGI("Error scenario or callback is nullptr"); + return; + } + BFileInfo bFileInfo(bundleName, fileName, 0); + callbacksIncrementalBackup_.onFileReady(bFileInfo, UniqueFd(fd), UniqueFd(manifestFd)); +} + +void ServiceReverse::IncrementalBackupOnBundleStarted(int32_t errCode, string bundleName) +{ + HILOGI("begin"); + if (scenario_ != Scenario::BACKUP || !callbacksIncrementalBackup_.onBundleStarted) { + HILOGI("Error scenario or callback is nullptr"); + return; + } + callbacksIncrementalBackup_.onBundleStarted(errCode, bundleName); +} + +void ServiceReverse::IncrementalBackupOnBundleFinished(int32_t errCode, string bundleName) +{ + HILOGI("begin"); + if (scenario_ != Scenario::BACKUP || !callbacksIncrementalBackup_.onBundleFinished) { + HILOGI("Error scenario or callback is nullptr"); + return; + } + callbacksIncrementalBackup_.onBundleFinished(errCode, bundleName); +} + +void ServiceReverse::IncrementalBackupOnAllBundlesFinished(int32_t errCode) +{ + HILOGI("errCode = %{public}d", errCode); + if (scenario_ != Scenario::BACKUP || !callbacksIncrementalBackup_.onAllBundlesFinished) { + HILOGI("Error scenario or callback is nullptr"); + return; + } + callbacksIncrementalBackup_.onAllBundlesFinished(errCode); +} + +void ServiceReverse::IncrementalRestoreOnBundleStarted(int32_t errCode, string bundleName) +{ + HILOGI("begin"); + if (scenario_ != Scenario::RESTORE || !callbacksIncrementalRestore_.onBundleStarted) { + HILOGI("Error scenario or callback is nullptr"); + return; + } + callbacksIncrementalRestore_.onBundleStarted(errCode, bundleName); +} + +void ServiceReverse::IncrementalRestoreOnBundleFinished(int32_t errCode, string bundleName) +{ + HILOGI("begin"); + if (scenario_ != Scenario::RESTORE || !callbacksIncrementalRestore_.onBundleFinished) { + HILOGI("Error scenario or callback is nullptr"); + return; + } + callbacksIncrementalRestore_.onBundleFinished(errCode, bundleName); +} + +void ServiceReverse::IncrementalRestoreOnAllBundlesFinished(int32_t errCode) +{ + HILOGI("errCode = %{public}d", errCode); + if (scenario_ != Scenario::RESTORE || !callbacksIncrementalRestore_.onAllBundlesFinished) { + HILOGI("Error scenario or callback is nullptr"); + return; + } + callbacksIncrementalRestore_.onAllBundlesFinished(errCode); +} + +void ServiceReverse::IncrementalRestoreOnFileReady(string bundleName, string fileName, int fd, int manifestFd) +{ + HILOGI("begin"); + if (scenario_ != Scenario::RESTORE || !callbacksIncrementalRestore_.onFileReady) { + HILOGI("Error scenario or callback is nullptr"); + return; + } + BFileInfo bFileInfo(bundleName, fileName, 0); + callbacksIncrementalRestore_.onFileReady(bFileInfo, UniqueFd(fd), UniqueFd(manifestFd)); +} + +ServiceReverse::ServiceReverse(BIncrementalBackupSession::Callbacks callbacks) + : scenario_(Scenario::BACKUP), callbacksIncrementalBackup_(callbacks) +{ +} + +ServiceReverse::ServiceReverse(BIncrementalRestoreSession::Callbacks callbacks) + : scenario_(Scenario::RESTORE), callbacksIncrementalRestore_(callbacks) +{ +} +} // namespace OHOS::FileManagement::Backup \ No newline at end of file diff --git a/frameworks/native/backup_kit_inner/src/service_reverse_stub.cpp b/frameworks/native/backup_kit_inner/src/service_reverse_stub.cpp index 7cfcb79c0..cda7f3521 100644 --- a/frameworks/native/backup_kit_inner/src/service_reverse_stub.cpp +++ b/frameworks/native/backup_kit_inner/src/service_reverse_stub.cpp @@ -63,6 +63,30 @@ ServiceReverseStub::ServiceReverseStub() &ServiceReverseStub::CmdRestoreOnAllBundlesFinished; opToInterfaceMap_[static_cast(IServiceReverseInterfaceCode::SERVICER_RESTORE_ON_FILE_READY)] = &ServiceReverseStub::CmdRestoreOnFileReady; + + opToInterfaceMap_[static_cast(IServiceReverseInterfaceCode::SERVICER_INCREMENTAL_BACKUP_ON_FILE_READY)] = + &ServiceReverseStub::CmdIncrementalBackupOnFileReady; + opToInterfaceMap_[static_cast( + IServiceReverseInterfaceCode::SERVICER_INCREMENTAL_BACKUP_ON_SUB_TASK_STARTED)] = + &ServiceReverseStub::CmdIncrementalBackupOnBundleStarted; + opToInterfaceMap_[static_cast( + IServiceReverseInterfaceCode::SERVICER_INCREMENTAL_BACKUP_ON_SUB_TASK_FINISHED)] = + &ServiceReverseStub::CmdIncrementalBackupOnBundleFinished; + opToInterfaceMap_[static_cast( + IServiceReverseInterfaceCode::SERVICER_INCREMENTAL_BACKUP_ON_TASK_FINISHED)] = + &ServiceReverseStub::CmdIncrementalBackupOnAllBundlesFinished; + + opToInterfaceMap_[static_cast( + IServiceReverseInterfaceCode::SERVICER_INCREMENTAL_RESTORE_ON_SUB_TASK_STARTED)] = + &ServiceReverseStub::CmdIncrementalRestoreOnBundleStarted; + opToInterfaceMap_[static_cast( + IServiceReverseInterfaceCode::SERVICER_INCREMENTAL_RESTORE_ON_SUB_TASK_FINISHED)] = + &ServiceReverseStub::CmdIncrementalRestoreOnBundleFinished; + opToInterfaceMap_[static_cast( + IServiceReverseInterfaceCode::SERVICER_INCREMENTAL_RESTORE_ON_TASK_FINISHED)] = + &ServiceReverseStub::CmdIncrementalRestoreOnAllBundlesFinished; + opToInterfaceMap_[static_cast(IServiceReverseInterfaceCode::SERVICER_INCREMENTAL_RESTORE_ON_FILE_READY)] = + &ServiceReverseStub::CmdIncrementalRestoreOnFileReady; } int32_t ServiceReverseStub::CmdBackupOnFileReady(MessageParcel &data, MessageParcel &reply) @@ -128,4 +152,70 @@ int32_t ServiceReverseStub::CmdRestoreOnFileReady(MessageParcel &data, MessagePa RestoreOnFileReady(bundleName, fileName, fd); return BError(BError::Codes::OK); } + +int32_t ServiceReverseStub::CmdIncrementalBackupOnFileReady(MessageParcel &data, MessageParcel &reply) +{ + auto bundleName = data.ReadString(); + auto fileName = data.ReadString(); + int fd = data.ReadFileDescriptor(); + int manifestFd = data.ReadFileDescriptor(); + IncrementalBackupOnFileReady(bundleName, fileName, fd, manifestFd); + return BError(BError::Codes::OK); +} + +int32_t ServiceReverseStub::CmdIncrementalBackupOnBundleStarted(MessageParcel &data, MessageParcel &reply) +{ + int32_t errCode = data.ReadInt32(); + auto bundleName = data.ReadString(); + IncrementalBackupOnBundleStarted(errCode, bundleName); + return BError(BError::Codes::OK); +} + +int32_t ServiceReverseStub::CmdIncrementalBackupOnBundleFinished(MessageParcel &data, MessageParcel &reply) +{ + int32_t errCode = data.ReadInt32(); + auto bundleName = data.ReadString(); + IncrementalBackupOnBundleFinished(errCode, bundleName); + return BError(BError::Codes::OK); +} + +int32_t ServiceReverseStub::CmdIncrementalBackupOnAllBundlesFinished(MessageParcel &data, MessageParcel &reply) +{ + int32_t errCode = data.ReadInt32(); + IncrementalBackupOnAllBundlesFinished(errCode); + return BError(BError::Codes::OK); +} + +int32_t ServiceReverseStub::CmdIncrementalRestoreOnBundleStarted(MessageParcel &data, MessageParcel &reply) +{ + int32_t errCode = data.ReadInt32(); + auto bundleName = data.ReadString(); + IncrementalRestoreOnBundleStarted(errCode, bundleName); + return BError(BError::Codes::OK); +} + +int32_t ServiceReverseStub::CmdIncrementalRestoreOnBundleFinished(MessageParcel &data, MessageParcel &reply) +{ + int32_t errCode = data.ReadInt32(); + auto bundleName = data.ReadString(); + IncrementalRestoreOnBundleFinished(errCode, bundleName); + return BError(BError::Codes::OK); +} + +int32_t ServiceReverseStub::CmdIncrementalRestoreOnAllBundlesFinished(MessageParcel &data, MessageParcel &reply) +{ + int32_t errCode = data.ReadInt32(); + IncrementalRestoreOnAllBundlesFinished(errCode); + return BError(BError::Codes::OK); +} + +int32_t ServiceReverseStub::CmdIncrementalRestoreOnFileReady(MessageParcel &data, MessageParcel &reply) +{ + auto bundleName = data.ReadString(); + auto fileName = data.ReadString(); + int fd = data.ReadFileDescriptor(); + int manifestFd = data.ReadFileDescriptor(); + IncrementalRestoreOnFileReady(bundleName, fileName, fd, manifestFd); + return BError(BError::Codes::OK); +} } // namespace OHOS::FileManagement::Backup \ No newline at end of file diff --git a/interfaces/inner_api/native/backup_kit_inner/BUILD.gn b/interfaces/inner_api/native/backup_kit_inner/BUILD.gn index 5d4dcbd28..02da6b9fd 100644 --- a/interfaces/inner_api/native/backup_kit_inner/BUILD.gn +++ b/interfaces/inner_api/native/backup_kit_inner/BUILD.gn @@ -43,9 +43,14 @@ ohos_shared_library("backup_kit_inner") { sources = [ "${path_backup}/frameworks/native/backup_kit_inner/src/b_file_info.cpp", + "${path_backup}/frameworks/native/backup_kit_inner/src/b_incremental_backup_session.cpp", + "${path_backup}/frameworks/native/backup_kit_inner/src/b_incremental_data.cpp", + "${path_backup}/frameworks/native/backup_kit_inner/src/b_incremental_restore_session.cpp", "${path_backup}/frameworks/native/backup_kit_inner/src/b_session_backup.cpp", "${path_backup}/frameworks/native/backup_kit_inner/src/b_session_restore.cpp", "${path_backup}/frameworks/native/backup_kit_inner/src/b_session_restore_async.cpp", + "${path_backup}/frameworks/native/backup_kit_inner/src/service_incremental_proxy.cpp", + "${path_backup}/frameworks/native/backup_kit_inner/src/service_incremental_reverse.cpp", "${path_backup}/frameworks/native/backup_kit_inner/src/service_proxy.cpp", "${path_backup}/frameworks/native/backup_kit_inner/src/service_reverse.cpp", "${path_backup}/frameworks/native/backup_kit_inner/src/service_reverse_stub.cpp", diff --git a/interfaces/inner_api/native/backup_kit_inner/backup_kit_inner.h b/interfaces/inner_api/native/backup_kit_inner/backup_kit_inner.h index 7277da994..dfe4e48a4 100644 --- a/interfaces/inner_api/native/backup_kit_inner/backup_kit_inner.h +++ b/interfaces/inner_api/native/backup_kit_inner/backup_kit_inner.h @@ -16,6 +16,8 @@ #ifndef OHOS_FILEMGMT_BACKUP_BACKUP_KIT_INNER_H #define OHOS_FILEMGMT_BACKUP_BACKUP_KIT_INNER_H +#include "impl/b_incremental_backup_session.h" +#include "impl/b_incremental_restore_session.h" #include "impl/b_session_backup.h" #include "impl/b_session_restore.h" #include "impl/b_session_restore_async.h" diff --git a/interfaces/inner_api/native/backup_kit_inner/impl/b_incremental_backup_session.h b/interfaces/inner_api/native/backup_kit_inner/impl/b_incremental_backup_session.h new file mode 100644 index 000000000..c0805aa79 --- /dev/null +++ b/interfaces/inner_api/native/backup_kit_inner/impl/b_incremental_backup_session.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2023 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_FILEMGMT_BACKUP_B_INCREMENTAL_BACKUP_BACKUP_H +#define OHOS_FILEMGMT_BACKUP_B_INCREMENTAL_BACKUP_BACKUP_H + +#include +#include +#include + +#include "b_file_info.h" +#include "b_incremental_data.h" +#include "errors.h" +#include "svc_death_recipient.h" +#include "unique_fd.h" + +namespace OHOS::FileManagement::Backup { +class BIncrementalBackupSession { +public: + struct Callbacks { + std::function onFileReady; // 当备份服务有文件待发送时执行的回调 + std::function onBundleStarted; // 当启动某个应用的备份流程结束时执行的回调函数 + std::function onBundleFinished; // 当某个应用的备份流程结束或意外中止时执行的回调函数 + std::function onAllBundlesFinished; // 当整个备份流程结束或意外中止时执行的回调函数 + std::function onBackupServiceDied; // 当备份服务意外死亡时执行的回调函数 + }; + +public: + /** + * @brief 获取一个用于控制备份流程的会话 + * + * @param callbacks 注册回调 + * @return std::unique_ptr 指向会话的智能指针。失败时为空指针 + */ + static std::unique_ptr Init(Callbacks callbacks); + + /** + * @brief 用于追加应用,现阶段仅支持在Start之前调用 + * + * @param bundlesToBackup 待备份的应用清单 + * @return ErrCode 规范错误码 + */ + ErrCode AppendBundles(std::vector bundlesToBackup); + + /** + * @brief 用于结束服务 + * + * @return ErrCode 规范错误码 + */ + ErrCode Release(); + + /** + * @brief 注册备份服务意外死亡时执行的回调函数 + * + * @param functor 回调函数 + */ + void RegisterBackupServiceDied(std::function functor); + +public: + ~BIncrementalBackupSession(); + +private: + sptr deathRecipient_; +}; +} // namespace OHOS::FileManagement::Backup + +#endif // OHOS_FILEMGMT_BACKUP_B_INCREMENTAL_BACKUP_BACKUP_H \ No newline at end of file diff --git a/interfaces/inner_api/native/backup_kit_inner/impl/b_incremental_data.h b/interfaces/inner_api/native/backup_kit_inner/impl/b_incremental_data.h new file mode 100644 index 000000000..0052e61f4 --- /dev/null +++ b/interfaces/inner_api/native/backup_kit_inner/impl/b_incremental_data.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2023 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_FILEMGMT_BACKUP_B_INCREMENTAL_DATA_H +#define OHOS_FILEMGMT_BACKUP_B_INCREMENTAL_DATA_H + +#include +#include + +#include "parcel.h" +#include "unique_fd.h" + +namespace OHOS::FileManagement::Backup { +struct BIncrementalData : public Parcelable { + std::string bundleName; + int64_t lastIncrementalTime; + int32_t manifestFd; + std::string backupParameters; + std::string backupPriority; + + BIncrementalData() = default; + BIncrementalData(std::string name, int64_t nTime, int fd, std::string parameters = "", std::string priority = "") + : bundleName(name), lastIncrementalTime(nTime), manifestFd(fd), backupParameters(parameters), + backupPriority(priority) + { + } + ~BIncrementalData() override = default; + + bool ReadFromParcel(Parcel &parcel); + bool Marshalling(Parcel &parcel) const override; + static BIncrementalData *Unmarshalling(Parcel &parcel); +}; +} // namespace OHOS::FileManagement::Backup + +#endif // OHOS_FILEMGMT_BACKUP_B_INCREMENTAL_DATA_H diff --git a/interfaces/inner_api/native/backup_kit_inner/impl/b_incremental_restore_session.h b/interfaces/inner_api/native/backup_kit_inner/impl/b_incremental_restore_session.h new file mode 100644 index 000000000..53293d2d9 --- /dev/null +++ b/interfaces/inner_api/native/backup_kit_inner/impl/b_incremental_restore_session.h @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2023 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_FILEMGMT_BACKUP_B_INCREMENTAL_RESTORE_RESTORE_H +#define OHOS_FILEMGMT_BACKUP_B_INCREMENTAL_RESTORE_RESTORE_H + +#include +#include +#include + +#include "b_file_info.h" +#include "b_incremental_data.h" +#include "errors.h" +#include "svc_death_recipient.h" +#include "unique_fd.h" + +namespace OHOS::FileManagement::Backup { +class BIncrementalRestoreSession { +public: + struct Callbacks { + std::function onFileReady; // 当备份服务有文件待发送时执行的回调 + std::function onBundleStarted; // 当启动某个应用的恢复流程结束时执行的回调函数 + std::function onBundleFinished; // 当某个应用的恢复流程结束或意外中止时执行的回调函数 + std::function onAllBundlesFinished; // 当整个恢复流程结束或意外中止时执行的回调函数 + std::function onBackupServiceDied; // 当备份服务意外死亡时执行的回调函数 + }; + +public: + /** + * @brief 获取一个用于控制恢复流程的会话 + * + * @param callbacks 注册的回调函数 + * @return std::unique_ptr 指向BRestoreSession的智能指针。失败时为空指针 + */ + static std::unique_ptr Init(Callbacks callbacks); + + /** + * @brief 通知备份服务文件内容已就绪 + * + * @param fileInfo 文件描述信息 + * @return ErrCode 规范错误码 + * @see GetFileHandle + */ + ErrCode PublishFile(BFileInfo fileInfo); + + /** + * @brief 请求恢复流程所需的真实文件 + * + * @param bundleName 应用名称 + * @param fileName 文件名称 + */ + ErrCode GetFileHandle(const std::string &bundleName, const std::string &fileName); + + /** + * @brief 用于追加应用,现阶段仅支持在Start之前调用 + * + * @param remoteCap 已打开的保存远端设备能力的Json文件。可使用GetLocalCapabilities方法获取 + * @param bundlesToRestore 待恢复的应用清单 + * @return ErrCode 规范错误码 + */ + ErrCode AppendBundles(UniqueFd remoteCap, std::vector bundlesToRestore); + + /** + * @brief 用于结束服务 + * + * @return ErrCode 规范错误码 + */ + ErrCode Release(); + + /** + * @brief 注册备份服务意外死亡时执行的回调函数 + * + * @param functor 回调函数 + */ + void RegisterBackupServiceDied(std::function functor); + +public: + ~BIncrementalRestoreSession(); + +private: + sptr deathRecipient_; +}; +} // namespace OHOS::FileManagement::Backup + +#endif // OHOS_FILEMGMT_BACKUP_B_INCREMENTAL_RESTORE_RESTORE_H \ No newline at end of file diff --git a/interfaces/inner_api/native/backup_kit_inner/impl/b_session_backup.h b/interfaces/inner_api/native/backup_kit_inner/impl/b_session_backup.h index 059e3b798..bed22250c 100644 --- a/interfaces/inner_api/native/backup_kit_inner/impl/b_session_backup.h +++ b/interfaces/inner_api/native/backup_kit_inner/impl/b_session_backup.h @@ -67,6 +67,13 @@ public: */ ErrCode Start(); + /** + * @brief 用于结束服务 + * + * @return ErrCode 规范错误码 + */ + ErrCode Release(); + /** * @brief 注册备份服务意外死亡时执行的回调函数 * diff --git a/interfaces/inner_api/native/backup_kit_inner/impl/b_session_restore.h b/interfaces/inner_api/native/backup_kit_inner/impl/b_session_restore.h index 4654a7bc5..14e730a21 100644 --- a/interfaces/inner_api/native/backup_kit_inner/impl/b_session_restore.h +++ b/interfaces/inner_api/native/backup_kit_inner/impl/b_session_restore.h @@ -85,6 +85,13 @@ public: */ ErrCode Start(); + /** + * @brief 用于结束服务 + * + * @return ErrCode 规范错误码 + */ + ErrCode Release(); + /** * @brief 注册备份服务意外死亡时执行的回调函数 * diff --git a/interfaces/inner_api/native/backup_kit_inner/impl/b_session_restore_async.h b/interfaces/inner_api/native/backup_kit_inner/impl/b_session_restore_async.h index 0d547909e..2b6e0ddcc 100644 --- a/interfaces/inner_api/native/backup_kit_inner/impl/b_session_restore_async.h +++ b/interfaces/inner_api/native/backup_kit_inner/impl/b_session_restore_async.h @@ -86,6 +86,13 @@ public: RestoreTypeEnum restoreType = RestoreTypeEnum::RESTORE_DATA_WAIT_SEND, int32_t userId = DEFAULT_INVAL_VALUE); + /** + * @brief 用于结束服务 + * + * @return ErrCode 规范错误码 + */ + ErrCode Release(); + public: explicit BSessionRestoreAsync(Callbacks callbacks) : callbacks_(callbacks) {}; ~BSessionRestoreAsync(); @@ -94,24 +101,6 @@ private: /** @brief 注册备份服务意外死亡时执行的回调函数 */ void OnBackupServiceDied(); - /** @brief 从暂存队列中取出一次待恢复应用请求 */ - void PopBundleInfo(); - - /** - * @brief 执行待恢复应用请求 - * - * @param info 待恢复应用请求信息 - */ - void AppendBundlesImpl(AppendBundleInfo info); - - /** - * @brief IPC请求异常时通知回调 - * - * @param errCode - * @param bundlesToRestore - */ - void OnBundleStarted(ErrCode errCode, const std::vector &bundlesToRestore); - /** * @brief 注册备份服务意外死亡时执行的回调函数 * diff --git a/interfaces/inner_api/native/backup_kit_inner/impl/i_extension.h b/interfaces/inner_api/native/backup_kit_inner/impl/i_extension.h index ac9e5c09d..c21393e67 100644 --- a/interfaces/inner_api/native/backup_kit_inner/impl/i_extension.h +++ b/interfaces/inner_api/native/backup_kit_inner/impl/i_extension.h @@ -32,6 +32,9 @@ public: virtual ErrCode HandleBackup() = 0; virtual ErrCode PublishFile(const std::string &fileName) = 0; virtual ErrCode HandleRestore() = 0; + virtual ErrCode GetIncrementalFileHandle(const std::string &fileName) = 0; + virtual ErrCode PublishIncrementalFile(const std::string &fileName) = 0; + virtual ErrCode HandleIncrementalBackup(UniqueFd incrementalFd, UniqueFd manifestFd) = 0; }; } // namespace OHOS::FileManagement::Backup diff --git a/interfaces/inner_api/native/backup_kit_inner/impl/i_extension_ipc_interface_code.h b/interfaces/inner_api/native/backup_kit_inner/impl/i_extension_ipc_interface_code.h index 50a8be51a..091f87107 100644 --- a/interfaces/inner_api/native/backup_kit_inner/impl/i_extension_ipc_interface_code.h +++ b/interfaces/inner_api/native/backup_kit_inner/impl/i_extension_ipc_interface_code.h @@ -24,6 +24,9 @@ enum class IExtensionInterfaceCode { CMD_PUBLISH_FILE, CMD_HANDLE_BACKUP, CMD_HANDLE_RESTORE, + CMD_GET_INCREMENTAL_FILE_HANDLE, + CMD_PUBLISH_INCREMENTAL_FILE, + CMD_HANDLE_INCREMENTAL_BACKUP, }; } // namespace OHOS::FileManagement::Backup diff --git a/interfaces/inner_api/native/backup_kit_inner/impl/i_service.h b/interfaces/inner_api/native/backup_kit_inner/impl/i_service.h index e8bb2202a..869a3ca98 100644 --- a/interfaces/inner_api/native/backup_kit_inner/impl/i_service.h +++ b/interfaces/inner_api/native/backup_kit_inner/impl/i_service.h @@ -22,6 +22,7 @@ #include #include "b_file_info.h" +#include "b_incremental_data.h" #include "i_service_ipc_interface_code.h" #include "i_service_reverse.h" #include "iremote_broker.h" @@ -50,6 +51,15 @@ public: int32_t userId = DEFAULT_INVAL_VALUE) = 0; virtual ErrCode AppendBundlesBackupSession(const std::vector &bundleNames) = 0; virtual ErrCode Finish() = 0; + virtual ErrCode Release() = 0; + virtual UniqueFd GetLocalCapabilitiesIncremental(const std::vector &bundleNames) = 0; + virtual ErrCode InitIncrementalBackupSession(sptr remote) = 0; + virtual ErrCode AppendBundlesIncrementalBackupSession(const std::vector &bundlesToBackup) = 0; + + virtual ErrCode PublishIncrementalFile(const BFileInfo &fileInfo) = 0; + virtual ErrCode AppIncrementalFileReady(const std::string &fileName, UniqueFd fd, UniqueFd manifestFd) = 0; + virtual ErrCode AppIncrementalDone(ErrCode errCode) = 0; + virtual ErrCode GetIncrementalFileHandle(const std::string &bundleName, const std::string &fileName) = 0; DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.Filemanagement.Backup.IService") }; diff --git a/interfaces/inner_api/native/backup_kit_inner/impl/i_service_ipc_interface_code.h b/interfaces/inner_api/native/backup_kit_inner/impl/i_service_ipc_interface_code.h index 797921043..0e224a108 100644 --- a/interfaces/inner_api/native/backup_kit_inner/impl/i_service_ipc_interface_code.h +++ b/interfaces/inner_api/native/backup_kit_inner/impl/i_service_ipc_interface_code.h @@ -30,6 +30,14 @@ enum class IServiceInterfaceCode { SERVICE_CMD_APPEND_BUNDLES_RESTORE_SESSION, SERVICE_CMD_APPEND_BUNDLES_BACKUP_SESSION, SERVICE_CMD_FINISH, + SERVICE_CMD_RELSEASE_SESSION, + SERVICE_CMD_GET_LOCAL_CAPABILITIES_INCREMENTAL, + SERVICE_CMD_INIT_INCREMENTAL_BACKUP_SESSION, + SERVICE_CMD_APPEND_BUNDLES_INCREMENTAL_BACKUP_SESSION, + SERVICE_CMD_PUBLISH_INCREMENTAL_FILE, + SERVICE_CMD_APP_INCREMENTAL_FILE_READY, + SERVICE_CMD_APP_INCREMENTAL_DONE, + SERVICE_CMD_GET_INCREMENTAL_FILE_NAME, }; } // namespace OHOS::FileManagement::Backup diff --git a/interfaces/inner_api/native/backup_kit_inner/impl/i_service_reverse.h b/interfaces/inner_api/native/backup_kit_inner/impl/i_service_reverse.h index 0d0f9a7fe..0f959c9c0 100644 --- a/interfaces/inner_api/native/backup_kit_inner/impl/i_service_reverse.h +++ b/interfaces/inner_api/native/backup_kit_inner/impl/i_service_reverse.h @@ -41,6 +41,19 @@ public: virtual void RestoreOnAllBundlesFinished(int32_t errCode) = 0; virtual void RestoreOnFileReady(std::string bundleName, std::string fileName, int fd) = 0; + virtual void IncrementalBackupOnFileReady(std::string bundleName, std::string fileName, int fd, int manifestFd) = 0; + virtual void IncrementalBackupOnBundleStarted(int32_t errCode, std::string bundleName) = 0; + virtual void IncrementalBackupOnBundleFinished(int32_t errCode, std::string bundleName) = 0; + virtual void IncrementalBackupOnAllBundlesFinished(int32_t errCode) = 0; + + virtual void IncrementalRestoreOnBundleStarted(int32_t errCode, std::string bundleName) = 0; + virtual void IncrementalRestoreOnBundleFinished(int32_t errCode, std::string bundleName) = 0; + virtual void IncrementalRestoreOnAllBundlesFinished(int32_t errCode) = 0; + virtual void IncrementalRestoreOnFileReady(std::string bundleName, + std::string fileName, + int fd, + int manifestFd) = 0; + DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.FileManagement.Backup.IServiceReverse") }; } // namespace OHOS::FileManagement::Backup diff --git a/interfaces/inner_api/native/backup_kit_inner/impl/i_service_reverse_ipc_interface_code.h b/interfaces/inner_api/native/backup_kit_inner/impl/i_service_reverse_ipc_interface_code.h index 5fc63b67e..b99203b22 100644 --- a/interfaces/inner_api/native/backup_kit_inner/impl/i_service_reverse_ipc_interface_code.h +++ b/interfaces/inner_api/native/backup_kit_inner/impl/i_service_reverse_ipc_interface_code.h @@ -27,6 +27,14 @@ enum class IServiceReverseInterfaceCode { SERVICER_RESTORE_ON_SUB_TASK_FINISHED, SERVICER_RESTORE_ON_TASK_FINISHED, SERVICER_RESTORE_ON_FILE_READY, + SERVICER_INCREMENTAL_BACKUP_ON_FILE_READY, + SERVICER_INCREMENTAL_BACKUP_ON_SUB_TASK_STARTED, + SERVICER_INCREMENTAL_BACKUP_ON_SUB_TASK_FINISHED, + SERVICER_INCREMENTAL_BACKUP_ON_TASK_FINISHED, + SERVICER_INCREMENTAL_RESTORE_ON_SUB_TASK_STARTED, + SERVICER_INCREMENTAL_RESTORE_ON_SUB_TASK_FINISHED, + SERVICER_INCREMENTAL_RESTORE_ON_TASK_FINISHED, + SERVICER_INCREMENTAL_RESTORE_ON_FILE_READY, }; } // namespace OHOS::FileManagement::Backup diff --git a/interfaces/inner_api/native/backup_kit_inner/impl/service_proxy.h b/interfaces/inner_api/native/backup_kit_inner/impl/service_proxy.h index 5273921a2..67a93868a 100644 --- a/interfaces/inner_api/native/backup_kit_inner/impl/service_proxy.h +++ b/interfaces/inner_api/native/backup_kit_inner/impl/service_proxy.h @@ -42,12 +42,23 @@ public: int32_t userId = DEFAULT_INVAL_VALUE) override; ErrCode AppendBundlesBackupSession(const std::vector &bundleNames) override; ErrCode Finish() override; + ErrCode Release() override; + UniqueFd GetLocalCapabilitiesIncremental(const std::vector &bundleNames) override; + ErrCode InitIncrementalBackupSession(sptr remote) override; + ErrCode AppendBundlesIncrementalBackupSession(const std::vector &bundlesToBackup) override; + + ErrCode PublishIncrementalFile(const BFileInfo &fileInfo) override; + ErrCode AppIncrementalFileReady(const std::string &fileName, UniqueFd fd, UniqueFd manifestFd) override; + ErrCode AppIncrementalDone(ErrCode errCode) override; + ErrCode GetIncrementalFileHandle(const std::string &bundleName, const std::string &fileName) override; public: explicit ServiceProxy(const sptr &impl) : IRemoteProxy(impl) {} ~ServiceProxy() override {} public: + template + bool WriteParcelableVector(const std::vector &parcelableVector, Parcel &data); static sptr GetInstance(); static void InvaildInstance(); diff --git a/services/backup.para b/services/backup.para index 8f4a7ef77..f4817d298 100644 --- a/services/backup.para +++ b/services/backup.para @@ -14,4 +14,7 @@ backup.debug.overrideExtensionConfig=false backup.debug.overrideAccountConfig=false -backup.debug.overrideAccountNumber=0 \ No newline at end of file +backup.debug.overrideAccountNumber=0 + +backup.overrideBackupSARelease=false +backup.overrideIncrementalRestore=false \ No newline at end of file diff --git a/services/backup_sa/BUILD.gn b/services/backup_sa/BUILD.gn index e89cb1f28..6a42bd130 100644 --- a/services/backup_sa/BUILD.gn +++ b/services/backup_sa/BUILD.gn @@ -29,6 +29,8 @@ ohos_shared_library("backup_sa") { "src/module_app_gallery/app_gallery_dispose_proxy.cpp", "src/module_external/bms_adapter.cpp", "src/module_external/sms_adapter.cpp", + "src/module_ipc/service_incremental_reverse_proxy.cpp", + "src/module_ipc/service_incremental.cpp", "src/module_ipc/service.cpp", "src/module_ipc/service_reverse_proxy.cpp", "src/module_ipc/service_stub.cpp", diff --git a/services/backup_sa/include/module_ipc/service.h b/services/backup_sa/include/module_ipc/service.h index 2a2e639bc..8c966e4e0 100644 --- a/services/backup_sa/include/module_ipc/service.h +++ b/services/backup_sa/include/module_ipc/service.h @@ -46,6 +46,16 @@ public: int32_t userId = DEFAULT_INVAL_VALUE) override; ErrCode AppendBundlesBackupSession(const std::vector &bundleNames) override; ErrCode Finish() override; + ErrCode Release() override; + + UniqueFd GetLocalCapabilitiesIncremental(const std::vector &bundleNames) override; + ErrCode InitIncrementalBackupSession(sptr remote) override; + ErrCode AppendBundlesIncrementalBackupSession(const std::vector &bundlesToBackup) override; + + ErrCode PublishIncrementalFile(const BFileInfo &fileInfo) override; + ErrCode AppIncrementalFileReady(const std::string &fileName, UniqueFd fd, UniqueFd manifestFd) override; + ErrCode AppIncrementalDone(ErrCode errCode) override; + ErrCode GetIncrementalFileHandle(const std::string &bundleName, const std::string &fileName) override; // 以下都是非IPC接口 public: @@ -168,6 +178,15 @@ private: */ void HandleRestoreDepsBundle(const std::string &bundleName); + /** + * @brief 增量备份恢复逻辑处理 + * + * @param bundleName + * @return true + * @return false + */ + bool IncrementalBackup(const std::string &bundleName); + private: static sptr instance_; static std::mutex instanceLock_; diff --git a/services/backup_sa/include/module_ipc/service_reverse_proxy.h b/services/backup_sa/include/module_ipc/service_reverse_proxy.h index 5fd75cb57..a7cc854fc 100644 --- a/services/backup_sa/include/module_ipc/service_reverse_proxy.h +++ b/services/backup_sa/include/module_ipc/service_reverse_proxy.h @@ -32,6 +32,16 @@ public: void RestoreOnAllBundlesFinished(int32_t errCode) override; void RestoreOnFileReady(std::string bundleName, std::string fileName, int fd) override; + void IncrementalBackupOnFileReady(std::string bundleName, std::string fileName, int fd, int manifestFd) override; + void IncrementalBackupOnBundleStarted(int32_t errCode, std::string bundleName) override; + void IncrementalBackupOnBundleFinished(int32_t errCode, std::string bundleName) override; + void IncrementalBackupOnAllBundlesFinished(int32_t errCode) override; + + void IncrementalRestoreOnBundleStarted(int32_t errCode, std::string bundleName) override; + void IncrementalRestoreOnBundleFinished(int32_t errCode, std::string bundleName) override; + void IncrementalRestoreOnAllBundlesFinished(int32_t errCode) override; + void IncrementalRestoreOnFileReady(std::string bundleName, std::string fileName, int fd, int manifestFd) override; + public: explicit ServiceReverseProxy(const sptr &impl) : IRemoteProxy(impl) {} ~ServiceReverseProxy() override = default; diff --git a/services/backup_sa/include/module_ipc/service_stub.h b/services/backup_sa/include/module_ipc/service_stub.h index 1049e1574..4fea6bb3c 100644 --- a/services/backup_sa/include/module_ipc/service_stub.h +++ b/services/backup_sa/include/module_ipc/service_stub.h @@ -45,6 +45,18 @@ private: int32_t CmdAppendBundlesRestoreSession(MessageParcel &data, MessageParcel &reply); int32_t CmdAppendBundlesBackupSession(MessageParcel &data, MessageParcel &reply); int32_t CmdFinish(MessageParcel &data, MessageParcel &reply); + int32_t CmdRelease(MessageParcel &data, MessageParcel &reply); + int32_t CmdGetLocalCapabilitiesIncremental(MessageParcel &data, MessageParcel &reply); + int32_t CmdInitIncrementalBackupSession(MessageParcel &data, MessageParcel &reply); + int32_t CmdAppendBundlesIncrementalBackupSession(MessageParcel &data, MessageParcel &reply); + int32_t CmdPublishIncrementalFile(MessageParcel &data, MessageParcel &reply); + int32_t CmdAppIncrementalFileReady(MessageParcel &data, MessageParcel &reply); + int32_t CmdAppIncrementalDone(MessageParcel &data, MessageParcel &reply); + int32_t CmdGetIncrementalFileHandle(MessageParcel &data, MessageParcel &reply); + +public: + template + bool ReadParcelableVector(std::vector &parcelableInfos, MessageParcel &data); }; } // namespace OHOS::FileManagement::Backup diff --git a/services/backup_sa/include/module_ipc/svc_extension_proxy.h b/services/backup_sa/include/module_ipc/svc_extension_proxy.h index b47ba5ded..ac48221f0 100644 --- a/services/backup_sa/include/module_ipc/svc_extension_proxy.h +++ b/services/backup_sa/include/module_ipc/svc_extension_proxy.h @@ -18,6 +18,7 @@ #include "i_extension.h" #include "iremote_proxy.h" +#include "unique_fd.h" namespace OHOS::FileManagement::Backup { class SvcExtensionProxy : public IRemoteProxy { @@ -27,6 +28,9 @@ public: ErrCode HandleBackup() override; ErrCode PublishFile(const std::string &fileName) override; ErrCode HandleRestore() override; + ErrCode GetIncrementalFileHandle(const std::string &fileName) override; + ErrCode PublishIncrementalFile(const std::string &fileName) override; + ErrCode HandleIncrementalBackup(UniqueFd incrementalFd, UniqueFd manifestFd) override; public: explicit SvcExtensionProxy(const sptr &remote) : IRemoteProxy(remote) {} diff --git a/services/backup_sa/include/module_ipc/svc_session_manager.h b/services/backup_sa/include/module_ipc/svc_session_manager.h index 46671ac84..7aa60d8d0 100644 --- a/services/backup_sa/include/module_ipc/svc_session_manager.h +++ b/services/backup_sa/include/module_ipc/svc_session_manager.h @@ -30,6 +30,7 @@ #include #include "b_file_info.h" +#include "b_incremental_data.h" #include "b_resources/b_constants.h" #include "i_service.h" #include "i_service_reverse.h" @@ -57,6 +58,10 @@ struct BackupExtInfo { /* Timer Status: true is start & false is stop */ bool timerStatus {false}; int64_t dataSize; + int64_t lastIncrementalTime; + int32_t manifestFd; + std::string backupParameters; + std::string backupPriority; }; class Service; @@ -75,6 +80,7 @@ public: */ int32_t userId {100}; RestoreTypeEnum restoreDataType {RESTORE_DATA_WAIT_SEND}; + bool isIncrementalBackup {false}; }; public: @@ -377,6 +383,29 @@ public: */ void ClearSessionData(); + /** + * @brief Get the Is Incremental Backup object + * + * @return true + * @return false + */ + bool GetIsIncrementalBackup(); + + /** + * @brief Set the Incremental Data object + * + * @param incrementalData + */ + void SetIncrementalData(const BIncrementalData &incrementalData); + + /** + * @brief Get the Manifest Fd object + * + * @param bundleName 应用名称 + * @return int32_t + */ + int32_t GetIncrementalManifestFd(const std::string &bundleName); + private: /** * @brief 获取backup extension ability diff --git a/services/backup_sa/include/module_sched/sched_scheduler.h b/services/backup_sa/include/module_sched/sched_scheduler.h index 419c87782..5757579fe 100644 --- a/services/backup_sa/include/module_sched/sched_scheduler.h +++ b/services/backup_sa/include/module_sched/sched_scheduler.h @@ -72,11 +72,7 @@ public: */ void TryUnloadService(); - void StartTimer() - { - extTime_.Setup(); - TryUnloadServiceTimer(); - } + void StartTimer(); public: explicit SchedScheduler(wptr reversePtr, wptr sessionPtr) diff --git a/services/backup_sa/src/module_ipc/service.cpp b/services/backup_sa/src/module_ipc/service.cpp index d882ef63f..148e9016c 100644 --- a/services/backup_sa/src/module_ipc/service.cpp +++ b/services/backup_sa/src/module_ipc/service.cpp @@ -592,6 +592,9 @@ void Service::ExtStart(const string &bundleName) { try { HILOGE("begin %{public}s", bundleName.data()); + if (IncrementalBackup(bundleName)) { + return; + } IServiceReverse::Scenario scenario = session_->GetScenario(); auto backUpConnection = session_->GetExtConnection(bundleName); auto proxy = backUpConnection->GetBackupExtProxy(); @@ -652,7 +655,16 @@ void Service::ExtConnectFailed(const string &bundleName, ErrCode ret) try { HILOGE("begin %{public}s", bundleName.data()); IServiceReverse::Scenario scenario = session_->GetScenario(); - if (scenario == IServiceReverse::Scenario::BACKUP) { + if (scenario == IServiceReverse::Scenario::BACKUP && session_->GetIsIncrementalBackup()) { + session_->GetServiceReverseProxy()->IncrementalBackupOnBundleStarted(ret, bundleName); + } else if (scenario == IServiceReverse::Scenario::RESTORE && + BackupPara().GetBackupOverrideIncrementalRestore()) { + session_->GetServiceReverseProxy()->IncrementalRestoreOnBundleStarted(ret, bundleName); + + DisposeErr disposeErr = AppGalleryDisposeProxy::GetInstance()->EndRestore(bundleName); + HILOGI("ExtConnectFailed EndRestore, code=%{public}d, bundleName=%{public}s", disposeErr, + bundleName.c_str()); + } else if (scenario == IServiceReverse::Scenario::BACKUP) { session_->GetServiceReverseProxy()->BackupOnBundleStarted(ret, bundleName); } else if (scenario == IServiceReverse::Scenario::RESTORE) { session_->GetServiceReverseProxy()->RestoreOnBundleStarted(ret, bundleName); @@ -677,7 +689,11 @@ void Service::ExtConnectFailed(const string &bundleName, ErrCode ret) void Service::NoticeClientFinish(const string &bundleName, ErrCode errCode) { auto scenario = session_->GetScenario(); - if (scenario == IServiceReverse::Scenario::BACKUP) { + if (scenario == IServiceReverse::Scenario::BACKUP && session_->GetIsIncrementalBackup()) { + session_->GetServiceReverseProxy()->IncrementalBackupOnBundleFinished(errCode, bundleName); + } else if (scenario == IServiceReverse::Scenario::RESTORE && BackupPara().GetBackupOverrideIncrementalRestore()) { + session_->GetServiceReverseProxy()->IncrementalRestoreOnBundleFinished(errCode, bundleName); + } else if (scenario == IServiceReverse::Scenario::BACKUP) { session_->GetServiceReverseProxy()->BackupOnBundleFinished(errCode, bundleName); } else if (scenario == IServiceReverse::Scenario::RESTORE) { session_->GetServiceReverseProxy()->RestoreOnBundleFinished(errCode, bundleName); @@ -783,12 +799,19 @@ void Service::OnAllBundlesFinished(ErrCode errCode) { if (session_->IsOnAllBundlesFinished()) { IServiceReverse::Scenario scenario = session_->GetScenario(); - if (scenario == IServiceReverse::Scenario::BACKUP) { + if (scenario == IServiceReverse::Scenario::BACKUP && session_->GetIsIncrementalBackup()) { + session_->GetServiceReverseProxy()->IncrementalBackupOnAllBundlesFinished(errCode); + } else if (scenario == IServiceReverse::Scenario::RESTORE && + BackupPara().GetBackupOverrideIncrementalRestore()) { + session_->GetServiceReverseProxy()->IncrementalRestoreOnAllBundlesFinished(errCode); + } else if (scenario == IServiceReverse::Scenario::BACKUP) { session_->GetServiceReverseProxy()->BackupOnAllBundlesFinished(errCode); } else if (scenario == IServiceReverse::Scenario::RESTORE) { session_->GetServiceReverseProxy()->RestoreOnAllBundlesFinished(errCode); } - sched_->TryUnloadServiceTimer(true); + if (!BackupPara().GetBackupOverrideBackupSARelease()) { + sched_->TryUnloadServiceTimer(true); + } } } diff --git a/services/backup_sa/src/module_ipc/service_incremental.cpp b/services/backup_sa/src/module_ipc/service_incremental.cpp new file mode 100644 index 000000000..f8ede49c4 --- /dev/null +++ b/services/backup_sa/src/module_ipc/service_incremental.cpp @@ -0,0 +1,321 @@ +/* + * Copyright (c) 2023 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * 注意: + * - 注意点1:本文件原则上只处理与IPC无关的业务逻辑 + * - 注意点2:This document, in principle, captures all exceptions. + * Prevent exceptions from spreading to insecure modules. + */ +#include "module_ipc/service.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "ability_manager_client.h" +#include "accesstoken_kit.h" +#include "b_error/b_error.h" +#include "b_error/b_excep_utils.h" +#include "b_file_info.h" +#include "b_json/b_json_cached_entity.h" +#include "b_json/b_json_entity_caps.h" +#include "b_ohos/startup/backup_para.h" +#include "b_process/b_multiuser.h" +#include "b_resources/b_constants.h" +#include "bundle_mgr_client.h" +#include "filemgmt_libhilog.h" +#include "ipc_skeleton.h" +#include "module_app_gallery/app_gallery_dispose_proxy.h" +#include "module_external/bms_adapter.h" +#include "module_ipc/svc_backup_connection.h" +#include "module_ipc/svc_restore_deps_manager.h" +#include "parameter.h" +#include "system_ability_definition.h" +#include "unique_fd.h" + +namespace OHOS::FileManagement::Backup { +using namespace std; + +namespace { +constexpr int32_t DEBUG_ID = 100; +} // namespace + +static inline int32_t GetUserIdDefault() +{ + auto [isDebug, debugId] = BackupPara().GetBackupDebugOverrideAccount(); + if (isDebug && debugId > DEBUG_ID) { + return debugId; + } + auto multiuser = BMultiuser::ParseUid(IPCSkeleton::GetCallingUid()); + if ((multiuser.userId == BConstants::SYSTEM_UID) || (multiuser.userId == BConstants::XTS_UID)) { + return BConstants::DEFAULT_USER_ID; + } + return multiuser.userId; +} + +ErrCode Service::Release() +{ + HILOGI("KILL"); + VerifyCaller(session_->GetScenario()); + SessionDeactive(); + return BError(BError::Codes::OK); +} + +UniqueFd Service::GetLocalCapabilitiesIncremental(const std::vector &bundleNames) +{ + HILOGI("Begin"); + return UniqueFd(-1); +} + +ErrCode Service::InitIncrementalBackupSession(sptr remote) +{ + HILOGI("Begin"); + try { + VerifyCaller(); + session_->Active({.clientToken = IPCSkeleton::GetCallingTokenID(), + .scenario = IServiceReverse::Scenario::BACKUP, + .clientProxy = remote, + .userId = GetUserIdDefault(), + .isIncrementalBackup = true}); + return BError(BError::Codes::OK); + } catch (const BError &e) { + StopAll(nullptr, true); + return e.GetCode(); + } +} + +ErrCode Service::AppendBundlesIncrementalBackupSession(const std::vector &bundlesToBackup) +{ + try { + HILOGI("Begin"); + session_->IncreaseSessionCnt(); // BundleMgrAdapter::GetBundleInfos可能耗时 + VerifyCaller(IServiceReverse::Scenario::BACKUP); + vector bundleNames {}; + for (auto &bundle : bundlesToBackup) { + bundleNames.emplace_back(bundle.bundleName); + } + auto backupInfos = BundleMgrAdapter::GetBundleInfos(bundleNames, session_->GetSessionUserId()); + session_->AppendBundles(bundleNames); + for (auto info : backupInfos) { + session_->SetBundleDataSize(info.name, info.spaceOccupied); + session_->SetBackupExtName(info.name, info.extensionName); + if (info.allToBackup == false) { + session_->GetServiceReverseProxy()->IncrementalBackupOnBundleStarted( + BError(BError::Codes::SA_FORBID_BACKUP_RESTORE), info.name); + session_->RemoveExtInfo(info.name); + } + } + for (auto &bundleInfo : bundlesToBackup) { + session_->SetIncrementalData(bundleInfo); + } + OnStartSched(); + session_->DecreaseSessionCnt(); + return BError(BError::Codes::OK); + } catch (const BError &e) { + session_->DecreaseSessionCnt(); + HILOGE("Failed, errCode = %{public}d", e.GetCode()); + return e.GetCode(); + } catch (...) { + session_->DecreaseSessionCnt(); + HILOGI("Unexpected exception"); + return EPERM; + } +} + +ErrCode Service::PublishIncrementalFile(const BFileInfo &fileInfo) +{ + try { + HILOGI("Begin"); + VerifyCaller(IServiceReverse::Scenario::RESTORE); + + auto backUpConnection = session_->GetExtConnection(fileInfo.owner); + auto proxy = backUpConnection->GetBackupExtProxy(); + if (!proxy) { + throw BError(BError::Codes::SA_INVAL_ARG, "Extension backup Proxy is empty"); + } + ErrCode res = proxy->PublishIncrementalFile(fileInfo.fileName); + if (res) { + HILOGE("Failed to publish file for backup extension"); + } + + return res; + } catch (const BError &e) { + return e.GetCode(); + } catch (const exception &e) { + HILOGI("Catched an unexpected low-level exception %{public}s", e.what()); + return EPERM; + } catch (...) { + HILOGI("Unexpected exception"); + return EPERM; + } +} + +ErrCode Service::AppIncrementalFileReady(const std::string &fileName, UniqueFd fd, UniqueFd manifestFd) +{ + try { + HILOGI("Begin"); + string callerName = VerifyCallerAndGetCallerName(); + if (fileName == BConstants::EXT_BACKUP_MANAGE) { + fd = session_->OnBunleExtManageInfo(callerName, move(fd)); + } + + if (session_->GetScenario() == IServiceReverse::Scenario::RESTORE) { + session_->GetServiceReverseProxy()->IncrementalRestoreOnFileReady(callerName, fileName, move(fd), + move(manifestFd)); + return BError(BError::Codes::OK); + } + + session_->GetServiceReverseProxy()->IncrementalBackupOnFileReady(callerName, fileName, move(fd), + move(manifestFd)); + if (session_->OnBunleFileReady(callerName, fileName)) { + auto backUpConnection = session_->GetExtConnection(callerName); + auto proxy = backUpConnection->GetBackupExtProxy(); + if (!proxy) { + throw BError(BError::Codes::SA_INVAL_ARG, "Extension backup Proxy is empty"); + } + // 通知extension清空缓存 + proxy->HandleClear(); + // 清除Timer + session_->BundleExtTimerStop(callerName); + // 通知TOOL 备份完成 + session_->GetServiceReverseProxy()->IncrementalBackupOnBundleFinished(BError(BError::Codes::OK), + callerName); + // 断开extension + backUpConnection->DisconnectBackupExtAbility(); + ClearSessionAndSchedInfo(callerName); + } + OnAllBundlesFinished(BError(BError::Codes::OK)); + return BError(BError::Codes::OK); + } catch (const BError &e) { + return e.GetCode(); // 任意异常产生,终止监听该任务 + } catch (const exception &e) { + HILOGI("Catched an unexpected low-level exception %{public}s", e.what()); + return EPERM; + } catch (...) { + HILOGI("Unexpected exception"); + return EPERM; + } +} + +ErrCode Service::AppIncrementalDone(ErrCode errCode) +{ + try { + HILOGI("Begin"); + string callerName = VerifyCallerAndGetCallerName(); + if (session_->OnBunleFileReady(callerName)) { + auto backUpConnection = session_->GetExtConnection(callerName); + auto proxy = backUpConnection->GetBackupExtProxy(); + if (!proxy) { + throw BError(BError::Codes::SA_INVAL_ARG, "Extension backup Proxy is empty"); + } + proxy->HandleClear(); + session_->BundleExtTimerStop(callerName); + IServiceReverse::Scenario scenario = session_->GetScenario(); + if (scenario == IServiceReverse::Scenario::BACKUP) { + session_->GetServiceReverseProxy()->IncrementalBackupOnBundleFinished(errCode, callerName); + } else if (scenario == IServiceReverse::Scenario::RESTORE) { + session_->GetServiceReverseProxy()->IncrementalRestoreOnBundleFinished(errCode, callerName); + } + backUpConnection->DisconnectBackupExtAbility(); + ClearSessionAndSchedInfo(callerName); + } + OnAllBundlesFinished(BError(BError::Codes::OK)); + return BError(BError::Codes::OK); + } catch (const BError &e) { + return e.GetCode(); // 任意异常产生,终止监听该任务 + } catch (const exception &e) { + HILOGI("Catched an unexpected low-level exception %{public}s", e.what()); + return EPERM; + } catch (...) { + HILOGI("Unexpected exception"); + return EPERM; + } +} + +ErrCode Service::GetIncrementalFileHandle(const std::string &bundleName, const std::string &fileName) +{ + try { + HILOGI("Begin"); + VerifyCaller(IServiceReverse::Scenario::RESTORE); + auto action = session_->GetServiceSchedAction(bundleName); + if (action == BConstants::ServiceSchedAction::RUNNING) { + auto backUpConnection = session_->GetExtConnection(bundleName); + auto proxy = backUpConnection->GetBackupExtProxy(); + if (!proxy) { + throw BError(BError::Codes::SA_INVAL_ARG, "Extension backup Proxy is empty"); + } + int res = proxy->GetIncrementalFileHandle(fileName); + if (res) { + HILOGE("Failed to extension file handle"); + } + } else { + SvcRestoreDepsManager::GetInstance().UpdateToRestoreBundleMap(bundleName, fileName); + session_->SetExtFileNameRequest(bundleName, fileName); + } + return BError(BError::Codes::OK); + } catch (const BError &e) { + return e.GetCode(); + } catch (const exception &e) { + HILOGI("Catched an unexpected low-level exception %{public}s", e.what()); + return EPERM; + } catch (...) { + HILOGI("Unexpected exception"); + return EPERM; + } +} + +bool Service::IncrementalBackup(const string &bundleName) +{ + IServiceReverse::Scenario scenario = session_->GetScenario(); + auto backUpConnection = session_->GetExtConnection(bundleName); + auto proxy = backUpConnection->GetBackupExtProxy(); + if (!proxy) { + throw BError(BError::Codes::SA_INVAL_ARG, "Extension backup Proxy is empty"); + } + if (scenario == IServiceReverse::Scenario::BACKUP && session_->GetIsIncrementalBackup()) { + UniqueFd fd; + UniqueFd manifestFd(session_->GetIncrementalManifestFd(bundleName)); + auto ret = proxy->HandleIncrementalBackup(move(fd), move(manifestFd)); + session_->GetServiceReverseProxy()->IncrementalBackupOnBundleStarted(ret, bundleName); + if (ret) { + ClearSessionAndSchedInfo(bundleName); + } + return true; + } else if (scenario == IServiceReverse::Scenario::RESTORE && BackupPara().GetBackupOverrideIncrementalRestore()) { + auto ret = proxy->HandleRestore(); + session_->GetServiceReverseProxy()->IncrementalRestoreOnBundleStarted(ret, bundleName); + auto fileNameVec = session_->GetExtFileNameRequest(bundleName); + for (auto &fileName : fileNameVec) { + ret = proxy->GetIncrementalFileHandle(fileName); + if (ret) { + HILOGE("Failed to extension file handle %{public}s", fileName.c_str()); + } + } + return true; + } + return false; +} +} // namespace OHOS::FileManagement::Backup diff --git a/services/backup_sa/src/module_ipc/service_incremental_reverse_proxy.cpp b/services/backup_sa/src/module_ipc/service_incremental_reverse_proxy.cpp new file mode 100644 index 000000000..dc9b1dfc3 --- /dev/null +++ b/services/backup_sa/src/module_ipc/service_incremental_reverse_proxy.cpp @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2023 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "module_ipc/service_reverse_proxy.h" + +#include "b_error/b_error.h" +#include "b_error/b_excep_utils.h" +#include "filemgmt_libhilog.h" +#include "module_app_gallery/app_gallery_dispose_proxy.h" + +namespace OHOS::FileManagement::Backup { +using namespace std; + +void ServiceReverseProxy::IncrementalBackupOnFileReady(string bundleName, string fileName, int fd, int manifestFd) +{ + HILOGI("Begin"); + BExcepUltils::BAssert(Remote(), BError::Codes::SDK_INVAL_ARG, "Remote is nullptr"); + MessageParcel data; + if (!data.WriteInterfaceToken(GetDescriptor()) || !data.WriteString(bundleName) || !data.WriteString(fileName) || + !data.WriteFileDescriptor(fd) || !data.WriteFileDescriptor(manifestFd)) { + throw BError(BError::Codes::SA_BROKEN_IPC); + } + + MessageParcel reply; + MessageOption option; + if (int err = Remote()->SendRequest( + static_cast(IServiceReverseInterfaceCode::SERVICER_INCREMENTAL_BACKUP_ON_FILE_READY), data, reply, + option); + err != ERR_OK) { + throw BError(BError::Codes::SA_BROKEN_IPC, to_string(err)); + } +} + +void ServiceReverseProxy::IncrementalBackupOnBundleStarted(int32_t errCode, string bundleName) +{ + HILOGI("Begin"); + BExcepUltils::BAssert(Remote(), BError::Codes::SDK_INVAL_ARG, "Remote is nullptr"); + MessageParcel data; + if (!data.WriteInterfaceToken(GetDescriptor()) || !data.WriteInt32(errCode) || !data.WriteString(bundleName)) { + throw BError(BError::Codes::SA_BROKEN_IPC); + }; + + MessageParcel reply; + MessageOption option; + if (int err = Remote()->SendRequest( + static_cast(IServiceReverseInterfaceCode::SERVICER_INCREMENTAL_BACKUP_ON_SUB_TASK_STARTED), data, + reply, option); + err != ERR_OK) { + throw BError(BError::Codes::SA_BROKEN_IPC, to_string(err)); + } +} + +void ServiceReverseProxy::IncrementalBackupOnBundleFinished(int32_t errCode, string bundleName) +{ + HILOGI("Begin"); + BExcepUltils::BAssert(Remote(), BError::Codes::SDK_INVAL_ARG, "Remote is nullptr"); + MessageParcel data; + if (!data.WriteInterfaceToken(GetDescriptor()) || !data.WriteInt32(errCode) || !data.WriteString(bundleName)) { + throw BError(BError::Codes::SA_BROKEN_IPC); + } + + MessageParcel reply; + MessageOption option; + if (int err = Remote()->SendRequest( + static_cast(IServiceReverseInterfaceCode::SERVICER_INCREMENTAL_BACKUP_ON_SUB_TASK_FINISHED), data, + reply, option); + err != ERR_OK) { + throw BError(BError::Codes::SA_BROKEN_IPC, to_string(err)); + } +} + +void ServiceReverseProxy::IncrementalBackupOnAllBundlesFinished(int32_t errCode) +{ + HILOGI("Begin"); + BExcepUltils::BAssert(Remote(), BError::Codes::SDK_INVAL_ARG, "Remote is nullptr"); + MessageParcel data; + if (!data.WriteInterfaceToken(GetDescriptor()) || !data.WriteInt32(errCode)) { + throw BError(BError::Codes::SA_BROKEN_IPC); + } + + MessageParcel reply; + MessageOption option; + if (int err = Remote()->SendRequest( + static_cast(IServiceReverseInterfaceCode::SERVICER_INCREMENTAL_BACKUP_ON_TASK_FINISHED), data, + reply, option); + err != ERR_OK) { + throw BError(BError::Codes::SA_BROKEN_IPC, to_string(err)); + } +} + +void ServiceReverseProxy::IncrementalRestoreOnBundleStarted(int32_t errCode, string bundleName) +{ + HILOGI("Begin"); + BExcepUltils::BAssert(Remote(), BError::Codes::SDK_INVAL_ARG, "Remote is nullptr"); + MessageParcel data; + if (!data.WriteInterfaceToken(GetDescriptor()) || !data.WriteInt32(errCode) || !data.WriteString(bundleName)) { + throw BError(BError::Codes::SA_BROKEN_IPC); + } + + MessageParcel reply; + MessageOption option; + if (int err = Remote()->SendRequest( + static_cast(IServiceReverseInterfaceCode::SERVICER_INCREMENTAL_RESTORE_ON_SUB_TASK_STARTED), data, + reply, option); + err != ERR_OK) { + throw BError(BError::Codes::SA_BROKEN_IPC, to_string(err)); + } +} + +void ServiceReverseProxy::IncrementalRestoreOnBundleFinished(int32_t errCode, string bundleName) +{ + HILOGI("Begin"); + BExcepUltils::BAssert(Remote(), BError::Codes::SDK_INVAL_ARG, "Remote is nullptr"); + MessageParcel data; + if (!data.WriteInterfaceToken(GetDescriptor()) || !data.WriteInt32(errCode) || !data.WriteString(bundleName)) { + throw BError(BError::Codes::SA_BROKEN_IPC); + } + + MessageParcel reply; + MessageOption option; + if (int err = Remote()->SendRequest( + static_cast(IServiceReverseInterfaceCode::SERVICER_INCREMENTAL_RESTORE_ON_SUB_TASK_FINISHED), + data, reply, option); + err != ERR_OK) { + throw BError(BError::Codes::SA_BROKEN_IPC, to_string(err)); + } + + DisposeErr disposeErr = AppGalleryDisposeProxy::GetInstance()->EndRestore(bundleName); + HILOGI("RestoreOnBundleFinished EndRestore, code=%{public}d, bundleName=%{public}s", disposeErr, + bundleName.c_str()); +} + +void ServiceReverseProxy::IncrementalRestoreOnAllBundlesFinished(int32_t errCode) +{ + HILOGI("Begin"); + BExcepUltils::BAssert(Remote(), BError::Codes::SDK_INVAL_ARG, "Remote is nullptr"); + MessageParcel data; + if (!data.WriteInterfaceToken(GetDescriptor()) || !data.WriteInt32(errCode)) { + throw BError(BError::Codes::SA_BROKEN_IPC); + } + + MessageParcel reply; + MessageOption option; + if (int err = Remote()->SendRequest( + static_cast(IServiceReverseInterfaceCode::SERVICER_INCREMENTAL_RESTORE_ON_TASK_FINISHED), data, + reply, option); + err != ERR_OK) { + throw BError(BError::Codes::SA_BROKEN_IPC, to_string(err)); + } +} + +void ServiceReverseProxy::IncrementalRestoreOnFileReady(string bundleName, string fileName, int fd, int manifestFd) +{ + HILOGI("Begin"); + BExcepUltils::BAssert(Remote(), BError::Codes::SDK_INVAL_ARG, "Remote is nullptr"); + MessageParcel data; + if (!data.WriteInterfaceToken(GetDescriptor()) || !data.WriteString(bundleName) || !data.WriteString(fileName) || + !data.WriteFileDescriptor(fd) || !data.WriteFileDescriptor(manifestFd)) { + throw BError(BError::Codes::SA_BROKEN_IPC); + } + + MessageParcel reply; + MessageOption option; + if (int err = Remote()->SendRequest( + static_cast(IServiceReverseInterfaceCode::SERVICER_INCREMENTAL_RESTORE_ON_FILE_READY), data, + reply, option); + err != ERR_OK) { + throw BError(BError::Codes::SA_BROKEN_IPC, to_string(err)); + } +} +} // namespace OHOS::FileManagement::Backup \ No newline at end of file diff --git a/services/backup_sa/src/module_ipc/service_stub.cpp b/services/backup_sa/src/module_ipc/service_stub.cpp index eb0f9470d..327574e6d 100644 --- a/services/backup_sa/src/module_ipc/service_stub.cpp +++ b/services/backup_sa/src/module_ipc/service_stub.cpp @@ -25,6 +25,7 @@ #include "b_error/b_error.h" #include "b_error/b_excep_utils.h" +#include "b_resources/b_constants.h" #include "filemgmt_libhilog.h" #include "module_ipc/service_reverse_proxy.h" @@ -52,6 +53,23 @@ ServiceStub::ServiceStub() opToInterfaceMap_[static_cast(IServiceInterfaceCode::SERVICE_CMD_APPEND_BUNDLES_BACKUP_SESSION)] = &ServiceStub::CmdAppendBundlesBackupSession; opToInterfaceMap_[static_cast(IServiceInterfaceCode::SERVICE_CMD_FINISH)] = &ServiceStub::CmdFinish; + opToInterfaceMap_[static_cast(IServiceInterfaceCode::SERVICE_CMD_RELSEASE_SESSION)] = + &ServiceStub::CmdRelease; + opToInterfaceMap_[static_cast(IServiceInterfaceCode::SERVICE_CMD_GET_LOCAL_CAPABILITIES_INCREMENTAL)] = + &ServiceStub::CmdGetLocalCapabilitiesIncremental; + opToInterfaceMap_[static_cast(IServiceInterfaceCode::SERVICE_CMD_INIT_INCREMENTAL_BACKUP_SESSION)] = + &ServiceStub::CmdInitIncrementalBackupSession; + opToInterfaceMap_[static_cast( + IServiceInterfaceCode::SERVICE_CMD_APPEND_BUNDLES_INCREMENTAL_BACKUP_SESSION)] = + &ServiceStub::CmdAppendBundlesIncrementalBackupSession; + opToInterfaceMap_[static_cast(IServiceInterfaceCode::SERVICE_CMD_PUBLISH_INCREMENTAL_FILE)] = + &ServiceStub::CmdPublishIncrementalFile; + opToInterfaceMap_[static_cast(IServiceInterfaceCode::SERVICE_CMD_APP_INCREMENTAL_FILE_READY)] = + &ServiceStub::CmdAppIncrementalFileReady; + opToInterfaceMap_[static_cast(IServiceInterfaceCode::SERVICE_CMD_APP_INCREMENTAL_DONE)] = + &ServiceStub::CmdAppIncrementalDone; + opToInterfaceMap_[static_cast(IServiceInterfaceCode::SERVICE_CMD_GET_INCREMENTAL_FILE_NAME)] = + &ServiceStub::CmdGetIncrementalFileHandle; } int32_t ServiceStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) @@ -257,4 +275,161 @@ int32_t ServiceStub::CmdFinish(MessageParcel &data, MessageParcel &reply) } return BError(BError::Codes::OK); } + +int32_t ServiceStub::CmdRelease(MessageParcel &data, MessageParcel &reply) +{ + HILOGI("Begin"); + int res = Release(); + if (!reply.WriteInt32(res)) { + return BError(BError::Codes::SA_BROKEN_IPC, string("Failed to send the result ") + to_string(res)); + } + return BError(BError::Codes::OK); +} + +int32_t ServiceStub::CmdGetLocalCapabilitiesIncremental(MessageParcel &data, MessageParcel &reply) +{ + HILOGI("Begin"); + vector bundleNames; + if (!ReadParcelableVector(bundleNames, data)) { + return BError(BError::Codes::SA_INVAL_ARG, "Failed to receive bundleNames"); + } + + UniqueFd fd(GetLocalCapabilitiesIncremental(bundleNames)); + if (!reply.WriteFileDescriptor(fd)) { + return BError(BError::Codes::SA_BROKEN_IPC, "Failed to send out the file"); + } + return BError(BError::Codes::OK); +} + +int32_t ServiceStub::CmdInitIncrementalBackupSession(MessageParcel &data, MessageParcel &reply) +{ + HILOGI("Begin"); + auto remote = data.ReadRemoteObject(); + if (!remote) { + return BError(BError::Codes::SA_INVAL_ARG, "Failed to receive the reverse stub"); + } + auto iremote = iface_cast(remote); + if (!iremote) { + return BError(BError::Codes::SA_INVAL_ARG, "Failed to receive the reverse stub"); + } + + int32_t res = InitIncrementalBackupSession(iremote); + if (!reply.WriteInt32(res)) { + stringstream ss; + ss << "Failed to send the result " << res; + return BError(BError::Codes::SA_BROKEN_IPC, ss.str()); + } + return BError(BError::Codes::OK); +} + +int32_t ServiceStub::CmdAppendBundlesIncrementalBackupSession(MessageParcel &data, MessageParcel &reply) +{ + HILOGI("Begin"); + vector bundlesToBackup; + if (!ReadParcelableVector(bundlesToBackup, data)) { + return BError(BError::Codes::SA_INVAL_ARG, "Failed to receive bundleNames"); + } + + int32_t res = AppendBundlesIncrementalBackupSession(bundlesToBackup); + if (!reply.WriteInt32(res)) { + return BError(BError::Codes::SA_BROKEN_IPC, string("Failed to send the result ") + to_string(res)); + } + return BError(BError::Codes::OK); +} + +int32_t ServiceStub::CmdPublishIncrementalFile(MessageParcel &data, MessageParcel &reply) +{ + HILOGI("Begin"); + unique_ptr fileInfo(data.ReadParcelable()); + if (!fileInfo) { + return BError(BError::Codes::SA_BROKEN_IPC, "Failed to receive fileInfo"); + } + int res = PublishIncrementalFile(*fileInfo); + if (!reply.WriteInt32(res)) { + stringstream ss; + ss << "Failed to send the result " << res; + return BError(BError::Codes::SA_BROKEN_IPC, ss.str()); + } + return BError(BError::Codes::OK); +} + +int32_t ServiceStub::CmdAppIncrementalFileReady(MessageParcel &data, MessageParcel &reply) +{ + HILOGI("Begin"); + string fileName; + if (!data.ReadString(fileName)) { + return BError(BError::Codes::SA_INVAL_ARG, "Failed to receive fileName"); + } + UniqueFd fd(data.ReadFileDescriptor()); + if (fd < 0) { + return BError(BError::Codes::SA_INVAL_ARG, "Failed to receive fd"); + } + + UniqueFd manifestFd(data.ReadFileDescriptor()); + if (manifestFd < 0) { + return BError(BError::Codes::SA_INVAL_ARG, "Failed to receive fd"); + } + + int res = AppIncrementalFileReady(fileName, move(fd), move(manifestFd)); + if (!reply.WriteInt32(res)) { + stringstream ss; + ss << "Failed to send the result " << res; + return BError(BError::Codes::SA_BROKEN_IPC, ss.str()); + } + return BError(BError::Codes::OK); +} + +int32_t ServiceStub::CmdAppIncrementalDone(MessageParcel &data, MessageParcel &reply) +{ + HILOGI("Begin"); + int32_t ret; + if (!data.ReadInt32(ret)) { + return BError(BError::Codes::SA_INVAL_ARG, "Failed to receive bool flag"); + } + int res = AppIncrementalDone(ret); + if (!reply.WriteInt32(res)) { + stringstream ss; + ss << "Failed to send the result " << res; + return BError(BError::Codes::SA_BROKEN_IPC, ss.str()); + } + return BError(BError::Codes::OK); +} + +int32_t ServiceStub::CmdGetIncrementalFileHandle(MessageParcel &data, MessageParcel &reply) +{ + HILOGI("Begin"); + string bundleName; + if (!data.ReadString(bundleName)) { + return BError(BError::Codes::SA_INVAL_ARG, "Failed to receive bundleName").GetCode(); + } + string fileName; + if (!data.ReadString(fileName)) { + return BError(BError::Codes::SA_INVAL_ARG, "Failed to receive fileName").GetCode(); + } + + return GetIncrementalFileHandle(bundleName, fileName); +} + +template +bool ServiceStub::ReadParcelableVector(std::vector &parcelableInfos, MessageParcel &data) +{ + int32_t infoSize = 0; + if (!data.ReadInt32(infoSize)) { + HILOGE("Failed to read Parcelable size."); + return false; + } + + parcelableInfos.clear(); + infoSize = (infoSize < BConstants::MAX_PARCELABLE_VECTOR_NUM) ? infoSize : BConstants::MAX_PARCELABLE_VECTOR_NUM; + for (int32_t index = 0; index < infoSize; index++) { + sptr info = data.ReadParcelable(); + if (info == nullptr) { + HILOGE("Failed to read Parcelable infos."); + return false; + } + parcelableInfos.emplace_back(move(*info)); + } + + return true; +} } // namespace OHOS::FileManagement::Backup diff --git a/services/backup_sa/src/module_ipc/svc_extension_proxy.cpp b/services/backup_sa/src/module_ipc/svc_extension_proxy.cpp index 8d1c9276c..0eec93ecb 100644 --- a/services/backup_sa/src/module_ipc/svc_extension_proxy.cpp +++ b/services/backup_sa/src/module_ipc/svc_extension_proxy.cpp @@ -134,4 +134,77 @@ ErrCode SvcExtensionProxy::HandleRestore() HILOGI("Successful"); return reply.ReadInt32(); } + +ErrCode SvcExtensionProxy::GetIncrementalFileHandle(const string &fileName) +{ + HILOGI("Start"); + BExcepUltils::BAssert(Remote(), BError::Codes::SDK_INVAL_ARG, "Remote is nullptr"); + MessageParcel data; + data.WriteInterfaceToken(GetDescriptor()); + + if (!data.WriteString(fileName)) { + BError(BError::Codes::SDK_INVAL_ARG, "Failed to send the fileName"); + return ErrCode(EPERM); + } + + MessageParcel reply; + MessageOption option; + int32_t ret = Remote()->SendRequest(static_cast(IExtensionInterfaceCode::CMD_GET_INCREMENTAL_FILE_HANDLE), + data, reply, option); + if (ret != NO_ERROR) { + HILOGE("Received error %{public}d when doing IPC", ret); + return ErrCode(ret); + } + + HILOGI("Successful"); + return reply.ReadInt32(); +} + +ErrCode SvcExtensionProxy::PublishIncrementalFile(const string &fileName) +{ + HILOGI("Start"); + BExcepUltils::BAssert(Remote(), BError::Codes::SDK_INVAL_ARG, "Remote is nullptr"); + MessageParcel data; + data.WriteInterfaceToken(GetDescriptor()); + + if (!data.WriteString(fileName)) { + BError(BError::Codes::SDK_INVAL_ARG, "Failed to send the fileName"); + return ErrCode(EPERM); + } + + MessageParcel reply; + MessageOption option; + int32_t ret = Remote()->SendRequest(static_cast(IExtensionInterfaceCode::CMD_PUBLISH_INCREMENTAL_FILE), + data, reply, option); + if (ret != NO_ERROR) { + HILOGE("Received error %{public}d when doing IPC", ret); + return ErrCode(ret); + } + + HILOGI("Successful"); + return reply.ReadInt32(); +} + +ErrCode SvcExtensionProxy::HandleIncrementalBackup(UniqueFd incrementalFd, UniqueFd manifestFd) +{ + HILOGI("Start"); + BExcepUltils::BAssert(Remote(), BError::Codes::SDK_INVAL_ARG, "Remote is nullptr"); + MessageParcel data; + data.WriteInterfaceToken(GetDescriptor()); + + data.WriteFileDescriptor(incrementalFd); + data.WriteFileDescriptor(manifestFd); + + MessageParcel reply; + MessageOption option; + int32_t ret = Remote()->SendRequest(static_cast(IExtensionInterfaceCode::CMD_HANDLE_INCREMENTAL_BACKUP), + data, reply, option); + if (ret != NO_ERROR) { + HILOGE("Received error %{public}d when doing IPC", ret); + return ErrCode(ret); + } + + HILOGI("Successful"); + return reply.ReadInt32(); +} } // namespace OHOS::FileManagement::Backup \ No newline at end of file diff --git a/services/backup_sa/src/module_ipc/svc_session_manager.cpp b/services/backup_sa/src/module_ipc/svc_session_manager.cpp index b82bd8c8c..6b2f8534c 100644 --- a/services/backup_sa/src/module_ipc/svc_session_manager.cpp +++ b/services/backup_sa/src/module_ipc/svc_session_manager.cpp @@ -30,6 +30,7 @@ #include "filemgmt_libhilog.h" #include "module_ipc/service.h" #include "module_ipc/svc_restore_deps_manager.h" +#include "unique_fd.h" namespace OHOS::FileManagement::Backup { using namespace std; @@ -618,6 +619,10 @@ void SvcSessionManager::ClearSessionData() extBundleTimer.Unregister(it->second.extTimerId); // disconnect extension if (it->second.schedAction == BConstants::ServiceSchedAction::RUNNING) { + auto proxy = it->second.backUpConnection->GetBackupExtProxy(); + if (proxy && impl_.restoreDataType != RestoreTypeEnum::RESTORE_DATA_READDY) { + proxy->HandleClear(); + } it->second.backUpConnection->DisconnectBackupExtAbility(); } // clear data @@ -625,4 +630,36 @@ void SvcSessionManager::ClearSessionData() } impl_.backupExtNameMap.clear(); } + +bool SvcSessionManager::GetIsIncrementalBackup() +{ + unique_lock lock(lock_); + if (!impl_.clientToken) { + throw BError(BError::Codes::SA_INVAL_ARG, "No caller token was specified"); + } + return impl_.isIncrementalBackup; +} + +void SvcSessionManager::SetIncrementalData(const BIncrementalData &incrementalData) +{ + unique_lock lock(lock_); + if (!impl_.clientToken) { + throw BError(BError::Codes::SA_INVAL_ARG, "No caller token was specified"); + } + auto it = GetBackupExtNameMap(incrementalData.bundleName); + it->second.lastIncrementalTime = incrementalData.lastIncrementalTime; + it->second.manifestFd = incrementalData.manifestFd; + it->second.backupParameters = incrementalData.backupParameters; + it->second.backupPriority = incrementalData.backupPriority; +} + +int32_t SvcSessionManager::GetIncrementalManifestFd(const string &bundleName) +{ + unique_lock lock(lock_); + if (!impl_.clientToken) { + throw BError(BError::Codes::SA_INVAL_ARG, "No caller token was specified"); + } + auto it = GetBackupExtNameMap(bundleName); + return it->second.manifestFd; +} } // namespace OHOS::FileManagement::Backup diff --git a/services/backup_sa/src/module_sched/sched_scheduler.cpp b/services/backup_sa/src/module_sched/sched_scheduler.cpp index 04e5db2bc..ffa5771bb 100644 --- a/services/backup_sa/src/module_sched/sched_scheduler.cpp +++ b/services/backup_sa/src/module_sched/sched_scheduler.cpp @@ -28,6 +28,7 @@ #include #include "b_error/b_error.h" +#include "b_ohos/startup/backup_para.h" #include "filemgmt_libhilog.h" #include "iservice_registry.h" #include "module_external/bms_adapter.h" @@ -117,6 +118,14 @@ void SchedScheduler::RemoveExtConn(const string &bundleName) } } +void SchedScheduler::StartTimer() +{ + extTime_.Setup(); + if (!BackupPara().GetBackupOverrideBackupSARelease()) { + TryUnloadServiceTimer(); + } +} + void SchedScheduler::TryUnloadServiceTimer(bool force) { auto tryUnload = [sessionPtr {sessionPtr_}]() { diff --git a/tests/mock/backup_kit_inner/b_session_backup_mock.cpp b/tests/mock/backup_kit_inner/b_session_backup_mock.cpp index f3a8f5193..4f34a37d7 100644 --- a/tests/mock/backup_kit_inner/b_session_backup_mock.cpp +++ b/tests/mock/backup_kit_inner/b_session_backup_mock.cpp @@ -92,4 +92,9 @@ ErrCode BSessionBackup::Finish() { return BError(BError::Codes::OK); } + +ErrCode BSessionBackup::Release() +{ + return BError(BError::Codes::OK); +} } // namespace OHOS::FileManagement::Backup \ No newline at end of file diff --git a/tests/mock/backup_kit_inner/b_session_restore_async_mock.cpp b/tests/mock/backup_kit_inner/b_session_restore_async_mock.cpp index 4068bd936..def40ed6e 100644 --- a/tests/mock/backup_kit_inner/b_session_restore_async_mock.cpp +++ b/tests/mock/backup_kit_inner/b_session_restore_async_mock.cpp @@ -96,5 +96,10 @@ ErrCode BSessionRestoreAsync::AppendBundles(UniqueFd remoteCap, void BSessionRestoreAsync::OnBackupServiceDied() {} +ErrCode BSessionRestoreAsync::Release() +{ + return BError(BError::Codes::OK); +} + void BSessionRestoreAsync::RegisterBackupServiceDied(function functor) {} } // namespace OHOS::FileManagement::Backup \ No newline at end of file diff --git a/tests/mock/backup_kit_inner/b_session_restore_mock.cpp b/tests/mock/backup_kit_inner/b_session_restore_mock.cpp index 49d4126bc..3af358b95 100644 --- a/tests/mock/backup_kit_inner/b_session_restore_mock.cpp +++ b/tests/mock/backup_kit_inner/b_session_restore_mock.cpp @@ -96,5 +96,10 @@ ErrCode BSessionRestore::Finish() return BError(BError::Codes::OK); } +ErrCode BSessionRestore::Release() +{ + return BError(BError::Codes::OK); +} + void BSessionRestore::RegisterBackupServiceDied(function functor) {} } // namespace OHOS::FileManagement::Backup \ No newline at end of file diff --git a/tests/mock/backup_kit_inner/service_proxy_mock.cpp b/tests/mock/backup_kit_inner/service_proxy_mock.cpp index cd0808e1a..760bd1158 100644 --- a/tests/mock/backup_kit_inner/service_proxy_mock.cpp +++ b/tests/mock/backup_kit_inner/service_proxy_mock.cpp @@ -98,6 +98,46 @@ ErrCode ServiceProxy::Finish() return BError(BError::Codes::OK); } +ErrCode ServiceProxy::Release() +{ + return BError(BError::Codes::OK); +} + +UniqueFd ServiceProxy::GetLocalCapabilitiesIncremental(const vector &bundleNames) +{ + return UniqueFd(-1); +} + +ErrCode ServiceProxy::InitIncrementalBackupSession(sptr remote) +{ + return BError(BError::Codes::OK); +} + +ErrCode ServiceProxy::AppendBundlesIncrementalBackupSession(const vector &bundlesToBackup) +{ + return BError(BError::Codes::OK); +} + +ErrCode ServiceProxy::PublishIncrementalFile(const BFileInfo &fileInfo) +{ + return BError(BError::Codes::OK); +} + +ErrCode ServiceProxy::AppIncrementalFileReady(const string &fileName, UniqueFd fd, UniqueFd manifestFd) +{ + return BError(BError::Codes::OK); +} + +ErrCode ServiceProxy::AppIncrementalDone(ErrCode errCode) +{ + return BError(BError::Codes::OK); +} + +ErrCode ServiceProxy::GetIncrementalFileHandle(const std::string &bundleName, const std::string &fileName) +{ + return BError(BError::Codes::OK); +} + sptr ServiceProxy::GetInstance() { if (!GetMockGetInstance()) { diff --git a/tests/mock/module_ipc/service_mock.cpp b/tests/mock/module_ipc/service_mock.cpp index 898c0f835..bf99081c7 100644 --- a/tests/mock/module_ipc/service_mock.cpp +++ b/tests/mock/module_ipc/service_mock.cpp @@ -129,4 +129,44 @@ void Service::OnStartSched() {} void Service::SendAppGalleryNotify(const BundleName &bundleName) {} void Service::SessionDeactive() {} + +ErrCode Service::Release() +{ + return BError(BError::Codes::OK); +} + +UniqueFd Service::GetLocalCapabilitiesIncremental(const std::vector &bundleNames) +{ + return UniqueFd(-1); +} + +ErrCode Service::InitIncrementalBackupSession(sptr remote) +{ + return BError(BError::Codes::OK); +} + +ErrCode Service::AppendBundlesIncrementalBackupSession(const std::vector &bundlesToBackup) +{ + return BError(BError::Codes::OK); +} + +ErrCode Service::PublishIncrementalFile(const BFileInfo &fileInfo) +{ + return BError(BError::Codes::OK); +} + +ErrCode Service::AppIncrementalFileReady(const string &fileName, UniqueFd fd, UniqueFd manifestFd) +{ + return BError(BError::Codes::OK); +} + +ErrCode Service::AppIncrementalDone(ErrCode errCode) +{ + return BError(BError::Codes::OK); +} + +ErrCode Service::GetIncrementalFileHandle(const string &bundleName, const string &fileName) +{ + return BError(BError::Codes::OK); +} } // namespace OHOS::FileManagement::Backup diff --git a/tests/mock/module_ipc/service_reverse_proxy_mock.cpp b/tests/mock/module_ipc/service_reverse_proxy_mock.cpp index 0f98e5e2e..456a81465 100644 --- a/tests/mock/module_ipc/service_reverse_proxy_mock.cpp +++ b/tests/mock/module_ipc/service_reverse_proxy_mock.cpp @@ -35,4 +35,20 @@ void ServiceReverseProxy::RestoreOnBundleFinished(int32_t errCode, string bundle void ServiceReverseProxy::RestoreOnAllBundlesFinished(int32_t errCode) {} void ServiceReverseProxy::RestoreOnFileReady(string bundleName, string fileName, int fd) {} + +void ServiceReverseProxy::IncrementalBackupOnFileReady(string bundleName, string fileName, int fd, int manifestFd) {} + +void ServiceReverseProxy::IncrementalBackupOnBundleStarted(int32_t errCode, string bundleName) {} + +void ServiceReverseProxy::IncrementalBackupOnBundleFinished(int32_t errCode, string bundleName) {} + +void ServiceReverseProxy::IncrementalBackupOnAllBundlesFinished(int32_t errCode) {} + +void ServiceReverseProxy::IncrementalRestoreOnBundleStarted(int32_t errCode, string bundleName) {} + +void ServiceReverseProxy::IncrementalRestoreOnBundleFinished(int32_t errCode, string bundleName) {} + +void ServiceReverseProxy::IncrementalRestoreOnAllBundlesFinished(int32_t errCode) {} + +void ServiceReverseProxy::IncrementalRestoreOnFileReady(string bundleName, string fileName, int fd, int manifestFd) {} } // namespace OHOS::FileManagement::Backup \ No newline at end of file diff --git a/tests/mock/module_ipc/service_stub_mock.cpp b/tests/mock/module_ipc/service_stub_mock.cpp index 07e131cac..3e65392b3 100644 --- a/tests/mock/module_ipc/service_stub_mock.cpp +++ b/tests/mock/module_ipc/service_stub_mock.cpp @@ -44,6 +44,21 @@ ServiceStub::ServiceStub() opToInterfaceMap_[static_cast(IServiceInterfaceCode::SERVICE_CMD_APPEND_BUNDLES_BACKUP_SESSION)] = &ServiceStub::CmdAppendBundlesBackupSession; opToInterfaceMap_[static_cast(IServiceInterfaceCode::SERVICE_CMD_FINISH)] = &ServiceStub::CmdFinish; + opToInterfaceMap_[static_cast(IServiceInterfaceCode::SERVICE_CMD_RELSEASE_SESSION)] = + &ServiceStub::CmdRelease; + opToInterfaceMap_[static_cast(IServiceInterfaceCode::SERVICE_CMD_GET_LOCAL_CAPABILITIES_INCREMENTAL)] = + &ServiceStub::CmdGetLocalCapabilitiesIncremental; + opToInterfaceMap_[static_cast(IServiceInterfaceCode::SERVICE_CMD_INIT_INCREMENTAL_BACKUP_SESSION)] = + &ServiceStub::CmdInitIncrementalBackupSession; + opToInterfaceMap_[static_cast( + IServiceInterfaceCode::SERVICE_CMD_APPEND_BUNDLES_INCREMENTAL_BACKUP_SESSION)] = + &ServiceStub::CmdAppendBundlesIncrementalBackupSession; + opToInterfaceMap_[static_cast(IServiceInterfaceCode::SERVICE_CMD_PUBLISH_INCREMENTAL_FILE)] = + &ServiceStub::CmdPublishIncrementalFile; + opToInterfaceMap_[static_cast(IServiceInterfaceCode::SERVICE_CMD_APP_INCREMENTAL_FILE_READY)] = + &ServiceStub::CmdAppIncrementalFileReady; + opToInterfaceMap_[static_cast(IServiceInterfaceCode::SERVICE_CMD_GET_INCREMENTAL_FILE_NAME)] = + &ServiceStub::CmdGetIncrementalFileHandle; } int32_t ServiceStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) @@ -159,4 +174,41 @@ int32_t ServiceStub::CmdFinish(MessageParcel &data, MessageParcel &reply) reply.WriteInt32(res); return BError(BError::Codes::OK); } + +int32_t ServiceStub::CmdRelease(MessageParcel &data, MessageParcel &reply) +{ + int res = Release(); + reply.WriteInt32(res); + return BError(BError::Codes::OK); +} + +int32_t ServiceStub::CmdGetLocalCapabilitiesIncremental(MessageParcel &data, MessageParcel &reply) +{ + return BError(BError::Codes::OK); +} + +int32_t ServiceStub::CmdInitIncrementalBackupSession(MessageParcel &data, MessageParcel &reply) +{ + return BError(BError::Codes::OK); +} + +int32_t ServiceStub::CmdAppendBundlesIncrementalBackupSession(MessageParcel &data, MessageParcel &reply) +{ + return BError(BError::Codes::OK); +} + +int32_t ServiceStub::CmdPublishIncrementalFile(MessageParcel &data, MessageParcel &reply) +{ + return BError(BError::Codes::OK); +} + +int32_t ServiceStub::CmdAppIncrementalFileReady(MessageParcel &data, MessageParcel &reply) +{ + return BError(BError::Codes::OK); +} + +int32_t ServiceStub::CmdGetIncrementalFileHandle(MessageParcel &data, MessageParcel &reply) +{ + return BError(BError::Codes::OK); +} } // namespace OHOS::FileManagement::Backup diff --git a/tests/mock/module_ipc/svc_extension_proxy_mock.cpp b/tests/mock/module_ipc/svc_extension_proxy_mock.cpp index 2403f2d2f..6c1fbe7e3 100644 --- a/tests/mock/module_ipc/svc_extension_proxy_mock.cpp +++ b/tests/mock/module_ipc/svc_extension_proxy_mock.cpp @@ -42,4 +42,19 @@ ErrCode SvcExtensionProxy::HandleRestore() { return 0; } + +ErrCode SvcExtensionProxy::GetIncrementalFileHandle(const string &fileName) +{ + return 0; +} + +ErrCode SvcExtensionProxy::PublishIncrementalFile(const string &fileName) +{ + return 0; +} + +ErrCode SvcExtensionProxy::HandleIncrementalBackup(UniqueFd incrementalFd, UniqueFd manifestFd) +{ + return 0; +} } // namespace OHOS::FileManagement::Backup \ No newline at end of file diff --git a/tests/mock/module_ipc/svc_session_manager_mock.cpp b/tests/mock/module_ipc/svc_session_manager_mock.cpp index 8c9ff7ab9..e5b8d488b 100644 --- a/tests/mock/module_ipc/svc_session_manager_mock.cpp +++ b/tests/mock/module_ipc/svc_session_manager_mock.cpp @@ -314,4 +314,16 @@ void SvcSessionManager::IncreaseSessionCnt() {} void SvcSessionManager::DecreaseSessionCnt() {} void SvcSessionManager::ClearSessionData() {} + +bool SvcSessionManager::GetIsIncrementalBackup() +{ + return true; +} + +void SvcSessionManager::SetIncrementalData(const BIncrementalData &incrementalData) {} + +int32_t SvcSessionManager::GetIncrementalManifestFd(const string &bundleName) +{ + return 0; +} } // namespace OHOS::FileManagement::Backup diff --git a/tests/mock/module_sched/sched_scheduler_mock.cpp b/tests/mock/module_sched/sched_scheduler_mock.cpp index 82fdc4485..65c744fa7 100644 --- a/tests/mock/module_sched/sched_scheduler_mock.cpp +++ b/tests/mock/module_sched/sched_scheduler_mock.cpp @@ -30,6 +30,8 @@ void SchedScheduler::ExecutingQueueTasks(const string &bundleName) {} void SchedScheduler::RemoveExtConn(const string &bundleName) {} +void SchedScheduler::StartTimer() {} + void SchedScheduler::TryUnloadServiceTimer(bool force) {} void SchedScheduler::TryUnloadService() {} diff --git a/tests/moduletests/backup_kit_inner/BUILD.gn b/tests/moduletests/backup_kit_inner/BUILD.gn index 961434ce1..9d382efd3 100644 --- a/tests/moduletests/backup_kit_inner/BUILD.gn +++ b/tests/moduletests/backup_kit_inner/BUILD.gn @@ -21,6 +21,7 @@ ohos_unittest("b_session_test") { "${path_backup}/frameworks/native/backup_kit_inner/src/b_session_backup.cpp", "${path_backup}/frameworks/native/backup_kit_inner/src/b_session_restore.cpp", "${path_backup}/frameworks/native/backup_kit_inner/src/b_session_restore_async.cpp", + "${path_backup}/frameworks/native/backup_kit_inner/src/service_incremental_reverse.cpp", "${path_backup}/frameworks/native/backup_kit_inner/src/service_reverse.cpp", "${path_backup}/frameworks/native/backup_kit_inner/src/service_reverse_stub.cpp", "b_session_backup_test.cpp", diff --git a/tests/unittests/backup_api/backup_impl/include/ext_extension_mock.h b/tests/unittests/backup_api/backup_impl/include/ext_extension_mock.h index bc7ed16eb..d6fe04fba 100644 --- a/tests/unittests/backup_api/backup_impl/include/ext_extension_mock.h +++ b/tests/unittests/backup_api/backup_impl/include/ext_extension_mock.h @@ -97,6 +97,21 @@ public: return BError(BError::Codes::OK); }; + ErrCode GetIncrementalFileHandle(const std::string &fileName) override + { + return BError(BError::Codes::OK); + }; + + ErrCode PublishIncrementalFile(const std::string &fileName) override + { + return BError(BError::Codes::OK); + }; + + ErrCode HandleIncrementalBackup(UniqueFd incrementalFd, UniqueFd manifestFd) override + { + return BError(BError::Codes::OK); + }; + private: int32_t nHandleBackupNum_ = 0; }; diff --git a/tests/unittests/backup_api/backup_impl/include/i_service_mock.h b/tests/unittests/backup_api/backup_impl/include/i_service_mock.h index 2af0cb1e1..3436577a1 100644 --- a/tests/unittests/backup_api/backup_impl/include/i_service_mock.h +++ b/tests/unittests/backup_api/backup_impl/include/i_service_mock.h @@ -110,6 +110,46 @@ public: { return BError(BError::Codes::OK); } + + ErrCode Release() override + { + return BError(BError::Codes::OK); + } + + UniqueFd GetLocalCapabilitiesIncremental(const std::vector &bundleNames) override + { + return UniqueFd(-1); + } + + ErrCode InitIncrementalBackupSession(sptr remote) override + { + return BError(BError::Codes::OK); + } + + ErrCode AppendBundlesIncrementalBackupSession(const std::vector &bundlesToBackup) override + { + return BError(BError::Codes::OK); + } + + ErrCode PublishIncrementalFile(const BFileInfo &fileInfo) + { + return BError(BError::Codes::OK); + } + + ErrCode AppIncrementalFileReady(const std::string &fileName, UniqueFd fd, UniqueFd manifestFd) + { + return BError(BError::Codes::OK); + } + + ErrCode AppIncrementalDone(ErrCode errCode) + { + return BError(BError::Codes::OK); + } + + ErrCode GetIncrementalFileHandle(const std::string &bundleName, const std::string &fileName) + { + return BError(BError::Codes::OK); + } }; } // namespace OHOS::FileManagement::Backup #endif // MOCK_I_SERVICE_MOCK_H \ No newline at end of file diff --git a/tests/unittests/backup_api/backup_impl/include/service_reverse_mock.h b/tests/unittests/backup_api/backup_impl/include/service_reverse_mock.h index e4f6e2a2a..9808e5d41 100644 --- a/tests/unittests/backup_api/backup_impl/include/service_reverse_mock.h +++ b/tests/unittests/backup_api/backup_impl/include/service_reverse_mock.h @@ -45,6 +45,16 @@ public: void RestoreOnBundleFinished(int32_t errCode, std::string bundleName) override {} void RestoreOnAllBundlesFinished(int32_t errCode) override {} void RestoreOnFileReady(std::string bundleName, std::string fileName, int fd) override {} + + void IncrementalBackupOnFileReady(std::string bundleName, std::string fileName, int fd, int manifestFd) override {} + void IncrementalBackupOnBundleStarted(int32_t errCode, std::string bundleName) override {} + void IncrementalBackupOnBundleFinished(int32_t errCode, std::string bundleName) override {} + void IncrementalBackupOnAllBundlesFinished(int32_t errCode) override {} + + void IncrementalRestoreOnBundleStarted(int32_t errCode, std::string bundleName) override {} + void IncrementalRestoreOnBundleFinished(int32_t errCode, std::string bundleName) override {} + void IncrementalRestoreOnAllBundlesFinished(int32_t errCode) override {} + void IncrementalRestoreOnFileReady(std::string bundleName, std::string fileName, int fd, int manifestFd) override {} }; } // namespace OHOS::FileManagement::Backup #endif // MOCK_SERVICE_REVERSE_MOCK_H \ No newline at end of file diff --git a/tests/unittests/backup_api/backup_impl/service_reverse_stub_test.cpp b/tests/unittests/backup_api/backup_impl/service_reverse_stub_test.cpp index c3f41057d..2fd0b60a7 100644 --- a/tests/unittests/backup_api/backup_impl/service_reverse_stub_test.cpp +++ b/tests/unittests/backup_api/backup_impl/service_reverse_stub_test.cpp @@ -47,6 +47,14 @@ public: MOCK_METHOD2(RestoreOnBundleFinished, void(int32_t errCode, string bundleName)); MOCK_METHOD1(RestoreOnAllBundlesFinished, void(int32_t errCode)); MOCK_METHOD3(RestoreOnFileReady, void(string bundleName, string fileName, int fd)); + MOCK_METHOD4(IncrementalBackupOnFileReady, void(string bundleName, string fileName, int fd, int manifestFd)); + MOCK_METHOD2(IncrementalBackupOnBundleStarted, void(int32_t errCode, string bundleName)); + MOCK_METHOD2(IncrementalBackupOnBundleFinished, void(int32_t errCode, string bundleName)); + MOCK_METHOD1(IncrementalBackupOnAllBundlesFinished, void(int32_t errCode)); + MOCK_METHOD2(IncrementalRestoreOnBundleStarted, void(int32_t errCode, std::string bundleName)); + MOCK_METHOD2(IncrementalRestoreOnBundleFinished, void(int32_t errCode, string bundleName)); + MOCK_METHOD1(IncrementalRestoreOnAllBundlesFinished, void(int32_t errCode)); + MOCK_METHOD4(IncrementalRestoreOnFileReady, void(string bundleName, string fileName, int fd, int manifestFd)); }; class ServiceReverseStubTest : public testing::Test { diff --git a/tests/unittests/backup_sa/module_ipc/BUILD.gn b/tests/unittests/backup_sa/module_ipc/BUILD.gn index fa9f7762e..3864c6553 100644 --- a/tests/unittests/backup_sa/module_ipc/BUILD.gn +++ b/tests/unittests/backup_sa/module_ipc/BUILD.gn @@ -68,6 +68,7 @@ ohos_unittest("backup_service_test") { "${path_backup_mock}/accesstoken/accesstoken_kit_mock.cpp", "${path_backup_mock}/module_ipc/app_gallery_dispose_proxy_mock.cpp", "${path_backup_mock}/timer/timer_mock.cpp", + "${path_backup}/services/backup_sa/src/module_ipc/service_incremental.cpp", "${path_backup}/services/backup_sa/src/module_ipc/service.cpp", "${path_backup}/services/backup_sa/src/module_ipc/svc_restore_deps_manager.cpp", "service_test.cpp", @@ -217,6 +218,7 @@ ohos_unittest("backup_restore_deps_manager_test") { sources = [ "${path_backup_mock}/accesstoken/accesstoken_kit_mock.cpp", "${path_backup}/services/backup_sa/src/module_app_gallery/app_gallery_dispose_proxy.cpp", + "${path_backup}/services/backup_sa/src/module_ipc/service_incremental.cpp", "${path_backup}/services/backup_sa/src/module_ipc/service.cpp", "${path_backup}/services/backup_sa/src/module_ipc/svc_restore_deps_manager.cpp", "svc_restore_deps_manager_test.cpp", diff --git a/tests/unittests/backup_sa/module_ipc/service_stub_test.cpp b/tests/unittests/backup_sa/module_ipc/service_stub_test.cpp index 8b06ed40c..2e221933d 100644 --- a/tests/unittests/backup_sa/module_ipc/service_stub_test.cpp +++ b/tests/unittests/backup_sa/module_ipc/service_stub_test.cpp @@ -53,6 +53,15 @@ public: ErrCode(UniqueFd fd, const std::vector &bundleNames, RestoreTypeEnum restoreType, int32_t userId)); MOCK_METHOD1(AppendBundlesBackupSession, ErrCode(const std::vector &bundleNames)); MOCK_METHOD0(Finish, ErrCode()); + MOCK_METHOD0(Release, ErrCode()); + MOCK_METHOD1(GetLocalCapabilitiesIncremental, UniqueFd(const std::vector &bundleNames)); + MOCK_METHOD1(InitIncrementalBackupSession, ErrCode(sptr remote)); + MOCK_METHOD1(AppendBundlesIncrementalBackupSession, ErrCode(const std::vector &bundlesToBackup)); + + MOCK_METHOD1(PublishIncrementalFile, ErrCode(const BFileInfo &fileInfo)); + MOCK_METHOD3(AppIncrementalFileReady, ErrCode(const std::string &fileName, UniqueFd fd, UniqueFd manifestFd)); + MOCK_METHOD1(AppIncrementalDone, ErrCode(ErrCode errCode)); + MOCK_METHOD2(GetIncrementalFileHandle, ErrCode(const std::string &bundleName, const std::string &fileName)); UniqueFd InvokeGetLocalCapabilities() { if (bCapabilities_) { @@ -466,4 +475,34 @@ HWTEST_F(ServiceStubTest, SUB_backup_sa_ServiceStub_Finish_0100, testing::ext::T } GTEST_LOG_(INFO) << "ServiceStubTest-end SUB_backup_sa_ServiceStub_Finish_0100"; } + +/** + * @tc.number: SUB_backup_sa_ServiceStub_Release_0100 + * @tc.name: SUB_backup_sa_ServiceStub_Release_0100 + * @tc.desc: Test function of Release interface for SUCCESS. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + * @tc.require: I6URNZ + */ +HWTEST_F(ServiceStubTest, SUB_backup_sa_ServiceStub_Release_0100, testing::ext::TestSize.Level0) +{ + GTEST_LOG_(INFO) << "ServiceStubTest-begin SUB_backup_sa_ServiceStub_Release_0100"; + try { + MockService service; + EXPECT_CALL(service, Release()).WillOnce(Return(BError(BError::Codes::OK))); + MessageParcel data; + MessageParcel reply; + MessageOption option; + + EXPECT_TRUE(data.WriteInterfaceToken(IService::GetDescriptor())); + EXPECT_EQ(BError(BError::Codes::OK), + service.OnRemoteRequest(static_cast(IServiceInterfaceCode::SERVICE_CMD_RELSEASE_SESSION), + data, reply, option)); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "ServiceStubTest-an exception occurred by Release."; + } + GTEST_LOG_(INFO) << "ServiceStubTest-end SUB_backup_sa_ServiceStub_Release_0100"; +} } // namespace OHOS::FileManagement::Backup \ No newline at end of file diff --git a/tools/backup_tool/src/tools_op_backup.cpp b/tools/backup_tool/src/tools_op_backup.cpp index d79b1ba62..e9c1e97e6 100644 --- a/tools/backup_tool/src/tools_op_backup.cpp +++ b/tools/backup_tool/src/tools_op_backup.cpp @@ -258,6 +258,7 @@ static int32_t InitPathCapFile(const string &pathCapFile, vector bundleN ctx->SetBundleFinishedCount(bundleNames.size()); ctx->Wait(); FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + ctx->session_->Release(); return 0; } diff --git a/tools/backup_tool/src/tools_op_restore.cpp b/tools/backup_tool/src/tools_op_restore.cpp index 333099dbd..9f21842b5 100644 --- a/tools/backup_tool/src/tools_op_restore.cpp +++ b/tools/backup_tool/src/tools_op_restore.cpp @@ -160,8 +160,8 @@ static void OnBundleFinished(shared_ptr ctx, ErrCode err, const BundleN ctx->UpdateBundleFinishedCount(); if (err != 0) { ctx->isAllBundelsFinished.store(true); - ctx->ClearBundleOfMap(name); } + ctx->ClearBundleOfMap(name); ctx->TryNotify(); } @@ -286,6 +286,7 @@ static int32_t InitPathCapFile(const string &pathCapFile, vector bundleN ctx->SetBundleFinishedCount(bundleNames.size()); RestoreApp(ctx, bundleNames); ctx->Wait(); + ctx->session_->Release(); return 0; } diff --git a/utils/include/b_ohos/startup/backup_para.h b/utils/include/b_ohos/startup/backup_para.h index 1f6cad364..bac2a4300 100644 --- a/utils/include/b_ohos/startup/backup_para.h +++ b/utils/include/b_ohos/startup/backup_para.h @@ -35,6 +35,20 @@ public: * @return int32_t值为配置项backup.debug.overrideAccountNumber值 */ std::tuple GetBackupDebugOverrideAccount(); + + /** + * @brief 获取backup.para配置项backup.overrideBackupSARelease的值 + * + * @return 获取的配置项backup.overrideBackupSARelease的值为true时则返回true,否则返回false + */ + bool GetBackupOverrideBackupSARelease(); + + /** + * @brief 获取backup.para配置项backup.overrideIncrementalRestore的值 + * + * @return 获取的配置项backup.overrideIncrementalRestore的值为true时则返回true,否则返回false + */ + bool GetBackupOverrideIncrementalRestore(); }; } // namespace OHOS::FileManagement::Backup diff --git a/utils/include/b_resources/b_constants.h b/utils/include/b_resources/b_constants.h index 9f4ae877b..61f061078 100644 --- a/utils/include/b_resources/b_constants.h +++ b/utils/include/b_resources/b_constants.h @@ -62,6 +62,7 @@ constexpr int EXT_CONNECT_MAX_COUNT = 3; // extension 最大启动数 constexpr int EXT_CONNECT_MAX_TIME = 15000; // SA 启动 extension 等待连接最大时间 constexpr int IPC_MAX_WAIT_TIME = 3000; // IPC通讯最大等待时间(s) +constexpr int MAX_PARCELABLE_VECTOR_NUM = 10000; // backup.para内配置项的名称,该配置项值为true时可在不更新hap包的情况下,可以读取包管理元数据配置文件的内容 static inline std::string BACKUP_DEBUG_OVERRIDE_EXTENSION_CONFIG_KEY = "backup.debug.overrideExtensionConfig"; @@ -70,6 +71,12 @@ static inline std::string BACKUP_DEBUG_OVERRIDE_EXTENSION_CONFIG_KEY = "backup.d static inline std::string BACKUP_DEBUG_OVERRIDE_ACCOUNT_CONFIG_KEY = "backup.debug.overrideAccountConfig"; static inline std::string BACKUP_DEBUG_OVERRIDE_ACCOUNT_NUMBER_KEY = "backup.debug.overrideAccountNumber"; +// backup.para内配置项的名称,该配置项为true时备份恢复支持Release接口调用 +static inline std::string BACKUP_OVERRIDE_BACKUP_SA_RELEASE_KEY = "backup.overrideBackupSARelease"; + +// backup.para内配置项的名称,该配置项为true时备份恢复支持增量恢复 +static inline std::string BACKUP_OVERRIDE_INCREMENTAL_KEY = "backup.overrideIncrementalRestore"; + // 应用备份数据暂存路径 static inline std::string_view SA_BUNDLE_BACKUP_BACKUP = "/backup/"; static inline std::string_view SA_BUNDLE_BACKUP_RESTORE = "/restore/"; diff --git a/utils/src/b_ohos/startup/backup_para.cpp b/utils/src/b_ohos/startup/backup_para.cpp index 8047ef0e1..c3028632a 100644 --- a/utils/src/b_ohos/startup/backup_para.cpp +++ b/utils/src/b_ohos/startup/backup_para.cpp @@ -66,6 +66,26 @@ bool BackupPara::GetBackupDebugOverrideExtensionConfig() return value == "true"; } +bool BackupPara::GetBackupOverrideBackupSARelease() +{ + auto [getCfgParaValSucc, value] = + GetConfigParameterValue(BConstants::BACKUP_OVERRIDE_BACKUP_SA_RELEASE_KEY, BConstants::BACKUP_PARA_VALUE_MAX); + if (!getCfgParaValSucc) { + throw BError(BError::Codes::SA_INVAL_ARG, "Fail to get configuration parameter value of backup.para"); + } + return value == "true"; +} + +bool BackupPara::GetBackupOverrideIncrementalRestore() +{ + auto [getCfgParaValSucc, value] = + GetConfigParameterValue(BConstants::BACKUP_OVERRIDE_INCREMENTAL_KEY, BConstants::BACKUP_PARA_VALUE_MAX); + if (!getCfgParaValSucc) { + throw BError(BError::Codes::SA_INVAL_ARG, "Fail to get configuration parameter value of backup.para"); + } + return value == "true"; +} + tuple BackupPara::GetBackupDebugOverrideAccount() { auto [getCfgParaValSucc, value] = GetConfigParameterValue(BConstants::BACKUP_DEBUG_OVERRIDE_ACCOUNT_CONFIG_KEY, -- Gitee From aa6be2c2c872ca717d6822a2030354679ea1a6a9 Mon Sep 17 00:00:00 2001 From: z30054037 Date: Thu, 28 Dec 2023 11:52:01 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E5=A2=9E=E9=87=8F=E5=A4=87=E4=BB=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: z30054037 Change-Id: Ic1dfac9981ec4c31d3339ecddd8fab44f61dbe60 --- .../native/backup_ext/include/ext_extension.h | 10 + .../native/backup_ext/src/ext_extension.cpp | 355 +++++++++++++++++- utils/BUILD.gn | 1 + utils/include/b_filesystem/b_file.h | 7 + utils/include/b_filesystem/b_file_hash.h | 32 ++ utils/src/b_filesystem/b_file.cpp | 42 +++ utils/src/b_filesystem/b_file_hash.cpp | 105 ++++++ 7 files changed, 549 insertions(+), 3 deletions(-) create mode 100644 utils/include/b_filesystem/b_file_hash.h create mode 100644 utils/src/b_filesystem/b_file_hash.cpp diff --git a/frameworks/native/backup_ext/include/ext_extension.h b/frameworks/native/backup_ext/include/ext_extension.h index a1683f9e1..4a1584835 100644 --- a/frameworks/native/backup_ext/include/ext_extension.h +++ b/frameworks/native/backup_ext/include/ext_extension.h @@ -25,6 +25,7 @@ #include "ext_backup_js.h" #include "ext_extension_stub.h" #include "thread_pool.h" +#include "unique_fd.h" namespace OHOS::FileManagement::Backup { class BackupExtExtension : public ExtExtensionStub { @@ -98,6 +99,15 @@ private: void AsyncTaskOnBackup(); + /** + * @brief IncrementalBackup + * + * @param incrementalFd storage fd + * @param manifestFd 云空间 fd + */ + int DoIncrementalBackup(UniqueFd incrementalFd, UniqueFd manifestFd); + + void AsyncTaskOnIncrementalBackup(UniqueFd incrementalFd, UniqueFd manifestFd); private: std::shared_mutex lock_; std::shared_ptr extension_; diff --git a/frameworks/native/backup_ext/src/ext_extension.cpp b/frameworks/native/backup_ext/src/ext_extension.cpp index e200f06ca..56765a731 100644 --- a/frameworks/native/backup_ext/src/ext_extension.cpp +++ b/frameworks/native/backup_ext/src/ext_extension.cpp @@ -16,6 +16,7 @@ #include "ext_extension.h" #include +#include #include #include #include @@ -36,6 +37,7 @@ #include "b_error/b_excep_utils.h" #include "b_filesystem/b_dir.h" #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_resources/b_constants.h" @@ -53,7 +55,24 @@ const string INDEX_FILE_BACKUP = string(BConstants::PATH_BUNDLE_BACKUP_HOME). const string INDEX_FILE_RESTORE = string(BConstants::PATH_BUNDLE_BACKUP_HOME). append(BConstants::SA_BUNDLE_BACKUP_RESTORE). append(BConstants::EXT_BACKUP_MANAGE); + +const string INDEX_FILE_INCREMENTAL_BACKUP = string(BConstants::PATH_BUNDLE_BACKUP_HOME). + append(BConstants::SA_BUNDLE_BACKUP_BACKUP) using namespace std; +struct FileInfo { + string filePath; + string mode; + string isDir; + string size; + string lmtime; + string fileHash; + string isIncr = "0"; // 是否增量 +}; + +namespace { +const int64_t DEFAULT_SLICE_SIZE = 100 * 1024 * 1024; // 分片文件大小为100M +const uint32_t MAX_FILE_COUNT = 6000; // 单个tar包最多包含6000个文件 +} // namespace void BackupExtExtension::VerifyCaller() { @@ -806,6 +825,196 @@ ErrCode BackupExtExtension::HandleRestore() return 0; } +static map GetIncrementalFile(const UniqueFd &fd) +{ + vector> infos = BFile::ReadIncrementalFile(fd); + map files; + if (infos.begin() != infos.end()) { + for (auto info : infos) { + string filePath = info.find("path") != info.end() ? info.find("path")->second : ""; + string mode = info.find("mode") != info.end() ? info.find("mode")->second : ""; + string dir = info.find("dir") != info.end() ? info.find("dir")->second : "0"; + string size = info.find("size") != info.end() ? info.find("size")->second : "0"; + string mtime = info.find("mtime") != info.end() ? info.find("mtime")->second : "0"; + string isIncr = info.find("isIncr") != info.end() ? info.find("isIncr")->second : "0"; + string hash = info.find("hash") != info.end() ? info.find("hash")->second : ""; + struct FileInfo file; + file.filePath = filePath; + file.mode = mode; + file.isDir = dir; + file.lmtime = mtime; + file.size = size; + file.fileHash = hash; + file.isIncr = isIncr; + files.try_emplace(filePath, file); + } + } + return files; +} + +static pair, map, map> CompareFiles( + const UniqueFd &cloudFd, + const UniqueFd &storageFd) +{ + map cloudFiles = GetIncrementalFile(cloudFd); + map storageFiles = GetIncrementalFile(storageFd); + map allFiles = {}; + map smallFiles = {}; + map bigFiles = {}; + for (auto &item : storageFiles) { + // 进行文件对比 + string path = item.first; + if (cloudFiles.find(path) == cloudFiles.end() || (item.second.isIncr == "1" + && (cloudFiles[path].size != item.second.size || cloudFiles[path].lmtime != item.second.lmtime))) { + auto [res, fileHash] = BFileHash::HashWithSHA256(path); + if (fileHash.empty()) { + continue; + } + item.second.fileHash = fileHash; + item.second.isIncr = "1"; + } else { + item.second.fileHash = cloudFiles[path].fileHash; + } + if (cloudFiles.find(path) == cloudFiles.end() || + (item.second.isIncr == "1" && cloudFiles.find(path)->second.fileHash != item.second.fileHash)) { + // 在云空间简报里不存在或者hash不一致 + // 区分大小文件 + if (item.second.size.toInt64() < BConstants::BIG_FILE_BOUNDARY) { + HILOGI("compareFiles Find small file"); + smallFiles.try_emplace(path, item.second); + } else { + struct stat sta = {}; + if (stat(path.data(), &sta) == -1) { + continue; + } + HILOGI("compareFiles Find big file"); + bigFiles.try_emplace(fileName, sta); + } + } + allFiles.try_emplace(path, item.second); + } + HILOGI("compareFiles Find small files total: %{public}d", smallFiles.size()); + HILOGI("compareFiles Find big files total: %{public}d", bigFiles.size()); + return {allFiles, smallFiles, bigFiles}; +} + +static void WriteFile(const string &filename, const map &srcFiles) +{ + fstream f; + f.open(filename.data(), ios::out); + // 前面2行先填充进去 + f << "version=1.0&attrNum=6" << endl; + f << "path;mode;dir;size;mtime;hash" << endl; + for (auto item : srcFiles) { + struct FileInfo info = item.second; + string str = item.first + ";" + info.mode + ";" + info.isDir + ";" + info.size; + str += ";" + info.lmtime + ";" + info.fileHash + ";"; + f << str << endl; + } + f.close(); + HILOGI("WriteFile path: %{public}s", filename); +} + +/** + * 获取增量的大文件的信息 +*/ +static TarMap GetIncrmentBigInfos(const map &files) +{ + auto getStringHash = [](const TarMap &m, const string &str) -> string { + ostringstream strHex; + strHex << hex; + + hash strHash; + size_t szHash = strHash(str); + strHex << setfill('0') << setw(BConstants::BIG_FILE_NAME_SIZE) << szHash; + string name = strHex.str(); + for (int i = 0; m.find(name) != m.end(); ++i, strHex.str("")) { + szHash = strHash(str + to_string(i)); + strHex << setfill('0') << setw(BConstants::BIG_FILE_NAME_SIZE) << szHash; + name = strHex.str(); + } + + return name; + }; + + TarMap bigFiles; + for (const auto &item : files) { + string md5Name = getStringHash(bigFiles, item.first); + if (!md5Name.empty()) { + bigFiles.emplace(md5Name, make_tuple(item.first, item.second, true)); + } + } + + return bigFiles; +} + +/** + * 增量tar包和简报信息回传 +*/ +static ErrCode IncrementalTarFileReady(const TarMap &bigFileInfo, const map &srcFiles, sptr proxy) +{ + string tarFile = bigFileInfo.begin()->first; + string manageFile = "" + if (tarFile.rfind(".tar") != string::npos) { + manageFile = tarFile.substr(0, tarFile.length() - 4).append(".txt"); + } else { + manageFile = tarFile + ".txt"; + } + + string file = INDEX_FILE_INCREMENTAL_BACKUP.append(manageFile); + WriteFile(file, srcFiles); + + string tarName = INDEX_FILE_INCREMENTAL_BACKUP.append(tarFile); + ErrCode ret = + proxy->AppIncrementalFileReady(tarName, UniqueFd(open(tarName.data(), O_RDONLY)), + UniqueFd(open(file.data(), O_RDONLY))); + if (SUCCEEDED(ret)) { + HILOGI("IncrementalTarFileReady: The application is packaged successfully"); + // 删除文件 + RemoveFile(file); + RemoveFile(tarName); + } else { + HILOGI("IncrementalTarFileReady interface fails to be invoked: %{public}d", ret); + } + return ret; +} + +/** + * 增量大文件和简报信息回传 +*/ +static ErrCode IncrementalBigFileReady(const TarMap &pkgInfo, const map &bigInfos, sptr proxy) +{ + ErrCode ret {ERR_OK}; + for (auto &item : pkgInfo) { + if (item.first.empty() || item.second.path.empty()) { + continue; + } + + UniqueFd fd(open(item.second.path.data(), O_RDONLY)); + if (fd < 0) { + HILOGE("IncrementalBigFileReady open file failed, file name is %{public}s, err = %{public}d", + item.second.path.c_str(), errno); + continue; + } + + struct FileInfo info = bigInfos.find(item.second.path); + string file = INDEX_FILE_INCREMENTAL_BACKUP.append(item.first).append(".txt"); + WriteFile(file, srcFiles); + + ret = proxy->AppIncrementalFileReady(item.first, fd, + UniqueFd(open(file.data(), O_RDONLY))); + if (SUCCEEDED(ret)) { + HILOGI("IncrementalBigFileReady : The application is packaged successfully, package name is %{public}s", + item.first.c_str()); + RemoveFile(file); + } else { + HILOGI( + "IncrementalBigFileReady interface fails to be invoked: %{public}d", ret); + } + } + return ret; +} + ErrCode BackupExtExtension::GetIncrementalFileHandle(const string &fileName) { HILOGI("begin"); @@ -818,10 +1027,150 @@ ErrCode BackupExtExtension::PublishIncrementalFile(const string &fileName) return BError(BError::Codes::OK); } -ErrCode BackupExtExtension::HandleIncrementalBackup(UniqueFd incrementalFd, UniqueFd manifestFd) +ErrCode BackupExtExtension::HandleIncrementalBackup(UniqueFdincrementalFd, UniqueFd manifestFd) { - HILOGI("begin"); - return BError(BError::Codes::OK); + string usrConfig = extension_->GetUsrConfig(); + BJsonCachedEntity cachedEntity(usrConfig); + auto cache = cachedEntity.Structuralize(); + if (!cache.GetAllowToBackupRestore()) { + HILOGI("Application does not allow backup or restore"); + return BError(BError::Codes::EXT_FORBID_BACKUP_RESTORE, "Application does not allow backup or restore") + .GetCode(); + } + AsyncTaskOnIncrementalBackup(UniqueFd incrementalFd, UniqueFd manifestFd); + return 0; +} + +void BackupExtExtension::AsyncTaskOnIncrementalBackup(UniqueFd incrementalFd, UniqueFd manifestFd) +{ + auto task = [obj {wptr(this)}, incrementalFd, manifestFd]() { + auto ptr = obj.promote(); + try { + BExcepUltils::BAssert(ptr, BError::Codes::EXT_BROKEN_FRAMEWORK, + "Ext extension handle have been already released"); + BExcepUltils::BAssert(ptr->extension_, BError::Codes::EXT_INVAL_ARG, + "extension handle have been already released"); + + ptr->extension_->DoIncrementalBackup(incrementalFd, manifestFd); + } catch (const BError &e) { + ptr->AppIncrementalDone(e.GetCode()); + } catch (const exception &e) { + HILOGE("Catched an unexpected low-level exception %{public}s", e.what()); + ptr->AppIncrementalDone(BError(BError::Codes::EXT_INVAL_ARG).GetCode()); + } catch (...) { + HILOGE("Failed to restore the ext bundle"); + ptr->AppIncrementalDone(BError(BError::Codes::EXT_INVAL_ARG).GetCode()); + } + }; + + threadPool_.AddTask([task]() { + try { + task(); + } catch (...) { + HILOGE("Failed to add task to thread pool"); + } + }); +} + +static void IncrementalPacket(const map &infos, TarMap &tar, sptr proxy) +{ + HILOGE("IncrementalPacket begin"); + string path = string(BConstants::PATH_BUNDLE_BACKUP_HOME).append(BConstants::SA_BUNDLE_BACKUP_BACKUP); + int64_t totalSize = 0; + uint32_t fileCount = 0; + vector packFiles; + map tarInfos + for (auto small : infos) { + totalSize += small.second.size.toInt64(); + fileCount += 1; + packFiles.emplace_back(small.first); + tarInfos.try_emplace(small.first, small.second); + if (totalSize >= DEFAULT_SLICE_SIZE || fileCount >= MAX_FILE_COUNT) { + TarMap tarMap {}; + TarFile::GetInstance().Packet(packFiles, "part", path, tarMap); + tar.insert(tarMap.begin(), tarMap.end()); + // 执行tar包回传功能 + IncrementalTarFileReady(tarMap, tarInfos, proxy); + totalSize = 0; + fileCount = 0; + packFiles.clear(); + tarInfos.clear(); + } + } + if (fileCount > 0) { + // 打包回传 + TarMap tarMap {}; + TarFile::GetInstance().Packet(packFiles, "part", path, tarMap); + IncrementalTarFileReady(tarMap, tarInfos, proxy); + tar.insert(tarMap.begin(), tarMap.end()); + packFiles.clear(); + tarInfos.clear(); + } +} + +static ErrCode IncrementalAllFileReady(const TarMap &pkgInfo, const map &srcFiles, + sptr proxy) +{ + BJsonCachedEntity cachedEntity( + UniqueFd(open(INDEX_FILE_BACKUP.data(), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR))); + auto cache = cachedEntity.Structuralize(); + cache.SetExtManage(pkgInfo); + cachedEntity.Persist(); + close(cachedEntity.GetFd().Release()); + + string file = INDEX_FILE_INCREMENTAL_BACKUP.append("all.txt"); + WriteFile(file, srcFiles); + UniqueFd fd(open(INDEX_FILE_BACKUP.data(), O_RDONLY)); + UniqueFd manifestFd(open(file.data(), O_RDONLY)); + ErrCode ret = + proxy->AppIncrementalFileReady(string(BConstants::EXT_BACKUP_MANAGE), fd, manifestFd); + if (SUCCEEDED(ret)) { + HILOGI("IncrementalAllFileReady successfully"); + RemoveFile(file); + } else { + HILOGI( + "successfully but the IncrementalAllFileReady interface fails to be invoked: %{public}d", ret); + } + return ret; } +int BackupExtExtension::DoIncrementalBackup(UniqueFd incrementalFd, UniqueFd manifestFd) +{ + HILOGI("Do increment backup"); + if (extension_->GetExtensionAction() != BConstants::ExtensionAction::BACKUP) { + return EPERM; + } + + string path = string(BConstants::PATH_BUNDLE_BACKUP_HOME).append(BConstants::SA_BUNDLE_BACKUP_BACKUP); + if (mkdir(path.data(), S_IRWXU) && errno != EEXIST) { + throw BError(errno); + } + + // 获取增量文件和全量数据 + auto [allFiles, smallFiles, bigFiles] = CompareFiles(manifestFd, incrementalFd); + if (smallFiles.size() == 0 && bigFiles.size() == 0) { + // 没有增量,则不需要上传 + return ERR_OK; + } + + auto proxy = ServiceProxy::GetInstance(); + if (proxy == nullptr) { + throw BError(BError::Codes::EXT_BROKEN_BACKUP_SA, std::generic_category().message(errno)); + } + // tar包数据 + TarMap tarMap; + IncrementalPacket(smallFiles, tarMap, proxy); + HILOGI("Do increment backup, IncrementalPacket end"); + + // 最后回传大文件 + TarMap bigMap = GetIncrmentBigInfos(bigFiles); + IncrementalBigFileReady(bigMap, bigFiles, proxy); + HILOGI("Do increment backup, IncrementalBigFileReady end"); + bigMap.insert(tarMap.begin(), tarMap.end()); + + // 回传manage.json和全量文件 + IncrementalAllFileReady(bigMap, allFiles, proxy) + HILOGI("Do increment backup, IncrementalAllFileReady end"); + return ERR_OK; +} } // namespace OHOS::FileManagement::Backup diff --git a/utils/BUILD.gn b/utils/BUILD.gn index ff90af981..a4a49f22b 100644 --- a/utils/BUILD.gn +++ b/utils/BUILD.gn @@ -83,6 +83,7 @@ ohos_shared_library("backup_utils") { "src/b_error/b_excep_utils.cpp", "src/b_filesystem/b_dir.cpp", "src/b_filesystem/b_file.cpp", + "src/b_filesystem/b_file_hash.cpp", "src/b_json/b_json_entity_ext_manage.cpp", "src/b_json/b_json_entity_extension_config.cpp", "src/b_ohos/startup/backup_para.cpp", diff --git a/utils/include/b_filesystem/b_file.h b/utils/include/b_filesystem/b_file.h index 863f4ad4b..f9a0055ff 100644 --- a/utils/include/b_filesystem/b_file.h +++ b/utils/include/b_filesystem/b_file.h @@ -61,6 +61,13 @@ public: */ static bool CopyFile(const string &from, const string &to); + /** + * @brief read incremental file info + * + * @param fd UniqueFd + */ + static vector> ReadIncrementalFile(const UniqueFd &fd); + private: }; } // namespace OHOS::FileManagement::Backup diff --git a/utils/include/b_filesystem/b_file_hash.h b/utils/include/b_filesystem/b_file_hash.h new file mode 100644 index 000000000..8fff58760 --- /dev/null +++ b/utils/include/b_filesystem/b_file_hash.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2023 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_FILEMGMT_BACKUP_B_FILE_HASH_H +#define OHOS_FILEMGMT_BACKUP_B_FILE_HASH_H + +#include +#include + +namespace OHOS::FileManagement::Backup { +using namespace std; +class BFileHash { +public: + static std::tuple HashWithMD5(const std::string &fpath); + static std::tuple HashWithSHA1(const std::string &fpath); + static std::tuple HashWithSHA256(const std::string &fpath); +}; +} // namespace OHOS::FileManagement::Backup + +#endif // OHOS_FILEMGMT_BACKUP_B_FILE_HASH_H \ No newline at end of file diff --git a/utils/src/b_filesystem/b_file.cpp b/utils/src/b_filesystem/b_file.cpp index aa8c36370..614fe60a4 100644 --- a/utils/src/b_filesystem/b_file.cpp +++ b/utils/src/b_filesystem/b_file.cpp @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include "b_error/b_error.h" #include "filemgmt_libhilog.h" @@ -140,4 +142,44 @@ bool BFile::CopyFile(const string &from, const string &to) } return false; } + +vector> BFile::ReadIncrementalFile(const UniqueFd &fd) +{ + string content = ReadFile(fd).get(); + vector> infos; + + vector lines = SplitString(content, '\n'); + if (lines.begin() != lines.end()) { + // 对第2行的数据做切分 + vector keys = SplitString(lines[1], ';'); + int num = keys.size() - 1; + cout << "num" << num << endl; + for (int i = 2; i < lines.size(); i++) { + map info; + // 如果结尾有;,就删除后再切分 + string newLine = lines[i]; + if (newLine[newLine.length() - 1] == ';') { + newLine = newLine.substr(0, newLine.length() - 1); + } + + vector words = SplitString(newLine, ';'); + if (words.begin() != words.end()) { + string filePath = ""; + int len = words.size(); + for (int j = 1; j < keys.size(); j++) { + int index = len - num - 1 + j; + info.try_emplace(keys[j], words[index]); + } + for (int j = 0; j < len - num; j++) { + filePath += words[j] + ";"; + } + filePath = filePath.substr(0, filePath.length() - 1); + info.try_emplace(keys[0], filePath); + + } + infos.emplace_back(info); + } + } + return infos; +} } // namespace OHOS::FileManagement::Backup \ No newline at end of file diff --git a/utils/src/b_filesystem/b_file_hash.cpp b/utils/src/b_filesystem/b_file_hash.cpp new file mode 100644 index 000000000..c3e162786 --- /dev/null +++ b/utils/src/b_filesystem/b_file_hash.cpp @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2023 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "b_filesystem/b_file_hash.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace OHOS::FileManagement::Backup { +using namespace std; + +static tuple HashFinal(int err, const unique_ptr &hashBuf, size_t hashLen) +{ + if (err) { + return { err, "" }; + } + + stringstream ss; + for (size_t i = 0; i < hashLen; ++i) { + const int hexPerByte = 2; + ss << std::uppercase << std::setfill('0') << std::setw(hexPerByte) << std::hex << + static_cast(hashBuf[i]); + } + + return { err, ss.str() }; +} + +static int ForEachFileSegment(const string &fpath, function executor) +{ + unique_ptr filp = { fopen(fpath.c_str(), "r"), fclose }; + if (!filp) { + return errno; + } + + const size_t pageSize { getpagesize() }; + auto buf = make_unique(pageSize); + size_t actLen; + do { + actLen = fread(buf.get(), 1, pageSize, filp.get()); + if (actLen > 0) { + executor(buf.get(), actLen); + } + } while (actLen == pageSize); + + return ferror(filp.get()) ? errno : 0; +} + +tuple BFileHash::HashWithMD5(const string &fpath) +{ + auto res = make_unique(MD5_DIGEST_LENGTH); + MD5_CTX ctx; + MD5_Init(&ctx); + auto md5Update = [ctx = &ctx](char *buf, size_t len) { + MD5_Update(ctx, buf, len); + }; + int err = ForEachFileSegment(fpath, md5Update); + MD5_Final(res.get(), &ctx); + return HashFinal(err, res, MD5_DIGEST_LENGTH); +} + +tuple BFileHash::HashWithSHA1(const string &fpath) +{ + auto res = make_unique(SHA_DIGEST_LENGTH); + SHA_CTX ctx; + SHA1_Init(&ctx); + auto sha1Update = [ctx = &ctx](char *buf, size_t len) { + SHA1_Update(ctx, buf, len); + }; + int err = ForEachFileSegment(fpath, sha1Update); + SHA1_Final(res.get(), &ctx); + return HashFinal(err, res, SHA_DIGEST_LENGTH); +} + +tuple BFileHash::HashWithSHA256(const string &fpath) +{ + auto res = make_unique(SHA256_DIGEST_LENGTH); + SHA256_CTX ctx; + SHA256_Init(&ctx); + auto sha256Update = [ctx = &ctx](char *buf, size_t len) { + SHA256_Update(ctx, buf, len); + }; + int err = ForEachFileSegment(fpath, sha256Update); + SHA256_Final(res.get(), &ctx); + return HashFinal(err, res, SHA256_DIGEST_LENGTH); +} + +} // namespace OHOS::FileManagement::Backup \ No newline at end of file -- Gitee From f3700b1af81f14510dab0de94f19567d716099c6 Mon Sep 17 00:00:00 2001 From: z30054037 Date: Thu, 28 Dec 2023 22:41:43 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E2=80=9C=E5=A2=9E=E9=87=8F=E5=A4=87?= =?UTF-8?q?=E4=BB=BD=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: z30054037 Change-Id: I32e436b9a2d524bf154a79b5129a478091e6056d --- bundle.json | 3 +- .../native/backup_ext/include/ext_extension.h | 13 +++ .../native/backup_ext/src/ext_extension.cpp | 104 +++++++++++------- tests/mock/b_filesystem/b_file_mock.cpp | 6 + .../backup_utils/b_filesystem/b_file_test.cpp | 54 +++++++++ utils/BUILD.gn | 4 + utils/src/b_filesystem/b_file.cpp | 22 +++- 7 files changed, 161 insertions(+), 45 deletions(-) diff --git a/bundle.json b/bundle.json index db8920b9d..991496713 100644 --- a/bundle.json +++ b/bundle.json @@ -41,7 +41,8 @@ ], "third_party": [ "bounds_checking_function", - "jsoncpp" + "jsoncpp", + "openssl" ] }, "adapted_system_type": [ "small", "standard" ], diff --git a/frameworks/native/backup_ext/include/ext_extension.h b/frameworks/native/backup_ext/include/ext_extension.h index 4a1584835..8fd2b1799 100644 --- a/frameworks/native/backup_ext/include/ext_extension.h +++ b/frameworks/native/backup_ext/include/ext_extension.h @@ -107,7 +107,20 @@ private: */ int DoIncrementalBackup(UniqueFd incrementalFd, UniqueFd manifestFd); + /** + * @brief AsyncTaskOnIncrementalBackup + * + * @param incrementalFd storage fd + * @param manifestFd 云空间 fd + */ void AsyncTaskOnIncrementalBackup(UniqueFd incrementalFd, UniqueFd manifestFd); + + /** + * @brief extension incremental backup restore is done + * + * @param errCode + */ + void AppIncrementalDone(ErrCode errCode); private: std::shared_mutex lock_; std::shared_ptr extension_; diff --git a/frameworks/native/backup_ext/src/ext_extension.cpp b/frameworks/native/backup_ext/src/ext_extension.cpp index 56765a731..52c24cf52 100644 --- a/frameworks/native/backup_ext/src/ext_extension.cpp +++ b/frameworks/native/backup_ext/src/ext_extension.cpp @@ -18,8 +18,10 @@ #include #include #include +#include #include #include +#include #include #include @@ -57,13 +59,13 @@ const string INDEX_FILE_RESTORE = string(BConstants::PATH_BUNDLE_BACKUP_HOME). append(BConstants::EXT_BACKUP_MANAGE); const string INDEX_FILE_INCREMENTAL_BACKUP = string(BConstants::PATH_BUNDLE_BACKUP_HOME). - append(BConstants::SA_BUNDLE_BACKUP_BACKUP) + append(BConstants::SA_BUNDLE_BACKUP_BACKUP); using namespace std; struct FileInfo { string filePath; string mode; string isDir; - string size; + int64_t size; string lmtime; string fileHash; string isIncr = "0"; // 是否增量 @@ -834,7 +836,12 @@ static map GetIncrementalFile(const UniqueFd &fd) string filePath = info.find("path") != info.end() ? info.find("path")->second : ""; string mode = info.find("mode") != info.end() ? info.find("mode")->second : ""; string dir = info.find("dir") != info.end() ? info.find("dir")->second : "0"; - string size = info.find("size") != info.end() ? info.find("size")->second : "0"; + int64_t size = 0; + try { + size = info.find("size") != info.end() ? stoll(info.find("size")->second) : 0; + } catch (const std::out_of_range &e) { + size = 0; + } string mtime = info.find("mtime") != info.end() ? info.find("mtime")->second : "0"; string isIncr = info.find("isIncr") != info.end() ? info.find("isIncr")->second : "0"; string hash = info.find("hash") != info.end() ? info.find("hash")->second : ""; @@ -852,15 +859,15 @@ static map GetIncrementalFile(const UniqueFd &fd) return files; } -static pair, map, map> CompareFiles( - const UniqueFd &cloudFd, - const UniqueFd &storageFd) +static tuple, map, map, + map> CompareFiles(const UniqueFd &cloudFd, const UniqueFd &storageFd) { map cloudFiles = GetIncrementalFile(cloudFd); map storageFiles = GetIncrementalFile(storageFd); map allFiles = {}; - map smallFiles = {}; + map smallFiles = {}; map bigFiles = {}; + map bigInfos = {}; for (auto &item : storageFiles) { // 进行文件对比 string path = item.first; @@ -879,23 +886,25 @@ static pair, map, mapsecond.fileHash != item.second.fileHash)) { // 在云空间简报里不存在或者hash不一致 // 区分大小文件 - if (item.second.size.toInt64() < BConstants::BIG_FILE_BOUNDARY) { + struct stat sta = {}; + if (stat(path.c_str(), &sta) == -1) { + continue; + } + if (sta.st_size < BConstants::BIG_FILE_BOUNDARY) { HILOGI("compareFiles Find small file"); + item.second.size = sta.st_size; smallFiles.try_emplace(path, item.second); } else { - struct stat sta = {}; - if (stat(path.data(), &sta) == -1) { - continue; - } HILOGI("compareFiles Find big file"); - bigFiles.try_emplace(fileName, sta); + bigFiles.try_emplace(path, sta); + bigInfos.try_emplace(path, item.second); } } allFiles.try_emplace(path, item.second); } HILOGI("compareFiles Find small files total: %{public}d", smallFiles.size()); HILOGI("compareFiles Find big files total: %{public}d", bigFiles.size()); - return {allFiles, smallFiles, bigFiles}; + return {allFiles, smallFiles, bigFiles, bigInfos}; } static void WriteFile(const string &filename, const map &srcFiles) @@ -907,12 +916,12 @@ static void WriteFile(const string &filename, const map f << "path;mode;dir;size;mtime;hash" << endl; for (auto item : srcFiles) { struct FileInfo info = item.second; - string str = item.first + ";" + info.mode + ";" + info.isDir + ";" + info.size; + string str = item.first + ";" + info.mode + ";" + info.isDir + ";" + to_string(info.size); str += ";" + info.lmtime + ";" + info.fileHash + ";"; f << str << endl; } f.close(); - HILOGI("WriteFile path: %{public}s", filename); + HILOGI("WriteFile path: %{public}s", filename.c_str()); } /** @@ -954,17 +963,17 @@ static TarMap GetIncrmentBigInfos(const map &files) static ErrCode IncrementalTarFileReady(const TarMap &bigFileInfo, const map &srcFiles, sptr proxy) { string tarFile = bigFileInfo.begin()->first; - string manageFile = "" + string manageFile = ""; if (tarFile.rfind(".tar") != string::npos) { manageFile = tarFile.substr(0, tarFile.length() - 4).append(".txt"); } else { manageFile = tarFile + ".txt"; } - string file = INDEX_FILE_INCREMENTAL_BACKUP.append(manageFile); + string file = string(INDEX_FILE_INCREMENTAL_BACKUP).append(manageFile); WriteFile(file, srcFiles); - string tarName = INDEX_FILE_INCREMENTAL_BACKUP.append(tarFile); + string tarName = string(INDEX_FILE_INCREMENTAL_BACKUP).append(tarFile); ErrCode ret = proxy->AppIncrementalFileReady(tarName, UniqueFd(open(tarName.data(), O_RDONLY)), UniqueFd(open(file.data(), O_RDONLY))); @@ -986,23 +995,26 @@ static ErrCode IncrementalBigFileReady(const TarMap &pkgInfo, const mapsecond; + string file = string(INDEX_FILE_INCREMENTAL_BACKUP).append(item.first).append(".txt"); + HILOGE("IncrementalBigFileReady write name is %{public}s", path.c_str()); + map bigInfo; + bigInfo.try_emplace(path, info); + WriteFile(file, bigInfo); - ret = proxy->AppIncrementalFileReady(item.first, fd, - UniqueFd(open(file.data(), O_RDONLY))); + ret = proxy->AppIncrementalFileReady(item.first, std::move(fd), UniqueFd(open(file.data(), O_RDONLY))); if (SUCCEEDED(ret)) { HILOGI("IncrementalBigFileReady : The application is packaged successfully, package name is %{public}s", item.first.c_str()); @@ -1027,31 +1039,33 @@ ErrCode BackupExtExtension::PublishIncrementalFile(const string &fileName) return BError(BError::Codes::OK); } -ErrCode BackupExtExtension::HandleIncrementalBackup(UniqueFdincrementalFd, UniqueFd manifestFd) +ErrCode BackupExtExtension::HandleIncrementalBackup(UniqueFd incrementalFd, UniqueFd manifestFd) { string usrConfig = extension_->GetUsrConfig(); BJsonCachedEntity cachedEntity(usrConfig); auto cache = cachedEntity.Structuralize(); if (!cache.GetAllowToBackupRestore()) { - HILOGI("Application does not allow backup or restore"); + HILOGE("Application does not allow backup or restore"); return BError(BError::Codes::EXT_FORBID_BACKUP_RESTORE, "Application does not allow backup or restore") .GetCode(); } - AsyncTaskOnIncrementalBackup(UniqueFd incrementalFd, UniqueFd manifestFd); + AsyncTaskOnIncrementalBackup(move(incrementalFd), move(manifestFd)); return 0; } void BackupExtExtension::AsyncTaskOnIncrementalBackup(UniqueFd incrementalFd, UniqueFd manifestFd) { - auto task = [obj {wptr(this)}, incrementalFd, manifestFd]() { + auto task = [obj {wptr(this)}, ifd(incrementalFd.Get()), mfd(manifestFd.Get())]() { auto ptr = obj.promote(); try { BExcepUltils::BAssert(ptr, BError::Codes::EXT_BROKEN_FRAMEWORK, "Ext extension handle have been already released"); BExcepUltils::BAssert(ptr->extension_, BError::Codes::EXT_INVAL_ARG, "extension handle have been already released"); - - ptr->extension_->DoIncrementalBackup(incrementalFd, manifestFd); + + auto ret = ptr->DoIncrementalBackup(UniqueFd(ifd), UniqueFd(mfd)); + ptr->AppIncrementalDone(ret); + HILOGE("Incremental backup app done %{public}d", ret); } catch (const BError &e) { ptr->AppIncrementalDone(e.GetCode()); } catch (const exception &e) { @@ -1079,9 +1093,9 @@ static void IncrementalPacket(const map &infos, TarMap int64_t totalSize = 0; uint32_t fileCount = 0; vector packFiles; - map tarInfos + map tarInfos; for (auto small : infos) { - totalSize += small.second.size.toInt64(); + totalSize += small.second.size; fileCount += 1; packFiles.emplace_back(small.first); tarInfos.try_emplace(small.first, small.second); @@ -1118,12 +1132,12 @@ static ErrCode IncrementalAllFileReady(const TarMap &pkgInfo, const mapAppIncrementalFileReady(string(BConstants::EXT_BACKUP_MANAGE), fd, manifestFd); + proxy->AppIncrementalFileReady(string(BConstants::EXT_BACKUP_MANAGE), std::move(fd), std::move(manifestFd)); if (SUCCEEDED(ret)) { HILOGI("IncrementalAllFileReady successfully"); RemoveFile(file); @@ -1147,7 +1161,7 @@ int BackupExtExtension::DoIncrementalBackup(UniqueFd incrementalFd, UniqueFd man } // 获取增量文件和全量数据 - auto [allFiles, smallFiles, bigFiles] = CompareFiles(manifestFd, incrementalFd); + auto [allFiles, smallFiles, bigFiles, bigInfos] = CompareFiles(manifestFd, incrementalFd); if (smallFiles.size() == 0 && bigFiles.size() == 0) { // 没有增量,则不需要上传 return ERR_OK; @@ -1164,13 +1178,23 @@ int BackupExtExtension::DoIncrementalBackup(UniqueFd incrementalFd, UniqueFd man // 最后回传大文件 TarMap bigMap = GetIncrmentBigInfos(bigFiles); - IncrementalBigFileReady(bigMap, bigFiles, proxy); + IncrementalBigFileReady(bigMap, bigInfos, proxy); HILOGI("Do increment backup, IncrementalBigFileReady end"); bigMap.insert(tarMap.begin(), tarMap.end()); // 回传manage.json和全量文件 - IncrementalAllFileReady(bigMap, allFiles, proxy) + IncrementalAllFileReady(bigMap, allFiles, proxy); HILOGI("Do increment backup, IncrementalAllFileReady end"); return ERR_OK; } + +void BackupExtExtension::AppIncrementalDone(ErrCode errCode) +{ + auto proxy = ServiceProxy::GetInstance(); + BExcepUltils::BAssert(proxy, BError::Codes::EXT_BROKEN_IPC, "Failed to obtain the ServiceProxy handle"); + auto ret = proxy->AppIncrementalDone(errCode); + if (ret != ERR_OK) { + HILOGE("Failed to notify the app done. err = %{public}d", ret); + } +} } // namespace OHOS::FileManagement::Backup diff --git a/tests/mock/b_filesystem/b_file_mock.cpp b/tests/mock/b_filesystem/b_file_mock.cpp index d3561215a..1e80a11dd 100644 --- a/tests/mock/b_filesystem/b_file_mock.cpp +++ b/tests/mock/b_filesystem/b_file_mock.cpp @@ -83,4 +83,10 @@ bool BFile::CopyFile(const string &from, const string &to) { return true; } + +vector> BFile::ReadIncrementalFile(const UniqueFd &fd) +{ + vector> infos; + return infos; +} } // namespace OHOS::FileManagement::Backup \ No newline at end of file diff --git a/tests/unittests/backup_utils/b_filesystem/b_file_test.cpp b/tests/unittests/backup_utils/b_filesystem/b_file_test.cpp index 5708ff760..e253747f9 100644 --- a/tests/unittests/backup_utils/b_filesystem/b_file_test.cpp +++ b/tests/unittests/backup_utils/b_filesystem/b_file_test.cpp @@ -160,4 +160,58 @@ HWTEST_F(BFileTest, b_file_Write_0100, testing::ext::TestSize.Level1) } GTEST_LOG_(INFO) << "BFileTest-end b_file_Write_0100"; } + +/** + * @brief 创建增量测试文件 + * + * @return tuple 文件路径、对比内容 + */ +static tuple GetTestIncrementalFile(const TestManager &tm) +{ + string path = tm.GetRootDirCurTest(); + string filePath = path + "incremental.txt"; + string content = "version=1.0&attrNum=6\npath;mode;dir;size;mtime;hash\n"; + string info = "a.txt;0660;0;10;123456;asd1asdasd;"; + if (bool contentCreate = SaveStringToFile(filePath, content + info, true); !contentCreate) { + throw system_error(errno, system_category()); + } + return {filePath, info}; +} + +/** + * @tc.number: SUB_backup_b_file_ReadIncrementalFile_0100 + * @tc.name: b_file_ReadIncrementalFile_0100 + * @tc.desc: 测试ReadIncrementalFile接口 + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + * @tc.require: I6F3GV + */ +HWTEST_F(BFileTest, b_file_ReadIncrementalFile_0100, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "BFileTest-begin b_file_ReadIncrementalFile_0100"; + try { + TestManager tm(__func__); + const auto [filePath, content] = GetTestFile(tm); + TestManager tmInFile("b_file_ReadIncrementalFile_0100"); + string fileInPath = tmInFile.GetRootDirCurTest().append("1.txt"); + BFile::Write(UniqueFd(open(filePath.data(), O_RDWR)), fileInPath); + vector> infos = BFile::ReadIncrementalFile(UniqueFd(open(fileInPath.c_str(), O_RDONLY))); + string incrInfo = ""; + for (auto item : infos) { + string filePath = info.find("path") != info.end() ? info.find("path")->second : ""; + string mode = info.find("mode") != info.end() ? info.find("mode")->second : ""; + string dir = info.find("dir") != info.end() ? info.find("dir")->second : "0"; + string size = info.find("size") != info.end() ? stoll(info.find("size")->second) : "0"; + string mtime = info.find("mtime") != info.end() ? info.find("mtime")->second : "0"; + string hash = info.find("hash") != info.end() ? info.find("hash")->second : ""; + incrInfo += filePath + ";" + mode + ";" + dir + ";" + size + ";" + mtime + ";" + hash + ";"; + } + EXPECT_EQ(incrInfo, content); + } catch (const exception &e) { + GTEST_LOG_(INFO) << "BFileTest-an exception occurred by Write."; + e.what(); + } + GTEST_LOG_(INFO) << "BFileTest-end b_file_ReadIncrementalFile_0100"; +} } // namespace OHOS::FileManagement::Backup \ No newline at end of file diff --git a/utils/BUILD.gn b/utils/BUILD.gn index a4a49f22b..9bd937cbe 100644 --- a/utils/BUILD.gn +++ b/utils/BUILD.gn @@ -110,6 +110,7 @@ ohos_shared_library("backup_utils") { "${path_backup}/interfaces/inner_api/native/backup_kit_inner/impl", "${path_rust}/crates/cxx/include", "${target_gen_dir}/rust/src", + "//third_party/openssl/include", ] deps = [ @@ -117,8 +118,11 @@ ohos_shared_library("backup_utils") { ":backup_cxx_gen", ":backup_cxx_rust", "${path_jsoncpp}:jsoncpp", + "//third_party/openssl:libcrypto_shared", ] + defines = [ "OPENSSL_SUPPRESS_DEPRECATED" ] + use_exceptions = true innerapi_tags = [ "platformsdk" ] part_name = "app_file_service" diff --git a/utils/src/b_filesystem/b_file.cpp b/utils/src/b_filesystem/b_file.cpp index 614fe60a4..d85b30ae9 100644 --- a/utils/src/b_filesystem/b_file.cpp +++ b/utils/src/b_filesystem/b_file.cpp @@ -143,6 +143,20 @@ bool BFile::CopyFile(const string &from, const string &to) return false; } +static vector SplitString(string str, char sep) +{ + stringstream ss(str); + string line; + vector splitArr; + while (!ss.eof()) { + getline(ss, line, sep); + if (!line.empty() || sep == ';') { + splitArr.push_back(line); + } + } + return splitArr; +} + vector> BFile::ReadIncrementalFile(const UniqueFd &fd) { string content = ReadFile(fd).get(); @@ -152,9 +166,9 @@ vector> BFile::ReadIncrementalFile(const UniqueFd &fd) if (lines.begin() != lines.end()) { // 对第2行的数据做切分 vector keys = SplitString(lines[1], ';'); - int num = keys.size() - 1; - cout << "num" << num << endl; - for (int i = 2; i < lines.size(); i++) { + int num = (int)keys.size() - 1; + + for (int i = 2; i < (int)lines.size(); i++) { map info; // 如果结尾有;,就删除后再切分 string newLine = lines[i]; @@ -166,7 +180,7 @@ vector> BFile::ReadIncrementalFile(const UniqueFd &fd) if (words.begin() != words.end()) { string filePath = ""; int len = words.size(); - for (int j = 1; j < keys.size(); j++) { + for (int j = 1; j < (int)keys.size(); j++) { int index = len - num - 1 + j; info.try_emplace(keys[j], words[index]); } -- Gitee From 254ab2994994b2d0bed4c151c0d49d25ec01b005 Mon Sep 17 00:00:00 2001 From: z30054037 Date: Fri, 29 Dec 2023 09:32:58 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E5=A2=9E=E9=87=8F=E5=A4=87=E4=BB=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: z30054037 Change-Id: I17aa17c2ff5b3aa47408458aa8967e1f63501ce8 --- tools/backup_tool/BUILD.gn | 1 + .../include/tools_op_incremental_backup.h | 24 ++ tools/backup_tool/src/main.cpp | 2 + .../src/tools_op_incremental_backup.cpp | 305 ++++++++++++++++++ utils/include/b_resources/b_constants.h | 1 + 5 files changed, 333 insertions(+) create mode 100644 tools/backup_tool/include/tools_op_incremental_backup.h create mode 100644 tools/backup_tool/src/tools_op_incremental_backup.cpp diff --git a/tools/backup_tool/BUILD.gn b/tools/backup_tool/BUILD.gn index b164c2006..83db49e08 100644 --- a/tools/backup_tool/BUILD.gn +++ b/tools/backup_tool/BUILD.gn @@ -39,6 +39,7 @@ ohos_executable("backup_tool") { "src/tools_op_backup.cpp", "src/tools_op_check_sa.cpp", "src/tools_op_help.cpp", + "src/tools_op_incremental_backup.cpp", "src/tools_op_restore.cpp", "src/tools_op_restore_async.cpp", ] diff --git a/tools/backup_tool/include/tools_op_incremental_backup.h b/tools/backup_tool/include/tools_op_incremental_backup.h new file mode 100644 index 000000000..e1d581d55 --- /dev/null +++ b/tools/backup_tool/include/tools_op_incremental_backup.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2023 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_FILEMGMT_BACKUP_TOOLS_OP_INCREMENTAL_BACKUP_H +#define OHOS_FILEMGMT_BACKUP_TOOLS_OP_INCREMENTAL_BACKUP_H + +namespace OHOS::FileManagement::Backup { + bool IncrementalBackUpRegister(); + +} // namespace OHOS::FileManagement::Backup + +#endif // OHOS_FILEMGMT_BACKUP_TOOLS_OP_INCREMENTAL_BACKUP_H \ No newline at end of file diff --git a/tools/backup_tool/src/main.cpp b/tools/backup_tool/src/main.cpp index 4de614c58..d1cef740c 100644 --- a/tools/backup_tool/src/main.cpp +++ b/tools/backup_tool/src/main.cpp @@ -27,6 +27,7 @@ int main() #include "tools_op_help.h" #include "tools_op_restore.h" #include "tools_op_restore_async.h" +#include "tools_op_incremental_backup.h" #include #include @@ -83,6 +84,7 @@ void ToolRegister() OHOS::FileManagement::Backup::CheckSaRegister(); OHOS::FileManagement::Backup::RestoreRegister(); OHOS::FileManagement::Backup::RestoreAsyncRegister(); + OHOS::FileManagement::Backup::IncrementalBackUpRegister(); } int ParseOpAndExecute(const int argc, char *const argv[]) diff --git a/tools/backup_tool/src/tools_op_incremental_backup.cpp b/tools/backup_tool/src/tools_op_incremental_backup.cpp new file mode 100644 index 000000000..d776b8bbd --- /dev/null +++ b/tools/backup_tool/src/tools_op_incremental_backup.cpp @@ -0,0 +1,305 @@ +/* + * Copyright (c) 2023 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "b_error/b_error.h" +#include "b_filesystem/b_file.h" +#include "b_json/b_json_entity_ext_manage.h" +#include "b_resources/b_constants.h" +#include "backup_kit_inner.h" +#include "base/hiviewdfx/hitrace/interfaces/native/innerkits/include/hitrace_meter/hitrace_meter.h" +#include "out/rk3568/obj/third_party/musl/intermidiates/linux/musl_src_ported/include/fcntl.h" +#include "out/rk3568/obj/third_party/musl/intermidiates/linux/musl_src_ported/include/stdio.h" +#include "service_proxy.h" +#include "tools_op.h" +#include "tools_op_backup.h" + +namespace OHOS::FileManagement::Backup { +using namespace std; + +class Session { +public: + void UpdateBundleReceivedFiles(const BundleName &bundleName, const string &fileName) + { + lock_guard lk(lock_); + bundleStatusMap_[bundleName].receivedFile.insert(fileName); + TryClearBundleOfMap(bundleName); + } + + void SetIndexFiles(const BundleName &bundleName, UniqueFd fd) + { + BJsonCachedEntity cachedEntity(move(fd)); + auto cache = cachedEntity.Structuralize(); + lock_guard lk(lock_); + bundleStatusMap_[bundleName].indexFile = cache.GetExtManage(); + } + + void TryNotify(bool flag = false) + { + if (flag == true) { + ready_ = true; + cv_.notify_all(); + } else if (bundleStatusMap_.size() == 0 && cnt_ == 0 && isAllBundelsFinished.load()) { + ready_ = true; + cv_.notify_all(); + } + } + + void UpdateBundleFinishedCount() + { + lock_guard lk(lock_); + cnt_--; + } + + void SetBundleFinishedCount(uint32_t cnt) + { + cnt_ = cnt; + } + + void Wait() + { + unique_lock lk(lock_); + cv_.wait(lk, [&] { return ready_; }); + } + + unique_ptr session_ = {}; + +private: + struct BundleStatus { + set receivedFile; + set indexFile; + }; + + void TryClearBundleOfMap(const BundleName &bundleName) + { + if (bundleStatusMap_[bundleName].indexFile == bundleStatusMap_[bundleName].receivedFile) { + bundleStatusMap_.erase(bundleName); + } + } + + map bundleStatusMap_; + mutable condition_variable cv_; + mutex lock_; + bool ready_ = false; + uint32_t cnt_ {0}; + +public: + std::atomic isAllBundelsFinished {false}; + string lastIncrementalTime; +}; + +static string GenHelpMsg() +{ + return "\t\tThis operation helps to backup application data.\n" + "\t\t--isLocal\t\t This parameter should be true or flase; true: local backup false: others.\n" + "\t\t--pathCapFile\t\t This parameter should be the path of the capability file.\n" + "\t\t--bundle\t\t This parameter is bundleName."; +} + +static void OnFileReady(shared_ptr ctx, const BFileInfo &fileInfo, UniqueFd fd, UniqueFd manifestFd) +{ + printf("FileReady owner = %s, fileName = %s, sn = %u, fd = %d, manifestFd = %d\n", fileInfo.owner.c_str(), + fileInfo.fileName.c_str(), fileInfo.sn, fd.Get(), manifestFd.Get()); + string tmpPath = string(BConstants::BACKUP_TOOL_INCREMENTAL_RECEIVE_DIR) + fileInfo.owner; + if (access(tmpPath.data(), F_OK) != 0 && mkdir(tmpPath.data(), S_IRWXU) != 0) { + throw BError(BError::Codes::TOOL_INVAL_ARG, generic_category().message(errno)); + } + tmpPath = tmpPath + "/" + ctx->lastIncrementalTime; + if (access(tmpPath.data(), F_OK) != 0 && mkdir(tmpPath.data(), S_IRWXU) != 0) { + throw BError(BError::Codes::TOOL_INVAL_ARG, generic_category().message(errno)); + } + string tmpDataPath = tmpPath + "/incremental"; + if (access(tmpDataPath.data(), F_OK) != 0 && mkdir(tmpDataPath.data(), S_IRWXU) != 0) { + throw BError(BError::Codes::TOOL_INVAL_ARG, generic_category().message(errno)); + } + UniqueFd fdLocal(open((tmpDataPath + "/" + fileInfo.fileName).data(), O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU)); + if (fdLocal < 0) { + throw BError(BError::Codes::TOOL_INVAL_ARG, generic_category().message(errno)); + } + BFile::SendFile(fdLocal, fd); + + // 简报文件保存 + string tmpmanifestPath = tmpPath + "/manifest"; + if (access(tmpDataPath.data(), F_OK) != 0 && mkdir(tmpDataPath.data(), S_IRWXU) != 0) { + throw BError(BError::Codes::TOOL_INVAL_ARG, generic_category().message(errno)); + } + UniqueFd fdManifest( + open((tmpmanifestPath + "/" + fileInfo.fileName + "_manifest").data(), O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU)); + if (fdManifest < 0) { + throw BError(BError::Codes::TOOL_INVAL_ARG, generic_category().message(errno)); + } + BFile::SendFile(fdManifest, fd); + if (fileInfo.fileName == BConstants::EXT_BACKUP_MANAGE) { + ctx->SetIndexFiles(fileInfo.owner, move(fd)); + } else { + ctx->UpdateBundleReceivedFiles(fileInfo.owner, fileInfo.fileName); + } + ctx->TryNotify(); +} + +static void OnBundleStarted(shared_ptr ctx, ErrCode err, const BundleName name) +{ + printf("BundleStarted errCode = %d, BundleName = %s\n", err, name.c_str()); + if (err != 0) { + ctx->isAllBundelsFinished.store(true); + ctx->UpdateBundleFinishedCount(); + ctx->TryNotify(); + } +} + +static void OnBundleFinished(shared_ptr ctx, ErrCode err, const BundleName name) +{ + printf("BundleFinished errCode = %d, BundleName = %s\n", err, name.c_str()); + ctx->UpdateBundleFinishedCount(); + ctx->TryNotify(); +} + +static void OnAllBundlesFinished(shared_ptr ctx, ErrCode err) +{ + ctx->isAllBundelsFinished.store(true); + if (err == 0) { + printf("all bundles backup finished end\n"); + } else { + printf("Failed to Unplanned Abort error: %d\n", err); + ctx->TryNotify(true); + return; + } + ctx->TryNotify(); +} + +static void OnBackupServiceDied(shared_ptr ctx) +{ + printf("backupServiceDied\n"); + ctx->TryNotify(true); +} + +static int32_t Init(const string &pathCapFile, + vector bundleNames, + const string &time, + const string &pathIncrementalFile) +{ + StartTrace(HITRACE_TAG_FILEMANAGEMENT, "InitPathCapFile"); + + if (access((BConstants::BACKUP_TOOL_INCREMENTAL_RECEIVE_DIR).data(), F_OK) != 0 && + mkdir((BConstants::BACKUP_TOOL_INCREMENTAL_RECEIVE_DIR).data(), S_IRWXU) != 0) { + throw BError(BError::Codes::TOOL_INVAL_ARG, generic_category().message(errno)); + } + + UniqueFd fdLocal(open(pathCapFile.data(), O_RDWR | O_CREAT | O_TRUNC, S_IRWXU)); + if (fdLocal < 0) { + fprintf(stderr, "Failed to open file. error: %d %s\n", errno, strerror(errno)); + return -EPERM; + } + auto proxy = ServiceProxy::GetInstance(); + if (!proxy) { + fprintf(stderr, "Get an empty backup sa proxy\n"); + return -EPERM; + } + vector bundlesToBackup; + for (auto &bundleName : bundleNames) { + BIncrementalData data; + data.bundleName = bundleName; + data.lastIncrementalTime = atoi(time.c_str()); + data.manifestFd = open(pathIncrementalFile.data(), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); + bundlesToBackup.push_back(data); + } + int fd = proxy->GetLocalCapabilitiesIncremental(bundlesToBackup); + if (fd < 0) { + fprintf(stderr, "error GetLocalCapabilitiesIncremental"); + } else { + BFile::SendFile(fdLocal, fd); + } + + auto ctx = make_shared(); + ctx->session_ = BIncrementalBackupSession::Init(BIncrementalBackupSession::Callbacks { + .onFileReady = bind(OnFileReady, ctx, placeholders::_1, placeholders::_2, placeholders::_3), + .onBundleStarted = bind(OnBundleStarted, ctx, placeholders::_1, placeholders::_2), + .onBundleFinished = bind(OnBundleFinished, ctx, placeholders::_1, placeholders::_2), + .onAllBundlesFinished = bind(OnAllBundlesFinished, ctx, placeholders::_1), + .onBackupServiceDied = bind(OnBackupServiceDied, ctx)}); + if (ctx->session_ == nullptr) { + printf("Failed to init backup\n"); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return -EPERM; + } + ctx->lastIncrementalTime = time; + int ret = ctx->session_->AppendBundles(bundlesToBackup); + if (ret != 0) { + printf("backup append bundles error: %d\n", ret); + throw BError(BError::Codes::TOOL_INVAL_ARG, "backup append bundles error"); + } + + ctx->SetBundleFinishedCount(bundleNames.size()); + ctx->Wait(); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + ctx->session_->Release(); + return 0; +} + +static int Exec(map> &mapArgToVal) +{ + if (mapArgToVal.find("pathCapFile") == mapArgToVal.end() || mapArgToVal.find("bundles") == mapArgToVal.end() || + mapArgToVal.find("incrementalTime") == mapArgToVal.end() || + mapArgToVal.find("incrementalFile") != mapArgToVal.end()) { + return -EPERM; + } + return Init(*(mapArgToVal["pathCapFile"].begin()), mapArgToVal["bundles"], + *(mapArgToVal["incrementalTime"].begin()), *(mapArgToVal["incrementalFile"].begin())); +} + +bool IncrementalBackUpRegister() +{ + return ToolsOp::Register(ToolsOp {ToolsOp::Descriptor { + .opName = {"incrementalbackup"}, + .argList = {{ + .paramName = "pathCapFile", + .repeatable = false, + }, + { + .paramName = "bundles", + .repeatable = true, + }, + { + .paramName = "incrementalTime", + .repeatable = false, + }, + { + .paramName = "incrementalFile", + .repeatable = false, + }}, + .funcGenHelpMsg = GenHelpMsg, + .funcExec = Exec, + }}); +} +} // namespace OHOS::FileManagement::Backup \ No newline at end of file diff --git a/utils/include/b_resources/b_constants.h b/utils/include/b_resources/b_constants.h index 61f061078..e728239c4 100644 --- a/utils/include/b_resources/b_constants.h +++ b/utils/include/b_resources/b_constants.h @@ -82,6 +82,7 @@ static inline std::string_view SA_BUNDLE_BACKUP_BACKUP = "/backup/"; static inline std::string_view SA_BUNDLE_BACKUP_RESTORE = "/restore/"; static inline std::string_view SA_BUNDLE_BACKUP_TMP_DIR = "/tmp/"; static inline std::string_view BACKUP_TOOL_RECEIVE_DIR = "/data/backup/received/"; +static inline std::string_view BACKUP_TOOL_INCREMENTAL_RECEIVE_DIR = "/data/backup/incrementalreceived/"; static inline std::string_view PATH_BUNDLE_BACKUP_HOME_EL1 = "/data/storage/el1/backup"; static inline std::string_view PATH_BUNDLE_BACKUP_HOME = "/data/storage/el2/backup"; static inline std::string_view BACKUP_TOOL_LINK_DIR = "/data/backup"; -- Gitee