diff --git a/frameworks/native/backup_ext/include/ext_backup.h b/frameworks/native/backup_ext/include/ext_backup.h index 395290b8ec3ca2ae7c03fda0216a30ef3a1504c9..c0599ba3e1296e4bacbe506ffddd4a4fecc6d64a 100644 --- a/frameworks/native/backup_ext/include/ext_backup.h +++ b/frameworks/native/backup_ext/include/ext_backup.h @@ -152,6 +152,11 @@ public: */ virtual ErrCode OnProcess(std::function callback); + /* + * @brief Called do onRelease. + */ + virtual ErrCode OnRelease(std::function callback, int32_t scenario); + /** * @brief 数据迁移判断 * diff --git a/frameworks/native/backup_ext/include/ext_backup_js.h b/frameworks/native/backup_ext/include/ext_backup_js.h index c69cc77a0c9e3bfcf02d46cfb9f8337cd71a41f7..3ca39ff0f9c33bffbb4b7d73675ad9cd86935f7e 100644 --- a/frameworks/native/backup_ext/include/ext_backup_js.h +++ b/frameworks/native/backup_ext/include/ext_backup_js.h @@ -137,6 +137,14 @@ public: */ ErrCode OnProcess(std::function callback) override; + /** + * @brief Call the app's onRelease + * + * @param callback The callBack. + * @param scenario The scenario: backup = 1, restore = 2. + */ + ErrCode OnRelease(std::function callback, int32_t scenario) override; + public: explicit ExtBackupJs(AbilityRuntime::JsRuntime &jsRuntime); ~ExtBackupJs(); @@ -152,6 +160,8 @@ private: std::function &argv)> ParseBackupExInfo(); + std::function &argv)> ParseReleaseInfo(); + ErrCode CallJSRestoreEx(); ErrCode CallJSRestore(); ErrCode CallJsOnBackupEx(); @@ -166,10 +176,12 @@ private: std::shared_ptr callbackInfoEx_; std::shared_ptr callbackInfo_; std::shared_ptr onProcessCallback_; + std::shared_ptr OnReleaseCallback_; std::condition_variable callJsCon_; std::mutex callJsMutex_; std::atomic callExtDefaultFunc_ {false}; // extension default method, onBackup or onRestore std::atomic callJsExMethodDone_ {false}; + int32_t scenario; }; } // namespace OHOS::FileManagement::Backup diff --git a/frameworks/native/backup_ext/include/ext_extension.h b/frameworks/native/backup_ext/include/ext_extension.h index 1a0086f2e7679b276d042f4c0a8f6e20641f2875..57cf9bf9eca9661d8ad0bd326a632fc1bfd0d556 100644 --- a/frameworks/native/backup_ext/include/ext_extension.h +++ b/frameworks/native/backup_ext/include/ext_extension.h @@ -64,6 +64,7 @@ public: ErrCode User0OnBackup() override; ErrCode UpdateDfxInfo(int64_t uniqId, uint32_t extConnectSpend, const std::string &bundleName) override; ErrCode CleanBundleTempDir() override; + ErrCode HandleOnRelease(bool isNeedWait = false) override; public: explicit BackupExtExtension(const std::shared_ptr &extension, @@ -77,16 +78,19 @@ public: onProcessTaskPool_.Start(BConstants::EXTENSION_THREAD_POOL_COUNT); reportOnProcessRetPool_.Start(BConstants::EXTENSION_THREAD_POOL_COUNT); doBackupPool_.Start(BConstants::EXTENSION_THREAD_POOL_COUNT); + onReleaseTaskPool_.Start(BConstants::EXTENSION_THREAD_POOL_COUNT); SetStagingPathProperties(); appStatistic_ = std::make_shared(); } ~BackupExtExtension() { onProcessTimeoutTimer_.Shutdown(); + onReleaseTimeoutTimer_.Shutdown(); threadPool_.Stop(); onProcessTaskPool_.Stop(); reportOnProcessRetPool_.Stop(); doBackupPool_.Stop(); + onReleaseTaskPool_.Stop(); if (callJsOnProcessThread_.joinable()) { callJsOnProcessThread_.join(); } @@ -386,6 +390,14 @@ private: template map MatchFiles(map files, vector endExcludes); void UpdateTarStat(uint64_t tarFileSize); + + void HandleExtDisconnect(); + void StartOnReleaseTimeOutTimer(wptr obj); + void CloseOnReleaseTimeOutTimer(); + void CallJsOnReleaseTask(wptr obj, int32_t scenario, bool isNeedDisconnect); + bool HandleGetExtOnRelease(); + void SetAppResultReport(const std::string resultInfo, ErrCode errCode); + std::function OnReleaseCallback(wptr obj); private: pair> GetFileInfos(const vector &includes, const vector &excludes); TarMap GetIncrmentBigInfos(const vector &files); @@ -432,6 +444,17 @@ private: std::shared_ptr appStatistic_ = nullptr; BackupRestoreScenario curScenario_ { BackupRestoreScenario::FULL_BACKUP }; + + OHOS::ThreadPool onReleaseTaskPool_; + Utils::Timer onReleaseTimeoutTimer_ {"onReleaseTimeoutTimer"}; + uint32_t onReleaseTimeoutTimerId_ { 0 }; + std::atomic stopWaitOnRelease_ {false}; + std::mutex onReleaseLock_; + std::condition_variable execOnReleaseCon_; + std::atomic needAppResultReport_ {false}; + std::string appResultReportInfo_; + ErrCode appResultReportErrCode_ { 0 }; + std::mutex serviceCallReleaseLock_; }; } // namespace OHOS::FileManagement::Backup diff --git a/frameworks/native/backup_ext/src/ext_backup.cpp b/frameworks/native/backup_ext/src/ext_backup.cpp index fc37b3296bfde94427df8120e971e2fb95ca5e7c..708312d533b49db45d3b895d0f3888725bdadef9 100644 --- a/frameworks/native/backup_ext/src/ext_backup.cpp +++ b/frameworks/native/backup_ext/src/ext_backup.cpp @@ -317,4 +317,10 @@ ErrCode ExtBackup::OnProcess(std::function callback) return ERR_OK; } +ErrCode ExtBackup::OnRelease(std::function callback, int32_t scenario) +{ + HILOGI("BackupExtensionAbility(base) OnRelease."); + return ERR_OK; +} + } // namespace OHOS::FileManagement::Backup diff --git a/frameworks/native/backup_ext/src/ext_backup_js.cpp b/frameworks/native/backup_ext/src/ext_backup_js.cpp index 23dedf3d3e33d0c593c0b1ceb28a9ef16c78dd17..27e88169ce956167d9914e385099587b5e47a32b 100644 --- a/frameworks/native/backup_ext/src/ext_backup_js.cpp +++ b/frameworks/native/backup_ext/src/ext_backup_js.cpp @@ -1018,6 +1018,58 @@ ErrCode ExtBackupJs::OnProcess(std::function c return errCode; } +ErrCode ExtBackupJs::OnRelease(std::function callback, int32_t scenario) +{ + HILOGI("BackupExtensionAbility(JS) OnRelease begin."); + BExcepUltils::BAssert(jsObj_, BError::Codes::EXT_BROKEN_FRAMEWORK, + "The app does not provide the OnProcess interface."); + scenario_ = scenario; + onReleaseCallback_ = std::make_shared(callback); + auto retParser = [jsRuntime {&jsRuntime_}, callbackInfo {onReleaseCallback_}](napi_env env, + napi_value result) -> bool { + if (!CheckPromise(env, result)) { + string str; + bool isExceptionPending; + napi_is_exception_pending(envir, &isExceptionPending); + HILOGI("napi exception pending = %{public}d.", isExceptionPending); + if (!callbackInfo) { + HILOGE("callbackInfo is nullptr"); + return false; + } + if (isExceptionPending) { + napi_value exception; + DealNapiException(envir, exception, str); + napi_fatal_exception(envir, exception); + callbackInfo->callback(BError(BError::Codes::EXT_THROW_EXCEPTION), str); + } else { + callbackInfo->callback(BError(BError::Codes::OK), str); + } + return true; + } + HILOGI("CheckPromise Js Method onRelease ok."); + return CallPromise(*jsRuntime, result, callbackInfo.get()); + }; + auto errCode = CallJsMethod("onRelease", jsRuntime_, jsObj_.get(), ParseReleaseInfo(), retParser); + if (errCode != ERR_OK) { + HILOGE("CallJsMethod error, code:%{public}d.", errCode); + } + HILOGI("BackupExtensionAbility(JS) OnRelease end."); + return errCode; +} + +std::function &argv)> ExtBackupJs::ParseReleaseInfo() +{ + auto onReleaseFun = [scenario(scenario_)](napi_env env, vector &argv) -> bool { + int32_t scenarioFlag = scenario; + HILOGI("ParseReleaseInfo, scenario:%{public}d", scenarioFlag); + napi_value scenarioValue = nullptr; + napi_create_int32(env, scenarioFlag, &scenarioValue); + argv.emplace_back(scenarioValue); + return true; + }; + return onReleaseFun; +} + void ExtBackupJs::InitTempPath(const std::string &bundleName) { std::string el2BackupDir(BConstants::PATH_BUNDLE_BACKUP_HOME); diff --git a/frameworks/native/backup_ext/src/ext_extension.cpp b/frameworks/native/backup_ext/src/ext_extension.cpp index 72010a892e74f6e647c1b62586948d54a9944a19..2f13f7145ebe8745ee4a24a7c939375537fe6fc1 100644 --- a/frameworks/native/backup_ext/src/ext_extension.cpp +++ b/frameworks/native/backup_ext/src/ext_extension.cpp @@ -1860,6 +1860,9 @@ void BackupExtExtension::AppDone(ErrCode errCode) if (ret != ERR_OK) { HILOGE("Failed to notify the app done. err = %{public}d", ret); } + if (HandleGetExtOnRelease()) { + HandleOnRelease(); + } } void BackupExtExtension::AppResultReport(const std::string restoreRetInfo, diff --git a/frameworks/native/backup_ext/src/sub_ext_extension.cpp b/frameworks/native/backup_ext/src/sub_ext_extension.cpp index b771262fe9607f5be56045047506b76b50142a1e..cf9ab433bcee4bc5e62fa7cb9ff1ed013a78debe 100644 --- a/frameworks/native/backup_ext/src/sub_ext_extension.cpp +++ b/frameworks/native/backup_ext/src/sub_ext_extension.cpp @@ -230,7 +230,7 @@ std::function BackupExtExtension::OnRestoreCallback( } else { std::string errInfo; BJsonUtil::BuildExtensionErrInfo(errInfo, errCode, errMsg); - extensionPtr->AppResultReport(errInfo, BackupRestoreScenario::FULL_RESTORE, errCode); + extensionPtr->SetAppResultReport(errInfo, errCode); } extensionPtr->DoClear(); }; @@ -269,7 +269,7 @@ std::function BackupExtExtension::OnRestoreExCallbac if (errCode == ERR_OK) { if (restoreRetInfo.size()) { HILOGI("Will notify restore result report"); - extensionPtr->AppResultReport(restoreRetInfo, BackupRestoreScenario::FULL_RESTORE); + extensionPtr->SetAppResultReport(restoreRetInfo, errCode); } return; } @@ -279,7 +279,7 @@ std::function BackupExtExtension::OnRestoreExCallbac } else { std::string errInfo; BJsonUtil::BuildExtensionErrInfo(errInfo, errCode, restoreRetInfo); - extensionPtr->AppResultReport(errInfo, BackupRestoreScenario::FULL_RESTORE, errCode); + extensionPtr->SetAppResultReport(errInfo, errCode); extensionPtr->DoClear(); } }; @@ -334,7 +334,7 @@ std::function BackupExtExtension::IncreOnRestoreExCa if (errCode == ERR_OK) { if (restoreRetInfo.size()) { extensionPtr->ReportAppStatistic("IncreOnRestoreExCallback", errCode); - extensionPtr->AppResultReport(restoreRetInfo, BackupRestoreScenario::INCREMENTAL_RESTORE); + extensionPtr->SetAppResultReport(restoreRetInfo, errCode); } return; } @@ -345,7 +345,7 @@ std::function BackupExtExtension::IncreOnRestoreExCa std::string errInfo; BJsonUtil::BuildExtensionErrInfo(errInfo, errCode, restoreRetInfo); extensionPtr->ReportAppStatistic("IncreOnRestoreExCallback", errCode); - extensionPtr->AppResultReport(errInfo, BackupRestoreScenario::INCREMENTAL_RESTORE, errCode); + extensionPtr->SetAppResultReport(errInfo, errCode); extensionPtr->DoClear(); } }; @@ -382,7 +382,7 @@ std::function BackupExtExtension::IncreOnRestoreCall std::string errInfo; BJsonUtil::BuildExtensionErrInfo(errInfo, errCode, errMsg); extensionPtr->ReportAppStatistic("IncreOnRestoreCallback", errCode); - extensionPtr->AppResultReport(errInfo, BackupRestoreScenario::INCREMENTAL_RESTORE, errCode); + extensionPtr->SetAppResultReport(errInfo, errCode); } extensionPtr->DoClear(); }; @@ -432,7 +432,7 @@ std::function BackupExtExtension::OnBackupCall if (!errMsg.empty()) { std::string errInfo; BJsonUtil::BuildExtensionErrInfo(errInfo, errCode, errMsg); - extensionPtr->AppResultReport(errInfo, BackupRestoreScenario::FULL_BACKUP, errCode); + extensionPtr->SetAppResultReport(errInfo, errCode); } extensionPtr->AppDone(errCode); extensionPtr->DoClear(); @@ -472,7 +472,7 @@ std::function BackupExtExtension::OnBackupExCa HILOGI("Will notify backup result report"); extensionPtr->FinishOnProcessTask(); extensionPtr->AsyncTaskBackup(extensionPtr->extension_->GetUsrConfig()); - extensionPtr->AppResultReport(backupExRetInfo, BackupRestoreScenario::FULL_BACKUP); + extensionPtr->SetAppResultReport(backupExRetInfo, errCode); } return; } @@ -481,7 +481,7 @@ std::function BackupExtExtension::OnBackupExCa if (!backupExRetInfo.empty()) { std::string errInfo; BJsonUtil::BuildExtensionErrInfo(errInfo, errCode, backupExRetInfo); - extensionPtr->AppResultReport(errInfo, BackupRestoreScenario::FULL_BACKUP, errCode); + extensionPtr->SetAppResultReport(errInfo, errCode); } extensionPtr->AppDone(errCode); extensionPtr->DoClear(); @@ -525,7 +525,7 @@ std::function BackupExtExtension::IncOnBackupC if (!errMsg.empty()) { std::string errInfo; BJsonUtil::BuildExtensionErrInfo(errInfo, errCode, errMsg); - extPtr->AppResultReport(errInfo, BackupRestoreScenario::INCREMENTAL_BACKUP, errCode); + extensionPtr->SetAppResultReport(errInfo, errCode); } extPtr->AppIncrementalDone(errCode); extPtr->DoClear(); @@ -569,7 +569,7 @@ std::function BackupExtExtension::IncOnBackupE extensionPtr->FinishOnProcessTask(); proxy->GetAppLocalListAndDoIncrementalBackup(); HILOGI("Will notify backup result report"); - extensionPtr->AppResultReport(backupExRetInfo, BackupRestoreScenario::INCREMENTAL_BACKUP); + extensionPtr->SetAppResultReport(backupExRetInfo, errCode); } return; } @@ -578,7 +578,7 @@ std::function BackupExtExtension::IncOnBackupE if (!backupExRetInfo.empty()) { std::string errInfo; BJsonUtil::BuildExtensionErrInfo(errInfo, errCode, backupExRetInfo); - extensionPtr->AppResultReport(errInfo, BackupRestoreScenario::INCREMENTAL_BACKUP, errCode); + extensionPtr->SetAppResultReport(errInfo, errCode); } extensionPtr->AppIncrementalDone(errCode); extensionPtr->DoClear(); @@ -792,6 +792,9 @@ void BackupExtExtension::AppIncrementalDone(ErrCode errCode) if (ret != ERR_OK) { HILOGE("Failed to notify the app done. err = %{public}d", ret); } + if (HandleGetExtOnRelease()) { + HandleOnRelease(); + } } ErrCode BackupExtExtension::GetBackupInfo(std::string &result) @@ -1681,4 +1684,147 @@ tuple BackupExtExtension::GetIncrementalBackupFileHandle() HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__); return {UniqueFd(BConstants::INVALID_FD_NUM), UniqueFd(BConstants::INVALID_FD_NUM)}; } + +std::function BackupExtExtension::OnReleaseCallback(wptr obj) +{ + HILOGI("Begin get HandleOnReleaseCallback"); + return [obj](ErrCode errCode, std::string errMsg) { + HILOGI("OnReleaseCallback: App onRelease end"); + auto extPtr = obj.promote(); + if (extPtr == nullptr) { + HILOGE("Ext extension handle have been released"); + return; + } + if (extPtr->extension_ == nullptr) { + HILOGE("Extension handle have been released"); + return; + } + if (extPtr->stopWaitOnRelease_.load()) { + HILOGE("App onRelease timeout"); + return; + } + if (errCode == ERR_OK) { + HILOGI("OnReleaseCallback: App onReleased successfully"); + extPtr->CloseOnReleaseTimeOutTimer(); + extPtr->stopWaitOnRelease_.store(true); + extPtr->execOnReleaseCon_.notify_all(); + return; + } + HILOGE("Call extension onRelease failed, errInfo = %{public}s", errMsg.c_str()); + }; +} + +ErrCode BackupExtExtension::HandleOnRelease(bool isNeedWait) +{ + HILOGI("HandleOnRelease Begin"); + auto ptr = wptr(this); + onReleaseTimeoutTimer_.Setup(); + StartOnReleaseTimeOutTimer(ptr); + int32_t scenario = static_cast(BConstants::ExtensionScenario::RESTORE); + if (curScenario_ == BackupRestoreScenario::FULL_BACKUP || + curScenario_ == BackupRestoreScenario::INCREMENTAL_BACKUP) { + scenario = static_cast(BConstants::ExtensionScenario::BACKUP); + } + // service主动release场景,等待onRelease完成或超时,备份/恢复完成场景不需等待 + CallJsOnReleaseTask(ptr, scenario, !isNeedWait); + if (isNeedWait) { + HILOGI("Wait onRelease to do"); + std::unique_lock lock(serviceCallReleaseLock_); + execOnReleaseCon_.wait(lock, [this] { return stopWaitOnRelease_.load(); }); + } + return ERR_OK; +} + +void BackupExtExtension::HandleExtDisconnect() +{ + HILOGI("Begin, curScenario:%{public}d", curScenario_); + auto proxy = ServiceClient::GetInstance(); + if (proxy == nullptr) { + HILOGE("Failed to obtain the ServiceClient handle"); + return; + } + bool isIncBackup = true; + if (curScenario_ == BackupRestoreScenario::FULL_BACKUP || curScenario_ == BackupRestoreScenario::FULL_RESTORE) { + isIncBackup = false; + } + auto ret = proxy->HandleExtDisconnect(isIncBackup); + if (ret != ERR_OK) { + HILOGE("Failed to HandleExtDisconnect. err = %{public}d", ret); + } +} + +bool BackupExtExtension::HandleGetExtOnRelease() { + HILOGI("HandleGetExtOnRelease begin"); + auto proxy = ServiceClient::GetInstance(); + if (proxy == nullptr) { + HILOGE("Failed to obtain the ServiceClient handle"); + return; + } + bool isExtOnRelease = false; + auto ret = proxy->GetExtOnRelease(isExtOnRelease); + if (ret != ERR_OK) { + HILOGE("Failed to GetExtOnRelease. err = %{public}d", ret); + } + return isExtOnRelease; +} + +void BackupExtExtension::StartOnReleaseTimerOutTimer(wptr obj) +{ + HILOGI("StartOnReleaseTimerOutTimer begin"); + int timeout = BConstants::APP_ON_RELEASE_MAX_TIMEOUT; + auto timeoutCallback = [obj]() { + auto extPtr = obj.promote(); + if (extPtr == nullptr) { + HILOGE("Start Create timeout callback failed, extPtr is empty"); + return; + } + HILOGI("OnRelease time out, need to stop wait"); + extPtr->stopWaitOnRelease_.store(true); + extPtr->execOnReleaseCon_.notify_all(); + return; + }; + uint32_t timerId = onReleaseTimeoutTimer_.Register(timeoutCallback, timeout, true); + onReleaseTimeoutTimerId_ = timerId; +} + +void BackupExtExtension::CloseOnReleaseTimeOutTimer() +{ + HILOGI("CloseOnReleaseTimeOutTimer begin"); + onReleaseTimeoutTimer_.Unregister(onReleaseTimeoutTimerId_); +} + +void BackupExtExtension::CallJsOnReleaseTask(wptr obj, int32_t scenario, bool isNeedDisconnect) +{ + HILOGI("Begin CallJsOnReleaseTask, scenario: %{public}d", scenario); + auto task = [obj, scenario, isNeedDisconnect]() { + auto extPtr = obj.promote(); + if (extPtr == nullptr || extPtr->extension_ == nullptr) { + HILOGE("Call js onRelease failed, extensionPtr is empty"); + return; + } + auto callBack = extPtr->OnReleaseCallback(obj); + ErrCode ret = extPtr->extension_->OnRelease(callback, scenario); + if (ret != ERR_OK) { + HILOGE("Call onRelease failed, ret = %{public}d", ret); + return; + } + std::unique_lock lock(extPtr->onReleaseLock_); + extPtr->execOnReleaseCon_.wait(lock, [extPtr] { return extPtr->stopWaitOnRelease_.load(); }); + if (extPtr->needAppResultReport_.load()) { + extPtr->AppResultReport(extPtr->appResultReportInfo_, extPtr->curScenario_, + extPtr->appResultReportErrCode_); + } else if (isNeedDisconnect) { + extPtr->HandleExtDisconnect(); + } + }; + onReleaseTaskPool_.AddTask([task]() { task(); }); +} + +void BackupExtExtension::SetAppResultReport(const std::string resultInfo, ErrCode errCode) +{ + needAppResultReport_.store(true); + appResultReportInfo_ = resultInfo; + appResultReportErrCode_ = errCode; + HandleOnRelease(); +} } // namespace OHOS::FileManagement::Backup diff --git a/interfaces/api/js/napi/backup_ext/backup_extension_ability.js b/interfaces/api/js/napi/backup_ext/backup_extension_ability.js index a4fdf706d28eecdb68227b6a47079f6ab71e4787..a6d51a71bc4fff5d1e428f8339560ead396cc09b 100644 --- a/interfaces/api/js/napi/backup_ext/backup_extension_ability.js +++ b/interfaces/api/js/napi/backup_ext/backup_extension_ability.js @@ -33,6 +33,10 @@ class BackupExtensionAbility { onProcess() { console.log(); } + + onRelease(scenario) { + console.log(); + } } export default BackupExtensionAbility; \ No newline at end of file diff --git a/services/backup_sa/IExtension.idl b/services/backup_sa/IExtension.idl index c9c88cd95628a6f5fd1b8ca0dd3fa4f06476510f..af52b923836001817a3bc2870fa584f7e95d5ebe 100644 --- a/services/backup_sa/IExtension.idl +++ b/services/backup_sa/IExtension.idl @@ -30,4 +30,5 @@ interface OHOS.FileManagement.Backup.IExtension{ [ipccode 13] void User0OnBackup(); [ipccode 14] void UpdateDfxInfo([in] long uniqId, [in] unsigned int extConnectSpend, [in] String bundleName); [ipccode 15] void CleanBundleTempDir(); + [ipccode 16] void HandleOnRelease([in] boolean isNeedWait); } \ No newline at end of file diff --git a/services/backup_sa/IService.idl b/services/backup_sa/IService.idl index d5cc82be5d7eeeee2875ae5f671cb53e2eb3a03c..1014352363da6f16fe9ba7b2315b82a43234aeaf 100644 --- a/services/backup_sa/IService.idl +++ b/services/backup_sa/IService.idl @@ -70,4 +70,6 @@ interface OHOS.FileManagement.Backup.IService{ [in] int serviceResultReportErrCode); [ipccode 38] void GetBackupDataSize([in] boolean isPreciseScan,[in] BIncrementalData[] bundleNameList); [ipccode 40] void CleanBundleTempDir([in] String bundleName); + [ipccode 41] void HandleExtDisconnect([in] boolean isIncBackup); + [ipccode 42] void GetExtOnRelease([out] boolean isExtOnRelease); } \ No newline at end of file diff --git a/services/backup_sa/include/module_ipc/service.h b/services/backup_sa/include/module_ipc/service.h index aa7913f2c3cabaeec00a46619956c4a2bffdb155..a9e5bb7aaa77ff08e9cced6832d6b0943cf415d1 100644 --- a/services/backup_sa/include/module_ipc/service.h +++ b/services/backup_sa/include/module_ipc/service.h @@ -113,6 +113,8 @@ public: ErrCode GetBackupDataSize(bool isPreciseScan, const std::vector& bundleNameList) override; ErrCode CleanBundleTempDir(const std::string &bundleName) override; + ErrCode HandleExtDisconnect(bool isIncBackup) override; + ErrCode GetExtOnRelease(bool &isExtOnRelease) override; // 以下都是非IPC接口 public: @@ -327,6 +329,8 @@ public: UniqueFd manifestFd, int32_t errCode); ErrCode SendFileHandle(const std::string &bundleName, const std::string &fileName); ErrCode SendIncrementalFileHandle(const std::string &bundleName, const std::string &fileName); + void SetExtOnRelease(const BundleName &bundleName, bool isOnRelease); + void RemoveExtOnRelease(const BundleName &bundleName); public: explicit Service(int32_t saID, bool runOnCreate = false) : SystemAbility(saID, runOnCreate) { @@ -771,6 +775,7 @@ private: std::atomic onScanning_ {false}; std::shared_ptr totalStatistic_ = nullptr; std::shared_ptr saStatistic_ = nullptr; + std::map> backupExtOnReleaseMap_; public: std::map> backupExtMutexMap_; std::map failedBundles_; diff --git a/services/backup_sa/src/module_ipc/service.cpp b/services/backup_sa/src/module_ipc/service.cpp index dfe4d5d5328efb00f1a30cd5ed9cace33662667e..9fc0f4dc0efba5a570079f2b7bcb92b043b27c06 100644 --- a/services/backup_sa/src/module_ipc/service.cpp +++ b/services/backup_sa/src/module_ipc/service.cpp @@ -1592,6 +1592,7 @@ ErrCode Service::ClearResidualBundleData(const std::string &bundleName) HILOGI("Current bundle will clean extension data, bundleName:%{public}s", bundleName.c_str()); ErrCode res = proxy->HandleClear(); if (backUpConnection->IsExtAbilityConnected()) { + proxy->HandleOnRelease(true); backUpConnection->DisconnectBackupExtAbility(); } ClearSessionAndSchedInfo(bundleName); @@ -2021,6 +2022,11 @@ void Service::DoTimeout(wptr ptr, std::string bundleName) HILOGE("Error, sessionConnection is empty, bundleName:%{public}s", bundleName.c_str()); return; } + auto proxy = sessionConnection->GetBackupExtProxy(); + if (!proxy) { + HILOGE("Extension backup Proxy is empty"); + return; + } sessionConnection->DisconnectBackupExtAbility(); } TimeoutRadarReport(scenario, bundleName); diff --git a/services/backup_sa/src/module_ipc/service_incremental.cpp b/services/backup_sa/src/module_ipc/service_incremental.cpp index 2215a7110019520e60ea98e957f2f62f97867af4..13445c63cd2a22382fc6d41a9ba54f73b485ab4e 100644 --- a/services/backup_sa/src/module_ipc/service_incremental.cpp +++ b/services/backup_sa/src/module_ipc/service_incremental.cpp @@ -688,11 +688,8 @@ ErrCode Service::AppIncrementalDone(ErrCode errCode) return BError(BError::Codes::SA_INVAL_ARG); } std::lock_guard lock(mutexPtr->callbackMutex); - ret = HandleCurAppDone(errCode, callerName, true); - if (ret != ERR_OK) { - HILOGE("Handle current app done error, bundleName:%{public}s", callerName.c_str()); - return ret; - } + SetExtOnRelease(callerName, true); + return BError(BError::Codes::OK); } RemoveExtensionMutex(callerName); OnAllBundlesFinished(BError(BError::Codes::OK)); @@ -1000,6 +997,7 @@ void Service::CancelTask(std::string bundleName, wptr ptr) proxy->HandleClear(); session->StopFwkTimer(bundleName); session->StopExtTimer(bundleName); + proxy->HandleOnRelease(true); backUpConnection->DisconnectBackupExtAbility(); thisPtr->ClearSessionAndSchedInfo(bundleName); IServiceReverseType::Scenario scenario = session->GetScenario(); diff --git a/services/backup_sa/src/module_ipc/sub_service.cpp b/services/backup_sa/src/module_ipc/sub_service.cpp index 71ba0c8ed8dca564163888cdb5765a3fe6cb7b4a..7585e4dc9cf904cad33b2f8f80aa625a3af77c99 100644 --- a/services/backup_sa/src/module_ipc/sub_service.cpp +++ b/services/backup_sa/src/module_ipc/sub_service.cpp @@ -383,11 +383,8 @@ ErrCode Service::AppDone(ErrCode errCode) return BError(BError::Codes::SA_INVAL_ARG); } std::lock_guard lock(mutexPtr->callbackMutex); - ret = HandleCurAppDone(errCode, callerName, false); - if (ret != ERR_OK) { - HILOGE("Handle current app done error, bundleName:%{public}s", callerName.c_str()); - return ret; - } + SetExtOnRelease(callerName, true); + return BError(BError::Codes::OK); } RemoveExtensionMutex(callerName); OnAllBundlesFinished(BError(BError::Codes::OK)); @@ -1416,4 +1413,71 @@ ErrCode Service::CleanBundleTempDir(const string &bundleName) session_->DecreaseSessionCnt(__PRETTY_FUNCTION__); return BError(BError::Codes::OK); } + +ErrCode Service::HandleExtDisconnect(bool isIncBackup) +{ + HILOGI("begin, isIncBackup: %{public}d", isIncBackup); + std::string callerName; + auto ret = VerifyCallerAndGetCallerName(callerName); + if (ret != ERR_OK) { + HILOGE("HandleExtDisconnect VerifyCaller failed, get bundle failed, ret:%{public}d", ret); + return ret; + } + std::shared_ptr mutexPtr = GetExtensionMutex(callerName); + if(mutexPtr == nullptr) { + HILOGE("extension mutex ptr is nullptr, bundleName:%{public}d", callerName.c_str()); + return BError(BError::Codes::SA_INVAL_ARG); + } + std::lock_guard lock(mutexPtr->callbackMutex); + ret = HandleCurAppDone(ret, callerName, isIncBackup); + if (ret != ERR_OK) { + HILOGE("Handle current app done error, bundleName:%{public}s", callerName.c_str()); + ret; + } + RemoveExtensionMutex(callerName); + RemoveExtOnRelease(callerName); + OnAllBundlesFinished(BError(BError::Codes::OK)); + return ret; +} + +ErrCode Service::GetExtOnRelease(bool &isExtOnRelease) +{ + std::string bundleName; + auto ret = VerifyCallerAndGetCallerName(bundleName); + if (ret != ERR_OK) { + HILOGE("GetExtOnRelease VerifyCaller failed, get bundle failed, ret:%{public}d", ret); + return ret; + } + auto it = backupExtOnReleaseMap_.find(bundleName); + if (it == backupExtOnReleaseMap_.end()) { + HILOGI("BackupExtOnReleaseMap not contain %{public}s", bundleName.c_str()); + backupExtOnReleaseMap_[bundleName] = false; + isExtOnRelease = backupExtOnReleaseMap_[bundleName].load(); + return ret; + } + HILOGI("BackupExtOnReleaseMap contain %{public}s", bundleName.c_str()); + isExtOnRelease = backupExtOnReleaseMap_[bundleName].load(); + return ret; +} + +void Service::SetExtOnRelease(const BundleName &bundleName, bool isOnRelease) +{ + HILOGI("Set bundleName:%{public}s isOnRelease:%{public}d", bundleName.c_str(), isOnRelease); + auto it = backupExtOnReleaseMap_.find(bundleName); + if (it == backupExtOnReleaseMap_.end()) { + backupExtOnReleaseMap_[bundleName] = isOnRelease; + return; + } + it->second.store(isOnRelease); +} + +void Service::RemoveExtOnRelease(const BundleName &bundleName) +{ + auto it = backupExtOnReleaseMap_.find(bundleName); + if (it == backupExtOnReleaseMap_.end()) { + HILOGI("BackupExtOnReleaseMap not contain %{public}s", bundleName.c_str()); + return; + } + backupExtOnReleaseMap_.erase(it); +} } \ 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 4293b6dc6722f78d676d78baf50d3f7d057b53a3..d3413e87fa2a6dde9e368e9dd2b7d14aa2c02e43 100644 --- a/services/backup_sa/src/module_ipc/svc_session_manager.cpp +++ b/services/backup_sa/src/module_ipc/svc_session_manager.cpp @@ -1079,6 +1079,7 @@ ErrCode SvcSessionManager::ClearSessionData() if (impl_.restoreDataType != RestoreTypeEnum::RESTORE_DATA_READDY) { ret = proxy->HandleClear(); } + proxy->HandleOnRelease(true); backUpConnection->DisconnectBackupExtAbility(); } if (ret != BError(BError::Codes::OK)) { @@ -1243,6 +1244,7 @@ bool SvcSessionManager::CleanAndCheckIfNeedWait(ErrCode &ret, std::vectorHandleOnRelease(true); backUpConnection->DisconnectBackupExtAbility(); it = impl_.backupExtNameMap.erase(it); } else { diff --git a/tests/mock/backup_ext/include/ext_backup_js_mock.h b/tests/mock/backup_ext/include/ext_backup_js_mock.h index 001051de586a286c9ecedc3f125af49c546a8632..5838cdaf7769ff70174ebcd04a137706f7636707 100644 --- a/tests/mock/backup_ext/include/ext_backup_js_mock.h +++ b/tests/mock/backup_ext/include/ext_backup_js_mock.h @@ -50,6 +50,8 @@ public: virtual ErrCode CallJsOnBackupEx() = 0; virtual ErrCode CallJsOnBackup() = 0; virtual void ExportJsContext() = 0; + virtual ErrCode OnRelease(std::function, int32_t scenario) = 0; + virtual std::function &argv) ParseReleaseInfo() = 0; public: virtual bool GetProfileFromAbility(const OHOS::AppExecFwk::AbilityInfo &, const std::string &, std::vector &) const = 0; diff --git a/tests/mock/backup_ext/include/ext_backup_mock.h b/tests/mock/backup_ext/include/ext_backup_mock.h index 76826057ba1cb173b13d8003330277e47cf5959b..bee304753dcd2b46d25cc3e8073efa2083b1715c 100644 --- a/tests/mock/backup_ext/include/ext_backup_mock.h +++ b/tests/mock/backup_ext/include/ext_backup_mock.h @@ -52,6 +52,7 @@ public: std::shared_ptr) = 0; virtual ErrCode GetParament(const AAFwk::Want &) = 0; virtual ErrCode OnProcess(std::function callback) = 0; + virtual ErrCode OnRelease(std::function callback, int32_t scenario) = 0; public: virtual std::unique_ptr LoadSystemModuleByEngine(napi_env, const std::string&, const napi_value*, size_t) = 0; @@ -97,6 +98,7 @@ public: std::shared_ptr)); MOCK_METHOD(ErrCode, GetParament, (const AAFwk::Want &)); MOCK_METHOD(napi_value, CreateExtBackupJsContext, (napi_env, std::shared_ptr)); + MOCK_METHOD(ErrCode, OnRelease, (std::function, int32_t)); public: MOCK_METHOD((std::unique_ptr), LoadSystemModuleByEngine, (napi_env, const std::string&, const napi_value*, size_t)); diff --git a/tests/mock/backup_ext/include/ext_extension_mock.h b/tests/mock/backup_ext/include/ext_extension_mock.h index c57e10ae2828e5cd3cde4fa500a5c30168d823f6..29d38690a19910778f535a656bf822de98dc42af 100644 --- a/tests/mock/backup_ext/include/ext_extension_mock.h +++ b/tests/mock/backup_ext/include/ext_extension_mock.h @@ -67,6 +67,7 @@ public: virtual std::function HandleTaskBackupEx(wptr) = 0; virtual void WaitToSendFd(std::chrono::system_clock::time_point&, int&) = 0; virtual void RefreshTimeInfo(std::chrono::system_clock::time_point&, int&) = 0; + virtual ErrCode HandleOnRelease(bool) = 0; public: BExtExtension() = default; virtual ~BExtExtension() = default; @@ -121,6 +122,7 @@ public: MOCK_METHOD(void, WaitToSendFd, ((std::chrono::system_clock::time_point&), int&)); MOCK_METHOD(void, RefreshTimeInfo, ((std::chrono::system_clock::time_point&), int&)); MOCK_METHOD(ErrCode, CleanBundleTempDir, ()); + MOCK_METHOD(ErrCode, HandleOnRelease, (bool)); }; } // namespace OHOS::FileManagement::Backup #endif // OHOS_FILEMGMT_BACKUP_EXT_EXTENSION_MOCK_H \ No newline at end of file diff --git a/tests/mock/backup_ext/src/ext_backup_js_mock.cpp b/tests/mock/backup_ext/src/ext_backup_js_mock.cpp index 1f97308fde56108e621e345b18289b508d09a9dc..3d64f12e9509bbf31b8af2aeb5e43499c688a733 100644 --- a/tests/mock/backup_ext/src/ext_backup_js_mock.cpp +++ b/tests/mock/backup_ext/src/ext_backup_js_mock.cpp @@ -98,4 +98,14 @@ ErrCode ExtBackupJs::InvokeAppExtMethod(ErrCode errCode, const string result) { return BExtBackupJs::extBackupJs->InvokeAppExtMethod(errCode, result); } + +function &argv)> ExtBackupJs::ParseReleaseInfo() +{ + return BExtBackupJs::extBackupJs->ParseReleaseInfo(); +} + +ErrCode ExtBackupJs::OnRelease(function callback, int32_t scenario) +{ + return BExtBackupJs::extBackupJs->OnRelease(callback, scenario); +} } // namespace OHOS::FileManagement::Backup diff --git a/tests/mock/backup_ext/src/ext_backup_mock.cpp b/tests/mock/backup_ext/src/ext_backup_mock.cpp index 16d6f55b5f87d21699d7fc81342b68ce95755ff5..43f091594b0e31ebf068591f64fcb7af8e57e9fa 100644 --- a/tests/mock/backup_ext/src/ext_backup_mock.cpp +++ b/tests/mock/backup_ext/src/ext_backup_mock.cpp @@ -138,4 +138,9 @@ ErrCode ExtBackup::OnProcess(function callback) { return BExtBackup::extBackup->OnProcess(callback); } + +ErrCode ExtBackup::OnRelease(function callback, int32_t scenario) +{ + return BExtBackup::extBackup->OnRelease(callback, scenario); +} } // namespace OHOS::FileManagement::Backup diff --git a/tests/mock/backup_ext/src/ext_extension_mock.cpp b/tests/mock/backup_ext/src/ext_extension_mock.cpp index f5bf98f3442f0b94de30bcc2d12ae6b22f8c7f4f..5fb269c40a4d7fe9c441276b2d1dd803eead3322 100644 --- a/tests/mock/backup_ext/src/ext_extension_mock.cpp +++ b/tests/mock/backup_ext/src/ext_extension_mock.cpp @@ -222,4 +222,9 @@ ErrCode BackupExtExtension::CleanBundleTempDir() { return BExtExtension::extExtension->CleanBundleTempDir(); } + +ErrCode BackupExtExtension::HandleOnRelease(bool isNeedWait) +{ + return BExtExtension::extExtension->HandleOnRelease(isNeedWait); +} } // namespace OHOS::FileManagement::Backup diff --git a/tests/mock/backup_kit_inner/service_proxy_mock.cpp b/tests/mock/backup_kit_inner/service_proxy_mock.cpp index d521ebec5a5b50ff13799758ed6201d78df17f9c..d19c2789353704e212ac887c173c99cf6199f7f9 100644 --- a/tests/mock/backup_kit_inner/service_proxy_mock.cpp +++ b/tests/mock/backup_kit_inner/service_proxy_mock.cpp @@ -260,4 +260,14 @@ ErrCode ServiceProxy::CleanBundleTempDir(const std::string& bundleName) { return BError(BError::Codes::OK); } + +ErrCode ServiceProxy::HandleExtDisconnect(bool isIncBackup) +{ + return BError(BError::Codes::OK); +} + +ErrCode ServiceProxy::GetExtOnRelease(bool isIncBackup) +{ + return BError(BError::Codes::OK); +} } // namespace OHOS::FileManagement::Backup \ No newline at end of file diff --git a/tests/mock/module_ipc/include/svc_extension_proxy_mock.h b/tests/mock/module_ipc/include/svc_extension_proxy_mock.h index 912fb53c72f5ff3fa25a4a34b595d433da04e535..d481b9ef5d251379a6db483c517fbe1338706634 100644 --- a/tests/mock/module_ipc/include/svc_extension_proxy_mock.h +++ b/tests/mock/module_ipc/include/svc_extension_proxy_mock.h @@ -40,6 +40,7 @@ MOCK_METHOD(ErrCode, UpdateFdSendRate, (const std::string &, int32_t)); MOCK_METHOD(ErrCode, User0OnBackup, ()); MOCK_METHOD(ErrCode, UpdateDfxInfo, (int64_t, uint32_t, const std::string &)); MOCK_METHOD(ErrCode, CleanBundleTempDir, ()); +MOCK_METHOD(ErrCode, HandleOnRelease, (bool)); }; } // namespace OHOS::FileManagement::Backup #endif // OHOS_FILEMGMT_BACKUP_SVC_BACKUP_CONNECTION_MOCK_H \ No newline at end of file diff --git a/tests/mock/module_ipc/service_mock.cpp b/tests/mock/module_ipc/service_mock.cpp index 6a945c4bade8a6c417adc9d3266f750ba18eb018..dfd89f062c477dec558c9ad5d8360bf04d86ec2b 100644 --- a/tests/mock/module_ipc/service_mock.cpp +++ b/tests/mock/module_ipc/service_mock.cpp @@ -423,4 +423,14 @@ bool Service::GetScanningInfo(wptr obj, size_t scannedSize, string &sca } void Service::SetScanningInfo(string &scanning, string name) {} + +ErrCode Service::HandleExtDisconnect(bool isIncBackup) +{ + return BError(BError::Codes::OK); +} + +ErrCode Service::GetOnRelease(bool &isExtOnRelease) +{ + 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 e73ee49e1927e317eb7833bc0c464c54d03ba54b..cfa3b04272f4d4fe30f45584d02f822ff2cf2689 100644 --- a/tests/mock/module_ipc/svc_extension_proxy_mock.cpp +++ b/tests/mock/module_ipc/svc_extension_proxy_mock.cpp @@ -93,4 +93,9 @@ ErrCode ExtensionProxy::CleanBundleTempDir() { return 0; } + +ErrCode ExtensionProxy::HandleOnRelease(bool isNeedWait) +{ + return 0; +} } // namespace OHOS::FileManagement::Backup \ No newline at end of file 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 4955834735cb887cbb673159732ddfa04bd41def..baf131ac5ff8e6df72f08d42c7be657b1ecdcf49 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 @@ -174,6 +174,11 @@ public: { return BError(BError::Codes::OK); }; + + ErrCode HandleOnRelease(bool isNeedWait) + { + return BError(BError::Codes::OK); + }; private: int32_t nHandleBackupNum_ = 0; }; diff --git a/tests/unittests/backup_sa/module_client/service_client_test.cpp b/tests/unittests/backup_sa/module_client/service_client_test.cpp index 0cecf86a55f6258b897c044e026a0c7537a7d943..852a1d5d1a84f76e285a3c77ed593964731893b6 100644 --- a/tests/unittests/backup_sa/module_client/service_client_test.cpp +++ b/tests/unittests/backup_sa/module_client/service_client_test.cpp @@ -408,4 +408,32 @@ HWTEST_F(ServiceClientTest, SUB_service_client_test_1400, testing::ext::TestSize EXPECT_EQ(fileName, ""); GTEST_LOG_(INFO) << "ServiceClientTest-end SUB_service_client_test_1400"; } + +HWTEST_F(ServiceClientTest, SUB_service_client_test_1500, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "ServiceClientTest-begin SUB_service_client_test_1500"; + proxy = ServiceClient::GetInstance(); + EXPECT_NE(proxy, nullptr); + ErrCode ret = proxy->HandleExtDisconnect(false); + EXPECT_EQ(ret, BError(BError::BackupErrorCode::E_INVAL)); + ret = proxy->HandleExtDisconnect(true); + EXPECT_EQ(ret, BError(BError::BackupErrorCode::E_INVAL)); + GTEST_LOG_(INFO) << "ServiceClientTest-end SUB_service_client_test_1500"; +} + +HWTEST_F(ServiceClientTest, SUB_service_client_test_1600, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "ServiceClientTest-begin SUB_service_client_test_1600"; + proxy = ServiceClient::GetInstance(); + EXPECT_NE(proxy, nullptr); + bool isExtOnRelease = false; + ErrCode ret = proxy->GetExtOnRelease(isExtOnRelease); + EXPECT_EQ(ret, BError(BError::BackupErrorCode::E_INVAL)); + EXPECT_EQ(isExtOnRelease, false); + isExtOnRelease = true; + ret = proxy->GetExtOnRelease(isExtOnRelease); + EXPECT_EQ(ret, BError(BError::BackupErrorCode::E_INVAL)); + EXPECT_EQ(isExtOnRelease, true); + GTEST_LOG_(INFO) << "ServiceClientTest-end SUB_service_client_test_1600"; +} } // namespace OHOS::FileManagement::Backup \ No newline at end of file diff --git a/tests/unittests/backup_sa/module_ipc/service_incremental_test.cpp b/tests/unittests/backup_sa/module_ipc/service_incremental_test.cpp index 5813e2ea9e089408d78b76435b7a47d5d7c2411c..b893f59d51a417bd56f1dd768ec7b7e3d91ea5b7 100644 --- a/tests/unittests/backup_sa/module_ipc/service_incremental_test.cpp +++ b/tests/unittests/backup_sa/module_ipc/service_incremental_test.cpp @@ -76,6 +76,10 @@ public: virtual UniqueFd GetLocalCapabilitiesForBundleInfos() = 0; virtual ErrCode GetBackupDataSize(bool, const std::vector&) = 0; virtual ErrCode CleanBundleTempDir(const std::string& bundleName) = 0; + virtual ErrCode HandleExtDisconnect(bool) = 0; + virtual ErrCode GetExtOnRelease(bool&) = 0; + virtual void SetExtOnRelease(const BundleName&, bool) = 0; + virtual void RemoveExtOnRelease(const BundleName&) = 0; public: virtual bool UpdateToRestoreBundleMap(const string&, const string&) = 0; public: @@ -131,6 +135,10 @@ public: MOCK_METHOD(UniqueFd, GetLocalCapabilitiesForBundleInfos, ()); MOCK_METHOD(ErrCode, GetBackupDataSize, (bool, const std::vector&)); MOCK_METHOD(ErrCode, CleanBundleTempDir, (const std::string&)); + MOCK_METHOD(ErrCode, HandleExtDisconnect, (bool)); + MOCK_METHOD(ErrCode, GetExtOnRelease, (bool&)); + MOCK_METHOD(void, SetExtOnRelease, (const BundleName&, bool)); + MOCK_METHOD(void, RemoveExtOnRelease, (const BundleName&)); public: MOCK_METHOD(bool, UpdateToRestoreBundleMap, (const string&, const string&)); }; @@ -440,6 +448,26 @@ ErrCode Service::CleanBundleTempDir(const std::string& bundleName) { return BService::serviceMock->CleanBundleTempDir(bundleName); } + +ErrCode Service::HandleExtDisconnect(bool isIncBackup) +{ + return BService::serviceMock->HandleExtDisconnect(isIncBackup); +} + +ErrCode Service::GetExtOnRelease(bool &isExtOnRelease) +{ + return BService::serviceMock->GetExtOnRelease(isExtOnRelease); +} + +void Service::SetExtOnRelease(const BundleName &bundleName, bool isOnRelease) +{ + return BService::serviceMock->SetExtOnRelease(bundleName, isOnRelease); +} + +void Servcie::RemoveExtOnRelease(const BundleName &bundleName) +{ + return BService::serviceMock->RemoveExtOnRelease(bundleName); +} } // namespace OHOS::FileManagement::Backup namespace OHOS::FileManagement::Backup { @@ -1262,21 +1290,11 @@ HWTEST_F(ServiceIncrementalTest, SUB_ServiceIncremental_AppIncrementalDone_0000, service->backupExtMutexMap_.clear(); EXPECT_CALL(*srvMock, VerifyCallerAndGetCallerName(_)).WillOnce(Return(BError(BError::Codes::OK).GetCode())); EXPECT_CALL(*session, OnBundleFileReady(_, _)).WillOnce(Return(false)); - EXPECT_CALL(*srvMock, HandleCurAppDone(_, _, _)) - .WillOnce(Return(BError(BError::Codes::SA_INVAL_ARG).GetCode())); - ret = service->AppIncrementalDone(BError(BError::Codes::SA_INVAL_ARG).GetCode()); - EXPECT_EQ(ret, BError(BError::Codes::SA_INVAL_ARG).GetCode()); - - service->backupExtMutexMap_.clear(); - EXPECT_CALL(*srvMock, VerifyCallerAndGetCallerName(_)).WillOnce(Return(BError(BError::Codes::OK).GetCode())); - EXPECT_CALL(*session, OnBundleFileReady(_, _)).WillOnce(Return(false)); - EXPECT_CALL(*srvMock, HandleCurAppDone(_, _, _)).WillOnce(Return(BError(BError::Codes::OK).GetCode())); ret = service->AppIncrementalDone(BError(BError::Codes::SA_INVAL_ARG).GetCode()); EXPECT_EQ(ret, BError(BError::Codes::OK).GetCode()); EXPECT_CALL(*srvMock, VerifyCallerAndGetCallerName(_)).WillOnce(Return(BError(BError::Codes::OK).GetCode())); EXPECT_CALL(*session, OnBundleFileReady(_, _)).WillOnce(Return(true)); - EXPECT_CALL(*srvMock, HandleCurAppDone(_, _, _)).WillOnce(Return(BError(BError::Codes::OK).GetCode())); ret = service->AppIncrementalDone(errCode); EXPECT_EQ(ret, BError(BError::Codes::OK).GetCode()); } catch (...) { diff --git a/tests/unittests/backup_sa/module_ipc/service_other_test.cpp b/tests/unittests/backup_sa/module_ipc/service_other_test.cpp index 733cbb46b8c1f5c7329f09440f786555209e5549..59eebaf8777a343b9196a17d5d83cf9cb040aef9 100644 --- a/tests/unittests/backup_sa/module_ipc/service_other_test.cpp +++ b/tests/unittests/backup_sa/module_ipc/service_other_test.cpp @@ -1306,19 +1306,16 @@ HWTEST_F(ServiceTest, SUB_Service_AppDone_0200, TestSize.Level1) EXPECT_CALL(*token, GetHapTokenInfo(_, _)).WillOnce(Return(0)); EXPECT_CALL(*jsonUtil, BuildBundleNameIndexInfo(_, _)).WillOnce(Return("")); EXPECT_CALL(*session, OnBundleFileReady(_, _)).WillOnce(Return(false)); - EXPECT_CALL(*session, GetExtConnection(_)).WillOnce(Return(nullptr)); auto ret = service->AppDone(errCode); - EXPECT_NE(ret, BError(BError::Codes::OK)); + EXPECT_EQ(ret, BError(BError::Codes::OK)); EXPECT_CALL(*skeleton, GetCallingTokenID()).WillOnce(Return(0)); EXPECT_CALL(*token, GetTokenType(_)).WillOnce(Return(Security::AccessToken::ATokenTypeEnum::TOKEN_HAP)); EXPECT_CALL(*token, GetHapTokenInfo(_, _)).WillOnce(Return(0)); EXPECT_CALL(*jsonUtil, BuildBundleNameIndexInfo(_, _)).WillOnce(Return("")); EXPECT_CALL(*session, OnBundleFileReady(_, _)).WillOnce(Return(true)); - EXPECT_CALL(*session, GetExtConnection(_)).WillOnce(Return(connect)); - EXPECT_CALL(*connect, GetBackupExtProxy()).WillOnce(Return(nullptr)); ret = service->AppDone(errCode); - EXPECT_NE(ret, BError(BError::Codes::OK)); + EXPECT_EQ(ret, BError(BError::Codes::OK)); } catch (...) { EXPECT_TRUE(false); GTEST_LOG_(INFO) << "ServiceTest-an exception occurred by AppDone."; @@ -1933,6 +1930,7 @@ HWTEST_F(ServiceTest, SUB_Service_DoTimeout_0000, TestSize.Level1) .WillOnce(Return(IServiceReverseType::Scenario::UNDEFINED)); EXPECT_CALL(*saUtils, IsSABundleName(_)).WillOnce(Return(false)).WillOnce(Return(true)); EXPECT_CALL(*session, GetExtConnection(_)).WillOnce(Return(connect)); + EXPECT_CALL(*connect, GetBackupExtProxy()).WillOnce(Return(svcProxy)); EXPECT_CALL(*connect, DisconnectBackupExtAbility()).WillOnce(Return(BError(BError::Codes::OK).GetCode())); EXPECT_CALL(*session, StopFwkTimer(_)).WillOnce(Return(true)); EXPECT_CALL(*session, StopExtTimer(_)).WillOnce(Return(true)); @@ -2514,4 +2512,209 @@ HWTEST_F(ServiceTest, SUB_Service_CleanBundleTempDir_0100, testing::ext::TestSiz } GTEST_LOG_(INFO) << "ServiceTest-end SUB_Service_CleanBundleTempDir_0100"; } + +/** + * @tc.number: SUB_Service_HandleExtDisconnect_0000 + * @tc.name: SUB_Service_HandleExtDisconnect_0000 + * @tc.desc: 测试 HandleExtDisconnect 的正常/异常分支 + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + * @tc.require: IC7RHQ + */ +HWTEST_F(ServiceTest, SUB_Service_HandleExtDisconnect_0000, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "ServiceTest-begin SUB_Service_HandleExtDisconnect_0000"; + try { + EXPECT_CALL(*skeleton, GetCallingTokenID()).WillOnce(Return(0)); + EXPECT_CALL(*token, GetTokenType(_)).WillOnce(Return(Security::AccessToken::ATokenTypeEnum::TOKEN_HAP)); + EXPECT_CALL(*token, GetHapTokenInfo(_, _)).WillOnce(Return(1)); + EXPECT_CALL(*param, GetBackupDebugOverrideAccount()).WillOnce(Return(make_pair(false, -1))); + EXPECT_CALL(*skeleton, GetCallingUid()).WillOnce(Return(BConstants::SYSTEM_UID)); + auto ret = service->HandleExtDisconnect(true); + EXPECT_EQ(ret, BError(BError::Codes::SA_INVAL_ARG).GetCode()); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "ServiceTest-an exception occurred by HandleExtDisconnect."; + } + GTEST_LOG_(INFO) << "ServiceTest-end SUB_Service_HandleExtDisconnect_0000"; +} + +/** + * @tc.number: SUB_Service_HandleExtDisconnect_0100 + * @tc.name: SUB_Service_HandleExtDisconnect_0100 + * @tc.desc: 测试 HandleExtDisconnect 的正常/异常分支 + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + * @tc.require: IC7RHQ + */ +HWTEST_F(ServiceTest, SUB_Service_HandleExtDisconnect_0100, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "ServiceTest-begin SUB_Service_HandleExtDisconnect_0100"; + try { + EXPECT_CALL(*skeleton, GetCallingTokenID()).WillOnce(Return(0)); + EXPECT_CALL(*token, GetTokenType(_)).WillOnce(Return(Security::AccessToken::ATokenTypeEnum::TOKEN_HAP)); + EXPECT_CALL(*token, GetHapTokenInfo(_, _)).WillOnce(Return(0)); + EXPECT_CALL(*jsonUtil, BuildBundleNameIndexInfo(_, _)).WillOnce(Return("")); + EXPECT_CALL(*session, GetExtConnection(_)).WillOnce(Return(nullptr)); + auto ret = service->HandleExtDisconnect(true); + EXPECT_EQ(ret, BError(BError::Codes::SA_INVAL_ARG).GetCode()); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "ServiceTest-an exception occurred by HandleExtDisconnect."; + } + GTEST_LOG_(INFO) << "ServiceTest-end SUB_Service_HandleExtDisconnect_0100"; +} + +/** + * @tc.number: SUB_Service_HandleExtDisconnect_0200 + * @tc.name: SUB_Service_HandleExtDisconnect_0200 + * @tc.desc: 测试 HandleExtDisconnect 的正常/异常分支 + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + * @tc.require: IC7RHQ + */ +HWTEST_F(ServiceTest, SUB_Service_HandleExtDisconnect_0200, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "ServiceTest-begin SUB_Service_HandleExtDisconnect_0200"; + try { + EXPECT_CALL(*skeleton, GetCallingTokenID()).WillOnce(Return(0)); + EXPECT_CALL(*token, GetTokenType(_)).WillOnce(Return(Security::AccessToken::ATokenTypeEnum::TOKEN_HAP)); + EXPECT_CALL(*token, GetHapTokenInfo(_, _)).WillOnce(Return(0)); + EXPECT_CALL(*jsonUtil, BuildBundleNameIndexInfo(_, _)).WillOnce(Return("")); + EXPECT_CALL(*session, GetExtConnection(_)).WillOnce(Return(connect)); + EXPECT_CALL(*connect, GetBackupExtProxy()).WillOnce(Return(nullptr)); + auto ret = service->HandleExtDisconnect(true); + EXPECT_EQ(ret, BError(BError::Codes::SA_INVAL_ARG).GetCode()); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "ServiceTest-an exception occurred by HandleExtDisconnect."; + } + GTEST_LOG_(INFO) << "ServiceTest-end SUB_Service_HandleExtDisconnect_0200"; +} + +/** + * @tc.number: SUB_Service_HandleExtDisconnect_0300 + * @tc.name: SUB_Service_HandleExtDisconnect_0300 + * @tc.desc: 测试 HandleExtDisconnect 的正常/异常分支 + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + * @tc.require: IC7RHQ + */ +HWTEST_F(ServiceTest, SUB_Service_HandleExtDisconnect_0300, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "ServiceTest-begin SUB_Service_HandleExtDisconnect_0300"; + try { + EXPECT_CALL(*skeleton, GetCallingTokenID()).WillOnce(Return(0)); + EXPECT_CALL(*token, GetTokenType(_)).WillOnce(Return(Security::AccessToken::ATokenTypeEnum::TOKEN_HAP)); + EXPECT_CALL(*token, GetHapTokenInfo(_, _)).WillOnce(Return(0)); + EXPECT_CALL(*jsonUtil, BuildBundleNameIndexInfo(_, _)).WillOnce(Return("")); + EXPECT_CALL(*session, GetExtConnection(_)).WillOnce(Return(connect)); + EXPECT_CALL(*connect, GetBackupExtProxy()).WillOnce(Return(svcProxy)); + EXPECT_CALL(*svcProxy, HandleClear()).WillOnce(Return(BError(BError::Codes::OK).GetCode())); + EXPECT_CALL(*session, StopFwkTimer(_)).WillOnce(Return(true)); + EXPECT_CALL(*session, StopExtTimer(_)).WillOnce(Return(true)); + EXPECT_CALL(*connect, DisconnectBackupExtAbility()).WillOnce(Return(BError(BError::Codes::OK).GetCode())); + EXPECT_CALL(*saUtils, IsSABundleName(_)).WillOnce(Return(true)); + EXPECT_CALL(*session, GetScenario()).WillOnce(Return(IServiceReverseType::Scenario::UNDEFINED)); + EXPECT_CALL(*cdConfig, DeleteClearBundleRecord(_)).WillOnce(Return(false)); + EXPECT_CALL(*session, IsOnAllBundlesFinished()).WillOnce(Return(false)); + auto ret = service->HandleExtDisconnect(true); + EXPECT_EQ(ret, BError(BError::Codes::OK).GetCode()); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "ServiceTest-an exception occurred by HandleExtDisconnect."; + } + GTEST_LOG_(INFO) << "ServiceTest-end SUB_Service_HandleExtDisconnect_0300"; +} + +/** + * @tc.number: SUB_Service_GetExtOnRelease_0000 + * @tc.name: SUB_Service_GetExtOnRelease_0000 + * @tc.desc: 测试 GetExtOnRelease 的正常/异常分支 + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + * @tc.require: IC7RHQ + */ +HWTEST_F(ServiceTest, SUB_Service_GetExtOnRelease_0000, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "ServiceTest-begin SUB_Service_GetExtOnRelease_0000"; + try { + bool isExtOnRelease = false; + EXPECT_CALL(*skeleton, GetCallingTokenID()).WillOnce(Return(0)); + EXPECT_CALL(*token, GetTokenType(_)).WillOnce(Return(Security::AccessToken::ATokenTypeEnum::TOKEN_HAP)); + EXPECT_CALL(*token, GetHapTokenInfo(_, _)).WillOnce(Return(1)); + EXPECT_CALL(*param, GetBackupDebugOverrideAccount()).WillOnce(Return(make_pair(false, -1))); + EXPECT_CALL(*skeleton, GetCallingUid()).WillOnce(Return(BConstants::SYSTEM_UID)); + auto ret = service->GetExtOnRelease(isExtOnRelease); + EXPECT_EQ(ret, BError(BError::Codes::SA_INVAL_ARG).GetCode()); + EXPECT_EQ(isExtOnRelease, false); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "ServiceTest-an exception occurred by HandleExtDisconnect."; + } + GTEST_LOG_(INFO) << "ServiceTest-end SUB_Service_GetExtOnRelease_0000"; +} + +/** + * @tc.number: SUB_Service_GetExtOnRelease_0100 + * @tc.name: SUB_Service_GetExtOnRelease_0100 + * @tc.desc: 测试 GetExtOnRelease 的正常/异常分支 + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + * @tc.require: IC7RHQ + */ +HWTEST_F(ServiceTest, SUB_Service_GetExtOnRelease_0100, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "ServiceTest-begin SUB_Service_GetExtOnRelease_0100"; + try { + bool isExtOnRelease = false; + EXPECT_CALL(*skeleton, GetCallingTokenID()).WillOnce(Return(0)); + EXPECT_CALL(*token, GetTokenType(_)).WillOnce(Return(Security::AccessToken::ATokenTypeEnum::TOKEN_HAP)); + EXPECT_CALL(*token, GetHapTokenInfo(_, _)).WillOnce(Return(0)); + EXPECT_CALL(*jsonUtil, BuildBundleNameIndexInfo(_, _)).WillOnce(Return("")); + auto ret = service->GetExtOnRelease(isExtOnRelease); + EXPECT_EQ(ret, BError(BError::Codes::SA_INVAL_ARG).GetCode()); + EXPECT_EQ(isExtOnRelease, false); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "ServiceTest-an exception occurred by HandleExtDisconnect."; + } + GTEST_LOG_(INFO) << "ServiceTest-end SUB_Service_GetExtOnRelease_0100"; +} + +/** + * @tc.number: SUB_Service_GetExtOnRelease_0200 + * @tc.name: SUB_Service_GetExtOnRelease_0200 + * @tc.desc: 测试 GetExtOnRelease 的正常/异常分支 + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + * @tc.require: IC7RHQ + */ +HWTEST_F(ServiceTest, SUB_Service_GetExtOnRelease_0200, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "ServiceTest-begin SUB_Service_GetExtOnRelease_0200"; + try { + bool isExtOnRelease = false; + EXPECT_CALL(*skeleton, GetCallingTokenID()).WillOnce(Return(0)); + EXPECT_CALL(*token, GetTokenType(_)).WillOnce(Return(Security::AccessToken::ATokenTypeEnum::TOKEN_HAP)); + EXPECT_CALL(*token, GetHapTokenInfo(_, _)).WillOnce(Return(0)); + EXPECT_CALL(*jsonUtil, BuildBundleNameIndexInfo(_, _)).WillOnce(Return("bundleName")); + service->SetExtOnRelease("bundleName", true); + auto ret = service->GetExtOnRelease(isExtOnRelease); + EXPECT_EQ(ret, BError(BError::Codes::OK).GetCode()); + EXPECT_EQ(isExtOnRelease, true); + service->RemoveExtOnRelease("bundleName"); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "ServiceTest-an exception occurred by HandleExtDisconnect."; + } + GTEST_LOG_(INFO) << "ServiceTest-end SUB_Service_GetExtOnRelease_0200"; +} } \ 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 59ee1ccbf141d5c15adf0a8a763206276cd0e592..2687c38e0cb48c1db43ad2e757bbcef9ebc15e6e 100644 --- a/utils/include/b_resources/b_constants.h +++ b/utils/include/b_resources/b_constants.h @@ -48,6 +48,12 @@ enum ServiceSchedAction { UNKNOWN = 5, }; +enum ExtensionScenario { + INVALID = 0, + BACKUP = 1, + RESTORE = 2, +}; + constexpr int SPAN_USERID_UID = 200000; constexpr int SYSTEM_UID = 0; constexpr int XTS_UID = 1; @@ -96,6 +102,8 @@ constexpr int APP_ON_PROCESS_MAX_TIMEOUT = 1000; // 应用的onProcess接口最 constexpr int FIRST_CALL_APP_ON_PROCESS_MAX_TIMEOUT = 15000; // 首次调用应用的onProcess接口最大超时时间为15秒 constexpr int APP_ON_PROCESS_TIMEOUT_MAX_COUNT = 3; // 应用的onProcess接口超时的上限次数 +constexpr int APP_ON_RELEASE_MAX_TIMEOUT = 5000; // 应用的onRelease接口最大超时时间为5秒 + // backup.para内配置项的名称,该配置项值为true时可在不更新hap包的情况下,可以读取包管理元数据配置文件的内容 static inline std::string BACKUP_DEBUG_OVERRIDE_EXTENSION_CONFIG_KEY = "backup.debug.overrideExtensionConfig"; static const bool BACKUP_DEBUG_OVERRIDE_EXTENSION_CONFIG_DEFAULT_VALUE = false;