From addc8bfb44f0724868c6a5bb3a2d009000ebf4c8 Mon Sep 17 00:00:00 2001 From: 18795846185 Date: Mon, 28 Apr 2025 17:21:23 +0800 Subject: [PATCH] clm20250427 Signed-off-by: 18795846185 Change-Id: Ibee3bddd33a8243788eac3847638482e09c811cd --- interfaces/inner_api/app_manager/BUILD.gn | 2 + .../include/appmgr/app_mgr_interface.h | 16 +++ .../appmgr/app_mgr_ipc_interface_code.h | 1 + .../include/appmgr/app_mgr_proxy.h | 10 ++ .../app_manager/include/appmgr/app_mgr_stub.h | 1 + .../include/appmgr/background_app_info.h | 38 ++++++ .../include/appmgr/configuration_policy.h | 32 +++++ .../app_manager/src/appmgr/app_mgr_proxy.cpp | 42 +++++++ .../app_manager/src/appmgr/app_mgr_stub.cpp | 39 ++++++ .../src/appmgr/background_app_info.cpp | 52 ++++++++ .../src/appmgr/configuration_policy.cpp | 61 ++++++++++ services/appmgr/include/app_mgr_service.h | 18 +++ .../appmgr/include/app_mgr_service_inner.h | 12 ++ services/appmgr/include/app_running_manager.h | 22 +++- services/appmgr/src/app_mgr_service.cpp | 15 +++ services/appmgr/src/app_mgr_service_inner.cpp | 17 +++ services/appmgr/src/app_running_manager.cpp | 110 +++++++++++++++++ test/fuzztest/BUILD.gn | 1 + .../appmgrservicefirst_fuzzer/BUILD.gn | 1 + .../appmgrservicefirst_fuzzer.cpp | 10 +- .../include/mock_app_mgr_service.h | 2 + .../app_mgr_proxy_test/app_mgr_proxy_test.cpp | 27 ++++ .../app_mgr_service_inner_sixth_test.cpp | 29 +++++ .../app_mgr_service_third_test.cpp | 45 +++++++ .../include/mock_permission_verification.h | 2 + .../mock/src/mock_permission_verification.cpp | 4 + .../app_mgr_stub_test/app_mgr_stub_test.cpp | 39 ++++++ .../app_running_manager_fourth_test.cpp | 115 ++++++++++++++++++ 28 files changed, 761 insertions(+), 2 deletions(-) create mode 100644 interfaces/inner_api/app_manager/include/appmgr/background_app_info.h create mode 100644 interfaces/inner_api/app_manager/include/appmgr/configuration_policy.h create mode 100644 interfaces/inner_api/app_manager/src/appmgr/background_app_info.cpp create mode 100644 interfaces/inner_api/app_manager/src/appmgr/configuration_policy.cpp diff --git a/interfaces/inner_api/app_manager/BUILD.gn b/interfaces/inner_api/app_manager/BUILD.gn index 1399bc36a1c..a3fc5c8bac0 100644 --- a/interfaces/inner_api/app_manager/BUILD.gn +++ b/interfaces/inner_api/app_manager/BUILD.gn @@ -88,11 +88,13 @@ ohos_shared_library("app_manager") { "src/appmgr/app_state_data.cpp", "src/appmgr/application_state_observer_proxy.cpp", "src/appmgr/application_state_observer_stub.cpp", + "src/appmgr/background_app_info.cpp", "src/appmgr/child_process_info.cpp", "src/appmgr/child_scheduler_proxy.cpp", "src/appmgr/child_scheduler_stub.cpp", "src/appmgr/configuration_observer_proxy.cpp", "src/appmgr/configuration_observer_stub.cpp", + "src/appmgr/configuration_policy.cpp", "src/appmgr/fault_data.cpp", "src/appmgr/kia_interceptor_proxy.cpp", "src/appmgr/kia_interceptor_stub.cpp", 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 7f8d7fa16a8..5535444099a 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,8 +24,10 @@ #include "app_mgr_ipc_interface_code.h" #include "app_record_id.h" #include "application_info.h" +#include "background_app_info.h" #include "bundle_info.h" #include "child_process_info.h" +#include "configuration_policy.h" #ifdef SUPPORT_CHILD_PROCESS #include "child_process_request.h" #endif // SUPPORT_CHILD_PROCESS @@ -435,6 +437,20 @@ public: */ virtual int32_t UpdateConfiguration(const Configuration &config, const int32_t userId = -1) = 0; + /** + * UpdateConfigurationForBackgroundApp + * + * @param appInfos Background application information. + * @param policy Update policy. + * @param userId configuration for the user + * @return Returns ERR_OK on success, others on failure. + */ + virtual int32_t UpdateConfigurationForBackgroundApp(const std::vector &appInfos, + const AppExecFwk::ConfigurationPolicy &policy, const int32_t userId = -1) + { + return 0; + } + /** * Update config by bundle name. * 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 c1a41987f34..0ce39819377 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 @@ -126,6 +126,7 @@ enum class AppMgrInterfaceCode { UPDATE_PROCESS_MEMORY_STATE = 100, GET_KILLED_PROCESS_INFO = 101, LAUNCH_ABILITY = 102, + UPDATE_CONFIGURATION_POLICY = 103, }; } // 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 c94043d9c70..38fedca8c07 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 @@ -417,6 +417,16 @@ public: virtual int32_t UpdateConfiguration(const Configuration &config, const int32_t userId = -1) override; + /** + * UpdateConfigurationForBackgroundApp + * @param appInfos Background application information. + * @param policy Update policy. + * @param userId configuration for the user + * @return Returns ERR_OK on success, others on failure. + */ + virtual int32_t UpdateConfigurationForBackgroundApp(const std::vector &appInfos, + const AppExecFwk::ConfigurationPolicy &policy, const int32_t userId = -1) override; + virtual int32_t UpdateConfigurationByBundleName(const Configuration &config, const std::string &name, int32_t appIndex = 0) override; 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 db8720f7c34..36aaf04feb2 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 @@ -101,6 +101,7 @@ private: int32_t HandleGetRenderProcessTerminationStatus(MessageParcel &data, MessageParcel &reply); int32_t HandleGetConfiguration(MessageParcel &data, MessageParcel &reply); int32_t HandleUpdateConfiguration(MessageParcel &data, MessageParcel &reply); + int32_t HandleUpdateConfigurationForBackgroundApp(MessageParcel &data, MessageParcel &reply); int32_t HandleUpdateConfigurationByBundleName(MessageParcel &data, MessageParcel &reply); int32_t HandleRegisterConfigurationObserver(MessageParcel &data, MessageParcel &reply); int32_t HandleUnregisterConfigurationObserver(MessageParcel &data, MessageParcel &reply); diff --git a/interfaces/inner_api/app_manager/include/appmgr/background_app_info.h b/interfaces/inner_api/app_manager/include/appmgr/background_app_info.h new file mode 100644 index 00000000000..b5978b0afa5 --- /dev/null +++ b/interfaces/inner_api/app_manager/include/appmgr/background_app_info.h @@ -0,0 +1,38 @@ +/* +* 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_BACKGROUND_APP_INFO_H +#define OHOS_ABILITY_RUNTIME_BACKGROUND_APP_INFO_H + +#include +#include + +#include "parcel.h" + +namespace OHOS { +namespace AppExecFwk { + +struct BackgroundAppInfo : public Parcelable { + std::string bandleName; + int32_t appIndex = -1; + bool ReadFromParcel(Parcel &parcel); + virtual bool Marshalling(Parcel &parcel) const override; + static BackgroundAppInfo *Unmarshalling(Parcel &parcel); +}; +} // namespace AppExecFwk +} // namespace OHOS + +#endif // OHOS_ABILITY_RUNTIME_BACKGROUND_APP_INFO_H + \ No newline at end of file diff --git a/interfaces/inner_api/app_manager/include/appmgr/configuration_policy.h b/interfaces/inner_api/app_manager/include/appmgr/configuration_policy.h new file mode 100644 index 00000000000..a67b5ebd563 --- /dev/null +++ b/interfaces/inner_api/app_manager/include/appmgr/configuration_policy.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 permissions and + * limitations under the License. + */ + +#ifndef OHOS_ABILITY_RUNTIME_CONFIGURATION_POLICY_H +#define OHOS_ABILITY_RUNTIME_CONFIGURATION_POLICY_H + +#include "parcel.h" + +namespace OHOS { +namespace AppExecFwk { +struct ConfigurationPolicy : public Parcelable { + bool ReadFromParcel(Parcel &parcel); + virtual bool Marshalling(Parcel &parcel) const override; + static ConfigurationPolicy *Unmarshalling(Parcel &parcel); + int8_t maxCountPerBatch = -1; + int16_t intervalTime = -1; +}; +} // namespace AppExecFwk +} // namespace OHOS +#endif // OHOS_ABILITY_RUNTIME_POLICY_INTERFACE_H \ No newline at end of file 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 b319ebc5712..7a500397886 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 @@ -28,6 +28,7 @@ namespace OHOS { namespace AppExecFwk { constexpr int32_t CYCLE_LIMIT = 1000; constexpr int32_t MAX_PROCESS_STATE_COUNT = 1000; +constexpr int32_t MAX_BACKGROUND_APP_COUNT = 1000; AppMgrProxy::AppMgrProxy(const sptr &impl) : IRemoteProxy(impl) {} @@ -950,6 +951,47 @@ int32_t AppMgrProxy::UpdateConfiguration(const Configuration &config, const int3 return reply.ReadInt32(); } +int32_t AppMgrProxy::UpdateConfigurationForBackgroundApp(const std::vector& appInfos, + const AppExecFwk::ConfigurationPolicy& policy, const int32_t userId) +{ + TAG_LOGI(AAFwkTag::APPMGR, "AppMgrProxy UpdateConfigurationForBackgroundApp"); + MessageParcel data; + MessageParcel reply; + MessageOption option(MessageOption::TF_SYNC); + if (!WriteInterfaceToken(data)) { + return IPC_PROXY_ERR; + } + auto size = appInfos.size(); + if (size == 0 || size > MAX_BACKGROUND_APP_COUNT) { + TAG_LOGE(AAFwkTag::APPMGR, "AppInfos size invalid"); + return ERR_INVALID_DATA; + } + if (!data.WriteUint32(size)) { + TAG_LOGE(AAFwkTag::APPMGR, "Write size failed"); + return ERR_FLATTEN_OBJECT; + } + for (const auto &info: appInfos) { + if (!data.WriteParcelable(&info)) { + TAG_LOGE(AAFwkTag::APPMGR, "Write appInfos failed"); + return ERR_FLATTEN_OBJECT; + } + } + if (!data.WriteParcelable(&policy)) { + TAG_LOGE(AAFwkTag::APPMGR, "parcel policy failed"); + return ERR_INVALID_DATA; + } + if (!data.WriteInt32(userId)) { + TAG_LOGE(AAFwkTag::APPMGR, "parcel userId failed"); + return ERR_INVALID_DATA; + } + int32_t ret = SendRequest(AppMgrInterfaceCode::UPDATE_CONFIGURATION_POLICY, data, reply, option); + if (ret != NO_ERROR) { + TAG_LOGE(AAFwkTag::APPMGR, "SendRequest is failed, error code: %{public}d", ret); + return ret; + } + return reply.ReadInt32(); +} + int32_t AppMgrProxy::UpdateConfigurationByBundleName(const Configuration &config, const std::string &name, int32_t appIndex) { 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 6d8fa4645e6..9849da61ab8 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 @@ -40,6 +40,7 @@ namespace OHOS { namespace AppExecFwk { constexpr int32_t CYCLE_LIMIT = 1000; constexpr int32_t MAX_PROCESS_STATE_COUNT = 1000; +constexpr int32_t MAX_BACKGROUND_APP_COUNT = 1000; AppMgrStub::AppMgrStub() {} @@ -386,6 +387,8 @@ int32_t AppMgrStub::OnRemoteRequestInnerEighth(uint32_t code, MessageParcel &dat return HandleGetKilledProcessInfo(data, reply); case static_cast(AppMgrInterfaceCode::LAUNCH_ABILITY): return HandleLaunchAbility(data, reply); + case static_cast(AppMgrInterfaceCode::UPDATE_CONFIGURATION_POLICY): + return HandleUpdateConfigurationForBackgroundApp(data, reply); } return INVALID_FD; } @@ -1014,6 +1017,42 @@ int32_t AppMgrStub::HandleUpdateConfiguration(MessageParcel &data, MessageParcel return NO_ERROR; } +int32_t AppMgrStub::HandleUpdateConfigurationForBackgroundApp(MessageParcel &data, MessageParcel &reply) +{ + TAG_LOGD(AAFwkTag::APPMGR, "called"); + std::vector appInfos; + uint32_t size = data.ReadUint32(); + if (size <= 0 || size > MAX_BACKGROUND_APP_COUNT) { + TAG_LOGE(AAFwkTag::APPMGR, "Invalid size"); + return ERR_INVALID_VALUE; + } + appInfos.resize(size); + if (appInfos.capacity() < size) { + TAG_LOGE(AAFwkTag::APPMGR, "Resource allocation error"); + return ERR_NO_MEMORY; + } + for (uint32_t i = 0; i < size; i++) { + std::unique_ptr tmpInfo(data.ReadParcelable()); + if (tmpInfo == nullptr) { + TAG_LOGE(AAFwkTag::APPMGR, "tmpInfo null"); + return ERR_INVALID_VALUE; + } + appInfos.push_back(*tmpInfo); + } + std::unique_ptr policy(data.ReadParcelable()); + if (policy == nullptr) { + TAG_LOGE(AAFwkTag::APPMGR, "policy null"); + return ERR_INVALID_VALUE; + } + int32_t userId = data.ReadInt32(); + int32_t result = UpdateConfigurationForBackgroundApp(appInfos, *policy, userId); + if (!reply.WriteInt32(result)) { + TAG_LOGE(AAFwkTag::APPMGR, "fail to write result."); + return ERR_INVALID_VALUE; + } + return NO_ERROR; +} + int32_t AppMgrStub::HandleUpdateConfigurationByBundleName(MessageParcel &data, MessageParcel &reply) { std::unique_ptr config(data.ReadParcelable()); diff --git a/interfaces/inner_api/app_manager/src/appmgr/background_app_info.cpp b/interfaces/inner_api/app_manager/src/appmgr/background_app_info.cpp new file mode 100644 index 00000000000..fb595e48142 --- /dev/null +++ b/interfaces/inner_api/app_manager/src/appmgr/background_app_info.cpp @@ -0,0 +1,52 @@ +/* + * 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 "background_app_info.h" +#include "hilog_tag_wrapper.h" +#include "nlohmann/json.hpp" +#include "parcel_macro_base.h" +#include "string_ex.h" + +namespace OHOS { +namespace AppExecFwk { + +bool BackgroundAppInfo::ReadFromParcel(Parcel &parcel) +{ + bandleName = Str16ToStr8(parcel.ReadString16()); + READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, appIndex); + + return true; +} + +BackgroundAppInfo *BackgroundAppInfo::Unmarshalling(Parcel &parcel) +{ + BackgroundAppInfo *info = new (std::nothrow) BackgroundAppInfo(); + if (info && !info->ReadFromParcel(parcel)) { + TAG_LOGE(AAFwkTag::APPMGR, "read from parcel failed"); + delete info; + info = nullptr; + } + return info; +} + +bool BackgroundAppInfo::Marshalling(Parcel &parcel) const +{ + WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(bandleName)); + WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, appIndex); + + return true; +} +} // namespace AppExecFwk +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/inner_api/app_manager/src/appmgr/configuration_policy.cpp b/interfaces/inner_api/app_manager/src/appmgr/configuration_policy.cpp new file mode 100644 index 00000000000..6a120b2eabf --- /dev/null +++ b/interfaces/inner_api/app_manager/src/appmgr/configuration_policy.cpp @@ -0,0 +1,61 @@ +/* + * 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 "configuration_policy.h" + +#include "hilog_tag_wrapper.h" + +namespace OHOS { +namespace AppExecFwk { +bool ConfigurationPolicy::ReadFromParcel(Parcel &parcel) +{ + if (!parcel.ReadInt8(maxCountPerBatch)) { + TAG_LOGE(AAFwkTag::APPMGR, "maxCountPerBatch read int8 failed."); + return false; + } + if (!parcel.ReadInt16(intervalTime)) { + TAG_LOGE(AAFwkTag::APPMGR, "intervalTime read int16 failed."); + return false; + } + + return true; +} + +ConfigurationPolicy *ConfigurationPolicy::Unmarshalling(Parcel &parcel) +{ + ConfigurationPolicy *policy = new (std::nothrow) ConfigurationPolicy(); + if (policy && !policy->ReadFromParcel(parcel)) { + delete policy; + policy = nullptr; + } + return policy; +} + +bool ConfigurationPolicy::Marshalling(Parcel &parcel) const +{ + if (!parcel.WriteInt8(maxCountPerBatch)) { + TAG_LOGE(AAFwkTag::APPMGR, "countPerTime write int8 failed."); + return false; + } + + if (!parcel.WriteInt16(intervalTime)) { + TAG_LOGE(AAFwkTag::APPMGR, "intervalTime write int16 failed."); + return false; + } + + return true; +} +} // 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 d5d48d2f2e0..9412c0a148d 100644 --- a/services/appmgr/include/app_mgr_service.h +++ b/services/appmgr/include/app_mgr_service.h @@ -426,6 +426,24 @@ public: */ virtual int32_t UpdateConfiguration(const Configuration &config, const int32_t userId = -1) override; + /** + * Internally, an asynchronous task will be initiated and tasks in the task list will be scheduled according to + * the policy. + * If during the execution of a task, a caller triggers UpdateConfiguration or UpdateConfigurationForBackgroundApp, + * the asynchronous task will be terminated. + * If the task has not been executed and the app is switched to the foreground, the task will be updated + * when brought to the foreground. The task will not be updated while in the background. + * Supported scope: colormode + * Only SA can call this method. + * + * @param appInfos Background application information. + * @param policy Update policy. + * @param userId configuration for the user + * @return Returns ERR_OK on success, others on failure. + */ + virtual int32_t UpdateConfigurationForBackgroundApp(const std::vector &appInfos, + const AppExecFwk::ConfigurationPolicy &policy, const int32_t userId = -1) override; + /** * Update config by bundle name. * diff --git a/services/appmgr/include/app_mgr_service_inner.h b/services/appmgr/include/app_mgr_service_inner.h index 706b986c740..e122c0b6afb 100644 --- a/services/appmgr/include/app_mgr_service_inner.h +++ b/services/appmgr/include/app_mgr_service_inner.h @@ -44,12 +44,14 @@ #include "app_scheduler_interface.h" #include "app_spawn_client.h" #include "appexecfwk_errors.h" +#include "background_app_info.h" #include "bundle_info.h" #include "bundle_mgr_helper.h" #ifdef SUPPORT_CHILD_PROCESS #include "child_process_info.h" #include "child_process_request.h" #endif // SUPPORT_CHILD_PROCESS +#include "configuration_policy.h" #include "cpp/mutex.h" #include "event_report.h" #include "exit_resident_process_manager.h" @@ -761,6 +763,16 @@ public: */ int32_t UpdateConfiguration(const Configuration &config, const int32_t userId = -1); + /** + * UpdateConfigurationForBackgroundApp + * @param appInfos Background application information. + * @param policy Update policy. + * @param userId configuration for the user + * @return Returns ERR_OK on success, others on failure. + */ + int32_t UpdateConfigurationForBackgroundApp(const std::vector &appInfos, + const AppExecFwk::ConfigurationPolicy &policy, const int32_t userId); + int32_t UpdateConfigurationByBundleName(const Configuration &config, const std::string &name, int32_t appIndex); std::shared_ptr GetConfiguration(); diff --git a/services/appmgr/include/app_running_manager.h b/services/appmgr/include/app_running_manager.h index e29f4436614..38e3aa50362 100644 --- a/services/appmgr/include/app_running_manager.h +++ b/services/appmgr/include/app_running_manager.h @@ -29,8 +29,10 @@ #include "app_running_record.h" #include "app_state_data.h" #include "application_info.h" +#include "background_app_info.h" #include "bundle_info.h" #include "configuration.h" +#include "configuration_policy.h" #include "iremote_object.h" #include "kill_process_config.h" #include "record_query_result.h" @@ -41,6 +43,11 @@ namespace OHOS { namespace Rosen { class WindowVisibilityInfo; +enum ConfigMode : uint32_t { + COLOR_MODE = 0, + FONT_SCALE = 1, + FONT_WEIGHT_SCALE = 2, +}; } namespace AppExecFwk { @@ -200,6 +207,16 @@ public: */ int32_t UpdateConfiguration(const Configuration &config, const int32_t userId = -1); + /** + * UpdateConfigurationForBackgroundApp + * @param appInfos Background application information. + * @param policy Update policy. + * @param userId configuration for the user + * @return Returns ERR_OK on success, others on failure. + */ + int32_t UpdateConfigurationForBackgroundApp(const std::vector &appInfos, + const AppExecFwk::ConfigurationPolicy &policy, const int32_t userId = -1); + /** * Update config by sa. * @@ -383,7 +400,8 @@ private: const std::shared_ptr& appMgrServiceInner); void AddRecordToDeadList(std::shared_ptr appRecord); void RemoveTimeoutDeadAppRecord(); - + void ExecuteConfigurationTask(const BackgroundAppInfo& info, const int32_t userId); + bool UpdateConfiguration(std::shared_ptr &appRecord, Rosen::ConfigMode configMode); private: std::mutex runningRecordMapMutex_; std::map> appRunningRecordMap_; @@ -394,6 +412,8 @@ private: std::mutex updateConfigurationDelayedLock_; std::map updateConfigurationDelayedMap_; + + std::vector appInfos_; }; } // namespace AppExecFwk } // namespace OHOS diff --git a/services/appmgr/src/app_mgr_service.cpp b/services/appmgr/src/app_mgr_service.cpp index 902172398a7..95cad8e437f 100644 --- a/services/appmgr/src/app_mgr_service.cpp +++ b/services/appmgr/src/app_mgr_service.cpp @@ -1078,6 +1078,21 @@ int32_t AppMgrService::UpdateConfiguration(const Configuration& config, const in return appMgrServiceInner_->UpdateConfiguration(config, userId); } +int32_t AppMgrService::UpdateConfigurationForBackgroundApp(const std::vector& appInfos, + const AppExecFwk::ConfigurationPolicy& policy, const int32_t userId) +{ + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + if (!AAFwk::PermissionVerification::GetInstance()->IsSACall()) { + TAG_LOGE(AAFwkTag::APPMGR, "caller not SA"); + return ERR_PERMISSION_DENIED; + } + if (!IsReady()) { + TAG_LOGE(AAFwkTag::APPMGR, "not ready"); + return ERR_INVALID_OPERATION; + } + return appMgrServiceInner_->UpdateConfigurationForBackgroundApp(appInfos, policy, userId); +} + int32_t AppMgrService::UpdateConfigurationByBundleName(const Configuration& config, const std::string &name, int32_t appIndex) { diff --git a/services/appmgr/src/app_mgr_service_inner.cpp b/services/appmgr/src/app_mgr_service_inner.cpp index 0b58f9ff66a..7a5af9a2bd1 100644 --- a/services/appmgr/src/app_mgr_service_inner.cpp +++ b/services/appmgr/src/app_mgr_service_inner.cpp @@ -5363,6 +5363,23 @@ int32_t AppMgrServiceInner::UpdateConfiguration(const Configuration &config, con return result; } +int32_t AppMgrServiceInner::UpdateConfigurationForBackgroundApp(const std::vector& appInfos, + const AppExecFwk::ConfigurationPolicy& policy, const int32_t userId) +{ + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + if (!appRunningManager_) { + TAG_LOGE(AAFwkTag::APPMGR, "appRunningManager_ null"); + return ERR_NO_INIT; + } + CHECK_CALLER_IS_SYSTEM_APP; + auto ret = AAFwk::PermissionVerification::GetInstance()->VerifyUpdateConfigurationPerm(); + if (ret != ERR_OK) { + TAG_LOGE(AAFwkTag::APPMGR, "permission verification failed"); + return ret; + } + return appRunningManager_->UpdateConfigurationForBackgroundApp(appInfos, policy, userId); +} + int32_t AppMgrServiceInner::UpdateConfigurationByBundleName(const Configuration &config, const std::string &name, int32_t appIndex) { diff --git a/services/appmgr/src/app_running_manager.cpp b/services/appmgr/src/app_running_manager.cpp index af0111b7571..883ae7f829e 100644 --- a/services/appmgr/src/app_running_manager.cpp +++ b/services/appmgr/src/app_running_manager.cpp @@ -986,6 +986,12 @@ int32_t AppRunningManager::UpdateConfiguration(const Configuration& config, cons auto appRunningMap = GetAppRunningRecordMap(); TAG_LOGD(AAFwkTag::APPMGR, "current app size %{public}zu", appRunningMap.size()); int32_t result = ERR_OK; + + for (auto &info : appInfos_) { + AAFwk::TaskHandlerWrap::GetFfrtHandler()->CancelTask(info.bandleName.c_str() + std::to_string(info.appIndex)); + } + appInfos_.clear(); + for (const auto& item : appRunningMap) { const auto& appRecord = item.second; if (appRecord && appRecord->GetState() == ApplicationState::APP_STATE_CREATE) { @@ -1018,6 +1024,110 @@ int32_t AppRunningManager::UpdateConfiguration(const Configuration& config, cons return result; } +bool AppRunningManager::UpdateConfiguration(std::shared_ptr& appRecord, Rosen::ConfigMode configMode) +{ + if (appRecord == nullptr) { + TAG_LOGE(AAFwkTag::APPMGR, "null ptr"); + return false; + } + + if (configMode != Rosen::ConfigMode::COLOR_MODE) { + TAG_LOGI(AAFwkTag::APPKIT, "not color mode"); + return false; + } + AppExecFwk::Configuration config; + auto delayConfig = appRecord->GetDelayConfiguration(); + if (delayConfig == nullptr) { + appRecord->ResetDelayConfiguration(); + TAG_LOGE(AAFwkTag::APPKIT, "delayConfig null"); + return false; + } else { + std::string value = delayConfig->GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE); + if (value == ConfigurationInner::EMPTY_STRING) { + TAG_LOGE(AAFwkTag::APPKIT, "colorMode null"); + return false; + } + config.AddItem(AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE, value); + TAG_LOGI(AAFwkTag::APPKIT, "colorMode: %{public}s", value.c_str()); + } + delayConfig->RemoveItem(AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE); + appRecord->UpdateConfiguration(config); + return true; +} + +void AppRunningManager::ExecuteConfigurationTask(const BackgroundAppInfo& info, const int32_t userId) +{ + auto appRunningMap = GetAppRunningRecordMap(); + + std::lock_guard guard(updateConfigurationDelayedLock_); + for (auto &item : updateConfigurationDelayedMap_) { + std::shared_ptr appRecord = nullptr; + auto it = appRunningMap.find(item.first); + if (it != appRunningMap.end()) { + appRecord = it->second; + } + if (appRecord == nullptr) { + continue; + } + bool userIdFlag = (userId == -1 || appRecord->GetUid() / BASE_USER_RANGE == 0 || appRecord->GetUid() / BASE_USER_RANGE == userId) ; + if (!userIdFlag) { + continue; + } + if (info.bandleName == appRecord->GetBundleName() && info.appIndex == appRecord->GetAppIndex() && item.second + && appRecord->GetState() == ApplicationState::APP_STATE_BACKGROUND) { + if (UpdateConfiguration(appRecord, Rosen::ConfigMode::COLOR_MODE)) { + item.second = false; + } + } + } + + return; +} + +int32_t AppRunningManager::UpdateConfigurationForBackgroundApp(const std::vector &appInfos, + const AppExecFwk::ConfigurationPolicy& policy, const int32_t userId) +{ + int32_t maxCountPerBatch = policy.maxCountPerBatch; + if (maxCountPerBatch < 1 ) { + TAG_LOGE(AAFwkTag::APPMGR, "maxCountPerBatch invalid"); + return ERR_INVALID_VALUE; + } + + int32_t intervalTime = policy.intervalTime; + if (intervalTime < 0 ) { + TAG_LOGE(AAFwkTag::APPMGR, "intervalTime invalid"); + return ERR_INVALID_VALUE; + } + + + for (auto &info : appInfos_) { + AAFwk::TaskHandlerWrap::GetFfrtHandler()->CancelTask(info.bandleName.c_str() + std::to_string(info.appIndex)); + } + appInfos_.clear(); + + appInfos_ = appInfos; + int32_t taskCount = 0; + int32_t batchCount = 0; + for (auto info : appInfos) { + auto policyTask = [weak = weak_from_this(), info, userId] { + auto appRuningMgr = weak.lock(); + if (appRuningMgr == nullptr) { + TAG_LOGE(AAFwkTag::APPMGR, "appRuningMgr null"); + return; + } + appRuningMgr->ExecuteConfigurationTask(info, userId); + }; + AAFwk::TaskHandlerWrap::GetFfrtHandler()->SubmitTask(policyTask, + info.bandleName.c_str() + std::to_string(info.appIndex), policy.intervalTime * batchCount); + if (++taskCount >= policy.maxCountPerBatch) { + batchCount++; + taskCount = 0; + } + } + + return ERR_OK; +} + int32_t AppRunningManager::UpdateConfigurationByBundleName(const Configuration &config, const std::string &name, int32_t appIndex) { diff --git a/test/fuzztest/BUILD.gn b/test/fuzztest/BUILD.gn index ba5e629d1aa..9f3b0c31114 100644 --- a/test/fuzztest/BUILD.gn +++ b/test/fuzztest/BUILD.gn @@ -225,6 +225,7 @@ group("fuzztest") { "appmanager_fuzzer:fuzztest", "appmgrclientrest_fuzzer:fuzztest", "appmgrrest_fuzzer:fuzztest", + "appmgrservicefirst_fuzzer:fuzztest", "appmgrstub_fuzzer:fuzztest", "apprunningstatusproxy_fuzzer:fuzztest", "appstateobservermanager_fuzzer:fuzztest", diff --git a/test/fuzztest/appmgrservicefirst_fuzzer/BUILD.gn b/test/fuzztest/appmgrservicefirst_fuzzer/BUILD.gn index 28adb930cbf..87d37d07925 100755 --- a/test/fuzztest/appmgrservicefirst_fuzzer/BUILD.gn +++ b/test/fuzztest/appmgrservicefirst_fuzzer/BUILD.gn @@ -58,6 +58,7 @@ ohos_fuzztest("AppMgrServiceFirstFuzzTest") { "napi:ace_napi", "safwk:system_ability_fwk", "samgr:samgr_proxy", + "hisysevent:libhisysevent", ] if (ability_runtime_graphics) { diff --git a/test/fuzztest/appmgrservicefirst_fuzzer/appmgrservicefirst_fuzzer.cpp b/test/fuzztest/appmgrservicefirst_fuzzer/appmgrservicefirst_fuzzer.cpp index 7c359ff9fab..17a0cbfb1f4 100644 --- a/test/fuzztest/appmgrservicefirst_fuzzer/appmgrservicefirst_fuzzer.cpp +++ b/test/fuzztest/appmgrservicefirst_fuzzer/appmgrservicefirst_fuzzer.cpp @@ -74,7 +74,7 @@ bool DoSomethingInterestingWithMyAPI(const char* data, size_t size) appMgrService->RegisterApplicationStateObserver(applicationStateObserver); appMgrService->UnregisterApplicationStateObserver(applicationStateObserver); pid_t pid = static_cast(GetU32Data(data)); - appMgrService->AddAppDeathRecipient(pid); + //appMgrService->AddAppDeathRecipient(pid); appMgrService->QueryServiceState(); sptr app = nullptr; appMgrService->AttachApplication(app); @@ -125,6 +125,14 @@ bool DoSomethingInterestingWithMyAPI(const char* data, size_t size) appMgrService->GetConfiguration(config); std::string bundleName(data, size); appMgrService->GetAppRunningStateByBundleName(bundleName); + std::vector appInfos; + BackgroundAppInfo appInfo; + appInfo.bandleName = bundleName; + appInfos.push_back(appInfo); + AppExecFwk::ConfigurationPolicy policy; + policy.maxCountPerBatch = static_cast(GetU32Data(data)); + policy.intervalTime = static_cast(GetU32Data(data)); + appMgrService->UpdateConfigurationForBackgroundApp(appInfos, policy); sptr callback; appMgrService->NotifyLoadRepairPatch(bundleName, callback); appMgrService->NotifyHotReloadPage(bundleName, callback); diff --git a/test/mock/services_appmgr_test/include/mock_app_mgr_service.h b/test/mock/services_appmgr_test/include/mock_app_mgr_service.h index 6b045aaa410..42b6f288ccd 100644 --- a/test/mock/services_appmgr_test/include/mock_app_mgr_service.h +++ b/test/mock/services_appmgr_test/include/mock_app_mgr_service.h @@ -74,6 +74,8 @@ public: MOCK_METHOD2(GetAbilityRecordsByProcessID, int(const int pid, std::vector>& tokens)); MOCK_METHOD1(GetConfiguration, int32_t(Configuration& config)); MOCK_METHOD2(UpdateConfiguration, int32_t(const Configuration& config, const int32_t userId)); + MOCK_METHOD3(UpdateConfigurationForBackgroundApp, int32_t(const std::vector &appInfos, + const AppExecFwk::ConfigurationPolicy &policy, const int32_t userId)); MOCK_METHOD3(UpdateConfigurationByBundleName, int32_t(const Configuration& config, const std::string &name, int32_t appIndex)); MOCK_METHOD1(RegisterConfigurationObserver, int32_t(const sptr& observer)); diff --git a/test/unittest/app_mgr_proxy_test/app_mgr_proxy_test.cpp b/test/unittest/app_mgr_proxy_test/app_mgr_proxy_test.cpp index 5ada63506c8..5b50a78c11f 100644 --- a/test/unittest/app_mgr_proxy_test/app_mgr_proxy_test.cpp +++ b/test/unittest/app_mgr_proxy_test/app_mgr_proxy_test.cpp @@ -936,5 +936,32 @@ HWTEST_F(AppMgrProxyTest, GetSupportedProcessCachePids_001, TestSize.Level2) TAG_LOGI(AAFwkTag::TEST, "%{public}s end.", __func__); } + +/** + * @tc.name: UpdateConfigurationForBackgroundApp_001 + * @tc.desc: UpdateConfigurationForBackgroundApp. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(AppMgrProxyTest, UpdateConfigurationForBackgroundApp_001, TestSize.Level2) +{ + TAG_LOGI(AAFwkTag::TEST, "%{public}s start.", __func__); + + EXPECT_CALL(*mockAppMgrService_, SendRequest(_, _, _, _)) + .Times(1) + .WillOnce(Invoke(mockAppMgrService_.GetRefPtr(), &MockAppMgrService::InvokeSendRequest)); + + std::vector appInfos; + ConfigurationPolicy policy; + int32_t userId = -1; + auto ret = appMgrProxy_->UpdateConfigurationForBackgroundApp(appInfos, policy, userId); + EXPECT_EQ(ret, ERR_INVALID_DATA); + BackgroundAppInfo info; + appInfos.push_back(info); + appMgrProxy_->UpdateConfigurationForBackgroundApp(appInfos, policy, userId); + EXPECT_EQ(mockAppMgrService_->code_, static_cast(AppMgrInterfaceCode::UPDATE_CONFIGURATION_POLICY)); + + TAG_LOGI(AAFwkTag::TEST, "%{public}s end.", __func__); +} } // namespace AppExecFwk } // namespace OHOS diff --git a/test/unittest/app_mgr_service_inner_sixth_test/app_mgr_service_inner_sixth_test.cpp b/test/unittest/app_mgr_service_inner_sixth_test/app_mgr_service_inner_sixth_test.cpp index 68573875469..a4e8c350c68 100644 --- a/test/unittest/app_mgr_service_inner_sixth_test/app_mgr_service_inner_sixth_test.cpp +++ b/test/unittest/app_mgr_service_inner_sixth_test/app_mgr_service_inner_sixth_test.cpp @@ -537,5 +537,34 @@ HWTEST_F(AppMgrServiceInnerSixthTest, IsAppRunningByBundleNameAndUserId_006, Tes GTEST_LOG_(INFO) << "IsAppRunningByBundleNameAndUserId_006 end"; } + +/** + * @tc.name: UpdateConfigurationForBackgroundApp_001 + * @tc.desc: update configuration policy. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(AppMgrServiceInnerSixthTest, UpdateConfigurationForBackgroundApp_001, TestSize.Level2) +{ + TAG_LOGI(AAFwkTag::TEST, "UpdateConfiguration_001 start"); + auto appMgrServiceInner = std::make_shared(); + EXPECT_NE(appMgrServiceInner, nullptr); + + std::vector appInfos; + AppExecFwk::ConfigurationPolicy policy; + int32_t userId = -1; + auto ret = appMgrServiceInner->UpdateConfigurationForBackgroundApp(appInfos, policy, userId); + EXPECT_NE(ret, 0); + + appMgrServiceInner->appRunningManager_ = nullptr; + ret = appMgrServiceInner->UpdateConfigurationForBackgroundApp(appInfos, policy, userId); + EXPECT_EQ(ret, ERR_NO_INIT); + + appMgrServiceInner->appRunningManager_ = std::make_shared(); + ret = appMgrServiceInner->UpdateConfigurationForBackgroundApp(appInfos, policy, userId); + EXPECT_EQ(ret, ERR_PERMISSION_DENIED); + + TAG_LOGI(AAFwkTag::TEST, "UpdateConfiguration_001 end"); +} } // namespace AppExecFwk } // namespace OHOS \ No newline at end of file diff --git a/test/unittest/app_mgr_service_third_test/app_mgr_service_third_test.cpp b/test/unittest/app_mgr_service_third_test/app_mgr_service_third_test.cpp index 8123f50c88e..10137b50f9a 100644 --- a/test/unittest/app_mgr_service_third_test/app_mgr_service_third_test.cpp +++ b/test/unittest/app_mgr_service_third_test/app_mgr_service_third_test.cpp @@ -293,5 +293,50 @@ HWTEST_F(AppMgrServiceThirdTest, LaunchAbility_001, TestSize.Level1) res = appMgrService->LaunchAbility(nullptr); EXPECT_EQ(res, AAFwk::ERR_NULL_APP_RUNNING_MANAGER); } + +/* + * Feature: AppMgrService + * Function: UpdateConfigurationForBackgroundApp + * SubFunction: NA + * FunctionPoints: AppMgrService UpdateConfigurationForBackgroundApp + * EnvConditions: NA + * CaseDescription: Verify UpdateConfigurationForBackgroundApp + */ +HWTEST_F(AppMgrServiceThirdTest, UpdateConfigurationForBackgroundApp_001, TestSize.Level2) +{ + auto appMgrService = std::make_shared(); + std::vector appInfos; + AppExecFwk::ConfigurationPolicy policy; + int32_t userId = -1; + appMgrService->SetInnerService(nullptr); + AAFwk::MyFlag::flag_ = 0; + int32_t res = appMgrService->UpdateConfigurationForBackgroundApp(appInfos, policy, userId); + EXPECT_EQ(res, ERR_PERMISSION_DENIED); + AAFwk::MyFlag::flag_ = 1; + res = appMgrService->UpdateConfigurationForBackgroundApp(appInfos, policy, userId); + EXPECT_EQ(res, ERR_INVALID_OPERATION); +} + +/* + * Feature: AppMgrService + * Function: UpdateConfigurationForBackgroundApp + * SubFunction: NA + * FunctionPoints: AppMgrService UpdateConfigurationForBackgroundApp + * EnvConditions: NA + * CaseDescription: Verify UpdateConfigurationForBackgroundApp + */ +HWTEST_F(AppMgrServiceThirdTest, UpdateConfigurationForBackgroundApp_002, TestSize.Level2) +{ + auto appMgrService = std::make_shared(); + std::vector appInfos; + AppExecFwk::ConfigurationPolicy policy; + int32_t userId = -1; + AAFwk::MyFlag::flag_ = 1; + appMgrService->SetInnerService(std::make_shared()); + appMgrService->taskHandler_ = taskHandler_; + appMgrService->eventHandler_ = std::make_shared(taskHandler_, appMgrService->appMgrServiceInner_); + int32_t res = appMgrService->UpdateConfigurationForBackgroundApp(appInfos, policy, userId); + EXPECT_EQ(res, ERR_PERMISSION_DENIED); +} } // namespace AppExecFwk } // namespace OHOS \ No newline at end of file diff --git a/test/unittest/app_mgr_service_third_test/mock/include/mock_permission_verification.h b/test/unittest/app_mgr_service_third_test/mock/include/mock_permission_verification.h index fbf95b001b9..d756be0553c 100644 --- a/test/unittest/app_mgr_service_third_test/mock/include/mock_permission_verification.h +++ b/test/unittest/app_mgr_service_third_test/mock/include/mock_permission_verification.h @@ -34,6 +34,8 @@ public: bool CheckSpecificSystemAbilityAccessPermission(const std::string &processName) const; bool VerifyRunningInfoPerm() const; bool JudgeCallerIsAllowedToUseSystemAPI() const; + bool IsSACall() const; + }; } // namespace AAFwk } // namespace OHOS diff --git a/test/unittest/app_mgr_service_third_test/mock/src/mock_permission_verification.cpp b/test/unittest/app_mgr_service_third_test/mock/src/mock_permission_verification.cpp index 8fbf6dc2eac..7affe2e839a 100644 --- a/test/unittest/app_mgr_service_third_test/mock/src/mock_permission_verification.cpp +++ b/test/unittest/app_mgr_service_third_test/mock/src/mock_permission_verification.cpp @@ -31,5 +31,9 @@ bool PermissionVerification::JudgeCallerIsAllowedToUseSystemAPI() const { return !!(MyFlag::flag_); } +bool PermissionVerification::IsSACall() const +{ + return (MyFlag::flag_ & MyFlag::FLAG::IS_SA_CALL); +} } // namespace AAFwk } // namespace OHOS \ No newline at end of file diff --git a/test/unittest/app_mgr_stub_test/app_mgr_stub_test.cpp b/test/unittest/app_mgr_stub_test/app_mgr_stub_test.cpp index 6050cf758f0..158f02158b1 100644 --- a/test/unittest/app_mgr_stub_test/app_mgr_stub_test.cpp +++ b/test/unittest/app_mgr_stub_test/app_mgr_stub_test.cpp @@ -762,5 +762,44 @@ HWTEST_F(AppMgrStubTest, GetSupportedProcessCachePids_001, TestSize.Level1) TAG_LOGI(AAFwkTag::TEST, "%{public}s end.", __func__); } + +/** + * @tc.name: UpdateConfigurationForBackgroundApp_001 + * @tc.desc: UpdateConfigurationForBackgroundApp. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(AppMgrStubTest, UpdateConfigurationForBackgroundApp_001, TestSize.Level1) +{ + TAG_LOGI(AAFwkTag::TEST, "%{public}s start.", __func__); + MessageParcel data; + MessageParcel reply; + MessageOption option; + + WriteInterfaceToken(data); + + std::vector appInfos; + AppExecFwk::ConfigurationPolicy policy; + int32_t userId = -1; + + BackgroundAppInfo info; + appInfos.push_back(info); + auto size = appInfos.size(); + data.WriteUint32(size); + + for (const auto &info: appInfos) { + data.WriteParcelable(&info); + } + data.WriteParcelable(&policy); + data.WriteInt32(userId); + + EXPECT_CALL(*mockAppMgrService_, UpdateConfigurationForBackgroundApp(_, _, _)).Times(1); + + auto result = mockAppMgrService_->OnRemoteRequest( + static_cast(AppMgrInterfaceCode::UPDATE_CONFIGURATION_POLICY), data, reply, option); + EXPECT_EQ(result, NO_ERROR); + + TAG_LOGI(AAFwkTag::TEST, "%{public}s end.", __func__); +} } // namespace AppExecFwk } // namespace OHOS diff --git a/test/unittest/app_running_manager_fourth_test/app_running_manager_fourth_test.cpp b/test/unittest/app_running_manager_fourth_test/app_running_manager_fourth_test.cpp index 08dd5fd6287..77a86fb26ab 100644 --- a/test/unittest/app_running_manager_fourth_test/app_running_manager_fourth_test.cpp +++ b/test/unittest/app_running_manager_fourth_test/app_running_manager_fourth_test.cpp @@ -955,5 +955,120 @@ HWTEST_F(AppRunningManagerFourthTest, AppRunningManager_OnRemoteRenderDied_0100, ret = appRunningManager->OnRemoteRenderDied(remote); EXPECT_EQ(ret, nullptr); } + +/** + * @tc.name: UpdateConfigurationForBackgroundApp_0100 + * @tc.desc: UpdateConfigurationForBackgroundApp. + * @tc.type: FUNC + */ +HWTEST_F(AppRunningManagerFourthTest, UpdateConfigurationForBackgroundApp_0100, TestSize.Level1) +{ + auto appRunningManager = std::make_shared(); + EXPECT_NE(appRunningManager, nullptr); + + std::vector appInfos; + AppExecFwk::ConfigurationPolicy policy; + int32_t userId = -1; + policy.maxCountPerBatch = -1; + auto ret = appRunningManager->UpdateConfigurationForBackgroundApp(appInfos, policy, userId); + EXPECT_EQ(ret, ERR_INVALID_VALUE); + + policy.maxCountPerBatch = 1; + policy.intervalTime = -1; + ret = appRunningManager->UpdateConfigurationForBackgroundApp(appInfos, policy, userId); + EXPECT_EQ(ret, ERR_INVALID_VALUE); + + policy.maxCountPerBatch = 1; + policy.intervalTime = 1; + BackgroundAppInfo info; + info.bandleName = "com.example.mytest"; + info.appIndex = 0; + appInfos.push_back(info); + ret = appRunningManager->UpdateConfigurationForBackgroundApp(appInfos, policy, userId); + EXPECT_EQ(ret, 0); +} + +/** + * @tc.name: UpdateConfiguration_0100 + * @tc.desc: UpdateConfiguration. + * @tc.type: FUNC + */ +HWTEST_F(AppRunningManagerFourthTest, UpdateConfiguration_0100, TestSize.Level1) +{ + auto appRunningManager = std::make_shared(); + EXPECT_NE(appRunningManager, nullptr); + + ApplicationInfo appInfo; + appInfo.name = "KeepAliveApp"; + appInfo.bundleName = "KeepAliveApplication"; + appInfo.uid = 2100; + auto app = std::make_shared(appInfo); + + std::shared_ptr appRecord = std::make_shared(app, 111, "KeepAliveApplication"); + auto ret = appRunningManager->UpdateConfiguration(appRecord, Rosen::ConfigMode::FONT_SCALE); + EXPECT_FALSE(ret); + + appRecord->delayConfiguration_ = nullptr; + ret = appRunningManager->UpdateConfiguration(appRecord, Rosen::ConfigMode::COLOR_MODE); + EXPECT_FALSE(ret); + + appRecord->delayConfiguration_ = std::make_shared(); + appRecord->delayConfiguration_->AddItem(AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE, + ConfigurationInner::EMPTY_STRING); + ret = appRunningManager->UpdateConfiguration(appRecord, Rosen::ConfigMode::COLOR_MODE); + EXPECT_FALSE(ret); + + appRecord->delayConfiguration_->AddItem(AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE, + ConfigurationInner::COLOR_MODE_DARK); + ret = appRunningManager->UpdateConfiguration(appRecord, Rosen::ConfigMode::COLOR_MODE); + EXPECT_TRUE(ret); + + appRecord = nullptr; + ret = appRunningManager->UpdateConfiguration(appRecord, Rosen::ConfigMode::COLOR_MODE); + EXPECT_FALSE(ret); +} + +/** + * @tc.name: ExecuteConfigurationTask_0100 + * @tc.desc: ExecuteConfigurationTask. + * @tc.type: FUNC + */ +HWTEST_F(AppRunningManagerFourthTest, ExecuteConfigurationTask_0100, TestSize.Level1) +{ + auto appRunningManager = std::make_shared(); + EXPECT_NE(appRunningManager, nullptr); + + BackgroundAppInfo info; + int32_t userId = 0; + ApplicationInfo appInfo; + appInfo.name = "KeepAliveApp"; + appInfo.bundleName = "KeepAliveApplication"; + appInfo.uid = 2100; + auto app = std::make_shared(appInfo); + std::shared_ptr appRecord = std::make_shared(app, 111, "KeepAliveApplication"); + + appRunningManager->updateConfigurationDelayedMap_.emplace(0, true); + appRunningManager->updateConfigurationDelayedMap_.emplace(1, true); + appRecord->appRecordId_ = 0; + appRecord->appIndex_ = 0; + appRecord->curState_ = ApplicationState::APP_STATE_BACKGROUND; + appRunningManager->appRunningRecordMap_.emplace(0, appRecord); + appRunningManager->appRunningRecordMap_.emplace(1, nullptr); + info.bandleName = "KeepAliveApplication"; + info.appIndex = 0; + userId = 1; + appRunningManager->ExecuteConfigurationTask(info, userId); + + userId = -1; + appRecord->delayConfiguration_ = nullptr; + appRunningManager->ExecuteConfigurationTask(info, userId); + + appRecord->delayConfiguration_ = std::make_shared(); + appRecord->delayConfiguration_->AddItem(AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE, + ConfigurationInner::COLOR_MODE_DARK); + appRunningManager->ExecuteConfigurationTask(info, userId); + std::string value = appRecord->delayConfiguration_->GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE); + EXPECT_TRUE(value == ConfigurationInner::EMPTY_STRING); +} } // namespace AppExecFwk } // namespace OHOS \ No newline at end of file -- Gitee