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 new file mode 100644 index 0000000000000000000000000000000000000000..21b3aaea2997adb12302115a0ebcbd8464feee8b --- /dev/null +++ b/frameworks/native/backup_kit_inner/src/b_session_restore_async.cpp @@ -0,0 +1,166 @@ +/* + * 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_session_restore_async.h" + +#include + +#include "b_error/b_error.h" +#include "b_resources/b_constants.h" +#include "filemgmt_libhilog.h" +#include "service_proxy.h" +#include "service_reverse.h" + +namespace OHOS::FileManagement::Backup { +using namespace std; + +BSessionRestoreAsync::BSessionRestoreAsync(Callbacks callbacks) : callbacks_(callbacks) +{ +} + +BSessionRestoreAsync::~BSessionRestoreAsync() +{ + 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_); + } + callbacks_ = {}; + deathRecipient_ = nullptr; +} + +//shared_ptr +unique_ptr BSessionRestoreAsync::Init(Callbacks callbacks) +{ + try { + auto restore = make_unique(callbacks); + return restore; + } catch (const exception &e) { + HILOGE("Failed to Restore because of %{public}s", e.what()); + } + return nullptr; +} + +ErrCode BSessionRestoreAsync::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->PublishFile(fileInfo); +} + +ErrCode BSessionRestoreAsync::GetFileHandle(const string &bundleName, const string &fileName, int32_t userId) +{ + auto proxy = ServiceProxy::GetInstance(); + if (proxy == nullptr) { + return BError(BError::Codes::SDK_BROKEN_IPC, "Failed to get backup service").GetCode(); + } + + return proxy->GetFileHandle(bundleName, fileName); +} + +ErrCode BSessionRestoreAsync::AppendBundles(UniqueFd remoteCap, vector bundlesToRestore, int32_t userId) +{ + { + std::unique_lock lock(mutex_); + workList_.push({move(remoteCap), move(bundlesToRestore), userId}); + } + + if (isAppend_.exchange(true)) { + return ERR_OK; + } else { + AppendBundlesAsync(); + } + + return ERR_OK; +} + +void BSessionRestoreAsync::RegisterBackupServiceDied(std::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) { + functor(); + }; + deathRecipient_ = sptr(new SvcDeathRecipient(callback)); + remoteObj->AddDeathRecipient(deathRecipient_); +} + +void BSessionRestoreAsync::OnBackupServiceDied() +{ + HILOGE("Backup service died"); + if (callbacks_.onBackupServiceDied) { + callbacks_.onBackupServiceDied(); + } + deathRecipient_ = nullptr; + ServiceProxy::InvaildInstance(); + AppendBundlesAsync(); +} + +// 取数据 +void BSessionRestoreAsync::AppendBundlesAsync() +{ + HILOGI("AppendBundlesAsync"); + AppendBundleInfos info; + isAppend_.store(true); + { + std::unique_lock lock(mutex_); + if (workList_.empty()) { + isAppend_.store(false); + return; + } + info = move(workList_.front()); + workList_.pop(); + } + + auto proxy = ServiceProxy::GetInstance(); + if (proxy == nullptr) { + BError(BError::Codes::SDK_BROKEN_IPC, "Failed to get backup service").GetCode(); + } + auto onBackupServiceDied = bind(&BSessionRestoreAsync::OnBackupServiceDied, this); + RegisterBackupServiceDied(onBackupServiceDied); + + Callbacks callbacksTmp {.onFileReady = callbacks_.onFileReady, + .onBundleStarted = callbacks_.onBundleStarted, + .onBundleFinished = callbacks_.onBundleFinished, + .onAllBundlesFinished = callbacks_.onAllBundlesFinished, + .onBackupServiceDied = onBackupServiceDied}; + int32_t res = proxy->InitRestoreSession(new ServiceReverse(callbacksTmp)); + if (res != 0) { + HILOGE("Failed to Restore because of %{public}d", res); + BError(BError::Codes::SDK_BROKEN_IPC, "Failed to int restore session").GetCode(); + } + res = proxy->AppendBundlesRestoreSession(move(info.remoteCap), info.bundlesToRestore, info.userId); + if (res != 0) { + HILOGE("Failed to Restore because of %{public}d", res); + BError(BError::Codes::SDK_BROKEN_IPC, "Failed to append bundles").GetCode(); + } +} +}// namespace OHOS::FileManagement::Backup \ No newline at end of file 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 new file mode 100644 index 0000000000000000000000000000000000000000..9393c23ce7da06e4e214f1bf90a1a758bf170bf7 --- /dev/null +++ b/interfaces/inner_api/native/backup_kit_inner/impl/b_session_restore_async.h @@ -0,0 +1,109 @@ +/* + * 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_SESSION_RESTORE_ASYNC_H +#define OHOS_FILEMGMT_BACKUP_B_SESSION_RESTORE_ASYNC_H + +#include +#include +#include +#include +#include + +#include "b_file_info.h" +#include "errors.h" +#include "svc_death_recipient.h" +#include "unique_fd.h" + +namespace OHOS::FileManagement::Backup { +class BSessionRestoreAsync { +public: + struct Callbacks { + std::function onFileReady; // 当备份服务有文件待发送时执行的回调 + std::function onBundleStarted; // 当启动某个应用的恢复流程结束时执行的回调函数 + std::function onBundleFinished; // 当某个应用的恢复流程结束或意外中止时执行的回调函数 + std::function onAllBundlesFinished; // 当整个恢复流程结束或意外中止时执行的回调函数 + std::function onBackupServiceDied; // 当备份服务意外死亡时执行的回调函数 + }; + + struct AppendBundleInfos { + UniqueFd remoteCap; + std::vector bundlesToRestore; + int32_t userId; + }; + +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 用于追加待恢复应用 + * + * @param remoteCap 已打开的保存远端设备能力的Json文件。可使用GetLocalCapabilities方法获取 + * @param bundlesToRestore 待恢复的应用清单 + * @param userId 用户ID + * @return ErrCode 规范错误码 + */ + ErrCode AppendBundles(UniqueFd remoteCap, std::vector bundlesToRestore , + int32_t userId = -1); + + /** + * @brief 注册备份服务意外死亡时执行的回调函数 + * + * @param functor 回调函数 + */ + void RegisterBackupServiceDied(std::function functor); + +public: + BSessionRestoreAsync(Callbacks callbacks); + ~BSessionRestoreAsync(); + +private: + void OnBackupServiceDied(); + + void AppendBundlesAsync(); + +private: + sptr deathRecipient_; + Callbacks callbacks_; + std::atomic isAppend_ { false }; + std::mutex mutex_; + std::queue workList_; +}; +} // namespace OHOS::FileManagement::Backup + +#endif // OHOS_FILEMGMT_BACKUP_B_SESSION_RESTORE_ASYNC_H \ No newline at end of file