From ed4e4e8e79f298b414362c12db8fb21684eb1ecf Mon Sep 17 00:00:00 2001 From: huaqingsimeng Date: Wed, 30 Aug 2023 17:57:33 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dentension=E8=A7=A6=E5=8F=91?= =?UTF-8?q?=E5=BA=94=E7=94=A8=E4=BE=A7=E6=8E=A5=E5=8F=A3=E6=9C=AA=E7=AD=89?= =?UTF-8?q?=E5=BE=85=E7=9B=B4=E6=8E=A5=E8=BF=94=E5=9B=9E=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: huaqingsimeng --- .../native/backup_ext/include/ext_backup.h | 14 +-- .../native/backup_ext/include/ext_backup_js.h | 16 +++- .../native/backup_ext/include/ext_extension.h | 2 + .../native/backup_ext/src/ext_backup.cpp | 4 +- .../native/backup_ext/src/ext_backup_js.cpp | 95 +++++++++++++++---- .../native/backup_ext/src/ext_extension.cpp | 93 ++++++++++++------ 6 files changed, 166 insertions(+), 58 deletions(-) diff --git a/frameworks/native/backup_ext/include/ext_backup.h b/frameworks/native/backup_ext/include/ext_backup.h index 7940adda9..73d64e731 100644 --- a/frameworks/native/backup_ext/include/ext_backup.h +++ b/frameworks/native/backup_ext/include/ext_backup.h @@ -25,11 +25,10 @@ namespace OHOS::FileManagement::Backup { class ExtBackup; -using CreatorFunc = std::function& runtime)>; +using CreatorFunc = std::function &runtime)>; class ExtBackup : public AbilityRuntime::ExtensionBase { public: - /** * @brief Called when this extension is started. You must override this function if you want to perform some * initialization operations during extension startup. @@ -87,7 +86,6 @@ public: void OnDisconnect(const AAFwk::Want &want) override; public: - /** * @brief Create Extension. * @@ -120,12 +118,12 @@ public: /** * @brief do backup. Subclasses can inherit to implement their own custom functionality. */ - virtual ErrCode OnBackup(void); + virtual ErrCode OnBackup(std::function callback); /** * @brief Called do restore. */ - virtual ErrCode OnRestore(void); + virtual ErrCode OnRestore(std::function callback); bool WasFromSpeicalVersion(void); @@ -133,18 +131,16 @@ public: ExtBackup() = default; ~ExtBackup() override = default; - static void SetCreator(const CreatorFunc& creator); + static void SetCreator(const CreatorFunc &creator); protected: - std::string appVersionStr_; int appVersionCode_; int restoreType_; private: - BConstants::ExtensionAction VerifyAndGetAction(const AAFwk::Want &want, - std::shared_ptr abilityInfo); + std::shared_ptr abilityInfo); ErrCode GetParament(const AAFwk::Want &want); diff --git a/frameworks/native/backup_ext/include/ext_backup_js.h b/frameworks/native/backup_ext/include/ext_backup_js.h index 37bdc9c1f..8e31897ff 100644 --- a/frameworks/native/backup_ext/include/ext_backup_js.h +++ b/frameworks/native/backup_ext/include/ext_backup_js.h @@ -16,6 +16,7 @@ #ifndef OHOS_FILEMGMT_BACKUP_EXT_BACKUP_JS_H #define OHOS_FILEMGMT_BACKUP_EXT_BACKUP_JS_H +#include #include #include #include @@ -52,6 +53,12 @@ struct CallJsParam { } }; +struct CallBackInfo { + std::function callback; + + CallBackInfo(std::function callbackIn) : callback(callbackIn) {} +}; + class ExtBackupJs : public ExtBackup { public: /** @@ -78,13 +85,17 @@ public: /** * @brief Call the app's OnBackup. + * + * @param callback The callback. */ - ErrCode OnBackup(void) override; + ErrCode OnBackup(std::function callback) override; /** * @brief Call the app's OnRestore. + * + * @param callback The callback. */ - ErrCode OnRestore(void) override; + ErrCode OnRestore(std::function callback) override; public: explicit ExtBackupJs(AbilityRuntime::JsRuntime &jsRuntime) : jsRuntime_(jsRuntime) {} @@ -106,6 +117,7 @@ private: AbilityRuntime::JsRuntime &jsRuntime_; std::unique_ptr jsObj_; + std::shared_ptr callbackInfo_; }; } // 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 daaf9eb67..10920695b 100644 --- a/frameworks/native/backup_ext/include/ext_extension.h +++ b/frameworks/native/backup_ext/include/ext_extension.h @@ -92,6 +92,8 @@ private: */ void AsyncTaskRestore(); + void AsyncTaskOnBackup(); + private: std::shared_mutex lock_; std::shared_ptr extension_; diff --git a/frameworks/native/backup_ext/src/ext_backup.cpp b/frameworks/native/backup_ext/src/ext_backup.cpp index 568c9309e..cf584ce06 100644 --- a/frameworks/native/backup_ext/src/ext_backup.cpp +++ b/frameworks/native/backup_ext/src/ext_backup.cpp @@ -217,13 +217,13 @@ bool ExtBackup::WasFromSpeicalVersion(void) return false; } -ErrCode ExtBackup::OnBackup(void) +ErrCode ExtBackup::OnBackup(function callback) { HILOGI("BackupExtensionAbility(base) OnBackup."); return ERR_OK; } -ErrCode ExtBackup::OnRestore(void) +ErrCode ExtBackup::OnRestore(function callback) { HILOGI("BackupExtensionAbility(base) OnRestore."); return ERR_OK; diff --git a/frameworks/native/backup_ext/src/ext_backup_js.cpp b/frameworks/native/backup_ext/src/ext_backup_js.cpp index 4b5e57a33..ef8cd0e7a 100644 --- a/frameworks/native/backup_ext/src/ext_backup_js.cpp +++ b/frameworks/native/backup_ext/src/ext_backup_js.cpp @@ -22,9 +22,9 @@ #include #include "bundle_mgr_client.h" +#include "js_extension_context.h" #include "js_runtime.h" #include "js_runtime_utils.h" -#include "js_extension_context.h" #include "napi/native_api.h" #include "napi/native_node_api.h" #include "napi_common_util.h" @@ -56,6 +56,57 @@ static string GetSrcPath(const AppExecFwk::AbilityInfo &info) return ""; } +static NativeValue *PromiseCallback(NativeEngine *engine, NativeCallbackInfo *info) +{ + if (info == nullptr || info->functionInfo == nullptr || info->functionInfo->data == nullptr) { + HILOGI("PromiseCallback, Invalid input info."); + return nullptr; + } + void *data = info->functionInfo->data; + auto *callbackInfo = static_cast(data); + callbackInfo->callback(); + info->functionInfo->data = nullptr; + return nullptr; +} + +static bool CheckPromise(NativeValue *result) +{ + if (result == nullptr) { + HILOGE("CheckPromise, result is null, no need to call promise."); + return false; + } + if (!result->IsPromise()) { + HILOGE("CheckPromise, result is not promise, no need to call promise."); + return false; + } + return true; +} + +static bool CallPromise(AbilityRuntime::JsRuntime &jsRuntime, NativeValue *result, CallBackInfo *callbackInfo) +{ + auto *retObj = AbilityRuntime::ConvertNativeValueTo(result); + if (retObj == nullptr) { + HILOGI("CallPromise, Failed to convert native value to NativeObject."); + return false; + } + NativeValue *then = retObj->GetProperty("then"); + if (then == nullptr) { + HILOGI("CallPromise, Failed to get property: then."); + return false; + } + if (!then->IsCallable()) { + HILOGI("CallPromise, property then is not callable."); + return false; + } + AbilityRuntime::HandleScope handleScope(jsRuntime); + auto &nativeEngine = jsRuntime.GetNativeEngine(); + auto promiseCallback = + nativeEngine.CreateFunction("promiseCallback", strlen("promiseCallback"), PromiseCallback, callbackInfo); + NativeValue *argv[1] = {promiseCallback}; + nativeEngine.CallFunction(result, then, argv, 1); + return true; +} + void ExtBackupJs::Init(const shared_ptr &record, const shared_ptr &application, shared_ptr &handler, @@ -93,8 +144,8 @@ void ExtBackupJs::Init(const shared_ptr &record, void ExtBackupJs::ExportJsContext(void) { - auto& engine = jsRuntime_.GetNativeEngine(); - NativeObject* obj = AbilityRuntime::ConvertNativeValueTo(jsObj_->Get()); + auto &engine = jsRuntime_.GetNativeEngine(); + NativeObject *obj = AbilityRuntime::ConvertNativeValueTo(jsObj_->Get()); if (obj == nullptr) { HILOGE("Failed to get BackupExtAbility object"); return; @@ -107,7 +158,7 @@ void ExtBackupJs::ExportJsContext(void) } HILOGI("CreateBackupExtAbilityContext"); - NativeValue* contextObj = CreateJsExtensionContext(engine, context); + NativeValue *contextObj = CreateJsExtensionContext(engine, context); auto contextRef = jsRuntime_.LoadSystemModule("application.ExtensionContext", &contextObj, 1); contextObj = contextRef->Get(); HILOGI("Bind context"); @@ -121,9 +172,9 @@ void ExtBackupJs::ExportJsContext(void) } HILOGI("Set backup extension ability context pointer is nullptr: %{public}d", context.get() == nullptr); - auto releaseContext = [](NativeEngine*, void* data, void*) { + auto releaseContext = [](NativeEngine *, void *data, void *) { HILOGI("Finalizer for weak_ptr backup extension ability context is called"); - delete static_cast*>(data); + delete static_cast *>(data); }; nativeObj->SetNativePointer(new std::weak_ptr(context), releaseContext, nullptr); } @@ -166,25 +217,29 @@ ExtBackupJs *ExtBackupJs::Create(const unique_ptr &runt return new ExtBackupJs(static_cast(*runtime)); } -ErrCode ExtBackupJs::OnBackup(void) +ErrCode ExtBackupJs::OnBackup(function callback) { HILOGI("BackupExtensionAbility(JS) OnBackup."); BExcepUltils::BAssert(jsObj_, BError::Codes::EXT_BROKEN_FRAMEWORK, "The app does not provide the onRestore interface."); - - auto retParser = [](NativeEngine &engine, NativeValue *result) -> bool { - return true; + callbackInfo_ = std::make_shared(callback); + auto retParser = [jsRuntime {&jsRuntime_}, callback, callbackInfo {callbackInfo_}](NativeEngine &engine, + NativeValue *result) -> bool { + if (!CheckPromise(result)) { + return false; + } + HILOGI("CheckPromise(JS) OnBackup ok."); + return CallPromise(*jsRuntime, result, callbackInfo.get()); }; auto errCode = CallJsMethod("onBackup", jsRuntime_, jsObj_.get(), {}, retParser); if (errCode != ERR_OK) { HILOGE("CallJsMethod error, code:%{public}d.", errCode); - return errCode; } - return ERR_OK; + return errCode; } -ErrCode ExtBackupJs::OnRestore(void) +ErrCode ExtBackupJs::OnRestore(function callback) { HILOGI("BackupExtensionAbility(JS) OnRestore."); BExcepUltils::BAssert(jsObj_, BError::Codes::EXT_BROKEN_FRAMEWORK, @@ -201,17 +256,21 @@ ErrCode ExtBackupJs::OnRestore(void) argv.push_back(param); return true; }; - - auto retParser = [](NativeEngine &engine, NativeValue *result) -> bool { - return true; + callbackInfo_ = std::make_shared(callback); + auto retParser = [jsRuntime {&jsRuntime_}, callback, callbackInfo {callbackInfo_}](NativeEngine &engine, + NativeValue *result) -> bool { + if (!CheckPromise(result)) { + return false; + } + HILOGI("CheckPromise(JS) OnRestore ok."); + return CallPromise(*jsRuntime, result, callbackInfo.get()); }; auto errCode = CallJsMethod("onRestore", jsRuntime_, jsObj_.get(), argParser, retParser); if (errCode != ERR_OK) { HILOGE("CallJsMethod error, code:%{public}d.", errCode); - return errCode; } - return ERR_OK; + return errCode; } static int DoCallJsMethod(CallJsParam *param) diff --git a/frameworks/native/backup_ext/src/ext_extension.cpp b/frameworks/native/backup_ext/src/ext_extension.cpp index 4ba5ff4ec..53cdf9bd1 100644 --- a/frameworks/native/backup_ext/src/ext_extension.cpp +++ b/frameworks/native/backup_ext/src/ext_extension.cpp @@ -206,7 +206,13 @@ ErrCode BackupExtExtension::PublishFile(const string &fileName) ErrCode BackupExtExtension::HandleBackup() { string usrConfig = extension_->GetUsrConfig(); - AsyncTaskBackup(usrConfig); + BJsonCachedEntity cachedEntity(usrConfig); + auto cache = cachedEntity.Structuralize(); + if (!cache.GetAllowToBackupRestore()) { + HILOGI("Application does not allow backup or restore"); + return BError(BError::Codes::EXT_INVAL_ARG, "Application does not allow backup or restore").GetCode(); + } + AsyncTaskOnBackup(); return 0; } @@ -322,22 +328,10 @@ void BackupExtExtension::AsyncTaskBackup(const string config) auto ptr = obj.promote(); BExcepUltils::BAssert(ptr, BError::Codes::EXT_BROKEN_FRAMEWORK, "Ext extension handle have been already released"); - try { BJsonCachedEntity cachedEntity(config); auto cache = cachedEntity.Structuralize(); - if (!cache.GetAllowToBackupRestore()) { - HILOGI("Application does not allow backup or restore"); - return; - } - BExcepUltils::BAssert(ptr->extension_, BError::Codes::EXT_INVAL_ARG, - "extension handle have been already released"); - - int ret = ptr->extension_->OnBackup(); - if (ret == ERR_OK) { - ret = ptr->DoBackup(cache); - } - + auto ret = ptr->DoBackup(cache); // REM: 处理返回结果 ret ptr->AppDone(ret); HILOGE("backup app done %{public}d", ret); @@ -467,13 +461,11 @@ void BackupExtExtension::AsyncTaskRestore() if (ret == ERR_OK) { HILOGI("after extra, do restore."); - BExcepUltils::BAssert(ptr->extension_, BError::Codes::EXT_INVAL_ARG, - "extension handle have been already released"); - ret = ptr->extension_->OnRestore(); + ptr->AsyncTaskRestoreForUpgrade(); + } else { + ptr->AppDone(ret); + ptr->DoClear(); } - - // 处理返回结果 - ptr->AppDone(ret); } catch (const BError &e) { ptr->AppDone(e.GetCode()); } catch (const exception &e) { @@ -483,8 +475,6 @@ void BackupExtExtension::AsyncTaskRestore() HILOGE("Failed to restore the ext bundle"); ptr->AppDone(BError(BError::Codes::EXT_INVAL_ARG).GetCode()); } - // 清空恢复目录 - ptr->DoClear(); }; // REM: 这里异步化了,需要做并发控制 @@ -503,12 +493,22 @@ void BackupExtExtension::AsyncTaskRestoreForUpgrade() { auto task = [obj {wptr(this)}]() { auto ptr = obj.promote(); - BExcepUltils::BAssert(ptr, BError::Codes::EXT_BROKEN_FRAMEWORK, - "Ext extension handle have been already released"); try { + BExcepUltils::BAssert(ptr, BError::Codes::EXT_BROKEN_FRAMEWORK, + "Ext extension handle have been already released"); BExcepUltils::BAssert(ptr->extension_, BError::Codes::EXT_INVAL_ARG, "extension handle have been already released"); - ptr->AppDone(ptr->extension_->OnRestore()); + + auto callBackup = [obj]() { + HILOGI("begin call restore"); + auto extensionPtr = obj.promote(); + BExcepUltils::BAssert(extensionPtr, BError::Codes::EXT_BROKEN_FRAMEWORK, + "Ext extension handle have been already released"); + extensionPtr->AppDone(BError(BError::Codes::OK)); + // 清空恢复目录 + extensionPtr->DoClear(); + }; + ptr->extension_->OnRestore(callBackup); } catch (const BError &e) { ptr->AppDone(e.GetCode()); } catch (const exception &e) { @@ -518,8 +518,6 @@ void BackupExtExtension::AsyncTaskRestoreForUpgrade() HILOGE("Failed to restore the ext bundle"); ptr->AppDone(BError(BError::Codes::EXT_INVAL_ARG).GetCode()); } - // 清空恢复目录 - ptr->DoClear(); }; // REM: 这里异步化了,需要做并发控制 @@ -563,4 +561,45 @@ void BackupExtExtension::AppDone(ErrCode errCode) HILOGE("Failed to notify the app done. err = %{public}d", ret); } } + +void BackupExtExtension::AsyncTaskOnBackup() +{ + auto task = [obj {wptr(this)}]() { + auto ptr = obj.promote(); + try { + BExcepUltils::BAssert(ptr, BError::Codes::EXT_BROKEN_FRAMEWORK, + "Ext extension handle have been already released"); + BExcepUltils::BAssert(ptr->extension_, BError::Codes::EXT_INVAL_ARG, + "extension handle have been already released"); + + auto callBackup = [obj]() { + HILOGI("begin call backup"); + auto extensionPtr = obj.promote(); + BExcepUltils::BAssert(extensionPtr, BError::Codes::EXT_BROKEN_FRAMEWORK, + "Ext extension handle have been already released"); + BExcepUltils::BAssert(extensionPtr->extension_, BError::Codes::EXT_INVAL_ARG, + "extension handle have been already released"); + extensionPtr->AsyncTaskBackup(extensionPtr->extension_->GetUsrConfig()); + }; + + ptr->extension_->OnBackup(callBackup); + } catch (const BError &e) { + ptr->AppDone(e.GetCode()); + } catch (const exception &e) { + HILOGE("Catched an unexpected low-level exception %{public}s", e.what()); + ptr->AppDone(BError(BError::Codes::EXT_INVAL_ARG).GetCode()); + } catch (...) { + HILOGE("Failed to restore the ext bundle"); + ptr->AppDone(BError(BError::Codes::EXT_INVAL_ARG).GetCode()); + } + }; + + threadPool_.AddTask([task]() { + try { + task(); + } catch (...) { + HILOGE("Failed to add task to thread pool"); + } + }); +} } // namespace OHOS::FileManagement::Backup -- Gitee