From 1ea6842d1f6f5f9c6cd938840c69e2a462964730 Mon Sep 17 00:00:00 2001 From: zhangzezhong Date: Fri, 6 Jun 2025 17:07:01 +0800 Subject: [PATCH] ability_manager add AbilityForegroundStateObserver Signed-off-by: zhangzezhong --- frameworks/ets/ani/ability_manager/BUILD.gn | 5 +- .../ets_ability_foreground_state_observer.h | 58 ++++++ .../include/sts_ability_manager.h | 10 - .../include/sts_ability_manager_utils.h | 4 + .../ets_ability_foreground_state_observer.cpp | 191 ++++++++++++++++++ .../src/sts_ability_manager.cpp | 175 +++++++++++++--- .../src/sts_ability_manager_utils.cpp | 93 ++++++++- .../ets/@ohos.app.ability.abilityManager.ets | 11 + frameworks/ets/ets/BUILD.gn | 18 ++ .../AbilityForegroundStateObserver.ets | 21 ++ 10 files changed, 547 insertions(+), 39 deletions(-) create mode 100644 frameworks/ets/ani/ability_manager/include/ets_ability_foreground_state_observer.h create mode 100644 frameworks/ets/ani/ability_manager/src/ets_ability_foreground_state_observer.cpp create mode 100644 frameworks/ets/ets/application/AbilityForegroundStateObserver.ets diff --git a/frameworks/ets/ani/ability_manager/BUILD.gn b/frameworks/ets/ani/ability_manager/BUILD.gn index fedaa89c1c0..b345a9706ca 100644 --- a/frameworks/ets/ani/ability_manager/BUILD.gn +++ b/frameworks/ets/ani/ability_manager/BUILD.gn @@ -32,6 +32,7 @@ ohos_shared_library("ability_ability_manager_ani_kit") { "${ability_runtime_path}/interfaces/inner_api/runtime/include", "${ability_runtime_path}/interfaces/kits/native/appkit/ability_runtime/context", "${ability_runtime_services_path}/common/include", + "${ability_runtime_path}/frameworks/ets/ani/ani_common/include", "${ability_runtime_path}/frameworks/ets/ani/enum_convert", ] @@ -41,8 +42,8 @@ ohos_shared_library("ability_ability_manager_ani_kit") { sources = [ "./src/sts_ability_manager.cpp", - "./src/sts_ability_manager_utils.cpp", - ] + "./src/ets_ability_foreground_state_observer.cpp", + "./src/sts_ability_manager_utils.cpp",] cflags = [] if (target_cpu == "arm") { diff --git a/frameworks/ets/ani/ability_manager/include/ets_ability_foreground_state_observer.h b/frameworks/ets/ani/ability_manager/include/ets_ability_foreground_state_observer.h new file mode 100644 index 00000000000..6073510705f --- /dev/null +++ b/frameworks/ets/ani/ability_manager/include/ets_ability_foreground_state_observer.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_ABILITY_RUNTIME_ETS_ABILITY_FOREGROUND_STATE_OBSERVER_H +#define OHOS_ABILITY_RUNTIME_ETS_ABILITY_FOREGROUND_STATE_OBSERVER_H + +#include + +#include "ability_foreground_state_observer_stub.h" +#include "ability_state_data.h" +#include "event_handler.h" +#include "sts_runtime.h" +#include "ani_common_util.h" +#include "native_engine/native_engine.h" + +namespace OHOS { +namespace AbilityRuntime { +using OHOS::AppExecFwk::AbilityForegroundStateObserverStub; +using OHOS::AppExecFwk::AbilityStateData; +class ETSAbilityForegroundStateObserver : public AbilityForegroundStateObserverStub { +public: + explicit ETSAbilityForegroundStateObserver(ani_vm *etsVm); + virtual ~ETSAbilityForegroundStateObserver() = default; + + void OnAbilityStateChanged(const AbilityStateData &abilityStateData); + void HandleOnAbilityStateChanged(const AbilityStateData &abilityStateData); + void AddEtsObserverObject(ani_env *env, ani_object etsObserverObject); + bool RemoveEtsObserverObject(const ani_object &observerObj); + STSNativeReference GetObserverObject(const ani_object &observerObject); + void RemoveAllEtsObserverObject(); + bool IsEmpty(); + void SetValid(bool valid); + void CallStsFunction(ani_env* env, ani_object etsObserverObject, + const char *methodName, const char *signature, ...); + inline size_t GetEtsObserverMapSize() { return etsObserverObjects_.size(); } +private: + void ReleaseObjectRefrence(ani_ref etsObjRef); + +private: + ani_vm *etsVm_; + volatile bool valid_ = true; + std::vector etsObserverObjects_; +}; +} // namespace AbilityRuntime +} // namespace OHOS +#endif // OHOS_ABILITY_RUNTIME_ETS_ABILITY_FOREGROUND_STATE_OBSERVER_H diff --git a/frameworks/ets/ani/ability_manager/include/sts_ability_manager.h b/frameworks/ets/ani/ability_manager/include/sts_ability_manager.h index a04a51bd1bd..c08948aadd7 100644 --- a/frameworks/ets/ani/ability_manager/include/sts_ability_manager.h +++ b/frameworks/ets/ani/ability_manager/include/sts_ability_manager.h @@ -22,16 +22,6 @@ namespace OHOS { namespace AbilityManagerSts { void StsAbilityManagerRegistryInit(ani_env *env); - -class StsAbilityManager final { -public: - static StsAbilityManager &GetInstance() - { - static StsAbilityManager instance; - return instance; - } - static void GetAbilityRunningInfos(ani_env *env, ani_object callback); -}; } // namespace AbilityManagerSts } // namespace OHOS #endif // OHOS_ABILITY_RUNTIME_STS_ABILITY_MANAGER_H diff --git a/frameworks/ets/ani/ability_manager/include/sts_ability_manager_utils.h b/frameworks/ets/ani/ability_manager/include/sts_ability_manager_utils.h index 294769ed7a5..f6e81f0c04a 100644 --- a/frameworks/ets/ani/ability_manager/include/sts_ability_manager_utils.h +++ b/frameworks/ets/ani/ability_manager/include/sts_ability_manager_utils.h @@ -17,11 +17,15 @@ #define OHOS_ABILITY_RUNTIME_STS_ABILITY_MANAGER_UTILS_H #include "ability_running_info.h" +#include "ability_state_data.h" #include "extension_running_info.h" #include "sts_runtime.h" namespace OHOS { namespace AbilityManagerSts { +using OHOS::AppExecFwk::AbilityStateData; +ani_object WrapAbilityStateData(ani_env *env, const AbilityStateData &abilityStateData); +bool SetAbilityStateData(ani_env *env, ani_object object, const AbilityStateData &abilityStateData); bool WrapAbilityRunningInfo(ani_env *env, ani_object &infoObj, const AAFwk::AbilityRunningInfo &info); bool WrapAbilityRunningInfoArray( ani_env *env, ani_object &arrayObj, const std::vector &infos); diff --git a/frameworks/ets/ani/ability_manager/src/ets_ability_foreground_state_observer.cpp b/frameworks/ets/ani/ability_manager/src/ets_ability_foreground_state_observer.cpp new file mode 100644 index 00000000000..389c5ec27e9 --- /dev/null +++ b/frameworks/ets/ani/ability_manager/src/ets_ability_foreground_state_observer.cpp @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ets_ability_foreground_state_observer.h" +#include "sts_ability_manager_utils.h" +#include "hilog_tag_wrapper.h" +#include "ani_common_util.h" + +namespace OHOS { +namespace AbilityRuntime { +namespace { +constexpr const char* ABILITY_FOREGROUND_STATE_OBSERVER_CLASS_NAME = + "Lapplication/AbilityForegroundStateObserver/AbilityForegroundStateObserver;"; +constexpr const char *SIGNATURE_ABILITY_STATE_DATA = "Lapplication/AbilityStateData/AbilityStateData;:V"; +} +ETSAbilityForegroundStateObserver::ETSAbilityForegroundStateObserver(ani_vm *etsVm) : etsVm_(etsVm) {} + +void ETSAbilityForegroundStateObserver::OnAbilityStateChanged(const AbilityStateData &abilityStateData) +{ + TAG_LOGD(AAFwkTag::ABILITYMGR, "OnAbilityStateChanged called"); + if (!valid_) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "invalid appms"); + return; + } + HandleOnAbilityStateChanged(abilityStateData); +} + +void ETSAbilityForegroundStateObserver::CallStsFunction(ani_env* env, ani_object stsObserverObject, + const char *methodName, const char *signature, ...) +{ + TAG_LOGD(AAFwkTag::ABILITYMGR, "call method:%{public}s", methodName); + ani_class cls; + ani_method method = nullptr; + ani_status status = ANI_OK; + if ((status = env->FindClass(ABILITY_FOREGROUND_STATE_OBSERVER_CLASS_NAME, &cls)) != ANI_OK) { + TAG_LOGE(AAFwkTag::DELEGATOR, "find observer failed status : %{public}d", status); + return; + } + if ((status = env->Class_FindMethod(cls, methodName, signature, &method)) != ANI_OK) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "status: %{public}d", status); + return; + } + env->ResetError(); + va_list args; + va_start(args, signature); + if ((status = env->Object_CallMethod_Void_V(stsObserverObject, method, args)) != ANI_OK) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "status: %{public}d", status); + return; + } + va_end(args); + TAG_LOGD(AAFwkTag::ABILITYMGR, "end"); + return; +} + +void ETSAbilityForegroundStateObserver::HandleOnAbilityStateChanged(const AbilityStateData &abilityStateData) +{ + TAG_LOGD(AAFwkTag::ABILITYMGR, "HandleOnAbilityStateChanged called"); + if (etsVm_ == nullptr) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "etsVm_ nullptr"); + return; + } + ani_env *env = nullptr; + ani_status status = ANI_ERROR; + ani_option interopEnabled { "--interop=disable", nullptr }; + ani_options aniArgs { 1, &interopEnabled }; + if ((status = etsVm_->AttachCurrentThread(&aniArgs, ANI_VERSION_1, &env)) != ANI_OK) { + TAG_LOGE(AAFwkTag::STSRUNTIME, "status : %{public}d", status); + return; + } + if (env == nullptr) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "env nullptr"); + return; + } + for (auto &item : etsObserverObjects_) { + auto abilityStateDataObj = AbilityManagerSts::WrapAbilityStateData(env, abilityStateData); + if (abilityStateDataObj != nullptr && item.aniRef != nullptr) { + CallStsFunction(env, reinterpret_cast(item.aniRef), + "onAbilityStateChanged", SIGNATURE_ABILITY_STATE_DATA, abilityStateDataObj); + } + } + if (etsVm_->DetachCurrentThread() != ANI_OK) { + TAG_LOGE(AAFwkTag::STSRUNTIME, "status : %{public}d", status); + } + TAG_LOGD(AAFwkTag::ABILITYMGR, "HandleOnAbilityStateChanged end"); +} + +void ETSAbilityForegroundStateObserver::AddEtsObserverObject(ani_env *env, ani_object etsObserverObject) +{ + TAG_LOGD(AAFwkTag::ABILITYMGR, "AddEtsObserverObject called"); + if (etsObserverObject == nullptr) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "null observer"); + return; + } + if (GetObserverObject(etsObserverObject).aniObj != nullptr) { + TAG_LOGD(AAFwkTag::ABILITYMGR, "observer exist"); + return; + } + ani_ref global = nullptr; + ani_status status = ANI_ERROR; + if ((status = env->GlobalReference_Create(etsObserverObject, &global)) != ANI_OK) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "status : %{public}d", status); + return; + } + STSNativeReference stRef; + stRef.aniObj = etsObserverObject; + stRef.aniRef = global; + etsObserverObjects_.emplace_back(stRef); + TAG_LOGD(AAFwkTag::ABILITYMGR, "AddEtsObserverObject end"); +} + +STSNativeReference ETSAbilityForegroundStateObserver::GetObserverObject(const ani_object &observerObject) +{ + if (observerObject == nullptr) { + return STSNativeReference(); + } + for (const auto& observer : etsObserverObjects_) { + if (observer.aniObj == observerObject) { + return observer; + } + } + return STSNativeReference(); +} + +void ETSAbilityForegroundStateObserver::ReleaseObjectRefrence(ani_ref etsObjRef) +{ + if (etsObjRef == nullptr) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "null etsObj"); + return; + } + if (etsVm_ == nullptr) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "null etsVm_"); + return; + } + ani_env *env = nullptr; + ani_status status = etsVm_->GetEnv(ANI_VERSION_1, &env); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "GetEnv failed status: %{public}d", status); + return; + } + if ((status = env->GlobalReference_Delete(etsObjRef)) != ANI_OK) { + TAG_LOGE(AAFwkTag::APPMGR, "GlobalReference_Delete failed status = %{public}d", status); + return; + } +} + +bool ETSAbilityForegroundStateObserver::RemoveEtsObserverObject(const ani_object &observerObj) +{ + if (observerObj == nullptr) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "null observer"); + return false; + } + auto etsNativeRefrence = GetObserverObject(observerObj); + if (etsNativeRefrence.aniObj != nullptr) { + etsObserverObjects_.emplace_back(etsNativeRefrence); + ReleaseObjectRefrence(etsNativeRefrence.aniRef); + } + return true; +} + +void ETSAbilityForegroundStateObserver::RemoveAllEtsObserverObject() +{ + auto itr = etsObserverObjects_.begin(); + for (; itr != etsObserverObjects_.end(); ++itr) { + ReleaseObjectRefrence(itr->aniRef); + itr = etsObserverObjects_.erase(itr); + } +} + +void ETSAbilityForegroundStateObserver::SetValid(const bool valid) +{ + valid_ = valid; +} + +bool ETSAbilityForegroundStateObserver::IsEmpty() +{ + return etsObserverObjects_.empty(); +} +} // namespace AbilityRuntime +} // namespace OHOS diff --git a/frameworks/ets/ani/ability_manager/src/sts_ability_manager.cpp b/frameworks/ets/ani/ability_manager/src/sts_ability_manager.cpp index 7759ce7b8ef..0facf29f0c5 100644 --- a/frameworks/ets/ani/ability_manager/src/sts_ability_manager.cpp +++ b/frameworks/ets/ani/ability_manager/src/sts_ability_manager.cpp @@ -15,14 +15,17 @@ #include "sts_ability_manager.h" -#include "ability_manager_client.h" #include "ability_business_error.h" +#include "ability_manager_client.h" #include "ability_manager_errors.h" +#include "ability_manager_interface.h" #include "ability_runtime_error_util.h" #include "ani_common_ability_state_data.h" #include "ani_common_want.h" +#include "app_mgr_constants.h" +#include "app_mgr_interface.h" +#include "ets_ability_foreground_state_observer.h" #include "hilog_tag_wrapper.h" -#include "ability_manager_interface.h" #include "if_system_ability_manager.h" #include "iservice_registry.h" #include "sts_ability_manager_utils.h" @@ -34,16 +37,39 @@ namespace AbilityManagerSts { constexpr int32_t ERR_FAILURE = -1; -sptr GetAbilityManagerInstance() +class EtsAbilityManager final { +public: + static ani_object GetForegroundUIAbilities(ani_env *env); + static void GetTopAbility(ani_env *env, ani_object callback); + static void GetAbilityRunningInfos(ani_env *env, ani_object callback); + static void NativeOn(ani_env *env, ani_string aniType, ani_object aniObserver); + static void NativeOff(ani_env *env, ani_string aniType, ani_object aniObserver); + +private: + static sptr GetAbilityManagerInstance(); + static sptr GetAppManagerInstance(); + static sptr observerForeground_; +}; + +sptr EtsAbilityManager::observerForeground_ = nullptr; + +sptr EtsAbilityManager::GetAbilityManagerInstance() { sptr systemAbilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); - sptr abilityManagerObj = - systemAbilityManager->GetSystemAbility(ABILITY_MGR_SERVICE_ID); + sptr abilityManagerObj = systemAbilityManager->GetSystemAbility(ABILITY_MGR_SERVICE_ID); return iface_cast(abilityManagerObj); } -static ani_object GetForegroundUIAbilities(ani_env *env) +sptr EtsAbilityManager::GetAppManagerInstance() +{ + sptr systemAbilityManager = + SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + sptr appObject = systemAbilityManager->GetSystemAbility(APP_MGR_SERVICE_ID); + return iface_cast(appObject); +} + +ani_object EtsAbilityManager::GetForegroundUIAbilities(ani_env *env) { TAG_LOGD(AAFwkTag::ABILITYMGR, "call GetForegroundUIAbilities"); @@ -76,7 +102,7 @@ static ani_object GetForegroundUIAbilities(ani_env *env) return aniArray; } -static void GetTopAbility(ani_env *env, ani_object callback) +void EtsAbilityManager::GetTopAbility(ani_env *env, ani_object callback) { TAG_LOGD(AAFwkTag::ABILITYMGR, "call GetTopAbility"); if (env == nullptr) { @@ -106,11 +132,118 @@ static void GetTopAbility(ani_env *env, ani_object callback) return; } AppExecFwk::AsyncCallback(env, reinterpret_cast(callbackRef), - OHOS::AbilityRuntime::CreateStsErrorByNativeErr(env, resultCode), + AbilityRuntime::CreateStsErrorByNativeErr(env, resultCode), elementNameobj); return; } +void EtsAbilityManager::GetAbilityRunningInfos(ani_env *env, ani_object callback) +{ + TAG_LOGD(AAFwkTag::ABILITYMGR, "GetAbilityRunningInfos"); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "null env"); + return; + } + std::vector infos; + auto errcode = AAFwk::AbilityManagerClient::GetInstance()->GetAbilityRunningInfos(infos); + ani_object retObject = nullptr; + WrapAbilityRunningInfoArray(env, retObject, infos); + AppExecFwk::AsyncCallback(env, callback, + AbilityRuntime::CreateStsErrorByNativeErr(env, errcode), retObject); +} + +void EtsAbilityManager::NativeOn(ani_env *env, ani_string aniType, ani_object aniObserver) +{ + TAG_LOGD(AAFwkTag::ABILITYMGR, "nativeOn called"); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "env null ptr"); + return; + } + std::string strType; + if (!AppExecFwk::GetStdString(env, aniType, strType)) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "GetStdString failed"); + AbilityRuntime::ThrowStsInvalidParamError(env, + "Parse param observer failed, must be a AbilityForegroundStateObserver."); + return; + } + ani_vm *aniVM = nullptr; + if (env->GetVM(&aniVM) != ANI_OK) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "get aniVM failed"); + AbilityRuntime::ThrowStsInvalidParamError(env, "Get aniVm failed."); + return; + } + if (observerForeground_ == nullptr) { + observerForeground_ = new (std::nothrow) AbilityRuntime::ETSAbilityForegroundStateObserver(aniVM); + if (observerForeground_ == nullptr) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "null observerForeground_"); + AbilityRuntime::ThrowStsError(env, AbilityRuntime::AbilityErrorCode::ERROR_CODE_INNER); + return; + } + } + if (observerForeground_->IsEmpty()) { + auto appManager = GetAppManagerInstance(); + if (appManager == nullptr) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "appManager null ptr"); + AbilityRuntime::ThrowStsError(env, AbilityRuntime::AbilityErrorCode::ERROR_CODE_INNER); + return; + } + int32_t ret = appManager->RegisterAbilityForegroundStateObserver(observerForeground_); + TAG_LOGD(AAFwkTag::ABILITYMGR, "ret: %{public}d", ret); + if (ret != NO_ERROR) { + AbilityRuntime::ThrowStsErrorByNativeErr(env, static_cast(ret)); + return; + } + } + observerForeground_->AddEtsObserverObject(env, aniObserver); + TAG_LOGD(AAFwkTag::ABILITYMGR, "nativeOn end"); +} + +void EtsAbilityManager::NativeOff(ani_env *env, ani_string aniType, ani_object aniObserver) +{ + TAG_LOGD(AAFwkTag::ABILITYMGR, "nativeOff called"); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "env null ptr"); + return; + } + std::string strType; + if (!AppExecFwk::GetStdString(env, aniType, strType)) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "GetStdString failed"); + AbilityRuntime::ThrowStsInvalidParamError(env, + "Parse param observer failed, must be a AbilityForegroundStateObserver."); + return; + } + if (observerForeground_ == nullptr) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "null observer"); + AbilityRuntime::ThrowStsError(env, AbilityRuntime::AbilityErrorCode::ERROR_CODE_INNER); + return; + } + ani_status status = ANI_OK; + ani_boolean isUndefined = false; + if ((status = env->Reference_IsUndefined(aniObserver, &isUndefined)) != ANI_OK) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "Failed to check undefined status : %{public}d", status); + return; + } + if (!isUndefined) { + observerForeground_->RemoveEtsObserverObject(aniObserver); + } else { + observerForeground_->RemoveAllEtsObserverObject(); + } + if (observerForeground_->IsEmpty()) { + auto appManager = GetAppManagerInstance(); + if (appManager == nullptr) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "appManager null ptr"); + AbilityRuntime::ThrowStsError(env, AbilityRuntime::AbilityErrorCode::ERROR_CODE_INNER); + return; + } + int32_t ret = appManager->UnregisterAbilityForegroundStateObserver(observerForeground_); + TAG_LOGD(AAFwkTag::ABILITYMGR, "ret: %{public}d", ret); + if (ret != NO_ERROR) { + AbilityRuntime::ThrowStsErrorByNativeErr(env, static_cast(ret)); + } + } + TAG_LOGD(AAFwkTag::ABILITYMGR, "nativeOff end"); +} + void StsAbilityManagerRegistryInit(ani_env *env) { TAG_LOGD(AAFwkTag::ABILITYMGR, "call StsAbilityManagerRegistryInit"); @@ -132,11 +265,16 @@ void StsAbilityManagerRegistryInit(ani_env *env) ani_native_function { "nativeGetForegroundUIAbilities", ":Lescompat/Array;", - reinterpret_cast(GetForegroundUIAbilities) + reinterpret_cast(EtsAbilityManager::GetForegroundUIAbilities) }, - ani_native_function {"nativeGetTopAbility", nullptr, reinterpret_cast(GetTopAbility)}, + ani_native_function {"nativeGetTopAbility", nullptr, + reinterpret_cast(EtsAbilityManager::GetTopAbility)}, ani_native_function { "nativeGetAbilityRunningInfos", "Lutils/AbilityUtils/AsyncCallbackWrapper;:V", - reinterpret_cast(StsAbilityManager::GetAbilityRunningInfos) }, + reinterpret_cast(EtsAbilityManager::GetAbilityRunningInfos) }, + ani_native_function { "nativeOn", nullptr, + reinterpret_cast(EtsAbilityManager::NativeOn) }, + ani_native_function { "nativeOff", nullptr, + reinterpret_cast(EtsAbilityManager::NativeOff) } }; status = env->Namespace_BindNativeFunctions(ns, methods.data(), methods.size()); if (status != ANI_OK) { @@ -155,7 +293,6 @@ ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result) TAG_LOGE(AAFwkTag::ABILITYMGR, "null vm or result"); return ANI_INVALID_ARGS; } - ani_env *env = nullptr; ani_status status = ANI_ERROR; status = vm->GetEnv(ANI_VERSION_1, &env); @@ -169,19 +306,5 @@ ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result) return ANI_OK; } } - -void StsAbilityManager::GetAbilityRunningInfos(ani_env *env, ani_object callback) -{ - TAG_LOGD(AAFwkTag::ABILITYMGR, "GetAbilityRunningInfos"); - if (env == nullptr) { - TAG_LOGE(AAFwkTag::ABILITYMGR, "null env"); - return; - } - std::vector infos; - auto errcode = AAFwk::AbilityManagerClient::GetInstance()->GetAbilityRunningInfos(infos); - ani_object retObject = nullptr; - WrapAbilityRunningInfoArray(env, retObject, infos); - AppExecFwk::AsyncCallback(env, callback, OHOS::AbilityRuntime::CreateStsErrorByNativeErr(env, errcode), retObject); -} } // namespace AbilityManagerSts } // namespace OHOS \ No newline at end of file diff --git a/frameworks/ets/ani/ability_manager/src/sts_ability_manager_utils.cpp b/frameworks/ets/ani/ability_manager/src/sts_ability_manager_utils.cpp index 6185737a75f..7d2c2793bf2 100644 --- a/frameworks/ets/ani/ability_manager/src/sts_ability_manager_utils.cpp +++ b/frameworks/ets/ani/ability_manager/src/sts_ability_manager_utils.cpp @@ -14,7 +14,9 @@ */ #include "sts_ability_manager_utils.h" - +#include +#include "ability_state.h" +#include "hilog_tag_wrapper.h" #include "ani_common_util.h" #include "ani_common_want.h" #include "ani_enum_convert.h" @@ -286,5 +288,94 @@ bool WrapExtensionRunningInfoInner( return true; } +bool SetAbilityStateData(ani_env *env, ani_object object, const AbilityStateData &abilityStateData) +{ + if (env == nullptr) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "null env"); + return false; + } + ani_status status = ANI_OK; + if ((status = env->Object_SetFieldByName_Ref(object, "moduleName", + OHOS::AppExecFwk::GetAniString(env, abilityStateData.moduleName))) != ANI_OK) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "moduleName failed status:%{public}d", status); + return false; + } + if ((status = env->Object_SetFieldByName_Ref(object, "bundleName", + OHOS::AppExecFwk::GetAniString(env, abilityStateData.bundleName))) != ANI_OK) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "bundleName failed status:%{public}d", status); + return false; + } + if ((status = env->Object_SetFieldByName_Ref(object, "abilityName", + OHOS::AppExecFwk::GetAniString(env, abilityStateData.abilityName))) != ANI_OK) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "abilityName failed status:%{public}d", status); + return false; + } + if ((status = env->Object_SetFieldByName_Int(object, "pid", static_cast(abilityStateData.pid))) + != ANI_OK) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "pid failed status:%{public}d", status); + return false; + } + if ((status = env->Object_SetFieldByName_Int(object, "uid", abilityStateData.uid)) != ANI_OK) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "uid failed status:%{public}d", status); + return false; + } + if ((status = env->Object_SetFieldByName_Int(object, "state", abilityStateData.abilityState)) != ANI_OK) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "state failed status:%{public}d", status); + return false; + } + if ((status = env->Object_SetFieldByName_Int(object, "abilityType", abilityStateData.abilityType)) != ANI_OK) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "abilityType failed status:%{public}d", status); + return false; + } + if ((status = env->Object_SetFieldByName_Boolean(object, "isAtomicService", + abilityStateData.isAtomicService)) != ANI_OK) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "isAtomicService failed status:%{public}d", status); + return false; + } + if ((status = env->Object_SetFieldByName_Ref(object, "appCloneIndex", + OHOS::AppExecFwk::createInt(env, abilityStateData.appCloneIndex))) != ANI_OK) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "appCloneIndex failed status:%{public}d", status); + return false; + } + return true; +} + +ani_object WrapAbilityStateData(ani_env *env, const AbilityStateData &abilityStateData) +{ + ani_class cls {}; + ani_status status = ANI_ERROR; + ani_method method {}; + ani_object object = nullptr; + if (env == nullptr) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "null env"); + return nullptr; + } + if ((status = env->FindClass("Lapplication/AbilityStateData/AbilityStateData;", &cls)) != ANI_OK) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "find class failed status : %{public}d", status); + return nullptr; + } + if (cls == nullptr) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "null cls"); + return nullptr; + } + if ((status = env->Class_FindMethod(cls, "", ":V", &method)) != ANI_OK) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "find ctor failed status : %{public}d", status); + return nullptr; + } + if ((status = env->Object_New(cls, method, &object)) != ANI_OK) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "Object_New AppStateData failed status : %{public}d", status); + return nullptr; + } + if (object == nullptr) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "null object"); + return nullptr; + } + if (!SetAbilityStateData(env, object, abilityStateData)) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "SetAppStateData failed"); + return nullptr; + } + return object; +} + } // namespace AbilityManagerSts } // namespace OHOS \ No newline at end of file diff --git a/frameworks/ets/ets/@ohos.app.ability.abilityManager.ets b/frameworks/ets/ets/@ohos.app.ability.abilityManager.ets index 3fb3b399ec6..4e5b7285658 100644 --- a/frameworks/ets/ets/@ohos.app.ability.abilityManager.ets +++ b/frameworks/ets/ets/@ohos.app.ability.abilityManager.ets @@ -99,6 +99,17 @@ export function getTopAbility(callback: AsyncCallback): void }); } +export native function nativeOn(type:string, observer: AbilityForegroundStateObserver): void; +function on(type: 'abilityForegroundState', observer: AbilityForegroundStateObserver): void +{ + nativeOn('abilityForegroundState', observer); +} + +export native function nativeOff(type:string, observer?: AbilityForegroundStateObserver): void; +function off(type: 'abilityForegroundState', observer?: AbilityForegroundStateObserver): void { + nativeOff('abilityForegroundState', observer); +} + export enum AbilityState { INITIAL = 0, FOCUS = 2, diff --git a/frameworks/ets/ets/BUILD.gn b/frameworks/ets/ets/BUILD.gn index 7d3c48df8f5..08d3b594f61 100644 --- a/frameworks/ets/ets/BUILD.gn +++ b/frameworks/ets/ets/BUILD.gn @@ -787,6 +787,23 @@ ohos_prebuilt_etc("ability_delegator_application_testRunner_abc_etc") { deps = [ ":ability_delegator_application_testRunner_abc" ] } +generate_static_abc("ability_foreground_state_observer_abc") { + base_url = "." + files = [ "./application/AbilityForegroundStateObserver.ets" ] + + is_boot_abc = "True" + device_dst_file = + "/system/framework/ability_foreground_state_observer_abc.abc" +} + +ohos_prebuilt_etc("ability_foreground_state_observer_abc_etc") { + source = "$target_out_dir/ability_foreground_state_observer_abc.abc" + module_install_dir = "framework" + subsystem_name = "ability" + part_name = "ability_runtime" + deps = [ ":ability_foreground_state_observer_abc" ] +} + generate_static_abc("ability_runtime_OpenLink_Options_abc") { base_url = "./" files = [ "./@ohos.app.ability.OpenLinkOptions.ets" ] @@ -1074,6 +1091,7 @@ group("ets_packages") { ":ability_delegator_application_testRunner_abc_etc", ":ability_delegator_args_abc_etc", ":ability_delegator_registry_abc_etc", + ":ability_foreground_state_observer_abc_etc", ":ability_runtime_abilityResult_abc_etc", ":ability_runtime_ability_abc_etc", ":ability_runtime_ability_callee_abc_etc", diff --git a/frameworks/ets/ets/application/AbilityForegroundStateObserver.ets b/frameworks/ets/ets/application/AbilityForegroundStateObserver.ets new file mode 100644 index 00000000000..c5652df4a32 --- /dev/null +++ b/frameworks/ets/ets/application/AbilityForegroundStateObserver.ets @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"), + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import AbilityStateData from 'application.AbilityStateData'; + +class AbilityForegroundStateObserver { + onAbilityStateChanged(abilityStateData: AbilityStateData): void {} +} + +export default AbilityForegroundStateObserver; \ No newline at end of file -- Gitee