diff --git a/frameworks/native/backup_ext/include/ext_backup.h b/frameworks/native/backup_ext/include/ext_backup.h index c0599ba3e1296e4bacbe506ffddd4a4fecc6d64a..b5fcd46650b3dd5e02d1f0cd39c8a36ec8c5cedc 100644 --- a/frameworks/native/backup_ext/include/ext_backup.h +++ b/frameworks/native/backup_ext/include/ext_backup.h @@ -185,6 +185,18 @@ public: * @brief Invoke the extended function of the APP */ virtual ErrCode InvokeAppExtMethod(ErrCode, const std::string); + + /** + * @brief Called do getBackupCompatibilityInfo. + */ + virtual ErrCode GetBackupCompatibilityInfo(std::function callbackEx, + std::string extInfo); + + /** + * @brief Called do getRestoreCompatibilityInfo. + */ + virtual ErrCode GetRestoreCompatibilityInfo(std::function callbackEx, + std::string extInfo); public: ExtBackup() = default; diff --git a/frameworks/native/backup_ext/include/ext_backup_js.h b/frameworks/native/backup_ext/include/ext_backup_js.h index f7f0c14f1e9ee6a96908427e7a5f98e8a019995e..6f87145ccdd87e88183f74f9780219ce20411bfe 100644 --- a/frameworks/native/backup_ext/include/ext_backup_js.h +++ b/frameworks/native/backup_ext/include/ext_backup_js.h @@ -145,6 +145,24 @@ public: */ ErrCode OnRelease(std::function callback, int32_t scenario) override; + /** + * @brief Call the app's GetBackupCompatibilityInfo + * + * @param callbackEx The callBackEx. + * @param extInfo The extInfo: json string. + */ + ErrCode GetBackupCompatibilityInfo(std::function callbackEx, + std::string extInfo) override; + + /** + * @brief Call the app's GetRestoreCompatibilityInfo + * + * @param callbackEx The callBackEx. + * @param extInfo The extInfo: json string. + */ + ErrCode GetRestoreCompatibilityInfo(std::function callbackEx, + std::string extInfo) override; + public: explicit ExtBackupJs(AbilityRuntime::JsRuntime &jsRuntime); ~ExtBackupJs(); @@ -161,6 +179,7 @@ private: std::function &argv)> ParseBackupExInfo(); std::function &argv)> ParseReleaseInfo(); + std::function &argv)> ParseCompatibilityInfo(); ErrCode CallJSRestoreEx(); ErrCode CallJSRestore(); @@ -182,6 +201,9 @@ private: std::atomic callExtDefaultFunc_ {false}; // extension default method, onBackup or onRestore std::atomic callJsExMethodDone_ {false}; int32_t scenario_ { 0 }; + + std::shared_ptr getComInfoCallbackEx_; + std::string extInfo_ {}; }; } // 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 6d545f815cdf023a7fbb92f085ed66cf96d22fec..cbc5b9c492b247f01608a93d73d7b423edc849a9 100644 --- a/frameworks/native/backup_ext/include/ext_extension.h +++ b/frameworks/native/backup_ext/include/ext_extension.h @@ -65,6 +65,7 @@ public: ErrCode UpdateDfxInfo(int64_t uniqId, uint32_t extConnectSpend, const std::string &bundleName) override; ErrCode CleanBundleTempDir() override; ErrCode HandleOnRelease(int32_t scenario) override; + ErrCode HandleGetCompatibilityInfo(const string &extInfo, int32_t scenario, string &compatibilityInfo) override; public: explicit BackupExtExtension(const std::shared_ptr &extension, @@ -400,6 +401,7 @@ private: void SetAppResultReport(const std::string resultInfo, ErrCode errCode); void HandleExtOnRelease(); std::function OnReleaseCallback(wptr obj); + std::function GetComInfoCallback(wptr obj); private: pair> GetFileInfos(const vector &includes, const vector &excludes); TarMap GetIncrmentBigInfos(const vector &files); @@ -457,6 +459,11 @@ private: std::string appResultReportInfo_; ErrCode appResultReportErrCode_ { 0 }; std::mutex serviceCallReleaseLock_; + + std::mutex getCompatibilityInfoLock_ {}; + std::condition_variable getCompatibilityInfoCon_ {}; + std::atomic stopGetComInfo_ {false}; + std::string compatibilityInfo_ {}; }; } // 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 75a48cdcdd02f3086cffb8f88bfcfe483e7869f6..304936753ad19eec1f1eb14374dd82b2bdd1c6de 100644 --- a/frameworks/native/backup_ext/src/ext_backup.cpp +++ b/frameworks/native/backup_ext/src/ext_backup.cpp @@ -326,4 +326,17 @@ ErrCode ExtBackup::OnRelease(std::function callback, return ERR_OK; } +ErrCode ExtBackup::GetBackupCompatibilityInfo(std::function callbackEx, + std::string extInfo) +{ + HILOGI("BackupExtensionAbility(base) GetBackupCompatibilityInfo."); + return ERR_OK; +} + +ErrCode ExtBackup::GetRestoreCompatibilityInfo(std::function callbackEx, + std::string extInfo) +{ + HILOGI("BackupExtensionAbility(base) GetRestoreCompatibilityInfo."); + 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 f8b190796ade4eda17638bb962b568b7c8e215e0..34d25631d46d0eed21670baa425faa176e1b34fd 100644 --- a/frameworks/native/backup_ext/src/ext_backup_js.cpp +++ b/frameworks/native/backup_ext/src/ext_backup_js.cpp @@ -1095,4 +1095,102 @@ void ExtBackupJs::InitTempPath(const std::string &bundleName) } } } + +ErrCode ExtBackupJs::GetBackupCompatibilityInfo(std::function callbackEx, + std::string extInfo) +{ + HILOGI("BackupExtensionAbility(JS) GetBackupCompatibilityInfo begin."); + BExcepUltils::BAssert(jsObj_, BError::Codes::EXT_BROKEN_FRAMEWORK, + "The app does not provide the GetBackupCompatibilityInfo interface."); + extInfo_ = extInfo; + getComInfoCallbackEx_ = std::make_shared(callbackEx); + auto retParser = [jsRuntime {&jsRuntime_}, callbackInfoEx {getComInfoCallbackEx_}](napi_env env, + napi_value result) -> bool { + if (!CheckPromise(env, result)) { + string str; + bool isExceptionPending; + napi_is_exception_pending(env, &isExceptionPending); + HILOGI("napi exception pending = %{public}d.", isExceptionPending); + if (!callbackInfoEx) { + HILOGE("callbackInfoEx is nullptr"); + return false; + } + if (isExceptionPending) { + napi_value exception; + DealNapiException(env, exception, str); + napi_fatal_exception(env, exception); + callbackInfoEx->callbackParam(BError(BError::Codes::EXT_THROW_EXCEPTION), str); + } else { + callbackInfoEx->callbackParam(BError(BError::Codes::OK), str); + } + return true; + } + HILOGI("CheckPromise Js Method GetBackupCompatibilityInfo ok."); + return CallPromiseEx(*jsRuntime, result, callbackInfoEx.get()); + }; + auto errCode = CallJsMethod("getBackupCompatibilityInfo", jsRuntime_, jsObj_.get(), + ParseCompatibilityInfo(), retParser); + if (errCode != ERR_OK) { + HILOGE("CallJsMethod error, code:%{public}d.", errCode); + } + HILOGI("BackupExtensionAbility(JS) GetBackupCompatibilityInfo end."); + return errCode; +} + +ErrCode ExtBackupJs::GetRestoreCompatibilityInfo(std::function callbackEx, + std::string extInfo) +{ + HILOGI("BackupExtensionAbility(JS) GetRestoreCompatibilityInfo begin."); + BExcepUltils::BAssert(jsObj_, BError::Codes::EXT_BROKEN_FRAMEWORK, + "The app does not provide the GetRestoreCompatibilityInfo interface."); + extInfo_ = extInfo; + getComInfoCallbackEx_ = std::make_shared(callbackEx); + auto retParser = [jsRuntime {&jsRuntime_}, callbackInfoEx {getComInfoCallbackEx_}](napi_env env, + napi_value result) -> bool { + if (!CheckPromise(env, result)) { + string str; + bool isExceptionPending; + napi_is_exception_pending(env, &isExceptionPending); + HILOGI("napi exception pending = %{public}d.", isExceptionPending); + if (!callbackInfoEx) { + HILOGE("callbackInfoEx is nullptr"); + return false; + } + if (isExceptionPending) { + napi_value exception; + DealNapiException(env, exception, str); + napi_fatal_exception(env, exception); + callbackInfoEx->callbackParam(BError(BError::Codes::EXT_THROW_EXCEPTION), str); + } else { + callbackInfoEx->callbackParam(BError(BError::Codes::OK), str); + } + return true; + } + HILOGI("CheckPromise Js Method GetRestoreCompatibilityInfo ok."); + return CallPromiseEx(*jsRuntime, result, callbackInfoEx.get()); + }; + auto errCode = CallJsMethod("getRestoreCompatibilityInfo", jsRuntime_, jsObj_.get(), + ParseCompatibilityInfo(), retParser); + if (errCode != ERR_OK) { + HILOGE("CallJsMethod error, code:%{public}d.", errCode); + } + HILOGI("BackupExtensionAbility(JS) GetRestoreCompatibilityInfo end."); + return errCode; +} + +std::function &argv)> ExtBackupJs::ParseCompatibilityInfo() +{ + auto getCompatibilityInfoFun = [extInfo(extInfo_)](napi_env env, vector &argv) -> bool { + napi_value extInfoValue = nullptr; + napi_create_object(env, &extInfoValue); + HILOGI("ParseCompatibilityInfo, extInfo is:%{public}s", GetAnonyString(extInfo).c_str()); + if (napi_create_string_utf8(env, extInfo.c_str(), extInfo.size(), &extInfoValue) != napi_ok) { + HILOGE("create napi string failed"); + return false; + } + argv.emplace_back(extInfoValue); + return true; + }; + return getCompatibilityInfoFun; +} } // namespace OHOS::FileManagement::Backup diff --git a/frameworks/native/backup_ext/src/sub_ext_extension.cpp b/frameworks/native/backup_ext/src/sub_ext_extension.cpp index 4cd89419b4a63e7e3af065837a8902bd147ef4ad..1da153964cf7d0353883066166df2ae436cc792d 100644 --- a/frameworks/native/backup_ext/src/sub_ext_extension.cpp +++ b/frameworks/native/backup_ext/src/sub_ext_extension.cpp @@ -1884,4 +1884,68 @@ void BackupExtExtension::HandleExtOnRelease() StartOnReleaseTimeOutTimer(ptr); CallJsOnReleaseTask(ptr, scenario, true); } + +std::function BackupExtExtension::GetComInfoCallback(wptr obj) +{ + HILOGI("Begin get GetComInfoCallback"); + return [obj](ErrCode errCode, std::string compatibilityInfo) { + HILOGI("GetComInfoCallback: App getCompatibilityInfo 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->stopGetComInfo_.load()) { + HILOGE("App getCompatibilityInfo timeout"); + return; + } + HILOGI("GetCompatibilityInfo end, errCode: %{public}d, compatibilityInfo size is %{public}zu", + errCode, compatibilityInfo.size()); + std::unique_lock lock(extPtr->getCompatibilityInfoLock_); + extPtr->compatibilityInfo_ = compatibilityInfo; + extPtr->stopGetComInfo_.store(true); + extPtr->getCompatibilityInfoCon_.notify_all(); + }; +} + +ErrCode BackupExtExtension::HandleGetCompatibilityInfo(const string &extInfo, int32_t scenario, + string &compatibilityInfo) +{ + try { + HILOGI("Begin, scenario: %{public}d, extInfo size: %{public}zu", scenario, extInfo.size()); + VerifyCaller(); + auto ptr = wptr(this); + auto callback = GetComInfoCallback(ptr); + ErrCode ret = ERR_OK; + compatibilityInfo = ""; + if (scenario == BConstants::ExtensionScenario::BACKUP) { + ret = extension_->GetBackupCompatibilityInfo(callback, extInfo); + } else if (scenario == BConstants::ExtensionScenario::RESTORE) { + ret = extension_->GetRestoreCompatibilityInfo(callback, extInfo); + } else { + return BError(BError::Codes::EXT_INVAL_ARG).GetCode(); + } + if (ret != ERR_OK) { + HILOGE("Call GetCompatibilityInfo failed, ret = %{public}d", ret); + return ret; + } + HILOGI("wait GetCompatibilityInfo"); + std::unique_lock lock(getCompatibilityInfoLock_); + auto noTimeout = getCompatibilityInfoCon_.wait_for(lock, + std::chrono::milliseconds(BConstants::APP_GETCOMINFO_MAX_TIMEOUT), + [this] { return this->stopGetComInfo_.load(); }); + if (noTimeout) { + compatibilityInfo = compatibilityInfo_; + } + HILOGI("getCompatibilityInfo size: %{public}zu", compatibilityInfo.size()); + return ret; + } catch (...) { + HILOGE("Failed to HandleGetCompatibilityInfo"); + return BError(BError::Codes::EXT_BROKEN_IPC).GetCode(); + } +} } // 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 index be5413d5d0d0b98c5a53d04c78b008b1b3743bb2..9f6ef2247c7c2ed817358f12cab8e062ac62a677 100644 --- a/frameworks/native/backup_kit_inner/src/b_incremental_backup_session.cpp +++ b/frameworks/native/backup_kit_inner/src/b_incremental_backup_session.cpp @@ -215,4 +215,15 @@ ErrCode BIncrementalBackupSession::CleanBundleTempDir(const std::string &bundleN } return proxy->CleanBundleTempDir(bundleName); } + +ErrCode BIncrementalBackupSession::GetCompatibilityInfo(const std::string &bundleName, const std::string &extInfo, + std::string &compatInfo) +{ + HILOGI("BIncrementalBackupSession::GetCompatibilityInfo"); + auto proxy = ServiceClient::GetInstance(); + if (proxy == nullptr) { + return BError(BError::Codes::SDK_BROKEN_IPC, "Failed to get backup service").GetCode(); + } + return proxy->GetCompatibilityInfo(bundleName, extInfo, compatInfo); +} } // namespace OHOS::FileManagement::Backup \ 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 index 78b92c231dd36323d6dd594e662ce6c5e9dbca6d..23fc5385edc25c3c86bba19e5623d5b285fc69a8 100644 --- a/frameworks/native/backup_kit_inner/src/b_incremental_restore_session.cpp +++ b/frameworks/native/backup_kit_inner/src/b_incremental_restore_session.cpp @@ -237,4 +237,15 @@ ErrCode BIncrementalRestoreSession::CleanBundleTempDir(const std::string &bundle } return proxy->CleanBundleTempDir(bundleName); } + +ErrCode BIncrementalRestoreSession::GetCompatibilityInfo(const std::string &bundleName, const std::string &extInfo, + std::string &compatInfo) +{ + HILOGI("BIncrementalRestoreSession::GetCompatibilityInfo"); + auto proxy = ServiceClient::GetInstance(); + if (proxy == nullptr) { + return BError(BError::Codes::SDK_BROKEN_IPC, "Failed to get backup service").GetCode(); + } + return proxy->GetCompatibilityInfo(bundleName, extInfo, compatInfo); +} } // 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 992125a31fa55a961dd1378d356e66339eeb00c6..ec93502a96b58bbd3ae52914c1a7b52de3410464 100644 --- a/frameworks/native/backup_kit_inner/src/b_session_backup.cpp +++ b/frameworks/native/backup_kit_inner/src/b_session_backup.cpp @@ -234,4 +234,15 @@ ErrCode BSessionBackup::CleanBundleTempDir(const std::string &bundleName) } return proxy->CleanBundleTempDir(bundleName); } + +ErrCode BSessionBackup::GetCompatibilityInfo(const std::string &bundleName, const std::string &extInfo, + std::string &compatInfo) +{ + HILOGI("BSessionBackup::GetCompatibilityInfo"); + auto proxy = ServiceClient::GetInstance(); + if (proxy == nullptr) { + return BError(BError::Codes::SDK_BROKEN_IPC, "Failed to get backup service").GetCode(); + } + return proxy->GetCompatibilityInfo(bundleName, extInfo, compatInfo); +} } // 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 34dfc57c322d5556b26677ea07bbfe614ee65148..e2215940cf1eab06e3345fbcf2a97afadfb8fcd4 100644 --- a/frameworks/native/backup_kit_inner/src/b_session_restore.cpp +++ b/frameworks/native/backup_kit_inner/src/b_session_restore.cpp @@ -215,4 +215,15 @@ ErrCode BSessionRestore::CleanBundleTempDir(const std::string &bundleName) } return proxy->CleanBundleTempDir(bundleName); } + +ErrCode BSessionRestore::GetCompatibilityInfo(const std::string &bundleName, const std::string &extInfo, + std::string &compatInfo) +{ + HILOGI("BSessionRestore::GetCompatibilityInfo"); + auto proxy = ServiceClient::GetInstance(); + if (proxy == nullptr) { + return BError(BError::Codes::SDK_BROKEN_IPC, "Failed to get backup service").GetCode(); + } + return proxy->GetCompatibilityInfo(bundleName, extInfo, compatInfo); +} } // namespace OHOS::FileManagement::Backup \ No newline at end of file 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 a6d51a71bc4fff5d1e428f8339560ead396cc09b..92f4078e6bc30ab9b1f19499b6317e6874a6a4c4 100644 --- a/interfaces/api/js/napi/backup_ext/backup_extension_ability.js +++ b/interfaces/api/js/napi/backup_ext/backup_extension_ability.js @@ -37,6 +37,14 @@ class BackupExtensionAbility { onRelease(scenario) { console.log(); } + + getBackupCompatibilityInfo(extInfo) { + console.log(); + } + + getRestoreCompatibilityInfo(extInfo) { + console.log(); + } } export default BackupExtensionAbility; \ No newline at end of file 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 index b32113789cdfe8600b667492ac01aec1179ba9e7..d1bbec06e649ae74c70da064e0dc473ef0a1defd 100644 --- 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 @@ -123,6 +123,16 @@ public: */ ErrCode CleanBundleTempDir(const std::string &bundleName); + /** + * @brief 获取备份或恢复的应用的兼容性信息 + * + * @param bundleName 应用名称 + * @param extInfo 导入给应用的信息 + * @param compatInfo 应用返回的兼容信息 + * @return ErrCode 规范错误码 + */ + ErrCode GetCompatibilityInfo(const std::string &bundleName, const std::string &extInfo, std::string &compatInfo); + public: ~BIncrementalBackupSession(); 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 index feaadb654955a5a2514c7932a86486a0d03931c8..64855efab2c4025d69aedbaa8daa8680190d2598 100644 --- 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 @@ -145,6 +145,16 @@ public: */ ErrCode CleanBundleTempDir(const std::string &bundleName); + /** + * @brief 获取备份或恢复的应用的兼容性信息 + * + * @param bundleName 应用名称 + * @param extInfo 导入给应用的信息 + * @param compatInfo 应用返回的兼容信息 + * @return ErrCode 规范错误码 + */ + ErrCode GetCompatibilityInfo(const std::string &bundleName, const std::string &extInfo, std::string &compatInfo); + public: ~BIncrementalRestoreSession(); 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 7f5cd583d69ebc0d36ed1e2d89734d14bda6e024..4382c0d08192aa6ed0522039b9cb98a33fa25d78 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 @@ -138,6 +138,16 @@ public: */ ErrCode CleanBundleTempDir(const std::string &bundleName); + /** + * @brief 获取备份或恢复的应用的兼容性信息 + * + * @param bundleName 应用名称 + * @param extInfo 导入给应用的信息 + * @param compatInfo 应用返回的兼容信息 + * @return ErrCode 规范错误码 + */ + ErrCode GetCompatibilityInfo(const std::string &bundleName, const std::string &extInfo, std::string &compatInfo); + public: ~BSessionBackup(); 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 4dd41dc361152df1629db1199a26bc6b545d07e5..e637a13545e0b8bf535e168838ce2faadcdb43f5 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 @@ -145,6 +145,16 @@ public: */ ErrCode CleanBundleTempDir(const std::string &bundleName); + /** + * @brief 获取备份或恢复的应用的兼容性信息 + * + * @param bundleName 应用名称 + * @param extInfo 导入给应用的信息 + * @param compatInfo 应用返回的兼容信息 + * @return ErrCode 规范错误码 + */ + ErrCode GetCompatibilityInfo(const std::string &bundleName, const std::string &extInfo, std::string &compatInfo); + public: ~BSessionRestore(); diff --git a/interfaces/kits/js/backup/session_backup_n_exporter.cpp b/interfaces/kits/js/backup/session_backup_n_exporter.cpp index bcd5846fc44b4275d0dac20243566eb6ef29214f..e1d5f6328f137ed573ee7dd59f0c8574c7d0ff5a 100644 --- a/interfaces/kits/js/backup/session_backup_n_exporter.cpp +++ b/interfaces/kits/js/backup/session_backup_n_exporter.cpp @@ -712,6 +712,81 @@ napi_value SessionBackupNExporter::CleanBundleTempDir(napi_env env, napi_callbac return NAsyncWorkPromise(env, thisVar).Schedule(className, cbExec, cbCompl).val_; } +static NContextCBExec GetCompatibilityInfoCBExec(napi_env env, const NFuncArg &funcArg, string bundleName, + string extInfo, shared_ptr compatInfo) +{ + auto backupEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!(backupEntity && (backupEntity->session))) { + HILOGE("Failed to get BackupSession entity."); + return nullptr; + } + return [entity {backupEntity}, bundleName, extInfo, compatInfo]() -> NError { + if (!(entity && (entity->session))) { + return NError(BError(BError::Codes::SDK_INVAL_ARG, "Backup session is nullptr").GetCode()); + } + return NError(entity->session->GetCompatibilityInfo(bundleName, extInfo, *compatInfo)); + }; +} + +static bool ParseCompatInfoParam(napi_env env, NFuncArg &funcArg, string &bundleName, string &extInfo) +{ + if (!funcArg.InitArgs(NARG_CNT::TWO)) { + HILOGE("Number of arguments unmatched"); + return false; + } + NVal jsBundleName(env, funcArg[NARG_POS::FIRST]); + auto [succ, bundleNamePtr, sizeStr] = jsBundleName.ToUTF8String(); + if (!succ) { + HILOGE("First arguments is not string."); + return false; + } + NVal jsExtInfo(env, funcArg[NARG_POS::SECOND]); + auto [succ1, extInfoPtr, sizeStr1] = jsExtInfo.ToUTF8String(); + if (!succ1) { + HILOGE("Second arguments is not string."); + return false; + } + bundleName = string(bundleNamePtr.get()); + extInfo = string(extInfoPtr.get()); + return true; +} + +napi_value SessionBackupNExporter::GetCompatibilityInfo(napi_env env, napi_callback_info cbinfo) +{ + HILOGI("Called SessionBackupNExporter::GetCompatibilityInfo begin."); + if (!SAUtils::CheckBackupPermission()) { + HILOGE("Has not permission!"); + NError(E_PERMISSION).ThrowErr(env); + return nullptr; + } + if (!SAUtils::IsSystemApp()) { + HILOGE("System App check fail!"); + NError(E_PERMISSION_SYS).ThrowErr(env); + return nullptr; + } + + NFuncArg funcArg(env, cbinfo); + string bundleName; + string extInfo; + if (!ParseCompatInfoParam(env, funcArg, bundleName, extInfo)) { + NError(E_PARAMS).ThrowErr(env); + return nullptr; + } + + auto compatInfo = std::make_shared(); + auto cbExec = GetCompatibilityInfoCBExec(env, funcArg, bundleName, extInfo, compatInfo); + if (cbExec == nullptr) { + NError(BError(BError::Codes::SDK_INVAL_ARG, "Failed to get BackupSession entity.").GetCode()).ThrowErr(env); + return nullptr; + } + auto cbCompl = [compatInfo](napi_env env, NError err) -> NVal { + return err ? NVal {env, err.GetNapiErr(env)} : NVal::CreateUTF8String(env, *compatInfo); + }; + + NVal thisVar(env, funcArg.GetThisVar()); + return NAsyncWorkPromise(env, thisVar).Schedule(className, cbExec, cbCompl).val_; +} + bool SessionBackupNExporter::Export() { HILOGD("called SessionBackupNExporter::Export begin"); @@ -722,6 +797,7 @@ bool SessionBackupNExporter::Export() NVal::DeclareNapiFunction("release", Release), NVal::DeclareNapiFunction("cancel", Cancel), NVal::DeclareNapiFunction("cleanBundleTempDir", CleanBundleTempDir), + NVal::DeclareNapiFunction("getCompatibilityInfo", GetCompatibilityInfo), }; auto [succ, classValue] = NClass::DefineClass(exports_.env_, className, Constructor, std::move(props)); diff --git a/interfaces/kits/js/backup/session_backup_n_exporter.h b/interfaces/kits/js/backup/session_backup_n_exporter.h index 708f3b9b714110e8d6bce8848788f324507405e2..92b0c82912aac77f6b4099d6a0cc65c5a97266d8 100644 --- a/interfaces/kits/js/backup/session_backup_n_exporter.h +++ b/interfaces/kits/js/backup/session_backup_n_exporter.h @@ -32,6 +32,7 @@ public: static napi_value Release(napi_env env, napi_callback_info cbinfo); static napi_value Cancel(napi_env env, napi_callback_info cbinfo); static napi_value CleanBundleTempDir(napi_env env, napi_callback_info cbinfo); + static napi_value GetCompatibilityInfo(napi_env env, napi_callback_info cbinfo); SessionBackupNExporter(napi_env env, napi_value exports); ~SessionBackupNExporter() override; diff --git a/interfaces/kits/js/backup/session_incremental_backup_n_exporter.cpp b/interfaces/kits/js/backup/session_incremental_backup_n_exporter.cpp index 6c7c377fd9611ed8416ba5f361d8b889ac7283d1..1cef934ed5dc6db1a9110e2f4fb237d4dbfc4580 100644 --- a/interfaces/kits/js/backup/session_incremental_backup_n_exporter.cpp +++ b/interfaces/kits/js/backup/session_incremental_backup_n_exporter.cpp @@ -711,6 +711,82 @@ napi_value SessionIncrementalBackupNExporter::CleanBundleTempDir(napi_env env, n return NAsyncWorkPromise(env, thisVar).Schedule(className, cbExec, cbCompl).val_; } + +static NContextCBExec GetCompatibilityInfoCBExec(napi_env env, const NFuncArg &funcArg, string bundleName, + string extInfo, shared_ptr compatInfo) +{ + auto backupEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!(backupEntity && (backupEntity->session))) { + HILOGE("Failed to get BackupSession entity."); + return nullptr; + } + return [entity {backupEntity}, bundleName, extInfo, compatInfo]() -> NError { + if (!(entity && (entity->session))) { + return NError(BError(BError::Codes::SDK_INVAL_ARG, "Backup session is nullptr").GetCode()); + } + return NError(entity->session->GetCompatibilityInfo(bundleName, extInfo, *compatInfo)); + }; +} + +static bool ParseCompatInfoParam(napi_env env, NFuncArg &funcArg, string &bundleName, string &extInfo) +{ + if (!funcArg.InitArgs(NARG_CNT::TWO)) { + HILOGE("Number of arguments unmatched"); + return false; + } + NVal jsBundleName(env, funcArg[NARG_POS::FIRST]); + auto [succ, bundleNamePtr, sizeStr] = jsBundleName.ToUTF8String(); + if (!succ) { + HILOGE("First arguments is not string."); + return false; + } + NVal jsExtInfo(env, funcArg[NARG_POS::SECOND]); + auto [succ1, extInfoPtr, sizeStr1] = jsExtInfo.ToUTF8String(); + if (!succ1) { + HILOGE("Second arguments is not string."); + return false; + } + bundleName = string(bundleNamePtr.get()); + extInfo = string(extInfoPtr.get()); + return true; +} + +napi_value SessionIncrementalBackupNExporter::GetCompatibilityInfo(napi_env env, napi_callback_info cbinfo) +{ + HILOGI("Called SessionIncrementalBackupNExporter::GetCompatibilityInfo begin."); + if (!SAUtils::CheckBackupPermission()) { + HILOGE("Has not permission!"); + NError(E_PERMISSION).ThrowErr(env); + return nullptr; + } + if (!SAUtils::IsSystemApp()) { + HILOGE("System App check fail!"); + NError(E_PERMISSION_SYS).ThrowErr(env); + return nullptr; + } + + NFuncArg funcArg(env, cbinfo); + string bundleName; + string extInfo; + if (!ParseCompatInfoParam(env, funcArg, bundleName, extInfo)) { + NError(E_PARAMS).ThrowErr(env); + return nullptr; + } + + auto compatInfo = std::make_shared(); + auto cbExec = GetCompatibilityInfoCBExec(env, funcArg, bundleName, extInfo, compatInfo); + if (cbExec == nullptr) { + NError(BError(BError::Codes::SDK_INVAL_ARG, "Failed to get BackupSession entity.").GetCode()).ThrowErr(env); + return nullptr; + } + auto cbCompl = [compatInfo](napi_env env, NError err) -> NVal { + return err ? NVal {env, err.GetNapiErr(env)} : NVal::CreateUTF8String(env, *compatInfo); + }; + + NVal thisVar(env, funcArg.GetThisVar()); + return NAsyncWorkPromise(env, thisVar).Schedule(className, cbExec, cbCompl).val_; +} + bool SessionIncrementalBackupNExporter::Export() { HILOGD("called SessionIncrementalBackupNExporter::Export begin"); @@ -721,6 +797,7 @@ bool SessionIncrementalBackupNExporter::Export() NVal::DeclareNapiFunction("release", Release), NVal::DeclareNapiFunction("cancel", Cancel), NVal::DeclareNapiFunction("cleanBundleTempDir", CleanBundleTempDir), + NVal::DeclareNapiFunction("getCompatibilityInfo", GetCompatibilityInfo), }; auto [succ, classValue] = NClass::DefineClass(exports_.env_, className, Constructor, std::move(props)); diff --git a/interfaces/kits/js/backup/session_incremental_backup_n_exporter.h b/interfaces/kits/js/backup/session_incremental_backup_n_exporter.h index 7f9547232f0fef20da12c0bdcb05b6fca8b11d1e..6ebba0c6f12c8492b104226a6e95a4f5610dc547 100644 --- a/interfaces/kits/js/backup/session_incremental_backup_n_exporter.h +++ b/interfaces/kits/js/backup/session_incremental_backup_n_exporter.h @@ -32,6 +32,7 @@ public: static napi_value Release(napi_env env, napi_callback_info cbinfo); static napi_value Cancel(napi_env env, napi_callback_info cbinfo); static napi_value CleanBundleTempDir(napi_env env, napi_callback_info cbinfo); + static napi_value GetCompatibilityInfo(napi_env env, napi_callback_info cbinfo); SessionIncrementalBackupNExporter(napi_env env, napi_value exports); ~SessionIncrementalBackupNExporter() override; diff --git a/interfaces/kits/js/backup/session_restore_n_exporter.cpp b/interfaces/kits/js/backup/session_restore_n_exporter.cpp index b57a9b27107490108e9e05971b4ecbb489e7000d..1540122302f28e39109320837770f4ff0cc214af 100644 --- a/interfaces/kits/js/backup/session_restore_n_exporter.cpp +++ b/interfaces/kits/js/backup/session_restore_n_exporter.cpp @@ -905,6 +905,84 @@ napi_value SessionRestoreNExporter::CleanBundleTempDir(napi_env env, napi_callba return NAsyncWorkPromise(env, thisVar).Schedule(className, cbExec, cbCompl).val_; } +static NContextCBExec GetCompatibilityInfoCBExec(napi_env env, const NFuncArg &funcArg, string bundleName, + string extInfo, shared_ptr compatInfo) +{ + auto restoreEntity = NClass::GetEntityOf(env, funcArg.GetThisVar()); + if (!(restoreEntity && (restoreEntity->sessionWhole || restoreEntity->sessionSheet))) { + HILOGE("Failed to get RestoreSession entity."); + return nullptr; + } + return [entity {restoreEntity}, bundleName, extInfo, compatInfo]() -> NError { + if (!(entity && (entity->sessionWhole || entity->sessionSheet))) { + return NError(BError(BError::Codes::SDK_INVAL_ARG, "restore session is nullptr").GetCode()); + } + if (entity->sessionWhole) { + return NError(entity->sessionWhole->GetCompatibilityInfo(bundleName, extInfo, *compatInfo)); + } + return NError(entity->sessionSheet->GetCompatibilityInfo(bundleName, extInfo, *compatInfo)); + }; +} + +static bool ParseCompatInfoParam(napi_env env, NFuncArg &funcArg, string &bundleName, string &extInfo) +{ + if (!funcArg.InitArgs(NARG_CNT::TWO)) { + HILOGE("Number of arguments unmatched"); + return false; + } + NVal jsBundleName(env, funcArg[NARG_POS::FIRST]); + auto [succ, bundleNamePtr, sizeStr] = jsBundleName.ToUTF8String(); + if (!succ) { + HILOGE("First arguments is not string."); + return false; + } + NVal jsExtInfo(env, funcArg[NARG_POS::SECOND]); + auto [succ1, extInfoPtr, sizeStr1] = jsExtInfo.ToUTF8String(); + if (!succ1) { + HILOGE("Second arguments is not string."); + return false; + } + bundleName = string(bundleNamePtr.get()); + extInfo = string(extInfoPtr.get()); + return true; +} + +napi_value SessionRestoreNExporter::GetCompatibilityInfo(napi_env env, napi_callback_info cbinfo) +{ + HILOGI("Called SessionRestore::GetCompatibilityInfo begin."); + if (!SAUtils::CheckBackupPermission()) { + HILOGE("Has not permission!"); + NError(E_PERMISSION).ThrowErr(env); + return nullptr; + } + if (!SAUtils::IsSystemApp()) { + HILOGE("System App check fail!"); + NError(E_PERMISSION_SYS).ThrowErr(env); + return nullptr; + } + + NFuncArg funcArg(env, cbinfo); + string bundleName; + string extInfo; + if (!ParseCompatInfoParam(env, funcArg, bundleName, extInfo)) { + NError(E_PARAMS).ThrowErr(env); + return nullptr; + } + + auto compatInfo = std::make_shared(); + auto cbExec = GetCompatibilityInfoCBExec(env, funcArg, bundleName, extInfo, compatInfo); + if (cbExec == nullptr) { + NError(BError(BError::Codes::SDK_INVAL_ARG, "Failed to get RestoreSession entity.").GetCode()).ThrowErr(env); + return nullptr; + } + auto cbCompl = [compatInfo](napi_env env, NError err) -> NVal { + return err ? NVal {env, err.GetNapiErr(env)} : NVal::CreateUTF8String(env, *compatInfo); + }; + + NVal thisVar(env, funcArg.GetThisVar()); + return NAsyncWorkPromise(env, thisVar).Schedule(className, cbExec, cbCompl).val_; +} + bool SessionRestoreNExporter::Export() { HILOGD("called SessionRestoreNExporter::Export begin"); @@ -916,6 +994,7 @@ bool SessionRestoreNExporter::Export() NVal::DeclareNapiFunction("release", Release), NVal::DeclareNapiFunction("cancel", Cancel), NVal::DeclareNapiFunction("cleanBundleTempDir", CleanBundleTempDir), + NVal::DeclareNapiFunction("getCompatibilityInfo", GetCompatibilityInfo), }; auto [succ, classValue] = NClass::DefineClass(exports_.env_, className, Constructor, std::move(props)); diff --git a/interfaces/kits/js/backup/session_restore_n_exporter.h b/interfaces/kits/js/backup/session_restore_n_exporter.h index 12a40fca8a98920d8b466a79b9331e036dbec53b..8924a4dfc8f3baf1bd0bb0e363c4ac9c87cdee89 100644 --- a/interfaces/kits/js/backup/session_restore_n_exporter.h +++ b/interfaces/kits/js/backup/session_restore_n_exporter.h @@ -36,6 +36,7 @@ public: static napi_value Release(napi_env env, napi_callback_info cbinfo); static napi_value Cancel(napi_env env, napi_callback_info cbinfo); static napi_value CleanBundleTempDir(napi_env env, napi_callback_info cbinfo); + static napi_value GetCompatibilityInfo(napi_env env, napi_callback_info cbinfo); SessionRestoreNExporter(napi_env env, napi_value exports); ~SessionRestoreNExporter() override; diff --git a/services/backup_sa/IExtension.idl b/services/backup_sa/IExtension.idl index eb1b0f34ab2c413c94a9143d8250eea1663f7b23..77725ada6cb9182aa261b13f6a3f9a3ade218b0a 100644 --- a/services/backup_sa/IExtension.idl +++ b/services/backup_sa/IExtension.idl @@ -31,4 +31,6 @@ interface OHOS.FileManagement.Backup.IExtension{ [ipccode 14] void UpdateDfxInfo([in] long uniqId, [in] unsigned int extConnectSpend, [in] String bundleName); [ipccode 15] void CleanBundleTempDir(); [ipccode 16] void HandleOnRelease([in] int scenario); + [ipccode 17] void HandleGetCompatibilityInfo([in] String extInfo, [in] int scenario, + [out] String compatibilityInfo); } \ No newline at end of file diff --git a/services/backup_sa/IService.idl b/services/backup_sa/IService.idl index 1fdf7524ec87347cde7aea00878f5df5e3376f31..dda0fe4a09cf303c1dc57b1bce3dd36aaa19a592 100644 --- a/services/backup_sa/IService.idl +++ b/services/backup_sa/IService.idl @@ -76,4 +76,5 @@ interface OHOS.FileManagement.Backup.IService{ [ipccode 42] void GetExtOnRelease([out] boolean isExtOnRelease); [ipccode 43] void AppFileReadyWithoutFd([in]String fileName, [in] int appFileReadyErrCode); [ipccode 44] void AppIncrementalFileReadyWithoutFd([in] String fileName, [in] int appIncrementalFileReadyErrCode); + [ipccode 45] void GetCompatibilityInfo([in] String bundleName, [in] String extInfo, [out] String compatInfo); } \ 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 4a56703c7cf1f4a3ce60977a9fda353360b357b1..3e5052d5ba4830bb34f15953dfc65d9492540ae0 100644 --- a/services/backup_sa/include/module_ipc/service.h +++ b/services/backup_sa/include/module_ipc/service.h @@ -120,6 +120,8 @@ public: ErrCode CleanBundleTempDir(const std::string &bundleName) override; ErrCode HandleExtDisconnect(bool isIncBackup) override; ErrCode GetExtOnRelease(bool &isExtOnRelease) override; + ErrCode GetCompatibilityInfo(const std::string &bundleName, const std::string &extInfo, + std::string &compatInfo) override; // 以下都是非IPC接口 public: diff --git a/services/backup_sa/src/module_external/bms_adapter.cpp b/services/backup_sa/src/module_external/bms_adapter.cpp index b5b2c0204cf5d1df0a0919c2dd32d9a6e44f27e6..67eb26936874a63f3bcb85a9cb25232c3f2516de 100644 --- a/services/backup_sa/src/module_external/bms_adapter.cpp +++ b/services/backup_sa/src/module_external/bms_adapter.cpp @@ -68,7 +68,7 @@ static sptr GetBundleManager() return iface_cast(bundleObj); } -static tuple GetAllowAndExtName( +static tuple GetAllowAndExtName( const vector &extensionInfos) { for (auto &&ext : extensionInfos) { @@ -84,9 +84,9 @@ static tuple GetAllowAndExtName BJsonCachedEntity cachedEntity(out[0], ext.bundleName); auto cache = cachedEntity.Structuralize(); return {cache.GetAllowToBackupRestore(), cache.GetFullBackupOnly(), ext.name, cache.GetRestoreDeps(), - cache.GetSupportScene(), cache.GetExtraInfo()}; + cache.GetSupportScene(), cache.GetExtraInfo(), cache.GetRequireCompatibility()}; } - return {false, false, "", "", "", Json::Value()}; + return {false, false, "", "", "", Json::Value(), false}; } static int64_t GetBundleStats(const string &bundleName, int32_t userId) @@ -135,7 +135,7 @@ vector BundleMgrAdapter::GetBundleInfos(const vecto HILOGE("Get current extension failed, bundleName:%{public}s", bundleName.c_str()); continue; } - auto [allToBackup, fullBackupOnly, extName, restoreDeps, supportScene, extraInfo] = + auto [allToBackup, fullBackupOnly, extName, restoreDeps, supportScene, extraInfo, requireCompatibility] = GetAllowAndExtName(bundleExtInfo.extensionInfos_); int64_t dataSize = 0; if (allToBackup) { @@ -143,7 +143,7 @@ vector BundleMgrAdapter::GetBundleInfos(const vecto } bundleInfos.emplace_back(BJsonEntityCaps::BundleInfo {bundleExtInfo.bundleInfo_.name, bundleExtInfo.bundleInfo_.appIndex, bundleExtInfo.bundleInfo_.versionCode, - bundleExtInfo.bundleInfo_.versionName, dataSize, 0, allToBackup, fullBackupOnly, + bundleExtInfo.bundleInfo_.versionName, dataSize, 0, allToBackup, fullBackupOnly, requireCompatibility, extName, restoreDeps, supportScene, extraInfo}); } HILOGI("End, bundleInfos size:%{public}zu", bundleInfos.size()); @@ -184,6 +184,7 @@ static bool GetBackupExtConfig(const vector &e backupPara.extraInfo = cache.GetExtraInfo(); backupPara.includes = cache.GetIncludes(); backupPara.excludes = cache.GetExcludes(); + backupPara.requireCompatibility = cache.GetRequireCompatibility(); return true; } return false; @@ -310,7 +311,8 @@ vector BundleMgrAdapter::GetBundleInfosForIncrement bundleInfos.emplace_back(BJsonEntityCaps::BundleInfo {bundleExtInfo.bundleInfo_.name, bundleExtInfo.bundleInfo_.appIndex, bundleExtInfo.bundleInfo_.versionCode, bundleExtInfo.bundleInfo_.versionName, 0, 0, backupPara.allToBackup, backupPara.fullBackupOnly, - backupPara.extensionName, backupPara.restoreDeps, backupPara.supportScene, backupPara.extraInfo}); + backupPara.requireCompatibility, backupPara.extensionName, backupPara.restoreDeps, backupPara.supportScene, + backupPara.extraInfo}); if (bundleExtInfo.bundleInfo_.appIndex > 0) { std::string bundleNameIndex = "+clone-" + std::to_string(bundleExtInfo.bundleInfo_.appIndex) + "+" + bundleExtInfo.bundleInfo_.name; @@ -349,12 +351,12 @@ vector BundleMgrAdapter::GetBundleInfosForIncrement HILOGI("Unsupported applications, name : %{public}s", installedBundle.name.data()); continue; } - auto [allToBackup, fullBackupOnly, extName, restoreDeps, supportScene, extraInfo] = + auto [allToBackup, fullBackupOnly, extName, restoreDeps, supportScene, extraInfo, requireCompatibility] = GetAllowAndExtName(installedBundle.extensionInfos); if (!allToBackup) { bundleInfos.emplace_back(BJsonEntityCaps::BundleInfo {installedBundle.name, installedBundle.appIndex, installedBundle.versionCode, installedBundle.versionName, 0, 0, allToBackup, fullBackupOnly, - extName, restoreDeps, supportScene, extraInfo}); + requireCompatibility, extName, restoreDeps, supportScene, extraInfo}); continue; } auto it = std::find_if(extraIncreData.begin(), extraIncreData.end(), @@ -404,13 +406,13 @@ vector BundleMgrAdapter::GetFullBundleInfos(int32_t bundleNames.emplace_back(bundleNameIndexInfo); continue; } - auto [allToBackup, fullBackupOnly, extName, restoreDeps, supportScene, extraInfo] = + auto [allToBackup, fullBackupOnly, extName, restoreDeps, supportScene, extraInfo, requireCompatibility] = GetAllowAndExtName(installedBundle.extensionInfos); if (!allToBackup) { HILOGI("Not allToBackup, bundleName = %{public}s", installedBundle.name.data()); bundleInfos.emplace_back(BJsonEntityCaps::BundleInfo {installedBundle.name, installedBundle.appIndex, - installedBundle.versionCode, installedBundle.versionName, 0, 0, allToBackup, fullBackupOnly, extName, - restoreDeps, supportScene, extraInfo}); + installedBundle.versionCode, installedBundle.versionName, 0, 0, allToBackup, fullBackupOnly, + requireCompatibility, extName, restoreDeps, supportScene, extraInfo}); continue; } bundleNames.emplace_back(installedBundle.name); @@ -464,7 +466,7 @@ std::vector BundleMgrAdapter::GetBundleInfosForSA() HILOGI("GetExtensionSaIds ret: %{public}d", ret); for (const auto &saId : saIds) { saBundleInfos.emplace_back(BJsonEntityCaps::BundleInfo {std::to_string(saId), 0, 0, "", 0, 0, true, false, - "", "", "", ""}); + false, "", "", "", ""}); } return saBundleInfos; } @@ -493,7 +495,8 @@ void BundleMgrAdapter::GetBundleInfoForSA(std::string bundleName, std::vector BundleMgrAdapter::GetBundleInfosForLoca bundleNames.emplace_back(bundleNameIndexInfo); continue; } - auto [allToBackup, fullBackupOnly, extName, restoreDeps, supportScene, extraInfo] = + auto [allToBackup, fullBackupOnly, extName, restoreDeps, supportScene, extraInfo, requireCompatibility] = GetAllowAndExtName(installedBundle.extensionInfos); if (!allToBackup) { HILOGI("Not allToBackup, bundleName = %{public}s, appIndex = %{public}d", @@ -601,7 +604,7 @@ std::vector BundleMgrAdapter::GetBundleInfosForLoca bundleInfos.emplace_back(BJsonEntityCaps::BundleInfo { installedBundle.name, installedBundle.appIndex, installedBundle.versionCode, installedBundle.versionName, - 0, 0, allToBackup, fullBackupOnly, + 0, 0, allToBackup, fullBackupOnly, requireCompatibility, extName, restoreDeps, supportScene, extraInfo}); } auto bundleInfosIndex = GetBundleInfosForIndex(bundleNames, userId); @@ -625,7 +628,7 @@ std::vector BundleMgrAdapter::GetBundleInfosForInde HILOGE("Get current extension failed, bundleName:%{public}s", bundleName.c_str()); continue; } - auto [allToBackup, fullBackupOnly, extName, restoreDeps, supportScene, extraInfo] = + auto [allToBackup, fullBackupOnly, extName, restoreDeps, supportScene, extraInfo, requireCompatibility] = GetAllowAndExtName(bundleExtInfo.extensionInfos_); if (!allToBackup) { HILOGI("Not allToBackup, bundleName = %{public}s, appIndex = %{public}d", @@ -635,7 +638,7 @@ std::vector BundleMgrAdapter::GetBundleInfosForInde bundleInfos.emplace_back(BJsonEntityCaps::BundleInfo { bundleExtInfo.bundleInfo_.name, bundleExtInfo.bundleInfo_.appIndex, bundleExtInfo.bundleInfo_.versionCode, bundleExtInfo.bundleInfo_.versionName, - 0, 0, allToBackup, fullBackupOnly, + 0, 0, allToBackup, fullBackupOnly, requireCompatibility, extName, restoreDeps, supportScene, extraInfo}); } HILOGI("End, bundleInfos size:%{public}zu", bundleInfos.size()); @@ -699,7 +702,8 @@ std::vector BundleMgrAdapter::GetBundleInfosForAppe bundleInfos.emplace_back(BJsonEntityCaps::BundleInfo {bundleExtInfo.bundleInfo_.name, bundleExtInfo.bundleInfo_.appIndex, bundleExtInfo.bundleInfo_.versionCode, bundleExtInfo.bundleInfo_.versionName, 0, 0, backupPara.allToBackup, backupPara.fullBackupOnly, - backupPara.extensionName, backupPara.restoreDeps, backupPara.supportScene, backupPara.extraInfo}); + backupPara.requireCompatibility, backupPara.extensionName, backupPara.restoreDeps, backupPara.supportScene, + backupPara.extraInfo}); } for (const auto &info : incrementalDataList) { if (SAUtils::IsSABundleName(info.bundleName)) { diff --git a/services/backup_sa/src/module_ipc/sub_service.cpp b/services/backup_sa/src/module_ipc/sub_service.cpp index 897c9bf1544b2a0e87a49de4240ff99cdeaafe43..d26e879c5aad864d037acef05d70a9cdcb59809d 100644 --- a/services/backup_sa/src/module_ipc/sub_service.cpp +++ b/services/backup_sa/src/module_ipc/sub_service.cpp @@ -1532,4 +1532,51 @@ void Service::HandleOnReleaseAndDisconnect(sptr sessionPtr, c proxy->HandleOnRelease(static_cast(sessionPtr->GetScenario())); sessionConnection->DisconnectBackupExtAbility(); } + +ErrCode Service::GetCompatibilityInfo(const std::string &bundleName, const std::string &extInfo, + std::string &compatInfo) +{ + HILOGI("Service::GetCompatibilityInfo begin bundleName: %{public}s", bundleName.c_str()); + HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__); + ErrCode err = VerifyCaller(); + if (err != ERR_OK) { + HILOGE("VerifyCaller failed"); + return err; + } + if (SAUtils::IsSABundleName(bundleName)) { + HILOGE("SA not support"); + return BError(BError::Codes::SA_INVAL_ARG); + } + if (session_ == nullptr) { + HILOGE("session is empty or busy"); + return BError(BError::Codes::SA_INVAL_ARG); + } + sptr backupConnection; + err = TryToConnectExt(bundleName, backupConnection); + if (err != BError(BError::Codes::OK)) { + return err; + } + std::unique_lock lock(getBackupInfoSyncLock_); + getBackupInfoCondition_.wait_for(lock, std::chrono::seconds(CONNECT_WAIT_TIME_S)); + if (isConnectDied_.load()) { + HILOGE("backupConnection connect timeout"); + isConnectDied_.store(false); + return BError(BError::Codes::EXT_ABILITY_DIED); + } + session_->IncreaseSessionCnt(__PRETTY_FUNCTION__); + auto proxy = backupConnection->GetBackupExtProxy(); + if (!proxy) { + HILOGE("Extension backup Proxy is empty."); + backupConnection->DisconnectBackupExtAbility(); + session_->DecreaseSessionCnt(__PRETTY_FUNCTION__); + return BError(BError::Codes::SA_INVAL_ARG); + } + err = proxy->HandleGetCompatibilityInfo(extInfo, static_cast(session_->GetScenario()), compatInfo); + if (err != BError(BError::Codes::OK)) { + HILOGE("HandleGetCompatibilityInfo failed"); + } + backupConnection->DisconnectBackupExtAbility(); + session_->DecreaseSessionCnt(__PRETTY_FUNCTION__); + return err; +} } \ No newline at end of file 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 5838cdaf7769ff70174ebcd04a137706f7636707..e8cf5e60c7befb18ca20e3a19e66f0840171497c 100644 --- a/tests/mock/backup_ext/include/ext_backup_js_mock.h +++ b/tests/mock/backup_ext/include/ext_backup_js_mock.h @@ -52,6 +52,9 @@ public: virtual void ExportJsContext() = 0; virtual ErrCode OnRelease(std::function, int32_t scenario) = 0; virtual std::function &argv) ParseReleaseInfo() = 0; + virtual ErrCode GetBackupCompatibilityInfo(std::function, std::string) = 0; + virtual ErrCode GetRestoreCompatibilityInfo(std::function, std::string) = 0; + virtual std::function &argv) ParseCompatibilityInfo() = 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 6e966d6e56f23003e2048637f8b88ee6345f4e0d..5fec0f97125189ed7b3ec014c65a850ed9346248 100644 --- a/tests/mock/backup_ext/include/ext_backup_mock.h +++ b/tests/mock/backup_ext/include/ext_backup_mock.h @@ -53,6 +53,8 @@ public: virtual ErrCode GetParament(const AAFwk::Want &) = 0; virtual ErrCode OnProcess(std::function callback) = 0; virtual ErrCode OnRelease(std::function callback, int32_t scenario) = 0; + virtual ErrCode GetBackupCompatibilityInfo(std::function, std::string) = 0; + virtual ErrCode GetRestoreCompatibilityInfo(std::function, std::string) = 0; virtual void SetBackupExtExtension(const wptr &) = 0; public: virtual std::unique_ptr LoadSystemModuleByEngine(napi_env, const std::string&, const napi_value*, @@ -100,6 +102,8 @@ public: 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)); + MOCK_METHOD(ErrCode, GetBackupCompatibilityInfo, (std::function, std::string)); + MOCK_METHOD(ErrCode, GetRestoreCompatibilityInfo, (std::function, std::string)); MOCK_METHOD(void, SetBackupExtExtension, (const wptr &)); public: MOCK_METHOD((std::unique_ptr), LoadSystemModuleByEngine, (napi_env, const std::string&, 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 3d64f12e9509bbf31b8af2aeb5e43499c688a733..ea41e0363b7a49c1e370f6a7067a3582a41314f4 100644 --- a/tests/mock/backup_ext/src/ext_backup_js_mock.cpp +++ b/tests/mock/backup_ext/src/ext_backup_js_mock.cpp @@ -108,4 +108,21 @@ ErrCode ExtBackupJs::OnRelease(function callback, int32_t { return BExtBackupJs::extBackupJs->OnRelease(callback, scenario); } + +ErrCode ExtBackupJs::GetBackupCompatibilityInfo(std::function callbackEx, + std::string extInfo) +{ + return BExtBackupJs::extBackupJs->GetBackupCompatibilityInfo(callbackEx, extInfo); +} + +ErrCode ExtBackupJs::GetRestoreCompatibilityInfo(std::function callbackEx, + std::string extInfo) +{ + return BExtBackupJs::extBackupJs->GetRestoreCompatibilityInfo(callbackEx, extInfo); +} + +std::function &argv)> ExtBackupJs::ParseCompatibilityInfo() +{ + return BExtBackupJs::extBackupJs->ParseCompatibilityInfo(); +} } // 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 9e76eb794cb940fb7cb23be0cf785c25b0a174c6..f2631eb9e7cd203c29886d44c05f7835309e9bfb 100644 --- a/tests/mock/backup_ext/src/ext_backup_mock.cpp +++ b/tests/mock/backup_ext/src/ext_backup_mock.cpp @@ -144,6 +144,18 @@ ErrCode ExtBackup::OnRelease(function callback, int3 return BExtBackup::extBackup->OnRelease(callback, scenario); } +ErrCode ExtBackup::GetBackupCompatibilityInfo(std::function callbackEx, + std::string extInfo) +{ + return BExtBackup::extBackup->GetBackupCompatibilityInfo(callbackEx, extInfo); +} + +ErrCode ExtBackup::GetRestoreCompatibilityInfo(std::function callbackEx, + std::string extInfo) +{ + return BExtBackup::extBackup->GetRestoreCompatibilityInfo(callbackEx, extInfo); +} + void ExtBackup::SetBackupExtExtension(const wptr &extExtension) { BExtBackup::extBackup->SetBackupExtExtension(extExtension); diff --git a/tests/mock/backup_kit_inner/service_proxy_mock.cpp b/tests/mock/backup_kit_inner/service_proxy_mock.cpp index fe62af42ec069eb39427fcb0da4e4b056feb5d42..e605bfbf5969f432b158313c11d2f2b22fc004e8 100644 --- a/tests/mock/backup_kit_inner/service_proxy_mock.cpp +++ b/tests/mock/backup_kit_inner/service_proxy_mock.cpp @@ -286,4 +286,10 @@ ErrCode ServiceProxy::GetExtOnRelease(bool &isExtOnRelease) { return BError(BError::Codes::OK); } + +ErrCode ServiceProxy::GetCompatibilityInfo(const std::string &bundleName, const std::string &extInfo, + std::string &compatInfo) +{ + return BError(BError::Codes::OK); +} } // namespace OHOS::FileManagement::Backup \ No newline at end of file diff --git a/tests/mock/module_external/bms_adapter_mock.cpp b/tests/mock/module_external/bms_adapter_mock.cpp index 83f98eace9c6da9f8e7640efded5c3e332d45bcd..9694e08bc5ed34dfe9de0bdc76e1296a2fed9345 100644 --- a/tests/mock/module_external/bms_adapter_mock.cpp +++ b/tests/mock/module_external/bms_adapter_mock.cpp @@ -32,7 +32,7 @@ vector BundleMgrAdapter::GetBundleInfos(const vecto { vector bundleInfos; bundleInfos.emplace_back( - BJsonEntityCaps::BundleInfo {"com.example.app2backup", 0, {}, {}, 0, 0, true, false, + BJsonEntityCaps::BundleInfo {"com.example.app2backup", 0, {}, {}, 0, 0, true, false, false, "com.example.app2backup"}); return bundleInfos; } @@ -47,7 +47,7 @@ vector BundleMgrAdapter::GetBundleInfosForIncrement { vector bundleInfos; bundleInfos.emplace_back( - BJsonEntityCaps::BundleInfo {"com.example.app2backup", 0, {}, {}, 0, 0, true, false, + BJsonEntityCaps::BundleInfo {"com.example.app2backup", 0, {}, {}, 0, 0, true, false, false, "com.example.app2backup"}); return bundleInfos; } @@ -57,7 +57,7 @@ vector BundleMgrAdapter::GetBundleInfosForIncrement { vector bundleInfos; bundleInfos.emplace_back( - BJsonEntityCaps::BundleInfo {"com.example.app2backup", 0, {}, {}, 0, 0, true, false, + BJsonEntityCaps::BundleInfo {"com.example.app2backup", 0, {}, {}, 0, 0, true, false, false, "com.example.app2backup"}); return bundleInfos; } @@ -67,7 +67,7 @@ vector BundleMgrAdapter::GetFullBundleInfos(int32_t { vector bundleInfos; bundleInfos.emplace_back( - BJsonEntityCaps::BundleInfo {"com.example.app2backup", 0, {}, {}, 0, 0, true, false, + BJsonEntityCaps::BundleInfo {"com.example.app2backup", 0, {}, {}, 0, 0, true, false, false, "com.example.app2backup"}); return bundleInfos; } @@ -87,7 +87,7 @@ vector BundleMgrAdapter::GetBundleInfosForAppend( { vector bundleInfos; bundleInfos.emplace_back( - BJsonEntityCaps::BundleInfo {"com.example.app2backup", 0, {}, {}, 0, 0, true, false, + BJsonEntityCaps::BundleInfo {"com.example.app2backup", 0, {}, {}, 0, 0, true, false, false, "com.example.app2backup"}); return bundleInfos; } @@ -96,7 +96,7 @@ std::vector BundleMgrAdapter::GetBundleInfosForLoca { vector bundleInfos; bundleInfos.emplace_back( - BJsonEntityCaps::BundleInfo {"com.example.app2backup", 0, {}, {}, 0, 0, true, false, + BJsonEntityCaps::BundleInfo {"com.example.app2backup", 0, {}, {}, 0, 0, true, false, false, "com.example.app2backup"}); return bundleInfos; } @@ -106,7 +106,7 @@ std::vector BundleMgrAdapter::GetBundleInfosForInde { vector bundleInfos; bundleInfos.emplace_back( - BJsonEntityCaps::BundleInfo {"com.example.app2backup", 0, {}, {}, 0, 0, true, false, + BJsonEntityCaps::BundleInfo {"com.example.app2backup", 0, {}, {}, 0, 0, true, false, false, "com.example.app2backup"}); return bundleInfos; } @@ -123,7 +123,7 @@ vector BundleMgrAdapter::GetBundleInfosForAppendBun { vector bundleInfos; bundleInfos.emplace_back( - BJsonEntityCaps::BundleInfo {"com.example.app2backup", 0, {}, {}, 0, 0, true, false, + BJsonEntityCaps::BundleInfo {"com.example.app2backup", 0, {}, {}, 0, 0, true, false, false, "com.example.app2backup"}); return bundleInfos; } 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 eb5600d4f5a113ea18caef96efd8562b4d26e950..ed98bfdd30296e55f16b267cfd97f4e8f29be98b 100644 --- a/tests/mock/module_ipc/include/svc_extension_proxy_mock.h +++ b/tests/mock/module_ipc/include/svc_extension_proxy_mock.h @@ -41,6 +41,7 @@ MOCK_METHOD(ErrCode, User0OnBackup, ()); MOCK_METHOD(ErrCode, UpdateDfxInfo, (int64_t, uint32_t, const std::string &)); MOCK_METHOD(ErrCode, CleanBundleTempDir, ()); MOCK_METHOD(ErrCode, HandleOnRelease, (int32_t)); +MOCK_METHOD(ErrCode, HandleGetCompatibilityInfo, (const std::string &, int32_t, std::string &)); }; } // 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 ed5c558fe6815869cba61c869ec40a487fc135a2..ff713dbb0e65b44b66450b6f4e69148b2343167f 100644 --- a/tests/mock/module_ipc/service_mock.cpp +++ b/tests/mock/module_ipc/service_mock.cpp @@ -450,4 +450,10 @@ ErrCode Service::GetExtOnRelease(bool &isExtOnRelease) { return BError(BError::Codes::OK); } + +ErrCode Service::GetCompatibilityInfo(const std::string &bundleName, const std::string &extInfo, + std::string &compatInfo) +{ + 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 00a120b78a6f4a329059a74f869a17a000daeb72..75891ebe2f21716ff2fc2c53bb87c666205d6e3f 100644 --- a/tests/mock/module_ipc/svc_extension_proxy_mock.cpp +++ b/tests/mock/module_ipc/svc_extension_proxy_mock.cpp @@ -98,4 +98,10 @@ ErrCode ExtensionProxy::HandleOnRelease(int32_t scenario) { return 0; } + +ErrCode ExtensionProxy::HandleGetCompatibilityInfo(const std::string &extInfo, int32_t scenario, + std::string &compatibilityInfo) +{ + return 0; +} } // namespace OHOS::FileManagement::Backup \ No newline at end of file diff --git a/tests/moduletests/backup_kit_inner/b_session_backup_test.cpp b/tests/moduletests/backup_kit_inner/b_session_backup_test.cpp index 727593169b963269156dc0efc9194f812601b4ef..5c616fb1275dd31ca2ac00525d9de6f64cbcc3c5 100644 --- a/tests/moduletests/backup_kit_inner/b_session_backup_test.cpp +++ b/tests/moduletests/backup_kit_inner/b_session_backup_test.cpp @@ -509,4 +509,35 @@ HWTEST_F(BSessionBackupTest, SUB_backup_b_session_backup_1300, testing::ext::Tes } GTEST_LOG_(INFO) << "BSessionBackupTest-end SUB_backup_b_session_backup_1300"; } + +/** + * @tc.number: SUB_BSessionBackup_GetCompatibilityInfo_0000 + * @tc.name: SUB_BSessionBackup_GetCompatibilityInfo_0000 + * @tc.desc: 测试 GetCompatibilityInfo 接口 + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + * @tc.require: NA + */ +HWTEST_F(BSessionBackupTest, SUB_BSessionBackup_GetCompatibilityInfo_0000, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "BSessionBackupTest-begin SUB_BSessionBackup_GetCompatibilityInfo_0000"; + try { + ASSERT_TRUE(backupPtr_ != nullptr); + std::string bundleName = "com.example.app"; + std::string extInfo = ""; + std::string compatInfo = ""; + SetMockGetInstance(false); + auto err = backupPtr_->GetCompatibilityInfo(bundleName, extInfo, compatInfo); + EXPECT_EQ(err, BError(BError::Codes::SDK_BROKEN_IPC).GetCode()); + + SetMockGetInstance(true); + err = backupPtr_->GetCompatibilityInfo(bundleName, extInfo, compatInfo); + EXPECT_EQ(err, ERR_OK); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "BSessionBackupTest-an exception occurred by GetCompatibilityInfo."; + } + GTEST_LOG_(INFO) << "BSessionBackupTest-end SUB_BSessionBackup_GetCompatibilityInfo_0000"; +} } // namespace OHOS::FileManagement::Backup \ No newline at end of file diff --git a/tests/moduletests/backup_kit_inner/b_session_restore_test.cpp b/tests/moduletests/backup_kit_inner/b_session_restore_test.cpp index cfac6d5a464857b7c65e9720b52b2c6d96dc2856..526da23547560f374a8a9b79d0c2ad8bd6352cb0 100644 --- a/tests/moduletests/backup_kit_inner/b_session_restore_test.cpp +++ b/tests/moduletests/backup_kit_inner/b_session_restore_test.cpp @@ -545,4 +545,35 @@ HWTEST_F(BSessionRestoreTest, SUB_backup_b_session_restore_1200, testing::ext::T } GTEST_LOG_(INFO) << "BSessionRestoreTest-end SUB_backup_b_session_restore_1200"; } + +/** + * @tc.number: SUB_BSessionRestore_GetCompatibilityInfo_0000 + * @tc.name: SUB_BSessionRestore_GetCompatibilityInfo_0000 + * @tc.desc: 测试 GetCompatibilityInfo 接口 + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + * @tc.require: NA + */ +HWTEST_F(BSessionRestoreTest, SUB_BSessionRestore_GetCompatibilityInfo_0000, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "BSessionRestoreTest-begin SUB_BSessionRestore_GetCompatibilityInfo_0000"; + try { + ASSERT_TRUE(restorePtr_ != nullptr); + std::string bundleName = "com.example.app"; + std::string extInfo = ""; + std::string compatInfo = ""; + SetMockGetInstance(false); + auto err = restorePtr_->GetCompatibilityInfo(bundleName, extInfo, compatInfo); + EXPECT_EQ(err, BError(BError::Codes::SDK_BROKEN_IPC).GetCode()); + + SetMockGetInstance(true); + err = restorePtr_->GetCompatibilityInfo(bundleName, extInfo, compatInfo); + EXPECT_EQ(err, ERR_OK); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "BSessionRestoreTest-an exception occurred by GetCompatibilityInfo."; + } + GTEST_LOG_(INFO) << "BSessionRestoreTest-end SUB_BSessionRestore_GetCompatibilityInfo_0000"; +} } // 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 79604825a7f9442abf04d1dc896e5dffef07d89b..38411a68e453c27abc5dabbb532f28c8c1caed9b 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 @@ -179,6 +179,12 @@ public: { return BError(BError::Codes::OK); }; + + ErrCode HandleGetCompatibilityInfo(const std::string &extInfo, int32_t scenario, + std::string &compatibilityInfo) 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 7f2c4e24ae912d733a313de1fb38a56a53da273e..6745527d428eea3f0e888c3324548af8d999e943 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 @@ -282,6 +282,11 @@ public: { return BError(BError::Codes::OK); }; + + ErrCode GetCompatibilityInfo(const std::string &bundleName, const std::string &extInfo, std::string &compatInfo) + { + 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_ext/ext_backup_js_test.cpp b/tests/unittests/backup_ext/ext_backup_js_test.cpp index df44d0ac8cfdec2c2ada82bf22803e18d81baff4..0605fb56f9eb7ea31b13a14e18ae9e535b359a98 100644 --- a/tests/unittests/backup_ext/ext_backup_js_test.cpp +++ b/tests/unittests/backup_ext/ext_backup_js_test.cpp @@ -1666,4 +1666,165 @@ HWTEST_F(ExtBackupJsTest, SUB_backup_ext_js_OnRelease_0200, testing::ext::TestSi } GTEST_LOG_(INFO) << "ExtBackupJsTest-end SUB_backup_ext_js_OnRelease_0200"; } + +/** + * @tc.number: SUB_backup_ext_js_GetBackupCompatibilityInfo_0100 + * @tc.name: SUB_backup_ext_js_GetBackupCompatibilityInfo_0100 + * @tc.desc: 测试 GetBackupCompatibilityInfo 各个分支成功与失败 + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + * @tc.require: issuesIAFBOS + */ +HWTEST_F(ExtBackupJsTest, SUB_backup_ext_js_GetBackupCompatibilityInfo_0100, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "ExtBackupJsTest-begin SUB_backup_ext_js_GetBackupCompatibilityInfo_0100"; + try { + std::string extInfo = ""; + EXPECT_CALL(*extBackupMock, GetNapiEnv()).WillOnce(Return(nullptr)).WillOnce(Return(nullptr)); + EXPECT_CALL(*napiMock, napi_is_exception_pending(_, _)).WillOnce(Return(napi_ok)); + EXPECT_CALL(*napiMock, napi_get_value_string_utf8(_, _, _, _, _)).WillOnce(Return(napi_invalid_arg)); + EXPECT_CALL(*napiMock, napi_send_cancelable_event(_, _, _, _, _, _)).WillOnce(Return(napi_invalid_arg)); + auto ret = extBackupJs->GetBackupCompatibilityInfo([](ErrCode, std::string){}, extInfo); + EXPECT_EQ(ret, EINVAL); + + EXPECT_CALL(*extBackupMock, GetNapiEnv()).WillOnce(Return(nullptr)).WillOnce(Return(nullptr)); + EXPECT_CALL(*napiMock, napi_is_exception_pending(_, _)) + .WillOnce(DoAll(SetArgPointee(true), Return(napi_ok))); + EXPECT_CALL(*napiMock, napi_get_and_clear_last_exception(_, _)).WillOnce(Return(napi_invalid_arg)); + EXPECT_CALL(*napiMock, napi_send_cancelable_event(_, _, _, _, _, _)).WillOnce(Return(napi_invalid_arg)); + ret = extBackupJs->GetBackupCompatibilityInfo([](ErrCode, std::string){}, extInfo); + EXPECT_EQ(ret, EINVAL); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "ExtBackupJsTest-an exception occurred by GetBackupCompatibilityInfo."; + } + GTEST_LOG_(INFO) << "ExtBackupJsTest-end SUB_backup_ext_js_GetBackupCompatibilityInfo_0100"; +} + +/** + * @tc.number: SUB_backup_ext_js_GetBackupCompatibilityInfo_0200 + * @tc.name: SUB_backup_ext_js_GetBackupCompatibilityInfo_0200 + * @tc.desc: 测试 GetBackupCompatibilityInfo 各个分支成功与失败 + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + * @tc.require: issuesIAFBOS + */ +HWTEST_F(ExtBackupJsTest, SUB_backup_ext_js_GetBackupCompatibilityInfo_0200, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "ExtBackupJsTest-begin SUB_backup_ext_js_GetBackupCompatibilityInfo_0200"; + try { + std::string extInfo = ""; + EXPECT_CALL(*extBackupMock, GetNapiEnv()).WillOnce(Return(nullptr)).WillOnce(Return(nullptr)); + EXPECT_CALL(*napiMock, napi_is_promise(_, _, _)) + .WillOnce(DoAll(SetArgPointee(true), Return(napi_ok))); + EXPECT_CALL(*napiMock, napi_open_handle_scope(_, _)).WillOnce(Return(napi_ok)); + EXPECT_CALL(*napiMock, napi_close_handle_scope(_, _)).WillOnce(Return(napi_ok)); + EXPECT_CALL(*napiMock, napi_get_named_property(_, _, _, _)).WillOnce(Return(napi_invalid_arg)); + EXPECT_CALL(*napiMock, napi_send_cancelable_event(_, _, _, _, _, _)).WillOnce(Return(napi_invalid_arg)); + auto ret = extBackupJs->GetBackupCompatibilityInfo([](ErrCode, std::string){}, extInfo); + EXPECT_EQ(ret, EINVAL); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "ExtBackupJsTest-an exception occurred by GetBackupCompatibilityInfo."; + } + GTEST_LOG_(INFO) << "ExtBackupJsTest-end SUB_backup_ext_js_GetBackupCompatibilityInfo_0200"; +} + +/** + * @tc.number: SUB_backup_ext_js_GetRestoreCompatibilityInfo_0100 + * @tc.name: SUB_backup_ext_js_GetRestoreCompatibilityInfo_0100 + * @tc.desc: 测试 GetRestoreCompatibilityInfo 各个分支成功与失败 + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + * @tc.require: issuesIAFBOS + */ +HWTEST_F(ExtBackupJsTest, SUB_backup_ext_js_GetRestoreCompatibilityInfo_0100, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "ExtBackupJsTest-begin SUB_backup_ext_js_GetRestoreCompatibilityInfo_0100"; + try { + std::string extInfo = ""; + EXPECT_CALL(*extBackupMock, GetNapiEnv()).WillOnce(Return(nullptr)).WillOnce(Return(nullptr)); + EXPECT_CALL(*napiMock, napi_is_exception_pending(_, _)).WillOnce(Return(napi_ok)); + EXPECT_CALL(*napiMock, napi_get_value_string_utf8(_, _, _, _, _)).WillOnce(Return(napi_invalid_arg)); + EXPECT_CALL(*napiMock, napi_send_cancelable_event(_, _, _, _, _, _)).WillOnce(Return(napi_invalid_arg)); + auto ret = extBackupJs->GetRestoreCompatibilityInfo([](ErrCode, std::string){}, extInfo); + EXPECT_EQ(ret, EINVAL); + + EXPECT_CALL(*extBackupMock, GetNapiEnv()).WillOnce(Return(nullptr)).WillOnce(Return(nullptr)); + EXPECT_CALL(*napiMock, napi_is_exception_pending(_, _)) + .WillOnce(DoAll(SetArgPointee(true), Return(napi_ok))); + EXPECT_CALL(*napiMock, napi_get_and_clear_last_exception(_, _)).WillOnce(Return(napi_invalid_arg)); + EXPECT_CALL(*napiMock, napi_send_cancelable_event(_, _, _, _, _, _)).WillOnce(Return(napi_invalid_arg)); + ret = extBackupJs->GetRestoreCompatibilityInfo([](ErrCode, std::string){}, extInfo); + EXPECT_EQ(ret, EINVAL); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "ExtBackupJsTest-an exception occurred by GetRestoreCompatibilityInfo."; + } + GTEST_LOG_(INFO) << "ExtBackupJsTest-end SUB_backup_ext_js_GetRestoreCompatibilityInfo_0100"; +} + +/** + * @tc.number: SUB_backup_ext_js_GetRestoreCompatibilityInfo_0200 + * @tc.name: SUB_backup_ext_js_GetRestoreCompatibilityInfo_0200 + * @tc.desc: 测试 GetRestoreCompatibilityInfo 各个分支成功与失败 + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + * @tc.require: issuesIAFBOS + */ +HWTEST_F(ExtBackupJsTest, SUB_backup_ext_js_GetRestoreCompatibilityInfo_0200, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "ExtBackupJsTest-begin SUB_backup_ext_js_GetRestoreCompatibilityInfo_0200"; + try { + std::string extInfo = ""; + EXPECT_CALL(*extBackupMock, GetNapiEnv()).WillOnce(Return(nullptr)).WillOnce(Return(nullptr)); + EXPECT_CALL(*napiMock, napi_is_promise(_, _, _)) + .WillOnce(DoAll(SetArgPointee(true), Return(napi_ok))); + EXPECT_CALL(*napiMock, napi_open_handle_scope(_, _)).WillOnce(Return(napi_ok)); + EXPECT_CALL(*napiMock, napi_close_handle_scope(_, _)).WillOnce(Return(napi_ok)); + EXPECT_CALL(*napiMock, napi_get_named_property(_, _, _, _)).WillOnce(Return(napi_invalid_arg)); + EXPECT_CALL(*napiMock, napi_send_cancelable_event(_, _, _, _, _, _)).WillOnce(Return(napi_invalid_arg)); + auto ret = extBackupJs->GetRestoreCompatibilityInfo([](ErrCode, std::string){}, extInfo); + EXPECT_EQ(ret, EINVAL); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "ExtBackupJsTest-an exception occurred by GetRestoreCompatibilityInfo."; + } + GTEST_LOG_(INFO) << "ExtBackupJsTest-end SUB_backup_ext_js_GetRestoreCompatibilityInfo_0200"; +} + +/** + * @tc.number: SUB_backup_ext_js_ParseCompatibilityInfo_0100 + * @tc.name: SUB_backup_ext_js_ParseCompatibilityInfo_0100 + * @tc.desc: 测试 ParseCompatibilityInfo 各个分支成功与失败 + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + * @tc.require: issuesIAFBOS + */ +HWTEST_F(ExtBackupJsTest, SUB_backup_ext_js_ParseCompatibilityInfo_0100, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "ExtBackupJsTest-begin SUB_backup_ext_js_ParseCompatibilityInfo_0100"; + try { + std::vector argv; + auto ext = extBackupJs->extInfo_; + extBackupJs->extInfo_ = "ext_info"; + EXPECT_CALL(*napiMock, napi_create_string_utf8(_, _, _, _)).WillOnce(Return(napi_ok)); + auto ret = extBackupJs->ParseCompatibilityInfo()(nullptr, argv); + EXPECT_TRUE(ret); + + EXPECT_CALL(*napiMock, napi_create_string_utf8(_, _, _, _)).WillOnce(Return(napi_invalid_arg)); + ret = extBackupJs->ParseCompatibilityInfo()(nullptr, argv); + extBackupJs->extInfo_ = ext; + EXPECT_FALSE(ret); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "ExtBackupJsTest-an exception occurred by ParseCompatibilityInfo."; + } + GTEST_LOG_(INFO) << "ExtBackupJsTest-end SUB_backup_ext_js_ParseCompatibilityInfo_0100"; +} } // namespace OHOS::FileManagement::Backup \ No newline at end of file diff --git a/tests/unittests/backup_ext/ext_extension_sub_test.cpp b/tests/unittests/backup_ext/ext_extension_sub_test.cpp index 106e8e2e399fdec409363c2cedfda61f3f79da03..ea5461cb823ca66720c131b17c4532673fbad32c 100644 --- a/tests/unittests/backup_ext/ext_extension_sub_test.cpp +++ b/tests/unittests/backup_ext/ext_extension_sub_test.cpp @@ -141,4 +141,83 @@ HWTEST_F(ExtExtensionSubTest, Ext_Extension_Sub_Test_0001, testing::ext::TestSiz } GTEST_LOG_(INFO) << "ExtExtensionSubTest-end Ext_Extension_Sub_Test_0001"; } + +/** + * @tc.number: Ext_Extension_Sub_GetComInfoCallback_Test_0100 + * @tc.name: Ext_Extension_Sub_GetComInfoCallback_Test_0100 + * @tc.desc: 测试GetComInfoCallback + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + * @tc.require: I9P3Y3 + */ +HWTEST_F(ExtExtensionSubTest, Ext_Extension_Sub_GetComInfoCallback_Test_0100, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "ExtExtensionSubTest-begin Ext_Extension_Sub_GetComInfoCallback_Test_0100"; + try { + std::string compatibilityInfo = "test"; + extExtension->GetComInfoCallback(nullptr)(BError(BError::Codes::OK).GetCode(), compatibilityInfo); + EXPECT_NE(extExtension->compatibilityInfo_, compatibilityInfo); + + auto extensionTmp = extExtension->extension_; + extExtension->extension_ = nullptr; + auto ptr = wptr(extExtension); + extExtension->GetComInfoCallback(ptr)(BError(BError::Codes::OK).GetCode(), compatibilityInfo); + extExtension->extension_ = extensionTmp; + EXPECT_NE(extExtension->compatibilityInfo_, compatibilityInfo); + + bool stopGetComInfo = extExtension->stopGetComInfo_.load(); + extExtension->stopGetComInfo_.store(true); + extExtension->GetComInfoCallback(ptr)(BError(BError::Codes::OK).GetCode(), compatibilityInfo); + extExtension->stopGetComInfo_.store(stopGetComInfo); + EXPECT_NE(extExtension->compatibilityInfo_, compatibilityInfo); + + extExtension->stopGetComInfo_.store(false); + extExtension->GetComInfoCallback(ptr)(BError(BError::Codes::OK).GetCode(), compatibilityInfo); + extExtension->stopGetComInfo_.store(stopGetComInfo); + EXPECT_EQ(extExtension->compatibilityInfo_, compatibilityInfo); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "ExtExtensionSubTest-an exception occurred by construction."; + } + GTEST_LOG_(INFO) << "ExtExtensionSubTest-end Ext_Extension_Sub_GetComInfoCallback_Test_0100"; +} + +/** + * @tc.number: Ext_Extension_Sub_HandleGetCompatibilityInfo_Test_0100 + * @tc.name: Ext_Extension_Sub_HandleGetCompatibilityInfo_Test_0100 + * @tc.desc: 测试HandleGetCompatibilityInfo + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + * @tc.require: I9P3Y3 + */ +HWTEST_F(ExtExtensionSubTest, Ext_Extension_Sub_HandleGetCompatibilityInfo_Test_0100, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "ExtExtensionSubTest-begin Ext_Extension_Sub_HandleGetCompatibilityInfo_Test_0100"; + try { + std::string extInfo = "test"; + std::string compatibilityInfo = ""; + int32_t scenario = BConstants::ExtensionScenario::BACKUP; + auto ret = extExtension->HandleGetCompatibilityInfo(extInfo, scenario, compatibilityInfo); + EXPECT_EQ(ret, BError(BError::Codes::OK).GetCode()); + + scenario = BConstants::ExtensionScenario::RESTORE; + ret = extExtension->HandleGetCompatibilityInfo(extInfo, scenario, compatibilityInfo); + EXPECT_EQ(ret, BError(BError::Codes::OK).GetCode()); + + scenario = BConstants::ExtensionScenario::INVALID; + ret = extExtension->HandleGetCompatibilityInfo(extInfo, scenario, compatibilityInfo); + EXPECT_EQ(ret, BError(BError::Codes::EXT_INVAL_ARG).GetCode()); + + EXPECT_CALL(*extBackupMock, GetBackupCompatibilityInfo(_, _)) + .WillOnce(Return(BError(BError::Codes::EXT_INVAL_ARG).GetCode())); + ret = extExtension->HandleGetCompatibilityInfo(extInfo, scenario, compatibilityInfo); + EXPECT_EQ(ret, BError(BError::Codes::EXT_INVAL_ARG).GetCode()); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "ExtExtensionSubTest-an exception occurred by construction."; + } + GTEST_LOG_(INFO) << "ExtExtensionSubTest-end Ext_Extension_Sub_HandleGetCompatibilityInfo_Test_0100"; +} } \ 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 314bcd04772f3ccc5e452a73cc0072cf46f8a8cc..918949c97432deda9e0e93aaf39ada7d2b451bdf 100644 --- a/tests/unittests/backup_sa/module_ipc/service_incremental_test.cpp +++ b/tests/unittests/backup_sa/module_ipc/service_incremental_test.cpp @@ -81,6 +81,7 @@ public: virtual ErrCode GetExtOnRelease(bool&) = 0; virtual void SetExtOnRelease(const BundleName&, bool) = 0; virtual void RemoveExtOnRelease(const BundleName&) = 0; + virtual ErrCode GetCompatibilityInfo(const std::string&, const std::string&, std::string&) = 0; public: virtual bool UpdateToRestoreBundleMap(const string&, const string&) = 0; public: @@ -141,6 +142,7 @@ public: MOCK_METHOD(ErrCode, GetExtOnRelease, (bool&)); MOCK_METHOD(void, SetExtOnRelease, (const BundleName&, bool)); MOCK_METHOD(void, RemoveExtOnRelease, (const BundleName&)); + MOCK_METHOD(ErrCode, GetCompatibilityInfo, (const std::string&, const std::string&, std::string&)); public: MOCK_METHOD(bool, UpdateToRestoreBundleMap, (const string&, const string&)); }; @@ -478,6 +480,12 @@ void Service::RemoveExtOnRelease(const BundleName &bundleName) { return BService::serviceMock->RemoveExtOnRelease(bundleName); } + +ErrCode Service::GetCompatibilityInfo(const std::string &bundleName, const std::string &extInfo, + std::string &compatInfo) +{ + return BService::serviceMock->GetCompatibilityInfo(bundleName, extInfo, compatInfo); +} } // namespace OHOS::FileManagement::Backup namespace OHOS::FileManagement::Backup { 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 8dd2ecd8169adf678ef1a52bfc437663a1a4e1e3..57a64d87fd04e16eb4631bdd7eb3d5f24b4f5a39 100644 --- a/tests/unittests/backup_sa/module_ipc/service_other_test.cpp +++ b/tests/unittests/backup_sa/module_ipc/service_other_test.cpp @@ -947,7 +947,7 @@ HWTEST_F(ServiceTest, SUB_Service_SetCurrentSessProperties_0100, TestSize.Level1 service->session_ = sptr(new SvcSessionManager(wptr(service))); service->SetCurrentSessProperties(info, isClearDataFlags, bundleNameIndexInfo); - info = BJsonEntityCaps::BundleInfo{BUNDLE_NAME, 0, {}, {}, 0, 0, true, false, BUNDLE_NAME}; + info = BJsonEntityCaps::BundleInfo {BUNDLE_NAME, 0, {}, {}, 0, 0, true, false, false, BUNDLE_NAME}; isClearDataFlags = {{BUNDLE_NAME, true}}; service->SetCurrentSessProperties(info, isClearDataFlags, bundleNameIndexInfo); } catch (...) { diff --git a/tests/unittests/backup_sa/module_ipc/sub_service_test.cpp b/tests/unittests/backup_sa/module_ipc/sub_service_test.cpp index 9c4d3fb16834396eb3cad1d2c30263ce8949281d..161dfe7c5ff79f2dcb8683ec330bb6458dc1a65d 100644 --- a/tests/unittests/backup_sa/module_ipc/sub_service_test.cpp +++ b/tests/unittests/backup_sa/module_ipc/sub_service_test.cpp @@ -2177,4 +2177,145 @@ HWTEST_F(ServiceTest, SUB_Service_GetExtOnRelease_0200, testing::ext::TestSize.L GTEST_LOG_(INFO) << "ServiceTest-an exception occurred by GetExtOnRelease."; } GTEST_LOG_(INFO) << "ServiceTest-end SUB_Service_GetExtOnRelease_0200"; +} + +/** + * @tc.number: SUB_Service_GetCompatibilityInfo_0000 + * @tc.name: SUB_Service_GetCompatibilityInfo_0000 + * @tc.desc: 测试 GetCompatibilityInfo 的正常/异常分支 + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + * @tc.require: NA + */ +HWTEST_F(ServiceTest, SUB_Service_GetCompatibilityInfo_0000, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "ServiceTest-begin SUB_Service_GetCompatibilityInfo_0000"; + try { + std::string bundleName = "com.ohos.test"; + std::string extInfo = ""; + std::string compatInfo = ""; + + EXPECT_CALL(*skeleton, GetCallingTokenID()).WillRepeatedly(Return(0)); + EXPECT_CALL(*token, GetTokenType(_)) + .WillRepeatedly(Return(Security::AccessToken::ATokenTypeEnum::TOKEN_NATIVE)); + EXPECT_CALL(*token, VerifyAccessToken(_, _)) + .WillOnce(Return(Security::AccessToken::PermissionState::PERMISSION_DENIED)) + .WillRepeatedly(Return(Security::AccessToken::PermissionState::PERMISSION_GRANTED)); + EXPECT_CALL(*param, GetBackupDebugOverrideAccount()) + .WillRepeatedly(Return(make_pair(true, DEBUG_ID + 1))); + EXPECT_CALL(*saUtils, IsSABundleName(_)).WillOnce(Return(true)); + + int res = service->GetCompatibilityInfo(bundleName, extInfo, compatInfo); + EXPECT_EQ(res, BError(BError::Codes::SA_REFUSED_ACT).GetCode()); + + res = service->GetCompatibilityInfo(bundleName, extInfo, compatInfo); + EXPECT_EQ(res, BError(BError::Codes::SA_INVAL_ARG).GetCode()); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "ServiceTest-an exception occurred by GetCompatibilityInfo."; + } + GTEST_LOG_(INFO) << "ServiceTest-end SUB_Service_GetCompatibilityInfo_0000"; +} + +/** + * @tc.number: SUB_Service_GetCompatibilityInfo_0100 + * @tc.name: SUB_Service_GetCompatibilityInfo_0100 + * @tc.desc: 测试 GetCompatibilityInfo 的正常/异常分支 + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + * @tc.require: NA + */ +HWTEST_F(ServiceTest, SUB_Service_GetCompatibilityInfo_0100, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "ServiceTest-begin SUB_Service_GetCompatibilityInfo_0100"; + try { + std::string bundleName = "com.ohos.test"; + std::string extInfo = ""; + std::string compatInfo = ""; + + EXPECT_CALL(*skeleton, GetCallingTokenID()).WillRepeatedly(Return(0)); + EXPECT_CALL(*token, GetTokenType(_)) + .WillRepeatedly(Return(Security::AccessToken::ATokenTypeEnum::TOKEN_NATIVE)); + EXPECT_CALL(*token, VerifyAccessToken(_, _)) + .WillRepeatedly(Return(Security::AccessToken::PermissionState::PERMISSION_GRANTED)); + EXPECT_CALL(*param, GetBackupDebugOverrideAccount()) + .WillRepeatedly(Return(make_pair(true, DEBUG_ID + 1))); + EXPECT_CALL(*saUtils, IsSABundleName(_)).WillRepeatedly(Return(false)); + + auto session_ = service->session_; + service->session_ = nullptr; + int res = service->GetCompatibilityInfo(bundleName, extInfo, compatInfo); + EXPECT_EQ(res, BError(BError::Codes::SA_INVAL_ARG).GetCode()); + service->session_ = session_; + + EXPECT_CALL(*session, GetExtConnection(_)).WillOnce(Return(nullptr)); + EXPECT_CALL(*session, CreateBackupConnection(_)).WillOnce(Return(nullptr)); + res = service->GetCompatibilityInfo(bundleName, extInfo, compatInfo); + EXPECT_EQ(res, BError(BError::Codes::SA_INVAL_ARG).GetCode()); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "ServiceTest-an exception occurred by GetCompatibilityInfo."; + } + GTEST_LOG_(INFO) << "ServiceTest-end SUB_Service_GetCompatibilityInfo_0100"; +} + +/** + * @tc.number: SUB_Service_GetCompatibilityInfo_0200 + * @tc.name: SUB_Service_GetCompatibilityInfo_0200 + * @tc.desc: 测试 GetCompatibilityInfo 的正常/异常分支 + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + * @tc.require: NA + */ +HWTEST_F(ServiceTest, SUB_Service_GetCompatibilityInfo_0200, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "ServiceTest-begin SUB_Service_GetCompatibilityInfo_0200"; + try { + std::string bundleName = "com.ohos.test"; + std::string extInfo = ""; + std::string compatInfo = ""; + + EXPECT_CALL(*skeleton, GetCallingTokenID()).WillRepeatedly(Return(0)); + EXPECT_CALL(*token, GetTokenType(_)) + .WillRepeatedly(Return(Security::AccessToken::ATokenTypeEnum::TOKEN_NATIVE)); + EXPECT_CALL(*token, VerifyAccessToken(_, _)) + .WillRepeatedly(Return(Security::AccessToken::PermissionState::PERMISSION_GRANTED)); + EXPECT_CALL(*param, GetBackupDebugOverrideAccount()) + .WillRepeatedly(Return(make_pair(true, DEBUG_ID + 1))); + EXPECT_CALL(*saUtils, IsSABundleName(_)).WillRepeatedly(Return(false)); + + auto callDied = [](const string &&bundleName, bool isCleanCalled) {}; + auto callConnected = [](const string &&bundleName) {}; + auto connectPtr = sptr(new SvcBackupConnection(callDied, callConnected, bundleName)); + EXPECT_CALL(*session, GetExtConnection(_)).WillRepeatedly(Return(wptr(connectPtr))); + EXPECT_CALL(*connect, IsExtAbilityConnected()).WillRepeatedly(Return(true)); + service->isConnectDied_ = true; + int res = service->GetCompatibilityInfo(bundleName, extInfo, compatInfo); + EXPECT_EQ(res, BError(BError::Codes::EXT_ABILITY_DIED).GetCode()); + + service->isConnectDied_ = false; + EXPECT_CALL(*connect, GetBackupExtProxy()) + .WillOnce(Return(nullptr)) + .WillRepeatedly(Return(svcProxy)); + EXPECT_CALL(*connect, DisconnectBackupExtAbility()).WillRepeatedly(Return(BError(BError::Codes::OK).GetCode())); + res = service->GetCompatibilityInfo(bundleName, extInfo, compatInfo); + EXPECT_EQ(res, BError(BError::Codes::SA_INVAL_ARG).GetCode()); + + EXPECT_CALL(*svcProxy, HandleGetCompatibilityInfo(_, _, _)) + .WillOnce(Return(BError(BError::Codes::SA_INVAL_ARG).GetCode())); + res = service->GetCompatibilityInfo(bundleName, extInfo, compatInfo); + EXPECT_EQ(res, BError(BError::Codes::SA_INVAL_ARG).GetCode()); + + EXPECT_CALL(*svcProxy, HandleGetCompatibilityInfo(_, _, _)) + .WillOnce(Return(BError(BError::Codes::OK).GetCode())); + res = service->GetCompatibilityInfo(bundleName, extInfo, compatInfo); + EXPECT_EQ(res, BError(BError::Codes::OK).GetCode()); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "ServiceTest-an exception occurred by GetCompatibilityInfo."; + } + GTEST_LOG_(INFO) << "ServiceTest-end SUB_Service_GetCompatibilityInfo_0200"; } \ No newline at end of file diff --git a/tests/unittests/backup_sa/session/b_incremental_session_test.cpp b/tests/unittests/backup_sa/session/b_incremental_session_test.cpp index 6cfb25ca466152cf04c04a4d9d4722d6afe078c8..817879ecbde855c5d7f43df9871b52ee1c918b0b 100644 --- a/tests/unittests/backup_sa/session/b_incremental_session_test.cpp +++ b/tests/unittests/backup_sa/session/b_incremental_session_test.cpp @@ -973,4 +973,80 @@ HWTEST_F(IncrementalSessionTest, SUB_b_incremental_session_test_2900, testing::e } GTEST_LOG_(INFO) << "IncrementalSessionTest-end SUB_b_incremental_session_test_2900"; } + +/** + * @tc.number: SUB_BIncrementalBackupSession_GetCompatibilityInfo_0000 + * @tc.name: SUB_BIncrementalBackupSession_GetCompatibilityInfo_0000 + * @tc.desc: 测试 GetCompatibilityInfo 接口 + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + * @tc.require: NA + */ +HWTEST_F(IncrementalSessionTest, SUB_BIncrementalBackupSession_GetCompatibilityInfo_0000, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "IncrementalSessionTest-begin SUB_BIncrementalBackupSession_GetCompatibilityInfo_0000"; + try { + std::string bundleName = "com.example.app"; + std::string extInfo = ""; + std::string compatInfo = ""; + + ServiceClient::serviceProxy_ = nullptr; + ASSERT_TRUE(backupSession != nullptr); + auto err = backupSession->GetCompatibilityInfo(bundleName, extInfo, compatInfo); + EXPECT_EQ(err, BError(BError::Codes::SDK_BROKEN_IPC).GetCode()); + + ServiceClient::serviceProxy_ = proxy; + EXPECT_CALL(*proxy, GetCompatibilityInfo(_, _, _)) + .WillOnce(Return(BError(BError::Codes::SDK_INVAL_ARG).GetCode())); + err = backupSession->GetCompatibilityInfo(bundleName, extInfo, compatInfo); + EXPECT_EQ(err, BError(BError::Codes::SDK_INVAL_ARG).GetCode()); + + EXPECT_CALL(*proxy, GetCompatibilityInfo(_, _, _)).WillOnce(Return(BError(BError::Codes::OK).GetCode())); + err = backupSession->GetCompatibilityInfo(bundleName, extInfo, compatInfo); + EXPECT_EQ(err, ERROR_OK); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "IncrementalSessionTest-an exception occurred by GetCompatibilityInfo."; + } + GTEST_LOG_(INFO) << "IncrementalSessionTest-end SUB_BIncrementalBackupSession_GetCompatibilityInfo_0000"; +} + +/** + * @tc.number: SUB_BIncrementalStoreSession_GetCompatibilityInfo_0000 + * @tc.name: SUB_BIncrementalStoreSession_GetCompatibilityInfo_0000 + * @tc.desc: 测试 GetCompatibilityInfo 接口 + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + * @tc.require: NA + */ +HWTEST_F(IncrementalSessionTest, SUB_BIncrementalStoreSession_GetCompatibilityInfo_0000, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "IncrementalSessionTest-begin SUB_BIncrementalStoreSession_GetCompatibilityInfo_0000"; + try { + std::string bundleName = "com.example.app"; + std::string extInfo = ""; + std::string compatInfo = ""; + + ServiceClient::serviceProxy_ = nullptr; + ASSERT_TRUE(restoreSession != nullptr); + auto err = restoreSession->GetCompatibilityInfo(bundleName, extInfo, compatInfo); + EXPECT_EQ(err, BError(BError::Codes::SDK_BROKEN_IPC).GetCode()); + + ServiceClient::serviceProxy_ = proxy; + EXPECT_CALL(*proxy, GetCompatibilityInfo(_, _, _)) + .WillOnce(Return(BError(BError::Codes::SDK_INVAL_ARG).GetCode())); + err = restoreSession->GetCompatibilityInfo(bundleName, extInfo, compatInfo); + EXPECT_EQ(err, BError(BError::Codes::SDK_INVAL_ARG).GetCode()); + + EXPECT_CALL(*proxy, GetCompatibilityInfo(_, _, _)).WillOnce(Return(BError(BError::Codes::OK).GetCode())); + err = restoreSession->GetCompatibilityInfo(bundleName, extInfo, compatInfo); + EXPECT_EQ(err, ERROR_OK); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "IncrementalSessionTest-an exception occurred by GetCompatibilityInfo."; + } + GTEST_LOG_(INFO) << "IncrementalSessionTest-end SUB_BIncrementalStoreSession_GetCompatibilityInfo_0000"; +} } // namespace OHOS::FileManagement::Backup \ No newline at end of file diff --git a/tests/unittests/backup_sa/session/service_proxy_mock.cpp b/tests/unittests/backup_sa/session/service_proxy_mock.cpp index 19d658f02d9374cfbbb5df88eccc9f2b5890e2b3..f07378af40c12d35dd7ebdbb6298aa0399aba6b5 100644 --- a/tests/unittests/backup_sa/session/service_proxy_mock.cpp +++ b/tests/unittests/backup_sa/session/service_proxy_mock.cpp @@ -260,4 +260,10 @@ ErrCode ServiceProxy::GetExtOnRelease(bool &isExtOnRelease) { return BError(BError::Codes::OK); } + +ErrCode ServiceProxy::GetCompatibilityInfo(const std::string &bundleName, const std::string &extInfo, + std::string &compatInfo) +{ + return BError(BError::Codes::OK); +} } // namespace OHOS::FileManagement::Backup \ No newline at end of file diff --git a/tests/unittests/backup_sa/session/service_proxy_mock.h b/tests/unittests/backup_sa/session/service_proxy_mock.h index b5675cf8eb72bef0047a99130976866b526db87e..40271c70dd1003c2275e27378e66dbd5426d4478 100644 --- a/tests/unittests/backup_sa/session/service_proxy_mock.h +++ b/tests/unittests/backup_sa/session/service_proxy_mock.h @@ -77,6 +77,7 @@ public: MOCK_METHOD1(CleanBundleTempDir, ErrCode(const std::string &bundleName)); MOCK_METHOD1(HandleExtDisconnect, ErrCode(bool isIncBackup)); MOCK_METHOD1(GetExtOnRelease, ErrCode(bool &isExtOnRelease)); + MOCK_METHOD3(GetCompatibilityInfo, ErrCode(const std::string&, const std::string&, std::string&)); }; } // End of namespace OHOS::FileManagement::Backup #endif // TEST_UNITTEST_SERVICE_PROXY_MOCK_H diff --git a/tests/unittests/backup_utils/b_json/b_json_entity_extension_config_test.cpp b/tests/unittests/backup_utils/b_json/b_json_entity_extension_config_test.cpp index 3da3ab4c133b0375b1fcbb8b7885c688ad5e848c..e91e5663fc8cbccd847ff75744ce761a9a74f354 100644 --- a/tests/unittests/backup_utils/b_json/b_json_entity_extension_config_test.cpp +++ b/tests/unittests/backup_utils/b_json/b_json_entity_extension_config_test.cpp @@ -1037,4 +1037,47 @@ HWTEST_F(BJsonEntityExtensionConfigTest, b_json_entity_extension_config_3700, te } GTEST_LOG_(INFO) << "BJsonEntityExtensionConfigTest-end b_json_entity_extension_config_3700"; } + +/** + * @tc.number: SUB_backup_b_json_entity_extension_config_3800 + * @tc.name: backup_b_json_entity_extension_config_3800 + * @tc.desc: 测试GetRequireCompatibility接口能否成功返回 + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 2 + * @tc.require: NA + */ +HWTEST_F(BJsonEntityExtensionConfigTest, backup_b_json_entity_extension_config_3800, testing::ext::TestSize.Level2) +{ + GTEST_LOG_(INFO) << "BJsonEntityExtensionConfigTest-begin backup_b_json_entity_extension_config_3800"; + try { + string_view sv1 = R"({"":true})"; + BJsonCachedEntity cachedEntity1(sv1); + auto cache1 = cachedEntity1.Structuralize(); + bool ret = cache1.GetRequireCompatibility(); + EXPECT_FALSE(ret); + + string_view sv2 = R"({"requireCompatibility1":true})"; + BJsonCachedEntity cachedEntity2(sv2); + auto cache2 = cachedEntity2.Structuralize(); + ret = cache2.GetRequireCompatibility(); + EXPECT_FALSE(ret); + + string_view sv3 = R"({"requireCompatibility":123})"; + BJsonCachedEntity cachedEntity3(sv3); + auto cache3 = cachedEntity3.Structuralize(); + ret = cache3.GetRequireCompatibility(); + EXPECT_FALSE(ret); + + string_view sv4 = R"({"requireCompatibility":true})"; + BJsonCachedEntity cachedEntity4(sv4); + auto cache4 = cachedEntity4.Structuralize(); + ret = cache4.GetRequireCompatibility(); + EXPECT_TRUE(ret); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "BJsonEntityExtensionConfigTest-an exception occurred by GetRequireCompatibility."; + } + GTEST_LOG_(INFO) << "BJsonEntityExtensionConfigTest-end backup_b_json_entity_extension_config_3800"; +} } // namespace OHOS::FileManagement::Backup \ No newline at end of file diff --git a/utils/include/b_json/b_json_entity_caps.h b/utils/include/b_json/b_json_entity_caps.h index 1321ecde546927b096a41a12f602eda548ea606a..eabbf02ad0373e1a226f223d1137a797417d6966 100644 --- a/utils/include/b_json/b_json_entity_caps.h +++ b/utils/include/b_json/b_json_entity_caps.h @@ -31,6 +31,7 @@ public: int64_t increSpaceOccupied; bool allToBackup; bool fullBackupOnly; + bool requireCompatibility; std::string extensionName; std::string restoreDeps; std::string supportScene; @@ -39,6 +40,7 @@ public: struct BundleBackupConfigPara { bool allToBackup; bool fullBackupOnly; + bool requireCompatibility; std::string extensionName; std::string restoreDeps; std::string supportScene; @@ -84,6 +86,7 @@ public: } arrObj["allToBackup"] = item.allToBackup; arrObj["fullBackupOnly"] = item.fullBackupOnly; + arrObj["requireCompatibility"] = item.requireCompatibility; arrObj["extensionName"] = item.extensionName; arrObj["restoreDeps"] = item.restoreDeps; arrObj["supportScene"] = item.supportScene; @@ -233,6 +236,10 @@ public: if (item.isMember("fullBackupOnly") && item["fullBackupOnly"].isBool()) { fullBackupOnly = item["fullBackupOnly"].asBool(); } + bool requireCompatibility = false; + if (item.isMember("requireCompatibility") && item["requireCompatibility"].isBool()) { + requireCompatibility = item["requireCompatibility"].asBool(); + } int appIndex = 0; if (item.isMember("appIndex") && item["appIndex"].isInt()) { appIndex = item["appIndex"].asInt(); @@ -244,7 +251,7 @@ public: bundleInfos.emplace_back(BundleInfo {item["name"].asString(), appIndex, item["versionCode"].asInt64(), item["versionName"].asString(), item["spaceOccupied"].asInt64(), increSpaceOccupied, item["allToBackup"].asBool(), fullBackupOnly, - item["extensionName"].asString(), + requireCompatibility, item["extensionName"].asString(), restoreDeps, supportScene, extraInfo}); } return bundleInfos; diff --git a/utils/include/b_json/b_json_entity_extension_config.h b/utils/include/b_json/b_json_entity_extension_config.h index 80177038e607849cd379295c1bdc685ad2415a60..8523f2e93a4c27cad138956084fc6954b5d770a4 100644 --- a/utils/include/b_json/b_json_entity_extension_config.h +++ b/utils/include/b_json/b_json_entity_extension_config.h @@ -76,6 +76,13 @@ public: */ Json::Value GetExtraInfo() const; + /** + * @brief 从JSon对象中获取兼容能力标志 + * + * @return 兼容标志: 应用是否要做兼容处理 + */ + bool GetRequireCompatibility() const; + public: std::string GetJSonSource(std::string_view jsonFromRealWorld, std::any option); diff --git a/utils/include/b_resources/b_constants.h b/utils/include/b_resources/b_constants.h index 2687c38e0cb48c1db43ad2e757bbcef9ebc15e6e..6075332a44db0b21ab3cbcd46ce03f90ae6cbc22 100644 --- a/utils/include/b_resources/b_constants.h +++ b/utils/include/b_resources/b_constants.h @@ -103,6 +103,8 @@ constexpr int FIRST_CALL_APP_ON_PROCESS_MAX_TIMEOUT = 15000; // 首次调用应 constexpr int APP_ON_PROCESS_TIMEOUT_MAX_COUNT = 3; // 应用的onProcess接口超时的上限次数 constexpr int APP_ON_RELEASE_MAX_TIMEOUT = 5000; // 应用的onRelease接口最大超时时间为5秒 +// 应用的getBackupCompatibilityInfo/getRestoreCompatibilityInfo接口最大超时时间为1秒 +constexpr int APP_GETCOMINFO_MAX_TIMEOUT = 1000; // backup.para内配置项的名称,该配置项值为true时可在不更新hap包的情况下,可以读取包管理元数据配置文件的内容 static inline std::string BACKUP_DEBUG_OVERRIDE_EXTENSION_CONFIG_KEY = "backup.debug.overrideExtensionConfig"; diff --git a/utils/src/b_json/b_json_entity_extension_config.cpp b/utils/src/b_json/b_json_entity_extension_config.cpp index a6e639d5104766d681d4fa708241c1151eb72d66..6f17cf0dae69f01a5eb6bf13898626a949caa462 100644 --- a/utils/src/b_json/b_json_entity_extension_config.cpp +++ b/utils/src/b_json/b_json_entity_extension_config.cpp @@ -179,4 +179,15 @@ string BJsonEntityExtensionConfig::GetRestoreDeps() const return obj_["restoreDeps"].asString(); } +bool BJsonEntityExtensionConfig::GetRequireCompatibility() const +{ + if (!obj_ || !obj_.isMember("requireCompatibility") || !obj_["requireCompatibility"].isBool()) { + HILOGD("Failed to get field requireCompatibility"); + return false; + } + + return obj_["requireCompatibility"].asBool(); +} + + } // namespace OHOS::FileManagement::Backup