From f4afd42368b98df818d1d57a1af428982955d546 Mon Sep 17 00:00:00 2001 From: zhangzezhong Date: Tue, 5 Aug 2025 22:55:57 -0400 Subject: [PATCH] abilitystage onMemoryLevel, etc. Signed-off-by: zhangzezhong --- .../ets/@ohos.app.ability.AbilityStage.ets | 26 +++ frameworks/native/appkit/BUILD.gn | 1 + .../ability_runtime/app/ets_ability_stage.cpp | 181 +++++++++++++++--- .../ability_runtime/app/ets_ability_stage.h | 19 +- 4 files changed, 196 insertions(+), 31 deletions(-) diff --git a/frameworks/ets/ets/@ohos.app.ability.AbilityStage.ets b/frameworks/ets/ets/@ohos.app.ability.AbilityStage.ets index e837fa773ad..e3dd0ebfd82 100644 --- a/frameworks/ets/ets/@ohos.app.ability.AbilityStage.ets +++ b/frameworks/ets/ets/@ohos.app.ability.AbilityStage.ets @@ -17,10 +17,29 @@ import { Configuration } from '@ohos.app.ability.Configuration' import AbilityStageContext from 'application.AbilityStageContext' import Want from '@ohos.app.ability.Want'; import { AbilityUtils } from './utils/AbilityUtils'; +import AbilityConstant from '@ohos.app.ability.AbilityConstant'; export default class AbilityStage { context: AbilityStageContext = new AbilityStageContext(); + private prepareTerminationCallbackPoint: long; + private native nativeOnPrepareTerminationCallback(): void; + private callOnPrepareTermination(): boolean { + const derivedClassType = AbilityUtils.getClassType(this); + if (derivedClassType === undefined) { + return false; + } + const classType = AbilityUtils.getClassType(new AbilityStage()); + if (classType === undefined) { + return false; + } + if (AbilityUtils.isOverride(derivedClassType, "onPrepareTerminationAsync", classType)) { + this.onPrepareTerminationAsync().then((data:AbilityConstant.PrepareTermination) => this.nativeOnPrepareTerminationCallback()); + return true; + } + return false; + } + onConfigurationUpdate(newConfig: Configuration): void { } @@ -77,4 +96,11 @@ export default class AbilityStage { async onNewProcessRequestAsync(want: Want): Promise { return ''; } + onPrepareTermination(): AbilityConstant.PrepareTermination { + return AbilityConstant.PrepareTermination.CANCEL; + } + + async onPrepareTerminationAsync(): Promise { + return AbilityConstant.PrepareTermination.CANCEL; + } } \ No newline at end of file diff --git a/frameworks/native/appkit/BUILD.gn b/frameworks/native/appkit/BUILD.gn index 26a1bfdfbb2..5c1b32df012 100644 --- a/frameworks/native/appkit/BUILD.gn +++ b/frameworks/native/appkit/BUILD.gn @@ -358,6 +358,7 @@ ohos_shared_library("ability_stage_ani") { "${ability_runtime_services_path}/abilitymgr/include/utils", "${ability_runtime_services_path}/abilitymgr/include", "${ability_runtime_utils_path}/global/constant", + "${ability_runtime_path}/frameworks/ets/ani/enum_convert", ] configs = [] diff --git a/frameworks/native/appkit/ability_runtime/app/ets_ability_stage.cpp b/frameworks/native/appkit/ability_runtime/app/ets_ability_stage.cpp index a994cd26321..8c4369c32a5 100644 --- a/frameworks/native/appkit/ability_runtime/app/ets_ability_stage.cpp +++ b/frameworks/native/appkit/ability_runtime/app/ets_ability_stage.cpp @@ -25,6 +25,7 @@ #include "ability_delegator_registry.h" #include "ani_common_configuration.h" #include "ani_common_want.h" +#include "ani_enum_convert.h" #include "configuration_convertor.h" #include "ets_ability_stage_context.h" #include "freeze_util.h" @@ -46,7 +47,58 @@ constexpr const char* CALLBACK_SUCCESS = "success"; constexpr const char* ABILITY_STAGE_CLASS_NAME = "L@ohos/app/ability/AbilityStage/AbilityStage;"; constexpr const char* ABILITY_STAGE_SYNC_METHOD_NAME = "L@ohos/app/ability/Want/Want;:Lstd/core/String;"; constexpr const char* ABILITY_STAGE_ASYNC_METHOD_NAME = "L@ohos/app/ability/Want/Want;:Z"; +constexpr const char* MEMORY_LEVEL_ENUM_NAME = + "L@ohos/app/ability/AbilityConstant/AbilityConstant/MemoryLevel;"; +constexpr const char *PREPARE_TERMINATION_CLASS_NAME = + ":L@ohos/app/ability/AbilityConstant/AbilityConstant/PrepareTermination;"; + +void OnPrepareTerminationPromiseCallback(ani_env* env, ani_object aniObj, ani_object dataObj) +{ + TAG_LOGD(AAFwkTag::APPKIT, "OnDestroyPromiseCallback called"); + + if (env == nullptr || aniObj == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "null env or null aniObj"); + return; + } + ani_long callbackPoint = 0; + ani_status status = ANI_ERROR; + if ((status = env->Object_GetFieldByName_Long(aniObj, "prepareTerminationCallbackPoint", &callbackPoint)) != + ANI_OK) { + TAG_LOGE(AAFwkTag::APPKIT, "status: %{public}d", status); + return; + } + auto *callbackInfo = + reinterpret_cast *>( + callbackPoint); + if (callbackInfo == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "null callbackInfo"); + return; + } + ani_boolean isUndefined = false; + if ((status = env->Reference_IsUndefined(dataObj, &isUndefined)) != ANI_OK) { + TAG_LOGE(AAFwkTag::APPKIT, "Failed to check undefined status : %{public}d", status); + return; + } + if (isUndefined) { + TAG_LOGE(AAFwkTag::APPKIT, "onPrepareTermination unimplemented"); + return; + } + ani_int result = 0; + if (!AAFwk::AniEnumConvertUtil::EnumConvert_EtsToNative(env, dataObj, result)) { + TAG_LOGE(AAFwkTag::APPKIT, "EnumConvert_EtsToNative param err"); + return; + } + AppExecFwk::OnPrepareTerminationResult prepareTerminationResult = { result, true }; + callbackInfo->Call(prepareTerminationResult); + AppExecFwk::AbilityTransactionCallbackInfo::Destroy(callbackInfo); + + if ((status = env->Object_SetFieldByName_Long(aniObj, "prepareTerminationCallbackPoint", + static_cast(0))) != ANI_OK) { + TAG_LOGE(AAFwkTag::APPKIT, "status : %{public}d", status); + return; + } } +} // namespace AbilityStage *ETSAbilityStage::Create( const std::unique_ptr& runtime, const AppExecFwk::HapModuleInfo& hapModuleInfo) @@ -137,16 +189,6 @@ void ETSAbilityStage::OnDestroy() const CallObjectMethod(false, "onDestroy", ":V"); } -std::string ETSAbilityStage::OnAcceptWant(const AAFwk::Want &want) -{ - return std::string(); -} - -std::string ETSAbilityStage::OnNewProcessRequest(const AAFwk::Want &want) -{ - return std::string(); -} - std::string ETSAbilityStage::OnAcceptWant(const AAFwk::Want &want, AppExecFwk::AbilityTransactionCallbackInfo *callbackInfo, bool &isAsync) { @@ -300,12 +342,12 @@ void ETSAbilityStage::OnConfigurationUpdated(const AppExecFwk::Configuration &co AbilityStage::OnConfigurationUpdated(configuration); auto env = etsRuntime_.GetAniEnv(); if (env == nullptr) { - TAG_LOGE(AAFwkTag::ABILITY, "env nullptr"); + TAG_LOGE(AAFwkTag::APPKIT, "env nullptr"); return; } auto application = application_.lock(); if (application == nullptr) { - TAG_LOGE(AAFwkTag::ABILITY, "application is null"); + TAG_LOGE(AAFwkTag::APPKIT, "application is null"); return; } auto fullConfig = application->GetConfiguration(); @@ -324,25 +366,40 @@ void ETSAbilityStage::OnConfigurationUpdated(const AppExecFwk::Configuration &co void ETSAbilityStage::OnMemoryLevel(int32_t level) { + TAG_LOGD(AAFwkTag::APPKIT, "OnMemoryLevel called"); + AbilityStage::OnMemoryLevel(level); + + auto env = etsRuntime_.GetAniEnv(); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "env nullptr"); + return; + } + ani_enum_item memoryLevelItem {}; + OHOS::AAFwk::AniEnumConvertUtil::EnumConvert_NativeToEts(env, + MEMORY_LEVEL_ENUM_NAME, level, memoryLevelItem); + + CallObjectMethod(false, "onMemoryLevel", "L@ohos/app/ability/AbilityConstant/AbilityConstant/MemoryLevel;:V", + memoryLevelItem); + TAG_LOGD(AAFwkTag::APPKIT, "end"); } bool ETSAbilityStage::CallObjectMethod(bool withResult, const char *name, const char *signature, ...) const { HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, std::string("CallObjectMethod:") + name); - TAG_LOGD(AAFwkTag::ABILITY, "CallObjectMethod: name:%{public}s", name); + TAG_LOGD(AAFwkTag::APPKIT, "CallObjectMethod: name:%{public}s", name); if (etsAbilityStageObj_ == nullptr) { - TAG_LOGE(AAFwkTag::ABILITY, "etsAbilityStageObj_ nullptr"); + TAG_LOGE(AAFwkTag::APPKIT, "etsAbilityStageObj_ nullptr"); return false; } auto env = etsRuntime_.GetAniEnv(); if (env == nullptr) { - TAG_LOGE(AAFwkTag::ABILITY, "env nullptr"); + TAG_LOGE(AAFwkTag::APPKIT, "env nullptr"); return false; } ani_status status = ANI_OK; ani_method method = nullptr; if ((status = env->Class_FindMethod(etsAbilityStageObj_->aniCls, name, signature, &method)) != ANI_OK) { - TAG_LOGE(AAFwkTag::ABILITY, "status: %{public}d", status); + TAG_LOGE(AAFwkTag::APPKIT, "status: %{public}d", status); return false; } env->ResetError(); @@ -351,7 +408,7 @@ bool ETSAbilityStage::CallObjectMethod(bool withResult, const char *name, const va_list args; va_start(args, signature); if ((status = env->Object_CallMethod_Boolean(etsAbilityStageObj_->aniObj, method, &res, args)) != ANI_OK) { - TAG_LOGE(AAFwkTag::ABILITY, "status: %{public}d", status); + TAG_LOGE(AAFwkTag::APPKIT, "status: %{public}d", status); etsRuntime_.HandleUncaughtError(); } va_end(args); @@ -360,7 +417,7 @@ bool ETSAbilityStage::CallObjectMethod(bool withResult, const char *name, const va_list args; va_start(args, signature); if ((status = env->Object_CallMethod_Void_V(etsAbilityStageObj_->aniObj, method, args)) != ANI_OK) { - TAG_LOGE(AAFwkTag::ABILITY, "status: %{public}d", status); + TAG_LOGE(AAFwkTag::APPKIT, "status: %{public}d", status); etsRuntime_.HandleUncaughtError(); return false; } @@ -496,6 +553,8 @@ bool ETSAbilityStage::BindNativeMethods() ani_native_function{ "nativeOnNewProcessRequestCallback", "Lstd/core/String;:V", reinterpret_cast(ETSAbilityStage::OnNewProcessRequestCallback)}, + ani_native_function{"nativeOnPrepareTerminationCallback", ":V", + reinterpret_cast(OnPrepareTerminationPromiseCallback)}, }; ani_class cls {}; ani_status status = env->FindClass(ABILITY_STAGE_CLASS_NAME, &cls); @@ -513,7 +572,7 @@ bool ETSAbilityStage::BindNativeMethods() void ETSAbilityStage::SetEtsAbilityStage(const std::shared_ptr &context) { if (context == nullptr) { - TAG_LOGE(AAFwkTag::ABILITY, "context nullptr"); + TAG_LOGE(AAFwkTag::APPKIT, "context nullptr"); return; } @@ -524,13 +583,13 @@ void ETSAbilityStage::SetEtsAbilityStage(const std::shared_ptr &context auto env = etsRuntime_.GetAniEnv(); if (env == nullptr) { - TAG_LOGE(AAFwkTag::ABILITY, "env nullptr"); + TAG_LOGE(AAFwkTag::APPKIT, "env nullptr"); return; } ani_object stageCtxObj = ETSAbilityStageContext::CreateEtsAbilityStageContext(env, context); if (stageCtxObj == nullptr) { - TAG_LOGE(AAFwkTag::ABILITY, "CreateEtsAbilityStageContext failed"); + TAG_LOGE(AAFwkTag::APPKIT, "CreateEtsAbilityStageContext failed"); return; } @@ -538,19 +597,93 @@ void ETSAbilityStage::SetEtsAbilityStage(const std::shared_ptr &context ani_field contextField; status = env->Class_FindField(etsAbilityStageObj_->aniCls, "context", &contextField); if (status != ANI_OK) { - TAG_LOGE(AAFwkTag::ABILITY, "Class_GetField context failed"); + TAG_LOGE(AAFwkTag::APPKIT, "Class_GetField context failed"); return; } ani_ref stageCtxObjRef = nullptr; if (env->GlobalReference_Create(stageCtxObj, &stageCtxObjRef) != ANI_OK) { - TAG_LOGE(AAFwkTag::ABILITY, "GlobalReference_Create stageCtxObj failed"); + TAG_LOGE(AAFwkTag::APPKIT, "GlobalReference_Create stageCtxObj failed"); return; } if (env->Object_SetField_Ref(etsAbilityStageObj_->aniObj, contextField, stageCtxObjRef) != ANI_OK) { - TAG_LOGE(AAFwkTag::ABILITY, "Object_SetField_Ref stageCtxObj failed"); + TAG_LOGE(AAFwkTag::APPKIT, "Object_SetField_Ref stageCtxObj failed"); + } +} + +bool ETSAbilityStage::OnPrepareTerminate( + AppExecFwk::AbilityTransactionCallbackInfo *callbackInfo, + bool &isAsync) const +{ + TAG_LOGD(AAFwkTag::APPKIT, "OnPrepareTerminate called"); + if (callbackInfo == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "callbackInfo nullptr"); + return false; + } + auto env = etsRuntime_.GetAniEnv(); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "null env"); + return false; + } + if (etsAbilityStageObj_ == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "null etsAbilityStageObj_"); + return false; + } + ani_long prepareTerminationCallbackPoint = reinterpret_cast(callbackInfo); + ani_status status = env->Object_SetFieldByName_Long(etsAbilityStageObj_->aniObj, "prepareTerminationCallbackPoint", + prepareTerminationCallbackPoint); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::APPKIT, "Object_SetFieldByName_Long status: %{public}d", status); + return false; + } + if (CallOnPrepareTerminateAsync(callbackInfo, isAsync)) { + TAG_LOGI(AAFwkTag::APPKIT, "onPrepareTerminationAsync is implemented"); + return true; + } + isAsync = false; + return CallOnPrepareTerminate(callbackInfo); +} + +bool ETSAbilityStage::CallOnPrepareTerminateAsync( + AppExecFwk::AbilityTransactionCallbackInfo *callbackInfo, + bool &isAsync) const +{ + isAsync = false; + if (callbackInfo == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "callbackInfo nullptr"); + return false; } + isAsync = CallObjectMethod(true, "callOnPrepareTermination", ":Z"); + return isAsync; } +bool ETSAbilityStage::CallOnPrepareTerminate( + AppExecFwk::AbilityTransactionCallbackInfo *callbackInfo) const +{ + TAG_LOGD(AAFwkTag::APPKIT, "CallOnPrepareTerminate call"); + if (callbackInfo == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "callbackInfo nullptr"); + return false; + } + ani_env *env = etsRuntime_.GetAniEnv(); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "null env"); + return false; + } + ani_object resObj = CallObjectMethod("onPrepareTermination", PREPARE_TERMINATION_CLASS_NAME); + if (resObj == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "onPrepareTermination unimplemented"); + return false; + } + ani_int result = 0; + if (!AAFwk::AniEnumConvertUtil::EnumConvert_EtsToNative(env, resObj, result)) { + TAG_LOGE(AAFwkTag::APPKIT, "EnumConvert_EtsToNative param err"); + return false; + } + AppExecFwk::OnPrepareTerminationResult prepareTerminationResult = { result, true }; + callbackInfo->Call(prepareTerminationResult); + AppExecFwk::AbilityTransactionCallbackInfo::Destroy(callbackInfo); + return true; +} } // namespace AbilityRuntime } // namespace OHOS diff --git a/interfaces/kits/native/appkit/ability_runtime/app/ets_ability_stage.h b/interfaces/kits/native/appkit/ability_runtime/app/ets_ability_stage.h index 099aac649f6..d7e410a6cf4 100644 --- a/interfaces/kits/native/appkit/ability_runtime/app/ets_ability_stage.h +++ b/interfaces/kits/native/appkit/ability_runtime/app/ets_ability_stage.h @@ -24,7 +24,6 @@ #include "configuration.h" #include "ets_native_reference.h" #include "ets_runtime.h" -#include "native_engine/native_value.h" #include "resource_manager.h" namespace OHOS { @@ -44,10 +43,6 @@ public: void OnDestroy() const override; - std::string OnAcceptWant(const AAFwk::Want &want) override; - - std::string OnNewProcessRequest(const AAFwk::Want &want) override; - std::string OnAcceptWant(const AAFwk::Want &want, AppExecFwk::AbilityTransactionCallbackInfo *callbackInfo, bool &isAsync) override; @@ -61,6 +56,10 @@ public: void OnConfigurationUpdated(const AppExecFwk::Configuration &configuration) override; void OnMemoryLevel(int32_t level) override; + + bool OnPrepareTerminate( + AppExecFwk::AbilityTransactionCallbackInfo *callbackInfo, + bool &isAsync) const override; private: bool CallObjectMethod(bool withResult, const char *name, const char *signature, ...) const; @@ -75,10 +74,16 @@ private: bool CallAcceptOrRequestAsync(ani_env *env, const AAFwk::Want &want, std::string &methodName, bool &isAsync) const; - bool BindNativeMethods(); - void SetEtsAbilityStage(const std::shared_ptr &context); + bool CallOnPrepareTerminate(AppExecFwk::AbilityTransactionCallbackInfo + *callbackInfo) const; + + bool CallOnPrepareTerminateAsync(AppExecFwk::AbilityTransactionCallbackInfo + *callbackInfo, bool &isAsync) const; + + bool BindNativeMethods(); + ETSRuntime& etsRuntime_; std::unique_ptr etsAbilityStageObj_; }; -- Gitee