From b31e63335c8e5b18470c2b51bd3d52a9e95c83df Mon Sep 17 00:00:00 2001 From: sty28558 Date: Wed, 3 Sep 2025 11:36:20 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=BA=94=E7=94=A8=E7=94=9F?= =?UTF-8?q?=E5=91=BD=E5=91=A8=E6=9C=9F=E6=8C=89=E9=9C=80=E7=9B=91=E5=90=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: sty28558 Change-Id: I96308b4a6b8c5252060cd0cb66454af4ba2da6e0 --- .../app/js_app_manager/js_app_manager.cpp | 42 +++- .../js_app_manager/js_app_manager_utils.cpp | 143 ++++++++++++ .../app/js_app_manager/js_app_manager_utils.h | 5 + frameworks/js/napi/inner/napi_common/BUILD.gn | 1 + .../napi_common_app_state_filter.cpp | 141 ++++++++++++ .../napi_common_app_state_filter.h | 32 +++ .../inner/napi_common/napi_common_util.cpp | 19 ++ .../napi/inner/napi_common/napi_common_util.h | 12 + interfaces/inner_api/app_manager/BUILD.gn | 1 + .../include/appmgr/app_mgr_client.h | 9 + .../include/appmgr/app_mgr_interface.h | 12 + .../appmgr/app_mgr_ipc_interface_code.h | 1 + .../include/appmgr/app_mgr_proxy.h | 9 + .../app_manager/include/appmgr/app_mgr_stub.h | 1 + .../include/appmgr/application_state_filter.h | 129 +++++++++++ .../app_manager/src/appmgr/app_mgr_client.cpp | 10 + .../app_manager/src/appmgr/app_mgr_proxy.cpp | 37 +++ .../app_manager/src/appmgr/app_mgr_stub.cpp | 21 ++ .../src/appmgr/application_state_filter.cpp | 182 +++++++++++++++ services/appmgr/include/app_mgr_service.h | 11 + .../appmgr/include/app_mgr_service_inner.h | 7 +- .../include/app_state_observer_manager.h | 16 +- services/appmgr/src/app_mgr_service.cpp | 12 + services/appmgr/src/app_mgr_service_inner.cpp | 13 +- services/appmgr/src/app_running_record.cpp | 3 +- .../appmgr/src/app_state_observer_manager.cpp | 208 ++++++++++++++--- test/unittest/BUILD.gn | 1 + .../application_state_filter_test/BUILD.gn | 55 +++++ .../application_state_filter_test.cpp | 217 ++++++++++++++++++ 29 files changed, 1295 insertions(+), 55 deletions(-) create mode 100644 frameworks/js/napi/inner/napi_common/napi_common_app_state_filter.cpp create mode 100644 frameworks/js/napi/inner/napi_common/napi_common_app_state_filter.h create mode 100644 interfaces/inner_api/app_manager/include/appmgr/application_state_filter.h create mode 100644 interfaces/inner_api/app_manager/src/appmgr/application_state_filter.cpp create mode 100644 test/unittest/application_state_filter_test/BUILD.gn create mode 100644 test/unittest/application_state_filter_test/application_state_filter_test.cpp diff --git a/frameworks/js/napi/app/js_app_manager/js_app_manager.cpp b/frameworks/js/napi/app/js_app_manager/js_app_manager.cpp index e49d958fa1d..ff64850992f 100644 --- a/frameworks/js/napi/app/js_app_manager/js_app_manager.cpp +++ b/frameworks/js/napi/app/js_app_manager/js_app_manager.cpp @@ -42,6 +42,7 @@ #include "js_runtime.h" #include "js_runtime_utils.h" #include "napi/native_api.h" +#include "napi_common_app_state_filter.h" #include "napi_common_util.h" #include "system_ability_definition.h" @@ -305,16 +306,46 @@ private: ThrowError(env, AbilityErrorCode::ERROR_CODE_INNER); return CreateJsUndefined(env); } - std::vector bundleNameList; // unwarp observer if (observer_ == nullptr) { observer_ = new JSAppStateObserver(env); } + OHOS::AppExecFwk::FilterCallback callbacks = static_cast( + static_cast(OHOS::AppExecFwk::FilterCallback::ON_FOREGROUND_APPLICATION_CHANGED) | + static_cast(OHOS::AppExecFwk::FilterCallback::ON_ABILITY_STATE_CHANGED) | + static_cast(OHOS::AppExecFwk::FilterCallback::ON_PROCESS_CREATED) | + static_cast(OHOS::AppExecFwk::FilterCallback::ON_PROCESS_STATE_CHANGED) | + static_cast(OHOS::AppExecFwk::FilterCallback::ON_APP_STARTED) | + static_cast(OHOS::AppExecFwk::FilterCallback::ON_APP_STOPPED) | + static_cast(OHOS::AppExecFwk::FilterCallback::ON_EXTENSION_STATE_CHANGED) + ); + OHOS::AppExecFwk::AppStateFilter appStateFilter {callbacks, OHOS::AppExecFwk::FilterBundleType::ALL, + OHOS::AppExecFwk::FilterAppStateType::ALL, OHOS::AppExecFwk::FilterProcessStateType::ALL, + OHOS::AppExecFwk::FilterAbilityStateType::ALL}; if (argc > ARGC_TWO) { - AppExecFwk::UnwrapArrayStringFromJS(env, argv[INDEX_TWO], bundleNameList); + bool isArray = true; + if (napi_is_array(env, argv[INDEX_TWO], &isArray) != napi_ok) { + TAG_LOGE(AAFwkTag::APPMGR, "judge array failed"); + ThrowError(env, AbilityErrorCode::ERROR_CODE_INNER); + return CreateJsUndefined(env); + } + if (isArray) { + if (!AppExecFwk::UnwrapArrayStringFromJS(env, argv[INDEX_TWO], bundleNameList)) { + ThrowInvalidParamError(env, "Parse bundleNameList failed, must be a string array."); + return CreateJsUndefined(env); + } + } else { + if (!AppExecFwk::UnwrapAppStateFilterFromJS(env, argv[INDEX_TWO], appStateFilter)) { + ThrowInvalidParamError(env, "Parse appStateFilter failed, value must be a combination of " + "values selected from enum FilterBundleType, FilterAppStateType, FilterProcessStateType " + "FilterAbilityStateType and FilterCallback."); + return CreateJsUndefined(env); + } + } } - int32_t ret = appManager_->RegisterApplicationStateObserver(observer_, bundleNameList); + int32_t ret = appManager_->RegisterApplicationStateObserverWithFilter(observer_, + bundleNameList, appStateFilter); if (ret == 0) { TAG_LOGD(AAFwkTag::APPMGR, "success"); int64_t observerId = serialNumber_; @@ -1875,6 +1906,11 @@ void JsAppManagerInitProperty(napi_env env, napi_value exportObj) napi_set_named_property(env, exportObj, "PreloadMode", PreloadModeInit(env)); napi_set_named_property(env, exportObj, "KeepAliveAppType", KeepAliveAppTypeInit(env)); napi_set_named_property(env, exportObj, "KeepAliveSetter", KeepAliveSetterInit(env)); + napi_set_named_property(env, exportObj, "FilterBundleType", FilterBundleTypeInit(env)); + napi_set_named_property(env, exportObj, "FilterAppStateType", FilterAppStateTypeInit(env)); + napi_set_named_property(env, exportObj, "FilterProcessStateType", FilterProcessStateTypeInit(env)); + napi_set_named_property(env, exportObj, "FilterAbilityStateType", FilterAbilityStateTypeInit(env)); + napi_set_named_property(env, exportObj, "FilterCallback", FilterCallbackInit(env)); } } // namespace AbilityRuntime } // namespace OHOS diff --git a/frameworks/js/napi/app/js_app_manager/js_app_manager_utils.cpp b/frameworks/js/napi/app/js_app_manager/js_app_manager_utils.cpp index f5498ba3309..de61e553ac9 100644 --- a/frameworks/js/napi/app/js_app_manager/js_app_manager_utils.cpp +++ b/frameworks/js/napi/app/js_app_manager/js_app_manager_utils.cpp @@ -17,6 +17,7 @@ #include +#include "application_state_filter.h" #include "hilog_tag_wrapper.h" #include "iapplication_state_observer.h" #include "js_app_process_state.h" @@ -400,5 +401,147 @@ napi_value CreateJsKeepAliveBundleInfoArray(napi_env env, const std::vector(AppExecFwk::FilterBundleType::APP))); + napi_set_named_property(env, object, "ATOMIC_SERVICE", + CreateJsValue(env, static_cast(AppExecFwk::FilterBundleType::ATOMIC_SERVICE))); + + return object; +} + +napi_value FilterAppStateTypeInit(napi_env env) +{ + TAG_LOGD(AAFwkTag::APPMGR, "called"); + + if (env == nullptr) { + TAG_LOGE(AAFwkTag::APPMGR, "null env"); + return nullptr; + } + + napi_value object = nullptr; + napi_create_object(env, &object); + if (object == nullptr) { + TAG_LOGE(AAFwkTag::APPMGR, "null obj"); + return nullptr; + } + + napi_set_named_property(env, object, "CREATE", + CreateJsValue(env, static_cast(AppExecFwk::FilterAppStateType::CREATE))); + napi_set_named_property(env, object, "FOREGROUND", + CreateJsValue(env, static_cast(AppExecFwk::FilterAppStateType::FOREGROUND))); + napi_set_named_property(env, object, "BACKGROUND", + CreateJsValue(env, static_cast(AppExecFwk::FilterAppStateType::BACKGROUND))); + napi_set_named_property(env, object, "DESTROY", + CreateJsValue(env, static_cast(AppExecFwk::FilterAppStateType::DESTROY))); + + return object; +} + +napi_value FilterProcessStateTypeInit(napi_env env) +{ + TAG_LOGD(AAFwkTag::APPMGR, "called"); + + if (env == nullptr) { + TAG_LOGE(AAFwkTag::APPMGR, "null env"); + return nullptr; + } + + napi_value object = nullptr; + napi_create_object(env, &object); + if (object == nullptr) { + TAG_LOGE(AAFwkTag::APPMGR, "null obj"); + return nullptr; + } + + napi_set_named_property(env, object, "CREATE", + CreateJsValue(env, static_cast(AppExecFwk::FilterProcessStateType::CREATE))); + napi_set_named_property(env, object, "FOREGROUND", + CreateJsValue(env, static_cast(AppExecFwk::FilterProcessStateType::FOREGROUND))); + napi_set_named_property(env, object, "BACKGROUND", + CreateJsValue(env, static_cast(AppExecFwk::FilterProcessStateType::BACKGROUND))); + napi_set_named_property(env, object, "DESTROY", + CreateJsValue(env, static_cast(AppExecFwk::FilterProcessStateType::DESTROY))); + + return object; +} + +napi_value FilterAbilityStateTypeInit(napi_env env) +{ + TAG_LOGD(AAFwkTag::APPMGR, "called"); + + if (env == nullptr) { + TAG_LOGE(AAFwkTag::APPMGR, "null env"); + return nullptr; + } + + napi_value object = nullptr; + napi_create_object(env, &object); + if (object == nullptr) { + TAG_LOGE(AAFwkTag::APPMGR, "null obj"); + return nullptr; + } + + napi_set_named_property(env, object, "CREATE", + CreateJsValue(env, static_cast(AppExecFwk::FilterAbilityStateType::CREATE))); + napi_set_named_property(env, object, "FOREGROUND", + CreateJsValue(env, static_cast(AppExecFwk::FilterAbilityStateType::FOREGROUND))); + napi_set_named_property(env, object, "BACKGROUND", + CreateJsValue(env, static_cast(AppExecFwk::FilterAbilityStateType::BACKGROUND))); + napi_set_named_property(env, object, "DESTROY", + CreateJsValue(env, static_cast(AppExecFwk::FilterAbilityStateType::DESTROY))); + + return object; +} + +napi_value FilterCallbackInit(napi_env env) +{ + TAG_LOGD(AAFwkTag::APPMGR, "called"); + + if (env == nullptr) { + TAG_LOGE(AAFwkTag::APPMGR, "null env"); + return nullptr; + } + + napi_value object = nullptr; + napi_create_object(env, &object); + if (object == nullptr) { + TAG_LOGE(AAFwkTag::APPMGR, "null obj"); + return nullptr; + } + + napi_set_named_property(env, object, "ON_FOREGROUND_APPLICATION_CHANGED", + CreateJsValue(env, static_cast(AppExecFwk::FilterCallback::ON_FOREGROUND_APPLICATION_CHANGED))); + napi_set_named_property(env, object, "ON_ABILITY_STATE_CHANGED", + CreateJsValue(env, static_cast(AppExecFwk::FilterCallback::ON_ABILITY_STATE_CHANGED))); + napi_set_named_property(env, object, "ON_PROCESS_CREATED", + CreateJsValue(env, static_cast(AppExecFwk::FilterCallback::ON_PROCESS_CREATED))); + napi_set_named_property(env, object, "ON_PROCESS_DIED", + CreateJsValue(env, static_cast(AppExecFwk::FilterCallback::ON_PROCESS_DIED))); + napi_set_named_property(env, object, "ON_PROCESS_STATE_CHANGED", + CreateJsValue(env, static_cast(AppExecFwk::FilterCallback::ON_PROCESS_STATE_CHANGED))); + napi_set_named_property(env, object, "ON_APP_STARTED", + CreateJsValue(env, static_cast(AppExecFwk::FilterCallback::ON_APP_STARTED))); + napi_set_named_property(env, object, "ON_APP_STOPPED", + CreateJsValue(env, static_cast(AppExecFwk::FilterCallback::ON_APP_STOPPED))); + + return object; +} } // namespace AbilityRuntime } // namespace OHOS diff --git a/frameworks/js/napi/app/js_app_manager/js_app_manager_utils.h b/frameworks/js/napi/app/js_app_manager/js_app_manager_utils.h index 9ce2dd06b7d..93876ccf84d 100644 --- a/frameworks/js/napi/app/js_app_manager/js_app_manager_utils.h +++ b/frameworks/js/napi/app/js_app_manager/js_app_manager_utils.h @@ -68,6 +68,11 @@ napi_value CreateJsRunningMultiInstanceInfosArray(napi_env env, const std::vecto napi_value CreateJsRunningMultiInstanceInfo(napi_env env, const RunningMultiInstanceInfo &info); napi_value CreateJsKeepAliveBundleInfo(napi_env env, const KeepAliveInfo &info); napi_value CreateJsKeepAliveBundleInfoArray(napi_env env, const std::vector& data); +napi_value FilterBundleTypeInit(napi_env env); +napi_value FilterAppStateTypeInit(napi_env env); +napi_value FilterProcessStateTypeInit(napi_env env); +napi_value FilterAbilityStateTypeInit(napi_env env); +napi_value FilterCallbackInit(napi_env env); } // namespace AbilityRuntime } // namespace OHOS #endif // OHOS_ABILITY_RUNTIME_JS_APP_MANAGER_UTILS_H diff --git a/frameworks/js/napi/inner/napi_common/BUILD.gn b/frameworks/js/napi/inner/napi_common/BUILD.gn index b950a7aab6f..d0befbd0117 100644 --- a/frameworks/js/napi/inner/napi_common/BUILD.gn +++ b/frameworks/js/napi/inner/napi_common/BUILD.gn @@ -31,6 +31,7 @@ ohos_shared_library("napi_common") { ] sources = [ + "napi_common_app_state_filter.cpp", "napi_common_configuration.cpp", "napi_common_execute_param.cpp", "napi_common_execute_result.cpp", diff --git a/frameworks/js/napi/inner/napi_common/napi_common_app_state_filter.cpp b/frameworks/js/napi/inner/napi_common/napi_common_app_state_filter.cpp new file mode 100644 index 00000000000..b519d96a49f --- /dev/null +++ b/frameworks/js/napi/inner/napi_common/napi_common_app_state_filter.cpp @@ -0,0 +1,141 @@ +/* + * 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 "application_state_filter.h" +#include "hilog_tag_wrapper.h" +#include "napi_common_app_state_filter.h" +#include "napi_common_util.h" + +namespace OHOS { +namespace AppExecFwk { +bool UnwrapFilterBundleTypeFromJS(napi_env env, napi_value param, FilterBundleType &filterBundleTypes) +{ + uint32_t bundleTypes = 0; + if (IsExistsByPropertyName(env, param, "bundleTypes")) { + if (!UnwrapUint32ByPropertyName(env, param, "bundleTypes", bundleTypes)) { + TAG_LOGE(AAFwkTag::JSNAPI, "Unwrap filterBundleTypes failed"); + return false; + } + uint32_t allBundleTypes = static_cast(FilterBundleType::APP) | + static_cast(FilterBundleType::ATOMIC_SERVICE); + if (bundleTypes & (~allBundleTypes)) { + TAG_LOGE(AAFwkTag::JSNAPI, "Invalid filterBundleTypes value: %{public}u", bundleTypes); + return false; + } + filterBundleTypes = static_cast(bundleTypes); + } + return true; +} + +bool UnwrapFilterAppStateTypeFromJS(napi_env env, napi_value param, FilterAppStateType &filterAppStateTypes) +{ + uint32_t appStateTypes = 0; + if (IsExistsByPropertyName(env, param, "appStateTypes")) { + if (!UnwrapUint32ByPropertyName(env, param, "appStateTypes", appStateTypes)) { + TAG_LOGE(AAFwkTag::JSNAPI, "Unwrap filterAppStateTypes failed"); + return false; + } + uint32_t allAppStateTypes = static_cast(FilterAppStateType::CREATE) | + static_cast(FilterAppStateType::FOREGROUND) | + static_cast(FilterAppStateType::BACKGROUND) | + static_cast(FilterAppStateType::DESTROY); + if (appStateTypes & (~allAppStateTypes)) { + TAG_LOGE(AAFwkTag::JSNAPI, "Invalid filterAppStateTypes value: %{public}u", appStateTypes); + return false; + } + filterAppStateTypes = static_cast(appStateTypes); + } + return true; +} + +bool UnwrapFilterProcessStateTypeFromJS(napi_env env, napi_value param, FilterProcessStateType &filterProcessStateTypes) +{ + uint32_t processStateTypes = 0; + if (IsExistsByPropertyName(env, param, "processStateTypes")) { + if (!UnwrapUint32ByPropertyName(env, param, "processStateTypes", processStateTypes)) { + TAG_LOGE(AAFwkTag::JSNAPI, "Unwrap filterProcessStateTypes failed"); + return false; + } + uint32_t allProcessStateTypes = static_cast(FilterProcessStateType::CREATE) | + static_cast(FilterProcessStateType::FOREGROUND) | + static_cast(FilterProcessStateType::BACKGROUND) | + static_cast(FilterProcessStateType::DESTROY); + if (processStateTypes & (~allProcessStateTypes)) { + TAG_LOGE(AAFwkTag::JSNAPI, "Invalid filterProcessStateTypes value: %{public}u", processStateTypes); + return false; + } + filterProcessStateTypes = static_cast(processStateTypes); + } + return true; +} + +bool UnwrapFilterAbilityStateTypeFromJS(napi_env env, napi_value param, FilterAbilityStateType &filterAbilityStateType) +{ + uint32_t abilityStateTypes = 0; + if (IsExistsByPropertyName(env, param, "abilityStateTypes")) { + if (!UnwrapUint32ByPropertyName(env, param, "abilityStateTypes", abilityStateTypes)) { + TAG_LOGE(AAFwkTag::JSNAPI, "Unwrap filterAbilityStateTypes failed"); + return false; + } + uint32_t allAbilityStateTypes = static_cast(FilterAbilityStateType::CREATE) | + static_cast(FilterAbilityStateType::FOREGROUND) | + static_cast(FilterAbilityStateType::BACKGROUND) | + static_cast(FilterAbilityStateType::DESTROY); + if (abilityStateTypes & (~allAbilityStateTypes)) { + TAG_LOGE(AAFwkTag::JSNAPI, "Invalid filterAbilityStateTypes value: %{public}u", abilityStateTypes); + return false; + } + filterAbilityStateType = static_cast(abilityStateTypes); + } + return true; +} + +bool UnwrapFilterCallbackFromJS(napi_env env, napi_value param, FilterCallback &filterCallback) +{ + uint32_t callbacks = 0; + if (IsExistsByPropertyName(env, param, "callbacks")) { + if (!UnwrapUint32ByPropertyName(env, param, "callbacks", callbacks)) { + TAG_LOGE(AAFwkTag::JSNAPI, "Unwrap filterCallbacks failed"); + return false; + } + uint32_t allCallbacks = static_cast(FilterCallback::ON_FOREGROUND_APPLICATION_CHANGED) | + static_cast(FilterCallback::ON_ABILITY_STATE_CHANGED) | + static_cast(FilterCallback::ON_PROCESS_CREATED) | + static_cast(FilterCallback::ON_PROCESS_DIED) | + static_cast(FilterCallback::ON_PROCESS_STATE_CHANGED) | + static_cast(FilterCallback::ON_APP_STARTED) | + static_cast(FilterCallback::ON_APP_STOPPED); + if (callbacks & (~allCallbacks)) { + TAG_LOGE(AAFwkTag::JSNAPI, "Invalid filterCallbacks value: %{public}u", callbacks); + return false; + } + filterCallback = static_cast(callbacks); + } + return true; +} + +bool UnwrapAppStateFilterFromJS(napi_env env, napi_value param, AppStateFilter &appStateFilter) +{ + if (UnwrapFilterBundleTypeFromJS(env, param, appStateFilter.bundleTypes) && + UnwrapFilterAppStateTypeFromJS(env, param, appStateFilter.appStateTypes) && + UnwrapFilterProcessStateTypeFromJS(env, param, appStateFilter.processStateTypes) && + UnwrapFilterAbilityStateTypeFromJS(env, param, appStateFilter.abilityStateTypes) && + UnwrapFilterCallbackFromJS(env, param, appStateFilter.callbacks)) { + return true; + } + return false; +} +} // namespace AppExecFwk +} // namespace OHOS diff --git a/frameworks/js/napi/inner/napi_common/napi_common_app_state_filter.h b/frameworks/js/napi/inner/napi_common/napi_common_app_state_filter.h new file mode 100644 index 00000000000..9a526f875ae --- /dev/null +++ b/frameworks/js/napi/inner/napi_common/napi_common_app_state_filter.h @@ -0,0 +1,32 @@ +/* + * 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 perns and + * limitations under the License. + */ + +#ifndef OHOS_ABILITY_RUNTIME_NAPI_COMMON_APP_STATE_FILTER +#define OHOS_ABILITY_RUNTIME_NAPI_COMMON_APP_STATE_FILTER + +#include "application_state_filter.h" +#include "napi/native_api.h" + +namespace OHOS { +namespace AppExecFwk { +bool UnwrapFilterBundleTypeFromJS(napi_env env, napi_value param, FilterBundleType &filterBundleTypes); +bool UnwrapFilterAppStateTypeFromJS(napi_env env, napi_value param, FilterAppStateType &filterAppStateTypes); +bool UnwrapFilterProcessStateTypeFromJS(napi_env env, napi_value param, FilterProcessStateType &processStateType); +bool UnwrapFilterAbilityStateTypeFromJS(napi_env env, napi_value param, FilterAbilityStateType &abilityStateType); +bool UnwrapFilterCallbackFromJS(napi_env env, napi_value param, FilterCallback &callback); +bool UnwrapAppStateFilterFromJS(napi_env env, napi_value param, AppStateFilter &appStateFilter); +} // namespace AppExecFwk +} // namespace OHOS +#endif // OHOS_ABILITY_RUNTIME_NAPI_COMMON_APP_STATE_FILTER diff --git a/frameworks/js/napi/inner/napi_common/napi_common_util.cpp b/frameworks/js/napi/inner/napi_common/napi_common_util.cpp index 7629889f4ee..050b792fe86 100644 --- a/frameworks/js/napi/inner/napi_common/napi_common_util.cpp +++ b/frameworks/js/napi/inner/napi_common/napi_common_util.cpp @@ -1320,5 +1320,24 @@ bool UnwrapLocaleFromJS(napi_env env, napi_value jsValue, std::string &value) return UnwrapStringFromJS2(env, locale, value); } + +/** + * @brief Get the native number(uint32) from the JSObject of the given property name. + * + * @param env The environment that the Node-API call is invoked under. + * @param jsObject Indicates object passed by JS. + * @param propertyName Indicates the name of the property. + * @param value Indicates the returned native value. + * + * @return Return true if successful, else return false. + */ +bool UnwrapUint32ByPropertyName(napi_env env, napi_value jsObject, const char *propertyName, uint32_t &value) +{ + napi_value jsValue = GetPropertyValueByPropertyName(env, jsObject, propertyName, napi_number); + if (jsValue != nullptr) { + return napi_get_value_uint32(env, jsValue, &value) == napi_ok; + } + return false; +} } // namespace AppExecFwk } // namespace OHOS diff --git a/frameworks/js/napi/inner/napi_common/napi_common_util.h b/frameworks/js/napi/inner/napi_common/napi_common_util.h index 40210b1de30..dd83a40975a 100644 --- a/frameworks/js/napi/inner/napi_common/napi_common_util.h +++ b/frameworks/js/napi/inner/napi_common/napi_common_util.h @@ -273,6 +273,18 @@ napi_value WrapLocaleToJS(napi_env env, const std::string &locale); bool UnwrapLocaleByPropertyName(napi_env env, napi_value jsObject, const char *propertyName, std::string &value); bool UnwrapLocaleFromJS(napi_env env, napi_value jsValue, std::string &value); + +/** + * @brief Get the native number(uint32) from the JSObject of the given property name. + * + * @param env The environment that the Node-API call is invoked under. + * @param jsObject Indicates object passed by JS. + * @param propertyName Indicates the name of the property. + * @param value Indicates the returned native value. + * + * @return Return true if successful, else return false. + */ +bool UnwrapUint32ByPropertyName(napi_env env, napi_value jsObject, const char *propertyName, uint32_t &value); } // namespace AppExecFwk } // namespace OHOS #endif // OHOS_ABILITY_RUNTIME_NAPI_COMMON_UTIL_H diff --git a/interfaces/inner_api/app_manager/BUILD.gn b/interfaces/inner_api/app_manager/BUILD.gn index d83479d9bdf..8ab423e112b 100644 --- a/interfaces/inner_api/app_manager/BUILD.gn +++ b/interfaces/inner_api/app_manager/BUILD.gn @@ -89,6 +89,7 @@ ohos_shared_library("app_manager") { "src/appmgr/app_state_callback_host.cpp", "src/appmgr/app_state_callback_proxy.cpp", "src/appmgr/app_state_data.cpp", + "src/appmgr/application_state_filter.cpp", "src/appmgr/application_state_observer_proxy.cpp", "src/appmgr/application_state_observer_stub.cpp", "src/appmgr/background_app_info.cpp", diff --git a/interfaces/inner_api/app_manager/include/appmgr/app_mgr_client.h b/interfaces/inner_api/app_manager/include/appmgr/app_mgr_client.h index f0d825d8021..c016335bbb7 100644 --- a/interfaces/inner_api/app_manager/include/appmgr/app_mgr_client.h +++ b/interfaces/inner_api/app_manager/include/appmgr/app_mgr_client.h @@ -25,6 +25,7 @@ #include "app_mgr_interface.h" #include "app_running_status_listener_interface.h" #include "application_info.h" +#include "application_state_filter.h" #include "bundle_info.h" #include "fault_data.h" #include "iapplication_state_observer.h" @@ -1015,6 +1016,14 @@ public: int32_t QueryRunningSharedBundles(pid_t pid, std::map &sharedBundles); int32_t VerifyKillProcessPermission(const std::string &bundleName) const; + + /** + * Register application, process or ability state observer. + * @param observer, bundleNameList, appStateFilter. + * @return Returns ERR_OK on success, others on failure. + */ + int32_t RegisterApplicationStateObserverWithFilter(sptr observer, + const std::vector &bundleNameList = {}, const AppStateFilter &appStateFilter = AppStateFilter()); private: void SetServiceManager(std::unique_ptr serviceMgr); diff --git a/interfaces/inner_api/app_manager/include/appmgr/app_mgr_interface.h b/interfaces/inner_api/app_manager/include/appmgr/app_mgr_interface.h index 23f1637d927..9a1fde01486 100644 --- a/interfaces/inner_api/app_manager/include/appmgr/app_mgr_interface.h +++ b/interfaces/inner_api/app_manager/include/appmgr/app_mgr_interface.h @@ -24,6 +24,7 @@ #include "app_mgr_ipc_interface_code.h" #include "app_record_id.h" #include "application_info.h" +#include "application_state_filter.h" #include "background_app_info.h" #include "bundle_info.h" #include "child_process_info.h" @@ -331,6 +332,17 @@ public: virtual int32_t RegisterApplicationStateObserver(const sptr &observer, const std::vector &bundleNameList = {}) = 0; + /** + * Register application/process/ability state observer. + * @param observer, bundleNameList, AppStateFilter. + * @return Returns ERR_OK on success, others on failure. + */ + virtual int32_t RegisterApplicationStateObserverWithFilter(sptr observer, + const std::vector &bundleNameList = {}, const AppStateFilter &appStateFilter = AppStateFilter()) + { + return 0; + } + /** * Unregister application or process state observer. * @param observer, ability token. diff --git a/interfaces/inner_api/app_manager/include/appmgr/app_mgr_ipc_interface_code.h b/interfaces/inner_api/app_manager/include/appmgr/app_mgr_ipc_interface_code.h index 84c34ddefb1..c650c94910c 100644 --- a/interfaces/inner_api/app_manager/include/appmgr/app_mgr_ipc_interface_code.h +++ b/interfaces/inner_api/app_manager/include/appmgr/app_mgr_ipc_interface_code.h @@ -136,6 +136,7 @@ enum class AppMgrInterfaceCode { PRELOAD_MODULE_FINISHED = 111, QUERY_RUNNING_SHARED_BUNDLES = 112, EXIT_MASTER_PROCESS_ROLE = 113, + REGISTER_APPLICATION_STATE_OBSERVER_WITH_FILTER = 114, }; } // AppExecFwk } // OHOS diff --git a/interfaces/inner_api/app_manager/include/appmgr/app_mgr_proxy.h b/interfaces/inner_api/app_manager/include/appmgr/app_mgr_proxy.h index b2ffb02bd46..727cdfdb947 100644 --- a/interfaces/inner_api/app_manager/include/appmgr/app_mgr_proxy.h +++ b/interfaces/inner_api/app_manager/include/appmgr/app_mgr_proxy.h @@ -869,6 +869,15 @@ public: */ int32_t ExitMasterProcessRole() override; + /** + * Register application, process or ability state observer. + * @param observer, AppStateFilter. + * @return Returns ERR_OK on success, others on failure. + */ + int32_t RegisterApplicationStateObserverWithFilter(sptr observer, + const std::vector &bundleNameList = {}, + const AppStateFilter &appStateFilter = AppStateFilter()) override; + private: bool SendTransactCmd(AppMgrInterfaceCode code, MessageParcel &data, MessageParcel &reply); bool WriteInterfaceToken(MessageParcel &data); diff --git a/interfaces/inner_api/app_manager/include/appmgr/app_mgr_stub.h b/interfaces/inner_api/app_manager/include/appmgr/app_mgr_stub.h index 0701c71a7bf..790efd5c6aa 100644 --- a/interfaces/inner_api/app_manager/include/appmgr/app_mgr_stub.h +++ b/interfaces/inner_api/app_manager/include/appmgr/app_mgr_stub.h @@ -201,6 +201,7 @@ private: int32_t HandlePromoteCurrentToCandidateMasterProcess(MessageParcel &data, MessageParcel &reply); int32_t HandleDemoteCurrentFromCandidateMasterProcess(MessageParcel &data, MessageParcel &reply); int32_t HandleExitMasterProcessRole(MessageParcel &data, MessageParcel &reply); + int32_t HandleRegisterApplicationStateObserverWithFilter(MessageParcel &data, MessageParcel &reply); DISALLOW_COPY_AND_MOVE(AppMgrStub); }; } // namespace AppExecFwk diff --git a/interfaces/inner_api/app_manager/include/appmgr/application_state_filter.h b/interfaces/inner_api/app_manager/include/appmgr/application_state_filter.h new file mode 100644 index 00000000000..34fe67f63b0 --- /dev/null +++ b/interfaces/inner_api/app_manager/include/appmgr/application_state_filter.h @@ -0,0 +1,129 @@ +/* + * 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_APPLICATION_STATE_FILTER_H +#define OHOS_ABILITY_RUNTIME_APPLICATION_STATE_FILTER_H + +#include "ability_state_data.h" +#include "app_state_data.h" +#include "page_state_data.h" +#include "preload_process_data.h" +#include "process_data.h" +#include "process_bind_data.h" +#include "parcel.h" + +namespace OHOS { +namespace AppExecFwk { +enum class FilterBundleType : uint32_t { + NONE = 0, + APP = 1 << 0, + ATOMIC_SERVICE = 1 << 1, + SHARED = 1 << 2, + APP_SERVICE_FWK = 1 << 3, + APP_PLUGIN = 1 << 4, + ALL = 0xFFFFFFFF, +}; + +enum class FilterAppStateType : uint32_t { + NONE = 0, + CREATE = 1 << 0, + FOREGROUND = 1 << 1, + BACKGROUND = 1 << 2, + DESTROY = 1 << 3, + READY = 1 << 4, + FOCUS = 1 << 5, + END = 1 << 6, + SET_COLD_START = 1 << 7, + CACHED = 1 << 8, + PRE_FOREGROUND = 1 << 9, + ALL = 0xFFFFFFFF, +}; + +enum class FilterProcessStateType : uint32_t { + NONE = 0, + CREATE = 1 << 0, + FOREGROUND = 1 << 1, + BACKGROUND = 1 << 2, + DESTROY = 1 << 3, + READY = 1 << 4, + FOCUS = 1 << 5, + END = 1 << 6, + CACHED = 1 << 7, + PRE_FOREGROUND = 1 << 8, + ALL = 0xFFFFFFFF, +}; + +enum class FilterAbilityStateType : uint32_t { + NONE = 0, + CREATE = 1 << 0, + FOREGROUND = 1 << 1, + BACKGROUND = 1 << 2, + DESTROY = 1 << 3, + READY = 1 << 4, + FOCUS = 1 << 5, + END = 1 << 6, + CONNECTED = 1 << 7, + DISCONNECTED = 1 << 8, + ALL = 0xFFFFFFFF, +}; + +enum class FilterCallback : uint32_t { + NONE = 0, + ON_FOREGROUND_APPLICATION_CHANGED = 1 << 0, + ON_ABILITY_STATE_CHANGED = 1 << 1, + ON_PROCESS_CREATED = 1 << 2, + ON_PROCESS_DIED = 1 << 3, + ON_PROCESS_STATE_CHANGED = 1 << 4, + ON_APP_STARTED = 1 << 5, + ON_APP_STOPPED = 1 << 6, + ON_EXTENSION_STATE_CHANGED = 1 << 7, + ON_WINDOW_SHOW = 1 << 8, + ON_WINDOW_HIDDEN = 1 << 9, + ON_APPLICATION_STATE_CHANGED = 1 << 10, + ON_APP_STATE_CHANGED = 1 << 11, + ON_PROCESS_REUSED = 1 << 12, + ON_PAGE_SHOW = 1 << 13, + ON_PAGE_HIDE = 1 << 14, + ON_APP_CACHE_STATE_CHANGED = 1 << 15, + ON_PROCESS_BINDING_RELATION_CHANGED = 1 << 16, + ON_KEEPALIVE_STATE_CHANGED = 1 << 17, + ON_PROCESS_PREFOREGROUND_CHANGED = 1 << 18, + ALL = 0xFFFFFFFF, +}; + +class AppStateFilter : public Parcelable { +public: + FilterCallback callbacks = FilterCallback::ALL; + FilterBundleType bundleTypes = FilterBundleType::ALL; + FilterAppStateType appStateTypes = FilterAppStateType::ALL; + FilterProcessStateType processStateTypes = FilterProcessStateType::ALL; + FilterAbilityStateType abilityStateTypes = FilterAbilityStateType::ALL; + + AppStateFilter(); + ~AppStateFilter() = default; + AppStateFilter(FilterCallback callbacks, FilterBundleType bundleTypes, FilterAppStateType appStateTypes, + FilterProcessStateType processStateTypes, FilterAbilityStateType abilityStateTypes); + bool ReadFromParcel(Parcel &parcel); + virtual bool Marshalling(Parcel &parcel) const override; + static AppStateFilter *Unmarshalling(Parcel &parcel); + bool Match(const AppStateFilter& filter); +}; +FilterAppStateType GetFilterTypeFromApplicationState(ApplicationState state); +FilterProcessStateType GetFilterTypeFromAppProcessState(AppProcessState state); +FilterAbilityStateType GetFilterTypeFromAbilityState(AbilityState state); +FilterBundleType GetFilterTypeFromBundleType(BundleType state); +} // namespace AppExecFwk +} // namespace OHOS +#endif // OHOS_ABILITY_RUNTIME_APPLICATION_STATE_FILTER_H diff --git a/interfaces/inner_api/app_manager/src/appmgr/app_mgr_client.cpp b/interfaces/inner_api/app_manager/src/appmgr/app_mgr_client.cpp index 92c19f685cf..825ffb18e73 100644 --- a/interfaces/inner_api/app_manager/src/appmgr/app_mgr_client.cpp +++ b/interfaces/inner_api/app_manager/src/appmgr/app_mgr_client.cpp @@ -1746,5 +1746,15 @@ int32_t AppMgrClient::VerifyKillProcessPermission(const std::string &bundleName) } return amsService->VerifyKillProcessPermission(bundleName); } + +int32_t AppMgrClient::RegisterApplicationStateObserverWithFilter(sptr observer, + const std::vector &bundleNameList, const AppStateFilter &appStateFilter) +{ + sptr service = iface_cast(mgrHolder_->GetRemoteObject()); + if (service == nullptr) { + return AppMgrResultCode::ERROR_SERVICE_NOT_CONNECTED; + } + return service->RegisterApplicationStateObserverWithFilter(observer, bundleNameList, appStateFilter); +} } // namespace AppExecFwk } // namespace OHOS diff --git a/interfaces/inner_api/app_manager/src/appmgr/app_mgr_proxy.cpp b/interfaces/inner_api/app_manager/src/appmgr/app_mgr_proxy.cpp index 396c3d446b8..3a6089da5d1 100644 --- a/interfaces/inner_api/app_manager/src/appmgr/app_mgr_proxy.cpp +++ b/interfaces/inner_api/app_manager/src/appmgr/app_mgr_proxy.cpp @@ -2499,5 +2499,42 @@ int32_t AppMgrProxy::QueryRunningSharedBundles(pid_t pid, std::map observer, + const std::vector &bundleNameList, const AppStateFilter &appStateFilter) +{ + if (!observer) { + TAG_LOGE(AAFwkTag::APPMGR, "observer null"); + return ERR_INVALID_VALUE; + } + TAG_LOGD(AAFwkTag::APPMGR, "RegisterApplicationStateObserverWithFilter start"); + MessageParcel data; + MessageParcel reply; + MessageOption option(MessageOption::TF_SYNC); + if (!WriteInterfaceToken(data)) { + TAG_LOGE(AAFwkTag::APPMGR, "Write interface token failed."); + return AAFwk::ERR_WRITE_INTERFACE_TOKEN_FAILED; + } + if (!data.WriteRemoteObject(observer->AsObject())) { + TAG_LOGE(AAFwkTag::APPMGR, "observer write failed."); + return ERR_FLATTEN_OBJECT; + } + if (!data.WriteStringVector(bundleNameList)) { + TAG_LOGE(AAFwkTag::APPMGR, "bundleNameList write failed."); + return ERR_FLATTEN_OBJECT; + } + if (!data.WriteParcelable(&appStateFilter)) { + TAG_LOGE(AAFwkTag::APPMGR, "appStateFilter write failed."); + return ERR_FLATTEN_OBJECT; + } + + auto error = SendRequest(AppMgrInterfaceCode::REGISTER_APPLICATION_STATE_OBSERVER_WITH_FILTER, + data, reply, option); + if (error != NO_ERROR) { + TAG_LOGE(AAFwkTag::APPMGR, "Send request error: %{public}d", error); + return error; + } + return reply.ReadInt32(); +} } // namespace AppExecFwk } // namespace OHOS diff --git a/interfaces/inner_api/app_manager/src/appmgr/app_mgr_stub.cpp b/interfaces/inner_api/app_manager/src/appmgr/app_mgr_stub.cpp index a99518bebb2..d8308df4d38 100644 --- a/interfaces/inner_api/app_manager/src/appmgr/app_mgr_stub.cpp +++ b/interfaces/inner_api/app_manager/src/appmgr/app_mgr_stub.cpp @@ -138,6 +138,8 @@ int32_t AppMgrStub::OnRemoteRequestInnerFirst(uint32_t code, MessageParcel &data return HandleUnregisterApplicationStateObserver(data, reply); case static_cast(AppMgrInterfaceCode::PRELOAD_MODULE_FINISHED): return HandlePreloadModuleFinished(data, reply); + case static_cast(AppMgrInterfaceCode::REGISTER_APPLICATION_STATE_OBSERVER_WITH_FILTER): + return HandleRegisterApplicationStateObserverWithFilter(data, reply); } return INVALID_FD; } @@ -2084,5 +2086,24 @@ int32_t AppMgrStub::HandleQueryRunningSharedBundles(MessageParcel &data, Message } return NO_ERROR; } + +int32_t AppMgrStub::HandleRegisterApplicationStateObserverWithFilter(MessageParcel &data, MessageParcel &reply) +{ + std::vector bundleNameList; + auto callback = iface_cast(data.ReadRemoteObject()); + if (callback == nullptr) { + TAG_LOGE(AAFwkTag::APPMGR, "Callback is null."); + return ERR_INVALID_VALUE; + } + data.ReadStringVector(&bundleNameList); + std::unique_ptr appStateFilter(data.ReadParcelable()); + if (appStateFilter == nullptr) { + TAG_LOGE(AAFwkTag::APPMGR, "appStateFilter is nullptr"); + return ERR_INVALID_VALUE; + } + int32_t result = RegisterApplicationStateObserverWithFilter(callback, bundleNameList, *appStateFilter); + reply.WriteInt32(result); + return NO_ERROR; +} } // namespace AppExecFwk } // namespace OHOS diff --git a/interfaces/inner_api/app_manager/src/appmgr/application_state_filter.cpp b/interfaces/inner_api/app_manager/src/appmgr/application_state_filter.cpp new file mode 100644 index 00000000000..258c4046f8f --- /dev/null +++ b/interfaces/inner_api/app_manager/src/appmgr/application_state_filter.cpp @@ -0,0 +1,182 @@ +/* + * 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 "application_state_filter.h" +#include "hilog_tag_wrapper.h" +#include "message_parcel.h" +#include "parcel_macro_base.h" +#include "string_ex.h" + +namespace OHOS { +namespace AppExecFwk { + +AppStateFilter::AppStateFilter() +{ +} + +AppStateFilter::AppStateFilter(FilterCallback callbacks, FilterBundleType bundleTypes, FilterAppStateType appStateTypes, + FilterProcessStateType processStateTypes, FilterAbilityStateType abilityStateTypes) + : callbacks(callbacks), + bundleTypes(bundleTypes), + appStateTypes(appStateTypes), + processStateTypes(processStateTypes), + abilityStateTypes(abilityStateTypes) +{ +} + +bool AppStateFilter::ReadFromParcel(Parcel &parcel) +{ + callbacks = static_cast(parcel.ReadUint32()); + bundleTypes = static_cast(parcel.ReadUint32()); + appStateTypes = static_cast(parcel.ReadUint32()); + processStateTypes = static_cast(parcel.ReadUint32()); + abilityStateTypes = static_cast(parcel.ReadUint32()); + return true; +} + +AppStateFilter *AppStateFilter::Unmarshalling(Parcel &parcel) +{ + AppStateFilter *obj = new (std::nothrow) AppStateFilter(); + if (obj && !obj->ReadFromParcel(parcel)) { + TAG_LOGW(AAFwkTag::APPMGR, "read from parcel failed"); + delete obj; + obj = nullptr; + } + return obj; +} + +bool AppStateFilter::Marshalling(Parcel &parcel) const +{ + if (!parcel.WriteUint32(static_cast(callbacks))) { + TAG_LOGE(AAFwkTag::APPMGR, "write callbacks failed"); + return false; + } + if (!parcel.WriteUint32(static_cast(bundleTypes))) { + TAG_LOGE(AAFwkTag::APPMGR, "write bundleTypes failed"); + return false; + } + if (!parcel.WriteUint32(static_cast(appStateTypes))) { + TAG_LOGE(AAFwkTag::APPMGR, "write appStateTypes failed"); + return false; + } + if (!parcel.WriteUint32(static_cast(processStateTypes))) { + TAG_LOGE(AAFwkTag::APPMGR, "write processStateTypes failed"); + return false; + } + if (!parcel.WriteUint32(static_cast(abilityStateTypes))) { + TAG_LOGE(AAFwkTag::APPMGR, "write abilityStateTypes failed"); + return false; + } + return true; +} + +bool AppStateFilter::Match(const AppStateFilter& filter) +{ + if (!(static_cast(bundleTypes) & static_cast(filter.bundleTypes)) || + !(static_cast(callbacks) & static_cast(filter.callbacks))) { + return false; + } + if ((static_cast(appStateTypes) & static_cast(filter.appStateTypes)) || + (static_cast(processStateTypes) & static_cast(filter.processStateTypes)) || + (static_cast(abilityStateTypes) & static_cast(filter.abilityStateTypes))) { + return true; + } + return false; +} + +std::unordered_map APPLICATION_STATE_TO_FILTER_MAP = { + {ApplicationState::APP_STATE_CREATE, FilterAppStateType::CREATE}, + {ApplicationState::APP_STATE_FOREGROUND, FilterAppStateType::FOREGROUND}, + {ApplicationState::APP_STATE_BACKGROUND, FilterAppStateType::BACKGROUND}, + {ApplicationState::APP_STATE_TERMINATED, FilterAppStateType::DESTROY}, + {ApplicationState::APP_STATE_READY, FilterAppStateType::READY}, + {ApplicationState::APP_STATE_FOCUS, FilterAppStateType::FOCUS}, + {ApplicationState::APP_STATE_END, FilterAppStateType::END}, + {ApplicationState::APP_STATE_SET_COLD_START, FilterAppStateType::SET_COLD_START}, + {ApplicationState::APP_STATE_CACHED, FilterAppStateType::CACHED}, + {ApplicationState::APP_STATE_PRE_FOREGROUND, FilterAppStateType::PRE_FOREGROUND}, +}; + +std::unordered_map APP_PROCESS_STATE_TO_FILTER_MAP = { + {AppProcessState::APP_STATE_CREATE, FilterProcessStateType::CREATE}, + {AppProcessState::APP_STATE_FOREGROUND, FilterProcessStateType::FOREGROUND}, + {AppProcessState::APP_STATE_BACKGROUND, FilterProcessStateType::BACKGROUND}, + {AppProcessState::APP_STATE_TERMINATED, FilterProcessStateType::DESTROY}, + {AppProcessState::APP_STATE_READY, FilterProcessStateType::READY}, + {AppProcessState::APP_STATE_FOCUS, FilterProcessStateType::FOCUS}, + {AppProcessState::APP_STATE_END, FilterProcessStateType::END}, + {AppProcessState::APP_STATE_CACHED, FilterProcessStateType::CACHED}, + {AppProcessState::APP_STATE_PRE_FOREGROUND, FilterProcessStateType::PRE_FOREGROUND}, +}; + +std::unordered_map ABILITY_STATE_TO_FILTER_MAP = { + {AbilityState::ABILITY_STATE_CREATE, FilterAbilityStateType::CREATE}, + {AbilityState::ABILITY_STATE_FOREGROUND, FilterAbilityStateType::FOREGROUND}, + {AbilityState::ABILITY_STATE_BACKGROUND, FilterAbilityStateType::BACKGROUND}, + {AbilityState::ABILITY_STATE_TERMINATED, FilterAbilityStateType::DESTROY}, + {AbilityState::ABILITY_STATE_READY, FilterAbilityStateType::READY}, + {AbilityState::ABILITY_STATE_FOCUS, FilterAbilityStateType::FOCUS}, + {AbilityState::ABILITY_STATE_END, FilterAbilityStateType::END}, + {AbilityState::ABILITY_STATE_CONNECTED, FilterAbilityStateType::CONNECTED}, + {AbilityState::ABILITY_STATE_DISCONNECTED, FilterAbilityStateType::DISCONNECTED}, +}; + +std::unordered_map BUNDLE_TYPE_TO_FILTER_MAP = { + {BundleType::APP, FilterBundleType::APP}, + {BundleType::ATOMIC_SERVICE, FilterBundleType::ATOMIC_SERVICE}, + {BundleType::SHARED, FilterBundleType::SHARED}, + {BundleType::APP_SERVICE_FWK, FilterBundleType::APP_SERVICE_FWK}, + {BundleType::APP_PLUGIN, FilterBundleType::APP_PLUGIN}, +}; + +FilterAppStateType GetFilterTypeFromApplicationState(ApplicationState state) +{ + auto it = APPLICATION_STATE_TO_FILTER_MAP.find(state); + if (it != APPLICATION_STATE_TO_FILTER_MAP.end()) { + return it->second; + } + TAG_LOGE(AAFwkTag::APPMGR, "get FilterType from ApplicationState failed"); + return FilterAppStateType::NONE; +} + +FilterProcessStateType GetFilterTypeFromAppProcessState(AppProcessState state) +{ + auto it = APP_PROCESS_STATE_TO_FILTER_MAP.find(state); + if (it != APP_PROCESS_STATE_TO_FILTER_MAP.end()) { + return it->second; + } + TAG_LOGE(AAFwkTag::APPMGR, "get FilterType from AppProcessState failed"); + return FilterProcessStateType::NONE; +} +FilterAbilityStateType GetFilterTypeFromAbilityState(AbilityState state) +{ + auto it = ABILITY_STATE_TO_FILTER_MAP.find(state); + if (it != ABILITY_STATE_TO_FILTER_MAP.end()) { + return it->second; + } + TAG_LOGE(AAFwkTag::APPMGR, "get FilterType from AbilityState failed"); + return FilterAbilityStateType::NONE; +} +FilterBundleType GetFilterTypeFromBundleType(BundleType state) +{ + auto it = BUNDLE_TYPE_TO_FILTER_MAP.find(state); + if (it != BUNDLE_TYPE_TO_FILTER_MAP.end()) { + return it->second; + } + TAG_LOGE(AAFwkTag::APPMGR, "get FilterType from BundleType failed"); + return FilterBundleType::NONE; +} +} // namespace AppExecFwk +} // namespace OHOS \ No newline at end of file diff --git a/services/appmgr/include/app_mgr_service.h b/services/appmgr/include/app_mgr_service.h index 79a7c7e2090..cd076b45401 100644 --- a/services/appmgr/include/app_mgr_service.h +++ b/services/appmgr/include/app_mgr_service.h @@ -34,6 +34,7 @@ #include "app_scheduler_proxy.h" #include "appexecfwk_errors.h" #include "application_info.h" +#include "application_state_filter.h" #include "if_system_ability_manager.h" #include "nocopyable.h" #include "system_ability.h" @@ -890,6 +891,16 @@ public: int32_t LaunchAbility(sptr token) override; virtual int32_t QueryRunningSharedBundles(pid_t pid, std::map &sharedBundles) override; + + /** + * Register application/process/ability state observer. + * @param observer, bundleNameList, appStateFilter. + * @return Returns ERR_OK on success, others on failure. + */ + int32_t RegisterApplicationStateObserverWithFilter(sptr observer, + const std::vector &bundleNameList = {}, + const AppStateFilter &appStateFilter = AppStateFilter()) override; + private: /** * Init, Initialize application services. diff --git a/services/appmgr/include/app_mgr_service_inner.h b/services/appmgr/include/app_mgr_service_inner.h index 8ecd6ea530d..11f04d4e6fb 100644 --- a/services/appmgr/include/app_mgr_service_inner.h +++ b/services/appmgr/include/app_mgr_service_inner.h @@ -44,6 +44,7 @@ #include "app_scheduler_interface.h" #include "app_spawn_client.h" #include "appexecfwk_errors.h" +#include "application_state_filter.h" #include "background_app_info.h" #include "bundle_info.h" #include "bundle_mgr_helper.h" @@ -168,8 +169,8 @@ public: * * @return */ - void StateChangedNotifyObserver( - const AbilityStateData abilityStateData, bool isAbility, bool isFromWindowFocusChanged); + void StateChangedNotifyObserver(const AbilityStateData abilityStateData, bool isAbility, + bool isFromWindowFocusChanged, BundleType bundleType = BundleType::APP); /** * RegisterAppStateCallback, register the callback. @@ -830,7 +831,7 @@ public: * @return Returns ERR_OK on success, others on failure. */ int32_t RegisterApplicationStateObserver(const sptr &observer, - const std::vector &bundleNameList = {}); + const std::vector &bundleNameList = {}, const AppStateFilter &appStateFilter = AppStateFilter()); /** * Unregister application or process state observer. diff --git a/services/appmgr/include/app_state_observer_manager.h b/services/appmgr/include/app_state_observer_manager.h index e2c4489cef4..9c4d36c8337 100644 --- a/services/appmgr/include/app_state_observer_manager.h +++ b/services/appmgr/include/app_state_observer_manager.h @@ -25,6 +25,7 @@ #include "app_foreground_state_observer_interface.h" #include "app_running_record.h" #include "app_state_data.h" +#include "application_state_filter.h" #include "cpp/mutex.h" #include "iapp_state_callback.h" #include "iapplication_state_observer.h" @@ -42,6 +43,7 @@ namespace AppExecFwk { struct AppStateObserverInfo { int32_t uid = 0; std::vector bundleNames; + AppStateFilter appStateFilter; }; using AppStateObserverMap = std::map, AppStateObserverInfo>; @@ -58,14 +60,14 @@ class AppStateObserverManager : public std::enable_shared_from_this &observer, - const std::vector &bundleNameList = {}); + const std::vector &bundleNameList = {}, const AppStateFilter &appStateFilter = AppStateFilter()); int32_t UnregisterApplicationStateObserver(const sptr &observer); int32_t RegisterAppForegroundStateObserver(const sptr &observer); int32_t UnregisterAppForegroundStateObserver(const sptr &observer); int32_t RegisterAbilityForegroundStateObserver(const sptr &observer); int32_t UnregisterAbilityForegroundStateObserver(const sptr &observer); - void StateChangedNotifyObserver( - const AbilityStateData abilityStateData, bool isAbility, bool isFromWindowFocusChanged); + void StateChangedNotifyObserver(const AbilityStateData abilityStateData, bool isAbility, + bool isFromWindowFocusChanged, BundleType bundleType = BundleType::APP); void OnAppStateChanged(const std::shared_ptr &appRecord, const ApplicationState state, bool needNotifyApp, bool isFromWindowFocusChanged); void OnAppStarted(const std::shared_ptr &appRecord); @@ -100,8 +102,8 @@ private: bool needNotifyApp, bool isFromWindowFocusChanged); void HandleOnAppStarted(const std::shared_ptr &appRecord); void HandleOnAppStopped(const std::shared_ptr &appRecord); - void HandleStateChangedNotifyObserver( - const AbilityStateData abilityStateData, bool isAbility, bool isFromWindowFocusChanged); + void HandleStateChangedNotifyObserver(const AbilityStateData abilityStateData, bool isAbility, + bool isFromWindowFocusChanged, BundleType bundleType = BundleType::APP); void HandleOnAppProcessCreated(const std::shared_ptr &appRecord, bool isPreload); void HandleOnRenderProcessCreated(const std::shared_ptr &RenderRecord, const bool isPreload); #ifdef SUPPORT_CHILD_PROCESS @@ -130,10 +132,10 @@ private: void OnObserverDied(const wptr &remote, const ObserverType &type); AppStateData WrapAppStateData(const std::shared_ptr &appRecord, const ApplicationState state, bool isFromWindowFocusChanged = false); - void HandleOnProcessCreated(const ProcessData &data); + void HandleOnProcessCreated(const ProcessData &data, BundleType bundleType = BundleType::APP); void HandleOnProcessStateChanged( const std::shared_ptr &appRecordm, bool isFromWindowFocusChanged = false); - void HandleOnProcessDied(const ProcessData &data); + void HandleOnProcessDied(const ProcessData &data, BundleType bundleType = BundleType::APP); void HandleOnProcessResued(const std::shared_ptr &appRecord); void HandleOnPageShow(const PageStateData pageStateData); void HandleOnPageHide(const PageStateData pageStateData); diff --git a/services/appmgr/src/app_mgr_service.cpp b/services/appmgr/src/app_mgr_service.cpp index ff2ceb5f03a..9ccbdeb235f 100644 --- a/services/appmgr/src/app_mgr_service.cpp +++ b/services/appmgr/src/app_mgr_service.cpp @@ -25,6 +25,7 @@ #include "ability_manager_xcollie.h" #include "app_death_recipient.h" #include "app_mgr_constants.h" +#include "application_state_filter.h" #include "datetime_ex.h" #include "fd_guard.h" #include "freeze_util.h" @@ -1952,5 +1953,16 @@ int32_t AppMgrService::QueryRunningSharedBundles(pid_t pid, std::mapQueryRunningSharedBundles(pid, sharedBundles); } + +int32_t AppMgrService::RegisterApplicationStateObserverWithFilter(sptr observer, + const std::vector &bundleNameList, const AppStateFilter &appStateFilter) +{ + TAG_LOGD(AAFwkTag::APPMGR, "begin"); + if (!IsReady()) { + TAG_LOGE(AAFwkTag::APPMGR, "not ready"); + return ERR_INVALID_OPERATION; + } + return appMgrServiceInner_->RegisterApplicationStateObserver(observer, bundleNameList, appStateFilter); +} } // namespace AppExecFwk } // namespace OHOS diff --git a/services/appmgr/src/app_mgr_service_inner.cpp b/services/appmgr/src/app_mgr_service_inner.cpp index aecfef532fb..3ceecd69d25 100644 --- a/services/appmgr/src/app_mgr_service_inner.cpp +++ b/services/appmgr/src/app_mgr_service_inner.cpp @@ -38,6 +38,7 @@ #include "app_state_observer_manager.h" #include "app_utils.h" #include "appfreeze_manager.h" +#include "application_state_filter.h" #include "application_state_observer_stub.h" #include "appspawn_util.h" #include "bundle_constants.h" @@ -3870,11 +3871,11 @@ void AppMgrServiceInner::OnAbilityStateChanged( } } -void AppMgrServiceInner::StateChangedNotifyObserver( - const AbilityStateData abilityStateData, bool isAbility, bool isFromWindowFocusChanged) +void AppMgrServiceInner::StateChangedNotifyObserver(const AbilityStateData abilityStateData, bool isAbility, + bool isFromWindowFocusChanged, BundleType bundleType) { DelayedSingleton::GetInstance()->StateChangedNotifyObserver( - abilityStateData, isAbility, isFromWindowFocusChanged); + abilityStateData, isAbility, isFromWindowFocusChanged, bundleType); } int32_t AppMgrServiceInner::StartPerfProcessByStartMsg(AppSpawnStartMsg &startMsg, @@ -5351,11 +5352,11 @@ void AppMgrServiceInner::NotifyAppStatusByCallerUid(const std::string &bundleNam NotifyAppStatusByCommonEventName(bundleName, eventData, want); } -int32_t AppMgrServiceInner::RegisterApplicationStateObserver( - const sptr &observer, const std::vector &bundleNameList) +int32_t AppMgrServiceInner::RegisterApplicationStateObserver(const sptr &observer, + const std::vector &bundleNameList, const AppStateFilter &appStateFilter) { return DelayedSingleton::GetInstance()->RegisterApplicationStateObserver( - observer, bundleNameList); + observer, bundleNameList, appStateFilter); } int32_t AppMgrServiceInner::UnregisterApplicationStateObserver(const sptr &observer) diff --git a/services/appmgr/src/app_running_record.cpp b/services/appmgr/src/app_running_record.cpp index 0ef699dad01..89d6657c080 100644 --- a/services/appmgr/src/app_running_record.cpp +++ b/services/appmgr/src/app_running_record.cpp @@ -773,9 +773,10 @@ void AppRunningRecord::StateChangedNotifyObserver(const std::shared_ptr(processType_); + BundleType bundleType = applicationInfo ? applicationInfo->bundleType : AppExecFwk::BundleType::APP; auto serviceInner = appMgrServiceInner_.lock(); if (serviceInner) { - serviceInner->StateChangedNotifyObserver(abilityStateData, isAbility, isFromWindowFocusChanged); + serviceInner->StateChangedNotifyObserver(abilityStateData, isAbility, isFromWindowFocusChanged, bundleType); } } diff --git a/services/appmgr/src/app_state_observer_manager.cpp b/services/appmgr/src/app_state_observer_manager.cpp index 44bca47cad7..c16f5626bb6 100644 --- a/services/appmgr/src/app_state_observer_manager.cpp +++ b/services/appmgr/src/app_state_observer_manager.cpp @@ -53,8 +53,8 @@ void AppStateObserverManager::Init() } } -int32_t AppStateObserverManager::RegisterApplicationStateObserver( - const sptr &observer, const std::vector &bundleNameList) +int32_t AppStateObserverManager::RegisterApplicationStateObserver(const sptr &observer, + const std::vector &bundleNameList, const AppStateFilter &appStateFilter) { TAG_LOGD(AAFwkTag::APPMGR, "called"); if (bundleNameList.size() > BUNDLE_NAME_LIST_MAX_SIZE) { @@ -74,7 +74,8 @@ int32_t AppStateObserverManager::RegisterApplicationStateObserver( return ERR_INVALID_VALUE; } std::lock_guard lockRegister(observerLock_); - appStateObserverMap_.emplace(observer, AppStateObserverInfo{IPCSkeleton::GetCallingUid(), bundleNameList}); + appStateObserverMap_.emplace(observer, AppStateObserverInfo{IPCSkeleton::GetCallingUid(), + bundleNameList, appStateFilter}); if (appStateObserverMap_.size() >= OBSERVER_SINGLE_COUNT_LOG && appStateObserverMap_.size() % OBSERVER_SINGLE_STEP_LOG == 0) { TAG_LOGW(AAFwkTag::APPMGR, "appStateObserverMap_ size:%{public}zu", appStateObserverMap_.size()); @@ -474,21 +475,21 @@ void AppStateObserverManager::OnChildProcessCreated(std::shared_ptrHandleStateChangedNotifyObserver(abilityStateData, isAbility, isFromWindowFocusChanged); + self->HandleStateChangedNotifyObserver(abilityStateData, isAbility, isFromWindowFocusChanged, bundleType); }; handler_->SubmitTask(task); } @@ -509,7 +510,14 @@ void AppStateObserverManager::HandleOnAppStarted(const std::shared_ptrsecond.bundleNames; auto iter = std::find(bundleNames.begin(), bundleNames.end(), data.bundleName); - if ((bundleNames.empty() || iter != bundleNames.end()) && it->first != nullptr) { + BundleType bundleType = appRecord->GetApplicationInfo() != nullptr ? + appRecord->GetApplicationInfo()->bundleType : BundleType::APP; + AppStateFilter appStateFilter {FilterCallback::ON_APP_STARTED, + GetFilterTypeFromBundleType(bundleType), + GetFilterTypeFromApplicationState(static_cast(data.state)), + FilterProcessStateType::NONE, FilterAbilityStateType::NONE}; + if ((bundleNames.empty() || iter != bundleNames.end()) && it->first != nullptr && + it->second.appStateFilter.Match(appStateFilter)) { it->first->OnAppStarted(data); } } @@ -530,7 +538,14 @@ void AppStateObserverManager::HandleOnAppStopped(const std::shared_ptrsecond.bundleNames; auto iter = std::find(bundleNames.begin(), bundleNames.end(), data.bundleName); - if ((bundleNames.empty() || iter != bundleNames.end()) && it->first != nullptr) { + BundleType bundleType = appRecord->GetApplicationInfo() != nullptr ? + appRecord->GetApplicationInfo()->bundleType : BundleType::APP; + AppStateFilter appStateFilter {FilterCallback::ON_APP_STOPPED, + GetFilterTypeFromBundleType(bundleType), + GetFilterTypeFromApplicationState(static_cast(data.state)), + FilterProcessStateType::NONE, FilterAbilityStateType::NONE}; + if ((bundleNames.empty() || iter != bundleNames.end()) && it->first != nullptr && + it->second.appStateFilter.Match(appStateFilter)) { it->first->OnAppStopped(data); } } @@ -543,6 +558,8 @@ void AppStateObserverManager::HandleAppStateChanged(const std::shared_ptrGetApplicationInfo() != nullptr ? + appRecord->GetApplicationInfo()->bundleType : BundleType::APP; if (state == ApplicationState::APP_STATE_FOREGROUND || state == ApplicationState::APP_STATE_BACKGROUND) { if (needNotifyApp && !isFromWindowFocusChanged) { AppStateData data = WrapAppStateData(appRecord, state, isFromWindowFocusChanged); @@ -565,10 +582,22 @@ void AppStateObserverManager::HandleAppStateChanged(const std::shared_ptrfirst != nullptr; if (valid) { - it->first->OnForegroundApplicationChanged(data); + AppStateFilter appStateFilter {FilterCallback::ON_FOREGROUND_APPLICATION_CHANGED, + GetFilterTypeFromBundleType(bundleType), + GetFilterTypeFromApplicationState(static_cast(data.state)), + FilterProcessStateType::NONE, FilterAbilityStateType::NONE}; + if (it->second.appStateFilter.Match(appStateFilter)) { + it->first->OnForegroundApplicationChanged(data); + } } if (valid && needNotifyApp) { - it->first->OnAppStateChanged(data); + AppStateFilter appStateFilter {FilterCallback::ON_APP_STATE_CHANGED, + GetFilterTypeFromBundleType(bundleType), + GetFilterTypeFromApplicationState(static_cast(data.state)), + FilterProcessStateType::NONE, FilterAbilityStateType::NONE}; + if (it->second.appStateFilter.Match(appStateFilter)) { + it->first->OnAppStateChanged(data); + } } } } @@ -581,7 +610,12 @@ void AppStateObserverManager::HandleAppStateChanged(const std::shared_ptrsecond.bundleNames; auto iter = std::find(bundleNames.begin(), bundleNames.end(), data.bundleName); - if ((bundleNames.empty() || iter != bundleNames.end()) && it->first != nullptr) { + AppStateFilter appStateFilter {FilterCallback::ON_APPLICATION_STATE_CHANGED, + GetFilterTypeFromBundleType(bundleType), + GetFilterTypeFromApplicationState(static_cast(data.state)), + FilterProcessStateType::NONE, FilterAbilityStateType::NONE}; + if ((bundleNames.empty() || iter != bundleNames.end()) && it->first != nullptr && + it->second.appStateFilter.Match(appStateFilter)) { it->first->OnApplicationStateChanged(data); } } @@ -589,7 +623,7 @@ void AppStateObserverManager::HandleAppStateChanged(const std::shared_ptrsecond.bundleNames; auto iter = std::find(bundleNames.begin(), bundleNames.end(), abilityStateData.bundleName); - if ((bundleNames.empty() || iter != bundleNames.end()) && it->first != nullptr) { - if (isAbility) { + if ((!bundleNames.empty() && iter == bundleNames.end()) || it->first == nullptr) { + continue; + } + if (isAbility) { + AppStateFilter appStateFilter {FilterCallback::ON_ABILITY_STATE_CHANGED, + GetFilterTypeFromBundleType(bundleType), + FilterAppStateType::NONE, FilterProcessStateType::NONE, + GetFilterTypeFromAbilityState(static_cast(abilityStateData.abilityState))}; + if (it->second.appStateFilter.Match(appStateFilter)) { it->first->OnAbilityStateChanged(abilityStateData); - } else { + } + } else { + AppStateFilter appStateFilter {FilterCallback::ON_EXTENSION_STATE_CHANGED, + GetFilterTypeFromBundleType(bundleType), + FilterAppStateType::NONE, FilterProcessStateType::NONE, + GetFilterTypeFromAbilityState(static_cast(abilityStateData.abilityState))}; + if (it->second.appStateFilter.Match(appStateFilter)) { it->first->OnExtensionStateChanged(abilityStateData); } } @@ -647,7 +694,9 @@ void AppStateObserverManager::HandleOnAppProcessCreated(const std::shared_ptrGetApplicationInfo() != nullptr ? + appRecord->GetApplicationInfo()->bundleType : BundleType::APP; + HandleOnProcessCreated(data, bundleType); } void AppStateObserverManager::HandleOnProcessResued(const std::shared_ptr &appRecord) @@ -665,7 +714,14 @@ void AppStateObserverManager::HandleOnProcessResued(const std::shared_ptrsecond.bundleNames; auto iter = std::find(bundleNames.begin(), bundleNames.end(), data.bundleName); - if ((bundleNames.empty() || iter != bundleNames.end()) && it->first != nullptr) { + BundleType bundleType = appRecord->GetApplicationInfo() != nullptr ? + appRecord->GetApplicationInfo()->bundleType : BundleType::APP; + AppStateFilter appStateFilter {FilterCallback::ON_PROCESS_REUSED, + GetFilterTypeFromBundleType(bundleType), FilterAppStateType::NONE, + GetFilterTypeFromAppProcessState(static_cast(data.state)), + FilterAbilityStateType::NONE}; + if ((bundleNames.empty() || iter != bundleNames.end()) && it->first != nullptr && + it->second.appStateFilter.Match(appStateFilter)) { it->first->OnProcessReused(data); } } @@ -685,7 +741,12 @@ void AppStateObserverManager::HandleOnRenderProcessCreated(const std::shared_ptr "RenderProcess Create, bundle:%{public}s, pid:%{public}d, uid:%{public}d, processType:%{public}d, " "processName:%{public}s, renderUid:%{public}d", data.bundleName.c_str(), data.pid, data.uid, data.processType, data.processName.c_str(), data.renderUid); - HandleOnProcessCreated(data); + BundleType bundleType = BundleType::APP; + if (renderRecord->GetHostRecord() != nullptr) { + bundleType = renderRecord->GetHostRecord()->GetApplicationInfo() != nullptr ? + renderRecord->GetHostRecord()->GetApplicationInfo()->bundleType : BundleType::APP; + } + HandleOnProcessCreated(data, bundleType); } #ifdef SUPPORT_CHILD_PROCESS @@ -705,17 +766,27 @@ void AppStateObserverManager::HandleOnChildProcessCreated(std::shared_ptrGetHostRecord() != nullptr) { + bundleType = childRecord->GetHostRecord()->GetApplicationInfo() != nullptr ? + childRecord->GetHostRecord()->GetApplicationInfo()->bundleType : BundleType::APP; + } + HandleOnProcessCreated(data, bundleType); } #endif // SUPPORT_CHILD_PROCESS -void AppStateObserverManager::HandleOnProcessCreated(const ProcessData &data) +void AppStateObserverManager::HandleOnProcessCreated(const ProcessData &data, BundleType bundleType) { auto appStateObserverMapCopy = GetAppStateObserverMapCopy(); for (auto it = appStateObserverMapCopy.begin(); it != appStateObserverMapCopy.end(); ++it) { const auto &bundleNames = it->second.bundleNames; auto iter = std::find(bundleNames.begin(), bundleNames.end(), data.bundleName); - if ((bundleNames.empty() || iter != bundleNames.end()) && it->first != nullptr) { + AppStateFilter appStateFilter {FilterCallback::ON_PROCESS_CREATED, + GetFilterTypeFromBundleType(bundleType), FilterAppStateType::NONE, + GetFilterTypeFromAppProcessState(static_cast(data.state)), + FilterAbilityStateType::NONE}; + if ((bundleNames.empty() || iter != bundleNames.end()) && it->first != nullptr && + it->second.appStateFilter.Match(appStateFilter)) { it->first->OnProcessCreated(data); } } @@ -742,7 +813,14 @@ void AppStateObserverManager::HandleOnProcessStateChanged( for (auto it = appStateObserverMapCopy.begin(); it != appStateObserverMapCopy.end(); ++it) { const auto &bundleNames = it->second.bundleNames; auto iter = std::find(bundleNames.begin(), bundleNames.end(), data.bundleName); - if ((bundleNames.empty() || iter != bundleNames.end()) && it->first != nullptr) { + BundleType bundleType = appRecord->GetApplicationInfo() != nullptr ? + appRecord->GetApplicationInfo()->bundleType : BundleType::APP; + AppStateFilter appStateFilter {FilterCallback::ON_PROCESS_STATE_CHANGED, + GetFilterTypeFromBundleType(bundleType), FilterAppStateType::NONE, + GetFilterTypeFromAppProcessState(static_cast(data.state)), + FilterAbilityStateType::NONE}; + if ((bundleNames.empty() || iter != bundleNames.end()) && it->first != nullptr && + it->second.appStateFilter.Match(appStateFilter)) { it->first->OnProcessStateChanged(data); } } @@ -764,7 +842,14 @@ void AppStateObserverManager::HandleOnWindowShow(const std::shared_ptrsecond.bundleNames; auto iter = std::find(bundleNames.begin(), bundleNames.end(), data.bundleName); - if ((bundleNames.empty() || iter != bundleNames.end()) && it->first != nullptr) { + BundleType bundleType = appRecord->GetApplicationInfo() != nullptr ? + appRecord->GetApplicationInfo()->bundleType : BundleType::APP; + AppStateFilter appStateFilter {FilterCallback::ON_WINDOW_SHOW, + GetFilterTypeFromBundleType(bundleType), FilterAppStateType::NONE, + GetFilterTypeFromAppProcessState(static_cast(data.state)), + FilterAbilityStateType::NONE}; + if ((bundleNames.empty() || iter != bundleNames.end()) && it->first != nullptr && + it->second.appStateFilter.Match(appStateFilter)) { it->first->OnWindowShow(data); } } @@ -786,7 +871,14 @@ void AppStateObserverManager::HandleOnWindowHidden(const std::shared_ptrsecond.bundleNames; auto iter = std::find(bundleNames.begin(), bundleNames.end(), data.bundleName); - if ((bundleNames.empty() || iter != bundleNames.end()) && it->first != nullptr) { + BundleType bundleType = appRecord->GetApplicationInfo() != nullptr ? + appRecord->GetApplicationInfo()->bundleType : BundleType::APP; + AppStateFilter appStateFilter {FilterCallback::ON_WINDOW_HIDDEN, + GetFilterTypeFromBundleType(bundleType), FilterAppStateType::NONE, + GetFilterTypeFromAppProcessState(static_cast(data.state)), + FilterAbilityStateType::NONE}; + if ((bundleNames.empty() || iter != bundleNames.end()) && it->first != nullptr && + it->second.appStateFilter.Match(appStateFilter)) { it->first->OnWindowHidden(data); } } @@ -803,7 +895,9 @@ void AppStateObserverManager::HandleOnAppProcessDied(const std::shared_ptrGetApplicationInfo() != nullptr ? + appRecord->GetApplicationInfo()->bundleType : BundleType::APP; + HandleOnProcessDied(data, bundleType); } void AppStateObserverManager::HandleOnRenderProcessDied(const std::shared_ptr &renderRecord) @@ -817,7 +911,12 @@ void AppStateObserverManager::HandleOnRenderProcessDied(const std::shared_ptrGetHostRecord() != nullptr) { + bundleType = renderRecord->GetHostRecord()->GetApplicationInfo() != nullptr ? + renderRecord->GetHostRecord()->GetApplicationInfo()->bundleType : BundleType::APP; + } + HandleOnProcessDied(data, bundleType); } #ifdef SUPPORT_CHILD_PROCESS @@ -837,17 +936,27 @@ void AppStateObserverManager::HandleOnChildProcessDied(std::shared_ptrGetHostRecord() != nullptr) { + bundleType = childRecord->GetHostRecord()->GetApplicationInfo() != nullptr ? + childRecord->GetHostRecord()->GetApplicationInfo()->bundleType : BundleType::APP; + } + HandleOnProcessDied(data, bundleType); } #endif // SUPPORT_CHILD_PROCESS -void AppStateObserverManager::HandleOnProcessDied(const ProcessData &data) +void AppStateObserverManager::HandleOnProcessDied(const ProcessData &data, BundleType bundleType) { auto appStateObserverMapCopy = GetAppStateObserverMapCopy(); for (auto it = appStateObserverMapCopy.begin(); it != appStateObserverMapCopy.end(); ++it) { const auto &bundleNames = it->second.bundleNames; auto iter = std::find(bundleNames.begin(), bundleNames.end(), data.bundleName); - if ((bundleNames.empty() || iter != bundleNames.end()) && it->first != nullptr) { + AppStateFilter appStateFilter {FilterCallback::ON_PROCESS_DIED, + GetFilterTypeFromBundleType(bundleType), FilterAppStateType::NONE, + GetFilterTypeFromAppProcessState(static_cast(data.state)), + FilterAbilityStateType::NONE}; + if ((bundleNames.empty() || iter != bundleNames.end()) && it->first != nullptr && + it->second.appStateFilter.Match(appStateFilter)) { it->first->OnProcessDied(data); } } @@ -1194,7 +1303,10 @@ void AppStateObserverManager::HandleOnPageShow(const PageStateData pageStateData for (auto it = appStateObserverMapCopy.begin(); it != appStateObserverMapCopy.end(); ++it) { const auto &bundleNames = it->second.bundleNames; auto iter = std::find(bundleNames.begin(), bundleNames.end(), pageStateData.bundleName); - if ((bundleNames.empty() || iter != bundleNames.end()) && it->first != nullptr) { + AppStateFilter appStateFilter {FilterCallback::ON_PAGE_SHOW, FilterBundleType::ALL, + FilterAppStateType::ALL, FilterProcessStateType::ALL, FilterAbilityStateType::ALL}; + if ((bundleNames.empty() || iter != bundleNames.end()) && it->first != nullptr && + it->second.appStateFilter.Match(appStateFilter)) { it->first->OnPageShow(pageStateData); } } @@ -1207,7 +1319,10 @@ void AppStateObserverManager::HandleOnPageHide(const PageStateData pageStateData for (auto it = appStateObserverMapCopy.begin(); it != appStateObserverMapCopy.end(); ++it) { const auto &bundleNames = it->second.bundleNames; auto iter = std::find(bundleNames.begin(), bundleNames.end(), pageStateData.bundleName); - if ((bundleNames.empty() || iter != bundleNames.end()) && it->first != nullptr) { + AppStateFilter appStateFilter {FilterCallback::ON_PAGE_HIDE, FilterBundleType::ALL, + FilterAppStateType::ALL, FilterProcessStateType::ALL, FilterAbilityStateType::ALL}; + if ((bundleNames.empty() || iter != bundleNames.end()) && it->first != nullptr && + it->second.appStateFilter.Match(appStateFilter)) { it->first->OnPageHide(pageStateData); } } @@ -1250,7 +1365,14 @@ void AppStateObserverManager::HandleOnAppCacheStateChanged(const std::shared_ptr for (auto it = appStateObserverMapCopy.begin(); it != appStateObserverMapCopy.end(); ++it) { const auto &bundleNames = it->second.bundleNames; auto iter = std::find(bundleNames.begin(), bundleNames.end(), data.bundleName); - if ((bundleNames.empty() || iter != bundleNames.end()) && it->first != nullptr) { + BundleType bundleType = appRecord->GetApplicationInfo() != nullptr ? + appRecord->GetApplicationInfo()->bundleType : BundleType::APP; + AppStateFilter appStateFilter {FilterCallback::ON_APP_CACHE_STATE_CHANGED, + GetFilterTypeFromBundleType(bundleType), + GetFilterTypeFromApplicationState(static_cast(data.state)), + FilterProcessStateType::NONE, FilterAbilityStateType::NONE}; + if ((bundleNames.empty() || iter != bundleNames.end()) && it->first != nullptr && + it->second.appStateFilter.Match(appStateFilter)) { it->first->OnAppCacheStateChanged(data); } } @@ -1319,7 +1441,10 @@ void AppStateObserverManager::HandleOnProcessBindingRelationChanged( for (auto it = appStateObserverMapCopy.begin(); it != appStateObserverMapCopy.end(); ++it) { const auto &bundleNames = it->second.bundleNames; auto iter = std::find(bundleNames.begin(), bundleNames.end(), data.bundleName); - if ((bundleNames.empty() || iter != bundleNames.end()) && it->first != nullptr) { + AppStateFilter appStateFilter {FilterCallback::ON_PROCESS_BINDING_RELATION_CHANGED, + FilterBundleType::ALL, FilterAppStateType::ALL, FilterProcessStateType::ALL, FilterAbilityStateType::ALL}; + if ((bundleNames.empty() || iter != bundleNames.end()) && it->first != nullptr && + it->second.appStateFilter.Match(appStateFilter)) { it->first->OnProcessBindingRelationChanged(data); } } @@ -1363,7 +1488,14 @@ void AppStateObserverManager::HandleOnKeepAliveStateChanged(const std::shared_pt for (auto it = appStateObserverMapCopy.begin(); it != appStateObserverMapCopy.end(); ++it) { const auto &bundleNames = it->second.bundleNames; auto iter = std::find(bundleNames.begin(), bundleNames.end(), data.bundleName); - if ((bundleNames.empty() || iter != bundleNames.end()) && it->first != nullptr) { + BundleType bundleType = appRecord->GetApplicationInfo() != nullptr ? + appRecord->GetApplicationInfo()->bundleType : BundleType::APP; + AppStateFilter appStateFilter {FilterCallback::ON_KEEPALIVE_STATE_CHANGED, + GetFilterTypeFromBundleType(bundleType), FilterAppStateType::NONE, + GetFilterTypeFromAppProcessState(static_cast(data.state)), + FilterAbilityStateType::NONE}; + if ((bundleNames.empty() || iter != bundleNames.end()) && it->first != nullptr && + it->second.appStateFilter.Match(appStateFilter)) { it->first->OnKeepAliveStateChanged(data); } } @@ -1416,7 +1548,13 @@ void AppStateObserverManager::HandleOnProcessPreForegroundChanged(std::shared_pt for (auto it = appStateObserverMapCopy.begin(); it != appStateObserverMapCopy.end(); ++it) { const auto &bundleNames = it->second.bundleNames; auto iter = std::find(bundleNames.begin(), bundleNames.end(), bundleName); - if ((bundleNames.empty() || iter != bundleNames.end()) && it->first != nullptr) { + BundleType bundleType = appRecord->GetApplicationInfo() != nullptr ? + appRecord->GetApplicationInfo()->bundleType : BundleType::APP; + AppStateFilter appStateFilter {FilterCallback::ON_PROCESS_PREFOREGROUND_CHANGED, + GetFilterTypeFromBundleType(bundleType), FilterAppStateType::ALL, + FilterProcessStateType::ALL, FilterAbilityStateType::ALL}; + if ((bundleNames.empty() || iter != bundleNames.end()) && it->first != nullptr && + it->second.appStateFilter.Match(appStateFilter)) { it->first->OnProcessPreForegroundChanged(preloadProcessData); } } diff --git a/test/unittest/BUILD.gn b/test/unittest/BUILD.gn index 4f5111ade05..cea61eec7c7 100644 --- a/test/unittest/BUILD.gn +++ b/test/unittest/BUILD.gn @@ -280,6 +280,7 @@ group("unittest") { "application_cleaner_second_test:unittest", "application_context_second_test:unittest", "application_context_test:unittest", + "application_state_filter_test:unittest", "assert_fault_callback_death_mgr_test:unittest", "atomic_service_status_callback_proxy_test:unittest", "atomic_service_status_callback_stub_test:unittest", diff --git a/test/unittest/application_state_filter_test/BUILD.gn b/test/unittest/application_state_filter_test/BUILD.gn new file mode 100644 index 00000000000..7823ee0c367 --- /dev/null +++ b/test/unittest/application_state_filter_test/BUILD.gn @@ -0,0 +1,55 @@ +# 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("//build/test.gni") +import("//foundation/ability/ability_runtime/ability_runtime.gni") + +module_output_path = "ability_runtime/ability_runtime/appmgrservice" + +ohos_unittest("ApplicationStateFilterTest") { + module_out_path = module_output_path + + configs = [ "${ability_runtime_services_path}/common:common_config" ] + + include_dirs = + [ "${ability_runtime_test_path}/mock/services_appmgr_test/include" ] + + sources = [ "application_state_filter_test.cpp" ] + + external_deps = [ + "ability_base:configuration", + "ability_base:want", + "ability_runtime:app_manager", + "bundle_framework:appexecfwk_base", + "c_utils:utils", + "googletest:gmock_main", + "googletest:gtest_main", + "hilog:libhilog", + "ipc:ipc_core", + ] + + defines = [] + if (background_task_mgr_continuous_task_enable) { + defines += [ "BGTASKMGR_CONTINUOUS_TASK_ENABLE" ] + } + + if (ability_command_for_test) { + defines += [ "ABILITY_COMMAND_FOR_TEST" ] + } +} + +group("unittest") { + testonly = true + + deps = [ ":ApplicationStateFilterTest" ] +} diff --git a/test/unittest/application_state_filter_test/application_state_filter_test.cpp b/test/unittest/application_state_filter_test/application_state_filter_test.cpp new file mode 100644 index 00000000000..96bcc80d4b6 --- /dev/null +++ b/test/unittest/application_state_filter_test/application_state_filter_test.cpp @@ -0,0 +1,217 @@ +/* + * 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 +#include "application_state_filter.h" +#include "hilog_tag_wrapper.h" +#include "ipc_types.h" +#include "mock_app_mgr_service.h" + +using namespace testing; +using namespace testing::ext; + +namespace OHOS { +namespace AppExecFwk { +namespace { +const int32_t INVAID_ID = 120; +} // namespace + +class ApplicationStateFilterTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp() override; + void TearDown() override; + + sptr mockAppMgrService_; + + void WriteInterfaceToken(MessageParcel& data); +}; + +void ApplicationStateFilterTest::SetUpTestCase(void) +{} + +void ApplicationStateFilterTest::TearDownTestCase(void) +{} + +void ApplicationStateFilterTest::SetUp() +{ + GTEST_LOG_(INFO) << "ApplicationStateFilterTest::SetUp()"; + + mockAppMgrService_ = new MockAppMgrService(); +} + +void ApplicationStateFilterTest::TearDown() +{} + +std::unordered_map APPLICATION_STATE_TO_FILTER_MAP = { + {ApplicationState::APP_STATE_CREATE, FilterAppStateType::CREATE}, + {ApplicationState::APP_STATE_FOREGROUND, FilterAppStateType::FOREGROUND}, + {ApplicationState::APP_STATE_BACKGROUND, FilterAppStateType::BACKGROUND}, + {ApplicationState::APP_STATE_TERMINATED, FilterAppStateType::DESTROY}, + {ApplicationState::APP_STATE_READY, FilterAppStateType::READY}, + {ApplicationState::APP_STATE_FOCUS, FilterAppStateType::FOCUS}, + {ApplicationState::APP_STATE_END, FilterAppStateType::END}, + {ApplicationState::APP_STATE_SET_COLD_START, FilterAppStateType::SET_COLD_START}, + {ApplicationState::APP_STATE_CACHED, FilterAppStateType::CACHED}, + {ApplicationState::APP_STATE_PRE_FOREGROUND, FilterAppStateType::PRE_FOREGROUND}, +}; + +std::unordered_map APP_PROCESS_STATE_TO_FILTER_MAP = { + {AppProcessState::APP_STATE_CREATE, FilterProcessStateType::CREATE}, + {AppProcessState::APP_STATE_FOREGROUND, FilterProcessStateType::FOREGROUND}, + {AppProcessState::APP_STATE_BACKGROUND, FilterProcessStateType::BACKGROUND}, + {AppProcessState::APP_STATE_TERMINATED, FilterProcessStateType::DESTROY}, + {AppProcessState::APP_STATE_READY, FilterProcessStateType::READY}, + {AppProcessState::APP_STATE_FOCUS, FilterProcessStateType::FOCUS}, + {AppProcessState::APP_STATE_END, FilterProcessStateType::END}, + {AppProcessState::APP_STATE_CACHED, FilterProcessStateType::CACHED}, + {AppProcessState::APP_STATE_PRE_FOREGROUND, FilterProcessStateType::PRE_FOREGROUND}, +}; + +std::unordered_map ABILITY_STATE_TO_FILTER_MAP = { + {AbilityState::ABILITY_STATE_CREATE, FilterAbilityStateType::CREATE}, + {AbilityState::ABILITY_STATE_FOREGROUND, FilterAbilityStateType::FOREGROUND}, + {AbilityState::ABILITY_STATE_BACKGROUND, FilterAbilityStateType::BACKGROUND}, + {AbilityState::ABILITY_STATE_TERMINATED, FilterAbilityStateType::DESTROY}, + {AbilityState::ABILITY_STATE_READY, FilterAbilityStateType::READY}, + {AbilityState::ABILITY_STATE_FOCUS, FilterAbilityStateType::FOCUS}, + {AbilityState::ABILITY_STATE_END, FilterAbilityStateType::END}, + {AbilityState::ABILITY_STATE_CONNECTED, FilterAbilityStateType::CONNECTED}, + {AbilityState::ABILITY_STATE_DISCONNECTED, FilterAbilityStateType::DISCONNECTED}, +}; + +std::unordered_map BUNDLE_TYPE_TO_FILTER_MAP = { + {BundleType::APP, FilterBundleType::APP}, + {BundleType::ATOMIC_SERVICE, FilterBundleType::ATOMIC_SERVICE}, + {BundleType::SHARED, FilterBundleType::SHARED}, + {BundleType::APP_SERVICE_FWK, FilterBundleType::APP_SERVICE_FWK}, + {BundleType::APP_PLUGIN, FilterBundleType::APP_PLUGIN}, +}; + +/** + * @tc.name: ApplicationStateFilter_GetFilterTypeFromApplicationState_001 + * @tc.desc: GetFilterTypeFromApplicationState + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(ApplicationStateFilterTest, ApplicationStateFilter_GetFilterTypeFromApplicationState_001, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "ApplicationStateFilter_GetFilterTypeFromApplicationState_001 start"; + auto result = GetFilterTypeFromApplicationState(ApplicationState::APP_STATE_CREATE); + EXPECT_EQ(result, FilterAppStateType::CREATE); + GTEST_LOG_(INFO) << "ApplicationStateFilter_GetFilterTypeFromApplicationState_001 end"; +} + +/** + * @tc.name: ApplicationStateFilter_GetFilterTypeFromApplicationState_002 + * @tc.desc: GetFilterTypeFromApplicationState + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(ApplicationStateFilterTest, ApplicationStateFilter_GetFilterTypeFromApplicationState_002, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "ApplicationStateFilter_GetFilterTypeFromApplicationState_002 start"; + auto result = GetFilterTypeFromApplicationState(static_cast(INVAID_ID)); + EXPECT_EQ(result, FilterAppStateType::NONE); + GTEST_LOG_(INFO) << "ApplicationStateFilter_GetFilterTypeFromApplicationState_002 end"; +} + +/** + * @tc.name: ApplicationStateFilter_GetFilterTypeFromAppProcessState_001 + * @tc.desc: GetFilterTypeFromAppProcessState + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(ApplicationStateFilterTest, ApplicationStateFilter_GetFilterTypeFromAppProcessState_001, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "ApplicationStateFilter_GetFilterTypeFromAppProcessState_001 start"; + auto result = GetFilterTypeFromAppProcessState(AppProcessState::APP_STATE_CREATE); + EXPECT_EQ(result, FilterProcessStateType::CREATE); + GTEST_LOG_(INFO) << "ApplicationStateFilter_GetFilterTypeFromAppProcessState_001 end"; +} + +/** + * @tc.name: ApplicationStateFilter_GetFilterTypeFromAppProcessState_002 + * @tc.desc: GetFilterTypeFromAppProcessState + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(ApplicationStateFilterTest, ApplicationStateFilter_GetFilterTypeFromAppProcessState_002, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "ApplicationStateFilter_GetFilterTypeFromAppProcessState_002 start"; + auto result = GetFilterTypeFromAppProcessState(static_cast(INVAID_ID)); + EXPECT_EQ(result, FilterProcessStateType::NONE); + GTEST_LOG_(INFO) << "ApplicationStateFilter_GetFilterTypeFromAppProcessState_002 end"; +} + +/** + * @tc.name: ApplicationStateFilter_GetFilterTypeFromAbilityState_001 + * @tc.desc: GetFilterTypeFromAbilityState + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(ApplicationStateFilterTest, ApplicationStateFilter_GetFilterTypeFromAbilityState_001, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "ApplicationStateFilter_GetFilterTypeFromAbilityState_001 start"; + auto result = GetFilterTypeFromAbilityState(AbilityState::ABILITY_STATE_CREATE); + EXPECT_EQ(result, FilterAbilityStateType::CREATE); + GTEST_LOG_(INFO) << "ApplicationStateFilter_GetFilterTypeFromAbilityState_001 end"; +} + +/** + * @tc.name: ApplicationStateFilter_GetFilterTypeFromAbilityState_002 + * @tc.desc: GetFilterTypeFromAbilityState + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(ApplicationStateFilterTest, ApplicationStateFilter_GetFilterTypeFromAbilityState_002, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "ApplicationStateFilter_GetFilterTypeFromAbilityState_002 start"; + auto result = GetFilterTypeFromAbilityState(static_cast(INVAID_ID)); + EXPECT_EQ(result, FilterAbilityStateType::NONE); + GTEST_LOG_(INFO) << "ApplicationStateFilter_GetFilterTypeFromAbilityState_002 end"; +} + +/** + * @tc.name: ApplicationStateFilter_GetFilterTypeFromBundleType_001 + * @tc.desc: GetFilterTypeFromBundleType + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(ApplicationStateFilterTest, ApplicationStateFilter_GetFilterTypeFromBundleType_001, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "ApplicationStateFilter_GetFilterTypeFromBundleType_001 start"; + auto result = GetFilterTypeFromBundleType(BundleType::APP); + EXPECT_EQ(result, FilterBundleType::CREATE); + GTEST_LOG_(INFO) << "ApplicationStateFilter_GetFilterTypeFromBundleType_001 end"; +} + +/** + * @tc.name: ApplicationStateFilter_GetFilterTypeFromBundleType_002 + * @tc.desc: GetFilterTypeFromBundleType + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(ApplicationStateFilterTest, ApplicationStateFilter_GetFilterTypeFromBundleType_002, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "ApplicationStateFilter_GetFilterTypeFromBundleType_002 start"; + auto result = GetFilterTypeFromBundleType(static_cast(INVAID_ID)); + EXPECT_EQ(result, FilterBundleType::NONE); + GTEST_LOG_(INFO) << "ApplicationStateFilter_GetFilterTypeFromBundleType_002 end"; +} + +} // namespace AppExecFwk +} // namespace OHOS -- Gitee