diff --git a/frameworks/ets/ani/app_manager/BUILD.gn b/frameworks/ets/ani/app_manager/BUILD.gn index 0e46637799e14550f053e041af235c5e8511e35c..fdaa1cbfbb39d8bd3fb774a14a3f2a02b013fd74 100644 --- a/frameworks/ets/ani/app_manager/BUILD.gn +++ b/frameworks/ets/ani/app_manager/BUILD.gn @@ -41,6 +41,7 @@ ohos_shared_library("ability_app_manager_ani_kit") { sources = [ "./src/sts_app_manager.cpp", "./src/sts_app_manager_utils.cpp", + "./src/ets_app_state_observer.cpp", ] cflags = [] diff --git a/frameworks/ets/ani/app_manager/include/ets_app_state_observer.h b/frameworks/ets/ani/app_manager/include/ets_app_state_observer.h new file mode 100644 index 0000000000000000000000000000000000000000..6b1e9fdc151bf777fbdb2b3505a7edf4cd838630 --- /dev/null +++ b/frameworks/ets/ani/app_manager/include/ets_app_state_observer.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2022 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_APP_STATE_OBSERVER_H +#define OHOS_ABILITY_RUNTIME_ETS_APP_STATE_OBSERVER_H + +#include "ani_common_util.h" +#include "application_state_observer_stub.h" +#include "event_handler.h" +#include "sts_runtime.h" + +namespace OHOS { +namespace AbilityRuntime { +using OHOS::AppExecFwk::ApplicationStateObserverStub; +using OHOS::AppExecFwk::AppStateData; +using OHOS::AppExecFwk::AbilityStateData; +using OHOS::AppExecFwk::ProcessData; +class EtsAppStateObserver : public ApplicationStateObserverStub { +public: + explicit EtsAppStateObserver(ani_vm *etsVm); + ~EtsAppStateObserver() override; + void OnForegroundApplicationChanged(const AppStateData &appStateData) override; + void OnAbilityStateChanged(const AbilityStateData &abilityStateData) override; + void OnExtensionStateChanged(const AbilityStateData &abilityStateData) override; + void OnProcessCreated(const ProcessData &processData) override; + void OnProcessStateChanged(const ProcessData &processData) override; + void OnProcessDied(const ProcessData &processData) override; + void HandleOnForegroundApplicationChanged(const AppStateData &appStateData); + void HandleOnAbilityStateChanged(const AbilityStateData &abilityStateData); + void HandleOnExtensionStateChanged(const AbilityStateData &abilityStateData); + void HandleOnProcessCreated(const ProcessData &processData); + void HandleOnProcessStateChanged(const ProcessData &processData); + void HandleOnProcessDied(const ProcessData &processData); + void CallStsFunction(ani_env* env, ani_object StsObserverObject, + const char *methodName, const char *signature, ...); + void AddStsObserverObject(ani_env *env, const int32_t observerId, ani_object StsObserverObject); + bool RemoveStsObserverObject(const int32_t observerId); + bool FindObserverByObserverId(const int32_t observerId); + size_t GetStsObserverMapSize(); + void SetValid(const bool valid); + void OnAppStarted(const AppStateData &appStateData) override; + void OnAppStopped(const AppStateData &appStateData) override; + void HandleOnAppStarted(const AppStateData &appStateData); + void HandleOnAppStopped(const AppStateData &appStateData); + bool GetAniEnv(ani_env *&env); + void DetachAniEnv(); + +private: + ani_vm *etsVm_; + volatile bool valid_ = true; + std::map stsObserverObjectMap_; +}; +} // namespace AbilityRuntime +} // namespace OHOS +#endif // OHOS_ABILITY_RUNTIME_ETS_APP_STATE_OBSERVER_H \ No newline at end of file diff --git a/frameworks/ets/ani/app_manager/include/sts_app_manager_utils.h b/frameworks/ets/ani/app_manager/include/sts_app_manager_utils.h index a3af678cbddae15c1e4c326e1ed1e07ec1542d72..88e321248be6c75cd0f45af6500e99d441af8a85 100644 --- a/frameworks/ets/ani/app_manager/include/sts_app_manager_utils.h +++ b/frameworks/ets/ani/app_manager/include/sts_app_manager_utils.h @@ -22,6 +22,7 @@ #include "running_multi_info.h" #include "process_data.h" #include "keep_alive_info.h" +#include "ability_state_data.h" namespace OHOS { namespace AppManagerSts { diff --git a/frameworks/ets/ani/app_manager/src/ets_app_state_observer.cpp b/frameworks/ets/ani/app_manager/src/ets_app_state_observer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..97f065206053b929721ccf1c85aab41c3e746261 --- /dev/null +++ b/frameworks/ets/ani/app_manager/src/ets_app_state_observer.cpp @@ -0,0 +1,398 @@ +/* + * Copyright (c) 2022-2024 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_app_state_observer.h" + +#include "ani_common_ability_state_data.h" +#include "ani_common_util.h" +#include "ani_common_want.h" +#include "hilog_tag_wrapper.h" +#include "sts_app_manager_utils.h" + +namespace OHOS { +namespace AbilityRuntime { +constexpr const char *SIGNATURE_APP_STATE_DATA = "Lapplication/AppStateData/AppStateData;:V"; +constexpr const char *SIGNATURE_ABILITY_STATE_DATA = "Lapplication/AbilityStateData/AbilityStateData;:V"; +constexpr const char *SIGNATURE_PROCESS_DATA = "Lapplication/ProcessData/ProcessData;:V"; +constexpr const char *CLASS_NAME_APPLIACTION_STATE_OBSERVER = + "Lapplication/ApplicationStateObserver/ApplicationStateObserver;"; + +EtsAppStateObserver::EtsAppStateObserver(ani_vm *etsVm) : etsVm_(etsVm) {} + +EtsAppStateObserver::~EtsAppStateObserver() = default; + +void EtsAppStateObserver::OnForegroundApplicationChanged(const AppStateData &appStateData) +{ + TAG_LOGD(AAFwkTag::APPMGR, "OnForegroundApplicationChanged bundleName:%{public}s,uid:%{public}d, state:%{public}d", + appStateData.bundleName.c_str(), appStateData.uid, appStateData.state); + if (!valid_) { + TAG_LOGE(AAFwkTag::APPMGR, "invalid appmgr"); + return; + } + HandleOnForegroundApplicationChanged(appStateData); +} + +void EtsAppStateObserver::HandleOnForegroundApplicationChanged(const AppStateData &appStateData) +{ + ani_env *env = nullptr; + if (!GetAniEnv(env)) { + TAG_LOGE(AAFwkTag::APPMGR, "Failed to getAniEnv"); + DetachAniEnv(); + return; + } + auto tmpMap = stsObserverObjectMap_; + for (auto &item : tmpMap) { + auto appStateDataObj = AppManagerSts::WrapAppStateData(env, appStateData); + if (appStateDataObj == nullptr) { + TAG_LOGE(AAFwkTag::APPMGR, "null appStateDataObj"); + DetachAniEnv(); + return; + } + CallStsFunction(env, item.second, "onForegroundApplicationChanged", SIGNATURE_APP_STATE_DATA, appStateDataObj); + } + DetachAniEnv(); +} + +void EtsAppStateObserver::OnAbilityStateChanged(const AbilityStateData &abilityStateData) +{ + TAG_LOGD(AAFwkTag::APPMGR, "OnAbilityStateChanged"); + if (!valid_) { + TAG_LOGE(AAFwkTag::APPMGR, "appMgr may has cancelled storage"); + return; + } + HandleOnAbilityStateChanged(abilityStateData); +} + +void EtsAppStateObserver::HandleOnAbilityStateChanged(const AbilityStateData &abilityStateData) +{ + ani_env *env = nullptr; + if (!GetAniEnv(env)) { + TAG_LOGE(AAFwkTag::APPMGR, "Failed to getAniEnv"); + DetachAniEnv(); + return; + } + auto tmpMap = stsObserverObjectMap_; + for (auto &item : tmpMap) { + auto abilityStateDataObj = OHOS::AppExecFwk::WrapAbilityStateData(env, abilityStateData); + if (abilityStateDataObj == nullptr) { + TAG_LOGE(AAFwkTag::APPMGR, "null abilityStateDataObj"); + DetachAniEnv(); + } + CallStsFunction(env, item.second, "onAbilityStateChanged", SIGNATURE_ABILITY_STATE_DATA, abilityStateDataObj); + } + DetachAniEnv(); +} + +void EtsAppStateObserver::OnExtensionStateChanged(const AbilityStateData &abilityStateData) +{ + TAG_LOGD(AAFwkTag::APPMGR, "called"); + if (!valid_) { + TAG_LOGE(AAFwkTag::APPMGR, "appMgr may destroyed"); + return; + } + HandleOnExtensionStateChanged(abilityStateData); +} + +void EtsAppStateObserver::HandleOnExtensionStateChanged(const AbilityStateData &abilityStateData) +{ + ani_env *env = nullptr; + if (!GetAniEnv(env)) { + TAG_LOGE(AAFwkTag::APPMGR, "Failed to getAniEnv"); + DetachAniEnv(); + return; + } + auto tmpMap = stsObserverObjectMap_; + for (auto &item : tmpMap) { + auto abilityStateDataObj = OHOS::AppExecFwk::WrapAbilityStateData(env, abilityStateData); + if (abilityStateDataObj == nullptr) { + TAG_LOGE(AAFwkTag::APPMGR, "null abilityStateDataObj"); + DetachAniEnv(); + } + CallStsFunction(env, item.second, "onAbilityStateChanged", SIGNATURE_ABILITY_STATE_DATA, abilityStateDataObj); + } + DetachAniEnv(); +} + +void EtsAppStateObserver::OnProcessCreated(const ProcessData &processData) +{ + TAG_LOGD(AAFwkTag::APPMGR, "OnProcessCreated"); + if (!valid_) { + TAG_LOGE(AAFwkTag::APPMGR, "appmgr may has cancelled storage"); + return; + } + HandleOnProcessCreated(processData); +} + +void EtsAppStateObserver::HandleOnProcessCreated(const ProcessData &processData) +{ + ani_env *env = nullptr; + if (!GetAniEnv(env)) { + TAG_LOGE(AAFwkTag::APPMGR, "Failed to getAniEnv"); + DetachAniEnv(); + return; + } + auto tmpMap = stsObserverObjectMap_; + for (auto &item : tmpMap) { + auto processDataObj = AppManagerSts::WrapProcessData(env, processData); + if (processDataObj == nullptr) { + TAG_LOGE(AAFwkTag::APPMGR, "null processDataObj"); + DetachAniEnv(); + return; + } + CallStsFunction(env, item.second, "onProcessCreated", SIGNATURE_PROCESS_DATA, processDataObj); + } + DetachAniEnv(); +} + +void EtsAppStateObserver::OnProcessStateChanged(const ProcessData &processData) +{ + TAG_LOGD(AAFwkTag::APPMGR, "called"); + if (!valid_) { + TAG_LOGE(AAFwkTag::APPMGR, "appMgr may destroyed"); + return; + } + HandleOnProcessStateChanged(processData); +} + +void EtsAppStateObserver::HandleOnProcessStateChanged(const ProcessData &processData) +{ + ani_env *env = nullptr; + if (!GetAniEnv(env)) { + TAG_LOGE(AAFwkTag::APPMGR, "Failed to getAniEnv"); + DetachAniEnv(); + return; + } + auto tmpMap = stsObserverObjectMap_; + for (auto &item : tmpMap) { + auto processDataObj = AppManagerSts::WrapProcessData(env, processData); + if (processDataObj == nullptr) { + TAG_LOGE(AAFwkTag::APPMGR, "null processDataObj"); + DetachAniEnv(); + return; + } + CallStsFunction(env, item.second, "onProcessStateChanged", SIGNATURE_PROCESS_DATA, processDataObj); + } + DetachAniEnv(); +} + +void EtsAppStateObserver::OnProcessDied(const ProcessData &processData) +{ + TAG_LOGD(AAFwkTag::APPMGR, "called"); + if (!valid_) { + TAG_LOGE(AAFwkTag::APPMGR, "appmgr may destroyed"); + return; + } + HandleOnProcessDied(processData); +} + +void EtsAppStateObserver::HandleOnProcessDied(const ProcessData &processData) +{ + ani_env *env = nullptr; + if (!GetAniEnv(env)) { + TAG_LOGE(AAFwkTag::APPMGR, "Failed to getAniEnv"); + DetachAniEnv(); + return; + } + auto tmpMap = stsObserverObjectMap_; + for (auto &item : tmpMap) { + auto processDataObj = AppManagerSts::WrapProcessData(env, processData); + if (processDataObj == nullptr) { + TAG_LOGE(AAFwkTag::APPMGR, "null processDataObj"); + DetachAniEnv(); + return; + } + CallStsFunction(env, item.second, "onProcessDied", SIGNATURE_PROCESS_DATA, processDataObj); + } + DetachAniEnv(); +} + +void EtsAppStateObserver::OnAppStarted(const AppStateData &appStateData) +{ + TAG_LOGD(AAFwkTag::APPMGR, "bundleName:%{public}s, uid:%{public}d, state:%{public}d", + appStateData.bundleName.c_str(), appStateData.uid, appStateData.state); + if (!valid_) { + TAG_LOGE(AAFwkTag::APPMGR, "appMgr may destroyed"); + return; + } + HandleOnAppStarted(appStateData); +} + +void EtsAppStateObserver::HandleOnAppStarted(const AppStateData &appStateData) +{ + TAG_LOGD(AAFwkTag::APPMGR, "bundleName:%{public}s, uid:%{public}d, state:%{public}d", + appStateData.bundleName.c_str(), appStateData.uid, appStateData.state); + ani_env *env = nullptr; + if (!GetAniEnv(env)) { + TAG_LOGE(AAFwkTag::APPMGR, "Failed to getAniEnv"); + DetachAniEnv(); + return; + } + auto tmpMap = stsObserverObjectMap_; + for (auto &item : tmpMap) { + auto appStateDataObj = AppManagerSts::WrapAppStateData(env, appStateData); + if (appStateDataObj == nullptr) { + TAG_LOGE(AAFwkTag::APPMGR, "null appStateDataObj"); + DetachAniEnv(); + return; + } + CallStsFunction(env, item.second, "onAppStarted", SIGNATURE_APP_STATE_DATA, appStateDataObj); + } + DetachAniEnv(); +} + +void EtsAppStateObserver::OnAppStopped(const AppStateData &appStateData) +{ + TAG_LOGD(AAFwkTag::APPMGR, "bundleName:%{public}s, uid:%{public}d, state:%{public}d", + appStateData.bundleName.c_str(), appStateData.uid, appStateData.state); + if (!valid_) { + TAG_LOGE(AAFwkTag::APPMGR, "appMgr may destroyed"); + return; + } + HandleOnAppStopped(appStateData); +} + +void EtsAppStateObserver::HandleOnAppStopped(const AppStateData &appStateData) +{ + TAG_LOGD(AAFwkTag::APPMGR, "bundleName:%{public}s, uid:%{public}d, state:%{public}d", + appStateData.bundleName.c_str(), appStateData.uid, appStateData.state); + ani_env *env = nullptr; + if (!GetAniEnv(env)) { + TAG_LOGE(AAFwkTag::APPMGR, "Failed to getAniEnv"); + DetachAniEnv(); + return; + } + auto tmpMap = stsObserverObjectMap_; + for (auto &item : tmpMap) { + auto appStateDataObj = AppManagerSts::WrapAppStateData(env, appStateData); + if (appStateDataObj == nullptr) { + TAG_LOGE(AAFwkTag::APPMGR, "null appStateDataObj"); + DetachAniEnv(); + return; + } + CallStsFunction(env, item.second, "onAppStopped", SIGNATURE_APP_STATE_DATA, appStateDataObj); + } + DetachAniEnv(); +} + +void EtsAppStateObserver::CallStsFunction( + ani_env *env, ani_object StsObserverObject, const char *methodName, const char *signature, ...) +{ + TAG_LOGD(AAFwkTag::APPMGR, "call method:%{public}s", methodName); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::APPMGR, "null env"); + return; + } + ani_class cls; + ani_method method = nullptr; + ani_status status = ANI_OK; + status = env->FindClass(CLASS_NAME_APPLIACTION_STATE_OBSERVER, &cls); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::APPMGR, "Failed to find ApplicationStateObserver, status: %{public}d", status); + return; + } + if (cls == nullptr) { + TAG_LOGE(AAFwkTag::APPMGR, "null cls"); + return; + } + if ((status = env->Class_FindMethod(cls, methodName, signature, &method)) != ANI_OK) { + TAG_LOGE(AAFwkTag::APPMGR, "Failed to find method, status: %{public}d", status); + return; + } + if (method == nullptr) { + TAG_LOGE(AAFwkTag::APPMGR, "null method"); + 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::APPMGR, "Failed to call %{public}s method,status: %{public}d", methodName, status); + return; + } + va_end(args); + return; +} + +void EtsAppStateObserver::AddStsObserverObject(ani_env *env, const int32_t observerId, ani_object StsObserverObject) +{ + TAG_LOGD(AAFwkTag::APPMGR, "AddStsObserverObject"); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::APPMGR, "null env"); + return; + } + ani_ref global = nullptr; + ani_status status = ANI_ERROR; + if ((status = env->GlobalReference_Create(StsObserverObject, &global)) != ANI_OK) { + TAG_LOGE(AAFwkTag::APPMGR, "status: %{public}d", status); + return; + } + if (global == nullptr) { + TAG_LOGE(AAFwkTag::APPMGR, "null StsObserverObject ref"); + return; + } + stsObserverObjectMap_.emplace(observerId, reinterpret_cast(global)); +} + +bool EtsAppStateObserver::RemoveStsObserverObject(const int32_t observerId) +{ + TAG_LOGD(AAFwkTag::APPMGR, "RemoveStsObserverObject"); + bool result = (stsObserverObjectMap_.erase(observerId) == 1); + return result; +} + +bool EtsAppStateObserver::FindObserverByObserverId(const int32_t observerId) +{ + auto item = stsObserverObjectMap_.find(observerId); + bool isExist = (item != stsObserverObjectMap_.end()); + return isExist; +} + +size_t EtsAppStateObserver::GetStsObserverMapSize() +{ + size_t length = stsObserverObjectMap_.size(); + return length; +} + +void EtsAppStateObserver::SetValid(const bool valid) +{ + valid_ = valid; +} + +bool EtsAppStateObserver::GetAniEnv(ani_env *&env) { + if (etsVm_ == nullptr) { + TAG_LOGE(AAFwkTag::APPMGR, "etsVm_ nullptr"); + return false; + } + 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::APPMGR, "status: %{public}d", status); + return false; + } + if (env == nullptr) { + return false; + } + return true; +} + +void EtsAppStateObserver::DetachAniEnv() { + ani_status status = ANI_ERROR; + if ((status = etsVm_->DetachCurrentThread()) != ANI_OK) { + TAG_LOGE(AAFwkTag::APPMGR, "status: %{public}d", status); + } +} +} // namespace AbilityRuntime +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/ets/ani/app_manager/src/sts_app_manager.cpp b/frameworks/ets/ani/app_manager/src/sts_app_manager.cpp index 5c97d602c19fdf81a116556493ef46d7104c86d0..5032bb30fd98189712c2c24f8c3519307bc489f3 100644 --- a/frameworks/ets/ani/app_manager/src/sts_app_manager.cpp +++ b/frameworks/ets/ani/app_manager/src/sts_app_manager.cpp @@ -14,6 +14,7 @@ */ #include "sts_app_manager.h" +#include "ets_app_state_observer.h" #include "hilog_tag_wrapper.h" #include "ability_manager_client.h" #include "ability_manager_interface.h" @@ -44,10 +45,12 @@ static const char* ON_SIGNATURE_FIRST static const char* ON_SIGNATURE_SECOND = "Lstd/core/String;Lapplication/ApplicationStateObserver/ApplicationStateObserver;:D"; - static const char* OFF_SIGNATURE_FIRST = "Lstd/core/String;DLutils/AbilityUtils/AsyncCallbackWrapper;:V"; class StsAppManager final { +private: + static int32_t serialNumber_; + static sptr appStateObserver_; public: static OHOS::sptr GetAppManagerInstance() { @@ -330,35 +333,83 @@ public: GetRunningProcessInfoByBundleNameAndUserId(env, stsBundleName, AppExecFwk::Constants::INVALID_UID, callback); } -static ani_double OnOnApplicationStateInner(ani_env *env, ani_string type, - ani_object observer, ani_object stsBundleNameList) -{ - TAG_LOGD(AAFwkTag::APPMGR, "OnOnApplicationStateInner called"); - if (env == nullptr) { - TAG_LOGE(AAFwkTag::APPMGR, "env null ptr"); - return ANI_ERROR; - } - std::string strType; - if (!OHOS::AppExecFwk::GetStdString(env, type, strType)) { - TAG_LOGE(AAFwkTag::APPMGR, "env null ptr"); - AbilityRuntime::ThrowStsErrorByNativeErr(env, - static_cast(AbilityRuntime::AbilityErrorCode::ERROR_CODE_INVALID_PARAM)); - return ANI_ERROR; - } - auto appManager = GetAppManagerInstance(); - if (appManager == nullptr) { - TAG_LOGE(AAFwkTag::APPMGR, "null appManager"); - AbilityRuntime::ThrowStsErrorByNativeErr(env, - static_cast(AbilityRuntime::AbilityErrorCode::ERROR_CODE_INNER)); - return ANI_ERROR; - } - - std::vector bundleNameList; - if (stsBundleNameList != nullptr) { - UnWrapArrayString(env, stsBundleNameList, bundleNameList); + static int64_t GetObserverId() + { + int64_t observerId = serialNumber_; + if (serialNumber_ < INT32_MAX) { + serialNumber_++; + } else { + serialNumber_ = 0; + } + return observerId; + } + + static bool CheckOnOnApplicationStateInnerParam(ani_env *env, ani_string type, ani_object observer, + ani_object stsBundleNameList, std::vector& bundleNameList) + { + if (env == nullptr) { + TAG_LOGE(AAFwkTag::APPMGR, "env null ptr"); + return false; + } + std::string strType; + if (!OHOS::AppExecFwk::GetStdString(env, type, strType)) { + TAG_LOGE(AAFwkTag::APPMGR, "GetStdString failed"); + AbilityRuntime::ThrowStsErrorByNativeErr(env, + static_cast(AbilityRuntime::AbilityErrorCode::ERROR_CODE_INVALID_PARAM)); + return false; + } + ani_boolean isUndefined = false; + ani_status status = ANI_OK; + if ((status = env->Reference_IsUndefined(stsBundleNameList, &isUndefined)) != ANI_OK) { + TAG_LOGE(AAFwkTag::APPMGR, "Failed to check undefined status : %{public}d", status); + return false; + } + if (!isUndefined && !UnWrapArrayString(env, stsBundleNameList, bundleNameList)) { + TAG_LOGE(AAFwkTag::APPMGR, "GetStdString failed"); + AbilityRuntime::ThrowStsErrorByNativeErr(env, + static_cast(AbilityRuntime::AbilityErrorCode::ERROR_CODE_INVALID_PARAM)); + return false; + } + return true; + } + + static ani_double OnOnApplicationStateInner(ani_env *env, ani_string type, ani_object observer, + ani_object stsBundleNameList) + { + TAG_LOGD(AAFwkTag::APPMGR, "OnOnApplicationStateInner called"); + std::vector bundleNameList; + if (!CheckOnOnApplicationStateInnerParam(env, type, observer, stsBundleNameList, bundleNameList)) { + return ANI_ERROR; + } + auto appManager = GetAppManagerInstance(); + if (appManager == nullptr) { + TAG_LOGE(AAFwkTag::APPMGR, "null appManager"); + AbilityRuntime::ThrowStsErrorByNativeErr(env, + static_cast(AbilityRuntime::AbilityErrorCode::ERROR_CODE_INNER)); + return ANI_ERROR; + } + ani_vm *aniVM = nullptr; + if (env->GetVM(&aniVM) != ANI_OK) { + TAG_LOGE(AAFwkTag::UI_EXT, "get aniVM failed"); + AbilityRuntime::ThrowStsInvalidParamError(env, "Get aniVm failed."); + return ANI_ERROR; + } + if (appStateObserver_ == nullptr) { + appStateObserver_ = new AbilityRuntime::EtsAppStateObserver(aniVM); + } + int32_t ret = appManager->RegisterApplicationStateObserver(appStateObserver_, bundleNameList); + TAG_LOGD(AAFwkTag::APPMGR, "err:%{public}d", ret); + if (ret == ERR_OK) { + int64_t observerId = GetObserverId(); + appStateObserver_->AddStsObserverObject(env, observerId, observer); + return observerId; + } else { + AbilityRuntime::ThrowStsErrorByNativeErr(env, static_cast(ret)); + return ANI_ERROR; + } + TAG_LOGD(AAFwkTag::APPMGR, "OnOnApplicationStateInner end"); + return ANI_OK; } - return ANI_OK; -} static ani_double OnOnApplicationStateFirst(ani_env *env, ani_string type, ani_object observer, ani_object stsBundleNameList) @@ -368,12 +419,62 @@ static ani_double OnOnApplicationStateInner(ani_env *env, ani_string type, static ani_double OnOnApplicationStateSecond(ani_env *env, ani_string type, ani_object observer) { - return OnOnApplicationStateInner(env, type, observer, nullptr); + ani_ref undefined = nullptr; + env->GetUndefined(&undefined); + return OnOnApplicationStateInner(env, type, observer, static_cast(undefined)); + } + + static void OnOff(ani_env *env, ani_string type, ani_double stsObserverId, ani_object callback) + { + TAG_LOGD(AAFwkTag::APPMGR, "OnOff called"); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::APPMGR, "env null ptr"); + return; + } + std::string strType; + if (!OHOS::AppExecFwk::GetStdString(env, type, strType)) { + TAG_LOGE(AAFwkTag::APPMGR, "GetStdString failed"); + AppExecFwk::AsyncCallback(env, callback, + OHOS::AbilityRuntime::CreateStsErrorByNativeErr(env, + static_cast(AbilityRuntime::AbilityErrorCode::ERROR_CODE_INVALID_PARAM)), nullptr); + return; + } + TAG_LOGD(AAFwkTag::APPMGR, "observerId:%{public}f", stsObserverId); + int64_t observerId = static_cast(stsObserverId); + + sptr appMgr = GetAppManagerInstance(); + if (appMgr == nullptr) { + TAG_LOGE(AAFwkTag::APPMGR, "appManager null ptr"); + AppExecFwk::AsyncCallback(env, callback, + OHOS::AbilityRuntime::CreateStsErrorByNativeErr(env, + static_cast(AbilityRuntime::AbilityErrorCode::ERROR_CODE_INNER)), nullptr); + return; + } + if (appStateObserver_ == nullptr) { + TAG_LOGE(AAFwkTag::APPMGR, "null observer"); + AppExecFwk::AsyncCallback(env, callback, + OHOS::AbilityRuntime::CreateStsErrorByNativeErr(env, + static_cast(AbilityRuntime::AbilityErrorCode::ERROR_CODE_INNER)), nullptr); + return; + } + if (!appStateObserver_->FindObserverByObserverId(observerId)) { + TAG_LOGE(AAFwkTag::APPMGR, "not find observer:%{public}d", static_cast(observerId)); + AppExecFwk::AsyncCallback(env, callback, + OHOS::AbilityRuntime::CreateStsErrorByNativeErr(env, + static_cast(AbilityRuntime::AbilityErrorCode::ERROR_CODE_INVALID_PARAM)), nullptr); + return; + } + int32_t ret = appMgr->UnregisterApplicationStateObserver(appStateObserver_); + if (ret == 0 && appStateObserver_->RemoveStsObserverObject(observerId)) { + TAG_LOGD(AAFwkTag::APPMGR, "OnOff success"); + } else { + TAG_LOGE(AAFwkTag::APPMGR, "OnOff err:%{public}d", ret); + } + AppExecFwk::AsyncCallback(env, callback, + OHOS::AbilityRuntime::CreateStsErrorByNativeErr(env, static_cast(ret)), nullptr); + TAG_LOGD(AAFwkTag::APPMGR, "OnOff end"); } -static void OnOff(ani_env *env, [[maybe_unused]]ani_class aniClss) -{ -} static void GetAppMemorySize(ani_env *env, ani_object callback) { TAG_LOGD(AAFwkTag::APPMGR, "GetAppMemorySize called"); @@ -901,6 +1002,9 @@ static void OnOff(ani_env *env, [[maybe_unused]]ani_class aniClss) } }; //StsAppManager +int32_t StsAppManager::serialNumber_ = 0; +sptr StsAppManager::appStateObserver_ = nullptr; + void StsAppManagerRegistryInit(ani_env *env) { TAG_LOGD(AAFwkTag::APPMGR, "StsAppManagerRegistryInit call"); diff --git a/frameworks/ets/ets/BUILD.gn b/frameworks/ets/ets/BUILD.gn index 822ac5228c753a67577f1a1a1458149dc09b50c2..2d54e76619ecfac4978c75b2d99704f414b57808 100644 --- a/frameworks/ets/ets/BUILD.gn +++ b/frameworks/ets/ets/BUILD.gn @@ -915,6 +915,22 @@ ohos_prebuilt_etc("ability_runtime_extension_running_info_abc_etc") { deps = [ ":ability_runtime_extension_running_info_abc" ] } +generate_static_abc("application_state_observer_abc") { + base_url = "./" + files = [ "./application/ApplicationStateObserver.ets" ] + + is_boot_abc = "True" + device_dst_file = "/system/framework/application_state_observer_abc.abc" +} + +ohos_prebuilt_etc("application_state_observer_abc_etc") { + source = "$target_out_dir/application_state_observer_abc.abc" + module_install_dir = "framework" + subsystem_name = "ability" + part_name = "ability_runtime" + deps = [ ":application_state_observer_abc" ] +} + group("ets_packages") { deps = [ ":ability_ability_application_abc_etc", @@ -967,6 +983,7 @@ group("ets_packages") { ":ability_runtime_want_agent_abc_etc", ":ability_runtime_want_agent_info_abc_etc", ":ability_runtime_want_constant_abc_etc", + ":application_state_observer_abc_etc", ":service_extension_ability_abc_etc", ":ui_extension_ability_ani_etc", ":ability_runtime_OpenLink_Options_abc_etc", diff --git a/frameworks/ets/ets/application/ApplicationStateObserver.ets b/frameworks/ets/ets/application/ApplicationStateObserver.ets new file mode 100644 index 0000000000000000000000000000000000000000..964c6910cfcbbc050aa983ab37722e995e131ac1 --- /dev/null +++ b/frameworks/ets/ets/application/ApplicationStateObserver.ets @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2021-2023 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 AppStateData from 'application.AppStateData'; +import AbilityStateData from 'application.AbilityStateData'; +import processData from 'application.ProcessData'; + +class ApplicationStateObserver { + + onForegroundApplicationChanged(appStateData: AppStateData): void {} + + onAbilityStateChanged(abilityStateData: AbilityStateData): void {} + + onProcessCreated(processData: ProcessData): void {} + + onProcessDied(processData: ProcessData): void {} + + onProcessStateChanged(processData: ProcessData): void {} + + onAppStopped(appStateData: AppStateData): void {} + + onAppStopped(appStateData: AppStateData): void {} +} + +export type ProcessData = processData; +export default ApplicationStateObserver; \ No newline at end of file