From b4fc97614f200a8adcd3dba4a4b5f2c928a7ce3b Mon Sep 17 00:00:00 2001 From: "cuijiawei14@huawei.com" Date: Fri, 2 Jun 2023 14:56:18 +0800 Subject: [PATCH] =?UTF-8?q?README=E6=95=B4=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: cuijiawei14@huawei.com --- README.md => README_ZH.md | 25 +- bundle.json | 2 - ...rce_schedule_socperf_architecture_ZH_1.png | Bin 32047 -> 43171 bytes patches/patches.json | 9 + ...ceschedule_resource_schedule_service.patch | 4804 +++++++++++++++++ 5 files changed, 4832 insertions(+), 8 deletions(-) rename README.md => README_ZH.md (85%) create mode 100644 patches/patches.json create mode 100644 patches/resourceschedule_resource_schedule_service.patch diff --git a/README.md b/README_ZH.md similarity index 85% rename from README.md rename to README_ZH.md index bb1e6aa..4b81512 100644 --- a/README.md +++ b/README_ZH.md @@ -8,6 +8,19 @@ SOC统一调频服务作为资源调度子系统的子模块,主要功能是 **图1** 统一调频部件架构图 ![架构图](figures/resource_schedule_socperf_architecture_ZH_1.png) + + + 架构说明: + + 1、应用调用系统服务,触发系统事件。 + + 2、在系统事件回调中通过统一调频提供的内部接口插入调频事件桩点。 + + 3、在资源调度服务中感知系统事件,转发给统一调频插件。 + + 4、在统一调频服务中根据系统事件查找配置,找到与其对应的调频配置,经过调频仲裁后得到最终的调频策略。 + + 5、统一调频模块将调频策略参数传递给内核完成调频。 ## 目录 ``` @@ -23,11 +36,11 @@ SOC统一调频服务作为资源调度子系统的子模块,主要功能是 │ └── server # SocPerf服务端代码,用于接受客户端发送的调频请求 ``` ## 编译构建 -编译32位ARM系统soc_perf部件 +编译32位ARM系统soc_perf部件: ``` ./build.sh --product-name {product_name} --ccache --build-target soc_perf ``` -编译64位ARM系统soc_perf部件 +编译64位ARM系统soc_perf部件: ``` ./build.sh --product-name {product_name} --ccache --target-cpu arm64 --build-target soc_perf ``` @@ -74,15 +87,15 @@ socperf_boost_config.xml使用的cmdID不能重复。 要实现点击场景的提频,分为点击事件插桩、事件上报给资源调度框架、框架给插件分发事件、生效调频服务四个步骤。 第一步, -ACE子系统仓内实现了对资源调度框架提供的可动态加载接口ReportData的封装,路径为/framework/base/ressched/ressched_report.h -并在/framework/core/gestures/click_recognizer.cpp增加了打点作为手势识别中对点击事件的判定 +ArkUI框架子系统仓内实现了对资源调度框架提供的可动态加载接口ReportData的封装,路径为/framework/base/ressched/ressched_report.h +并在/framework/core/gestures/click_recognizer.cpp增加了打点作为手势识别中对点击事件的判定。 第二步, -通过动态加载libressched_client.z.so,调用资源调度框架提供的接口ReportData,ACE子系统将点击事件上报给全局资源调度子系统 +通过动态加载libressched_client.z.so,调用资源调度框架提供的接口ReportData,ACE子系统将点击事件上报给全局资源调度子系统。 第三步, 在资源调度框架里,点击事件类型定义在/ressched/interfaces/innerkits/ressched_client/include/res_type.h内,为RES_TYPE_CLICK_RECOGNIZE -由于调频插件socperf_plugin在初始化过程中已完成了对该点击事件的订阅,因此框架会在接受到事件通知时将点击事件分发给调频插件 +由于调频插件socperf_plugin在初始化过程中已完成了对该点击事件的订阅,因此框架会在接受到事件通知时将点击事件分发给调频插件。 第四步, 调频插件socperf_plugin对于点击事件分配了cmdID:PERF_REQUEST_CMD_ID_EVENT_CLICK,路径在/ressched/plugins/socperf_plugin/src/socperf_plugin.cpp下 diff --git a/bundle.json b/bundle.json index 8525dfb..a164d05 100644 --- a/bundle.json +++ b/bundle.json @@ -15,8 +15,6 @@ "syscap": [], "features": [], "adapted_system_type": [ - "mini", - "small", "standard" ], "rom": "2048KB", diff --git a/figures/resource_schedule_socperf_architecture_ZH_1.png b/figures/resource_schedule_socperf_architecture_ZH_1.png index ade045fe411dd0e61a89827b059ab02d0365e351..921882579fff14355e5c7306436f21c241893adc 100644 GIT binary patch literal 43171 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 I<6hYR0G#*}asU7T literal 32047 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
7(oP!DHV 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 diff --git a/patches/patches.json b/patches/patches.json new file mode 100644 index 0000000..2f446a2 --- /dev/null +++ b/patches/patches.json @@ -0,0 +1,9 @@ +{ + "patches": [ + { + "project":"resourceschedule_resource_schedule_service", + "patch_file":"resourceschedule_resource_schedule_service.patch", + "path":"foundation/resourceschedule/resource_schedule_service" + } + ] +} \ No newline at end of file diff --git a/patches/resourceschedule_resource_schedule_service.patch b/patches/resourceschedule_resource_schedule_service.patch new file mode 100644 index 0000000..79874af --- /dev/null +++ b/patches/resourceschedule_resource_schedule_service.patch @@ -0,0 +1,4804 @@ +diff --git a/soc_perf/bundle.json b/soc_perf/bundle.json +deleted file mode 100644 +index 2226fca..0000000 +--- a/soc_perf/bundle.json ++++ /dev/null +@@ -1,72 +0,0 @@ +-{ +- "name": "@ohos/soc_perf", +- "description": "resource schedule service", +- "version": "3.1", +- "license": "Apache License 2.0", +- "publishAs": "code-segment", +- "segment": { +- "destPath": "foundation/resourceschedule/resource_schedule_service/soc_perf" +- }, +- "dirs": {}, +- "scripts": {}, +- "component": { +- "name": "soc_perf", +- "subsystem": "resourceschedule", +- "syscap": [], +- "features": [], +- "adapted_system_type": [ +- "mini", +- "small", +- "standard" +- ], +- "rom": "2048KB", +- "ram": "10240KB", +- "deps": { +- "components": [ +- "c_utils", +- "config_policy", +- "eventhandler", +- "hitrace_native", +- "hiviewdfx_hilog_native", +- "ipc", +- "libxml2", +- "safwk", +- "samgr" +- ], +- "third_party": [] +- }, +- "build": { +- "group_type": { +- "base_group" : [ +- "//foundation/resourceschedule/resource_schedule_service/soc_perf/profile:socperf_config" +- ], +- "fwk_group" : [ +- "//foundation/resourceschedule/resource_schedule_service/soc_perf/interfaces/inner_api/socperf_client:socperf_client" +- ], +- "service_group" : [ +- "//foundation/resourceschedule/resource_schedule_service/soc_perf/sa_profile:socperf_sa_profile", +- "//foundation/resourceschedule/resource_schedule_service/soc_perf/services:socperf_server" +- ] +- }, +- "inner_kits": [ +- { +- "header": { +- "header_base": "//foundation/resourceschedule/resource_schedule_service/soc_perf/interfaces/inner_api/socperf_client/include", +- "header_files": [ +- "i_socperf_service.h", +- "socperf_action_type.h", +- "socperf_client.h", +- "socperf_proxy.h" +- ] +- }, +- "name": "//foundation/resourceschedule/resource_schedule_service/soc_perf/interfaces/inner_api/socperf_client:socperf_client" +- } +- ], +- "test": [ +- "//foundation/resourceschedule/resource_schedule_service/soc_perf/test/unittest:unittest", +- "//foundation/resourceschedule/resource_schedule_service/soc_perf/test/fuzztest:fuzztest", +- "//foundation/resourceschedule/resource_schedule_service/soc_perf/test/testutil:socperf_test" +- ] +- } +- } +-} +\ No newline at end of file +diff --git a/soc_perf/common/include/socperf_log.h b/soc_perf/common/include/socperf_log.h +deleted file mode 100644 +index 0723b1e..0000000 +--- a/soc_perf/common/include/socperf_log.h ++++ /dev/null +@@ -1,75 +0,0 @@ +-/* +- * Copyright (c) 2023 Huawei Device Co., Ltd. +- * Licensed under the Apache License, Version 2.0 (the "License"); +- * you may not use this file except in compliance with the License. +- * You may obtain a copy of the License at +- * +- * http://www.apache.org/licenses/LICENSE-2.0 +- * +- * Unless required by applicable law or agreed to in writing, software +- * distributed under the License is distributed on an "AS IS" BASIS, +- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +- * See the License for the specific language governing permissions and +- * limitations under the License. +- */ +- +-#ifndef SOC_PERF_COMMON_INCLUDE_SOCPERF_LOG_H +-#define SOC_PERF_COMMON_INCLUDE_SOCPERF_LOG_H +- +-#include "hilog/log.h" +- +-namespace OHOS { +-namespace SOCPERF { +-#ifndef LOG_TAG_SOC_PERF +-#define LOG_TAG_SOC_PERF "socperf" +-#endif +- +-#ifndef LOG_TAG_DOMAIN_ID_SOC_PERF +-#define LOG_TAG_DOMAIN_ID_SOC_PERF 0xD001703 +-#endif +- +-static constexpr OHOS::HiviewDFX::HiLogLabel SOC_PERF_LOG_LABEL = { +- LOG_CORE, +- LOG_TAG_DOMAIN_ID_SOC_PERF, +- LOG_TAG_SOC_PERF +-}; +- +-class SocPerfLog { +-public: +- SocPerfLog() = delete; +- ~SocPerfLog() = delete; +- +- static bool IsDebugLogEnabled() +- { +- return isDebugLogEnabled_; +- } +- +- static void EnableDebugLog() +- { +- isDebugLogEnabled_ = true; +- } +- +- static void DisableDebugLog() +- { +- isDebugLogEnabled_ = false; +- } +- +-private: +- static bool isDebugLogEnabled_; +-}; +- +-#define SOC_PERF_PRINT_LOG(Level, fmt, ...) \ +- OHOS::HiviewDFX::HiLog::Level(SOC_PERF_LOG_LABEL, "[%{public}s]: " fmt, __FUNCTION__, ##__VA_ARGS__) +- +-#define SOC_PERF_LOGD(fmt, ...) \ +- if (SocPerfLog::IsDebugLogEnabled()) \ +- SOC_PERF_PRINT_LOG(Debug, fmt, ##__VA_ARGS__) +- +-#define SOC_PERF_LOGI(fmt, ...) SOC_PERF_PRINT_LOG(Info, fmt, ##__VA_ARGS__) +-#define SOC_PERF_LOGW(fmt, ...) SOC_PERF_PRINT_LOG(Warn, fmt, ##__VA_ARGS__) +-#define SOC_PERF_LOGE(fmt, ...) SOC_PERF_PRINT_LOG(Error, fmt, ##__VA_ARGS__) +-#define SOC_PERF_LOGF(fmt, ...) SOC_PERF_PRINT_LOG(Fatal, fmt, ##__VA_ARGS__) +-} // namespace SOCPERF +-} // namespace OHOS +- +-#endif // SOC_PERF_COMMON_INCLUDE_SOCPERF_LOG_H +diff --git a/soc_perf/common/src/socperf_log.cpp b/soc_perf/common/src/socperf_log.cpp +deleted file mode 100644 +index 90c819d..0000000 +--- a/soc_perf/common/src/socperf_log.cpp ++++ /dev/null +@@ -1,22 +0,0 @@ +-/* +- * Copyright (c) 2023 Huawei Device Co., Ltd. +- * Licensed under the Apache License, Version 2.0 (the "License"); +- * you may not use this file except in compliance with the License. +- * You may obtain a copy of the License at +- * +- * http://www.apache.org/licenses/LICENSE-2.0 +- * +- * Unless required by applicable law or agreed to in writing, software +- * distributed under the License is distributed on an "AS IS" BASIS, +- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +- * See the License for the specific language governing permissions and +- * limitations under the License. +- */ +- +-#include "socperf_log.h" +- +-namespace OHOS { +-namespace SOCPERF { +-bool SocPerfLog::isDebugLogEnabled_ = HiLogIsLoggable(LOG_TAG_DOMAIN_ID_SOC_PERF, LOG_TAG_SOC_PERF, LOG_DEBUG); +-} // namespace SOCPERF +-} // namespace OHOS +diff --git a/soc_perf/interfaces/inner_api/socperf_client/BUILD.gn b/soc_perf/interfaces/inner_api/socperf_client/BUILD.gn +deleted file mode 100644 +index 09b4d7b..0000000 +--- a/soc_perf/interfaces/inner_api/socperf_client/BUILD.gn ++++ /dev/null +@@ -1,45 +0,0 @@ +-# Copyright (c) 2022-2023 Huawei Device Co., Ltd. +-# Licensed under the Apache License, Version 2.0 (the "License"); +-# you may not use this file except in compliance with the License. +-# You may obtain a copy of the License at +-# +-# http://www.apache.org/licenses/LICENSE-2.0 +-# +-# Unless required by applicable law or agreed to in writing, software +-# distributed under the License is distributed on an "AS IS" BASIS, +-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-# See the License for the specific language governing permissions and +-# limitations under the License. +- +-import("//build/ohos.gni") +-import("../../../soc_perf.gni") +- +-config("socperf_client_public_config") { +- include_dirs = [ +- "include", +- "${socperf_common}/include", +- ] +-} +- +-ohos_shared_library("socperf_client") { +- sources = [ +- "${socperf_common}/src/socperf_log.cpp", +- "src/socperf_client.cpp", +- "src/socperf_proxy.cpp", +- ] +- +- public_configs = [ ":socperf_client_public_config" ] +- +- external_deps = [ +- "c_utils:utils", +- "hiviewdfx_hilog_native:libhilog", +- "ipc:ipc_single", +- "safwk:system_ability_fwk", +- "samgr:samgr_proxy", +- ] +- +- innerapi_tags = [ "platformsdk" ] +- version_script = "libsocperf_client.versionscript" +- part_name = "soc_perf" +- subsystem_name = "resourceschedule" +-} +diff --git a/soc_perf/interfaces/inner_api/socperf_client/include/i_socperf_service.h b/soc_perf/interfaces/inner_api/socperf_client/include/i_socperf_service.h +deleted file mode 100644 +index abbafb5..0000000 +--- a/soc_perf/interfaces/inner_api/socperf_client/include/i_socperf_service.h ++++ /dev/null +@@ -1,93 +0,0 @@ +-/* +- * Copyright (c) 2022-2023 Huawei Device Co., Ltd. +- * Licensed under the Apache License, Version 2.0 (the "License"); +- * you may not use this file except in compliance with the License. +- * You may obtain a copy of the License at +- * +- * http://www.apache.org/licenses/LICENSE-2.0 +- * +- * Unless required by applicable law or agreed to in writing, software +- * distributed under the License is distributed on an "AS IS" BASIS, +- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +- * See the License for the specific language governing permissions and +- * limitations under the License. +- */ +- +-#ifndef SOC_PERF_INTERFACES_INNER_API_SOCPERF_CLIENT_INCLUDE_I_SOCPERF_SERVICE_H +-#define SOC_PERF_INTERFACES_INNER_API_SOCPERF_CLIENT_INCLUDE_I_SOCPERF_SERVICE_H +- +-#include +-#include "iremote_broker.h" +-#include "iremote_stub.h" +-#include "iremote_proxy.h" +-#include "iremote_object.h" +-#include "system_ability.h" +-#include "system_ability_definition.h" +-#include "if_system_ability_manager.h" +-#include "iservice_registry.h" +-#include "socperf_action_type.h" +- +-namespace OHOS { +-namespace SOCPERF { +-class ISocPerfService : public IRemoteBroker { +-public: +- /** +- * @brief Sending a performance request. +- * +- * @param cmdId scene id defined in config file. +- * @param msg Additional string info, which is used for other extensions. +- */ +- virtual void PerfRequest(int32_t cmdId, const std::string& msg) = 0; +- +- /** +- * @brief Sending a performance request. +- * +- * @param cmdId Scene id defined in config file. +- * @param onOffTag Indicates the start of end of a long-term frequency increase event. +- * @param msg Additional string info, which is used for other extensions. +- */ +- virtual void PerfRequestEx(int32_t cmdId, bool onOffTag, const std::string& msg) = 0; +- +- /** +- * @brief Sending a power limit boost request. +- * +- * @param onOffTag Indicates the start of end of a power limit boost event. +- * @param msg Additional string info, which is used for other extensions. +- */ +- virtual void PowerLimitBoost(bool onOffTag, const std::string& msg) = 0; +- +- /** +- * @brief Sending a thermal limit boost request. +- * +- * @param onOffTag Indicates the start of end of a thermal limit boost event. +- * @param msg Additional string info, which is used for other extensions. +- */ +- virtual void ThermalLimitBoost(bool onOffTag, const std::string& msg) = 0; +- +- /** +- * @brief Sending a limit request. +- * +- * @param clientId Used to indentify the caller of frequency limiting, such as +- * the thermal module or power consumption module. +- * @param configs Indicates the specific value to be limited. +- * @param msg Additional string info, which is used for other extensions. +- */ +- virtual void LimitRequest(int32_t clientId, +- const std::vector& tags, const std::vector& configs, const std::string& msg) = 0; +- +-public: +- enum { +- TRANS_IPC_ID_PERF_REQUEST = 0x0001, +- TRANS_IPC_ID_PERF_REQUEST_EX = 0x0002, +- TRANS_IPC_ID_POWER_LIMIT_BOOST_FREQ = 0x0005, +- TRANS_IPC_ID_THERMAL_LIMIT_BOOST_FREQ = 0x0008, +- TRANS_IPC_ID_LIMIT_REQUEST = 0x0009, +- }; +- +-public: +- DECLARE_INTERFACE_DESCRIPTOR(u"Resourceschedule.ISocPerfService"); +-}; +-} // namespace SOCPERF +-} // namespace OHOS +- +-#endif // SOC_PERF_INTERFACES_INNER_API_SOCPERF_CLIENT_INCLUDE_I_SOCPERF_SERVICE_H +diff --git a/soc_perf/interfaces/inner_api/socperf_client/include/socperf_action_type.h b/soc_perf/interfaces/inner_api/socperf_client/include/socperf_action_type.h +deleted file mode 100644 +index d7a8a42..0000000 +--- a/soc_perf/interfaces/inner_api/socperf_client/include/socperf_action_type.h ++++ /dev/null +@@ -1,32 +0,0 @@ +-/* +- * Copyright (c) 2023 Huawei Device Co., Ltd. +- * Licensed under the Apache License, Version 2.0 (the "License"); +- * you may not use this file except in compliance with the License. +- * You may obtain a copy of the License at +- * +- * http://www.apache.org/licenses/LICENSE-2.0 +- * +- * Unless required by applicable law or agreed to in writing, software +- * distributed under the License is distributed on an "AS IS" BASIS, +- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +- * See the License for the specific language governing permissions and +- * limitations under the License. +- */ +- +-#ifndef SOC_PERF_INTERFACES_INNER_API_SOCPERF_CLIENT_INCLUDE_SOCPERF_ACTION_TYPE_H +-#define SOC_PERF_INTERFACES_INNER_API_SOCPERF_CLIENT_INCLUDE_SOCPERF_ACTION_TYPE_H +- +-#include +- +-namespace OHOS { +-namespace SOCPERF { +-enum ActionType : uint32_t { +- ACTION_TYPE_PERF, +- ACTION_TYPE_POWER, +- ACTION_TYPE_THERMAL, +- ACTION_TYPE_MAX +-}; +-} // namespace SOCPERF +-} // namespace OHOS +- +-#endif // SOC_PERF_INTERFACES_INNER_API_SOCPERF_CLIENT_INCLUDE_SOCPERF_ACTION_TYPE_H +diff --git a/soc_perf/interfaces/inner_api/socperf_client/include/socperf_client.h b/soc_perf/interfaces/inner_api/socperf_client/include/socperf_client.h +deleted file mode 100644 +index a638e48..0000000 +--- a/soc_perf/interfaces/inner_api/socperf_client/include/socperf_client.h ++++ /dev/null +@@ -1,114 +0,0 @@ +-/* +- * Copyright (c) 2022-2023 Huawei Device Co., Ltd. +- * Licensed under the Apache License, Version 2.0 (the "License"); +- * you may not use this file except in compliance with the License. +- * You may obtain a copy of the License at +- * +- * http://www.apache.org/licenses/LICENSE-2.0 +- * +- * Unless required by applicable law or agreed to in writing, software +- * distributed under the License is distributed on an "AS IS" BASIS, +- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +- * See the License for the specific language governing permissions and +- * limitations under the License. +- */ +- +-#ifndef SOC_PERF_INTERFACES_INNER_API_SOCPERF_CLIENT_INCLUDE_SOCPERF_CLIENT_H +-#define SOC_PERF_INTERFACES_INNER_API_SOCPERF_CLIENT_INCLUDE_SOCPERF_CLIENT_H +- +-#include // for int32_t +-#include // for string +-#include // for vector +-#include "i_socperf_service.h" // for ISocPerfService +- +-namespace OHOS { +-namespace SOCPERF { +-class SocPerfClient { +-public: +- /** +- * @brief Get the Instance object +- * +- * @return SocPerfClient& +- */ +- static SocPerfClient& GetInstance(); +- +- /** +- * @brief Sending a performance request. +- * +- * @param cmdId Scene id defined in config file. +- * @param msg Additional string info, which is used for other extensions. +- */ +- void PerfRequest(int32_t cmdId, const std::string& msg); +- +- /** +- * @brief Sending a performance request. +- * +- * @param cmdId Scene id defined in config file. +- * @param onOffTag Indicates the start of end of a long-term frequency increase event. +- * @param msg Additional string info, which is used for other extensions. +- */ +- void PerfRequestEx(int32_t cmdId, bool onOffTag, const std::string& msg); +- +- /** +- * @brief Sending a power limit boost request. +- * +- * @param onOffTag Indicates the start of end of a power limit boost event. +- * @param msg Additional string info, which is used for other extensions. +- */ +- void PowerLimitBoost(bool onOffTag, const std::string& msg); +- +- /** +- * @brief Sending a thermal limit boost request. +- * +- * @param onOffTag Indicates the start of end of a thermal limit boost event. +- * @param msg Additional string info, which is used for other extensions. +- */ +- void ThermalLimitBoost(bool onOffTag, const std::string& msg); +- +- /** +- * @brief Sending a limit request. +- * +- * @param clientId Used to indentify the caller of frequency limiting, such as +- * the thermal module or power consumption module. +- * @param configs Indicates the specific value to be limited. +- * @param msg Additional string info, which is used for other extensions. +- */ +- void LimitRequest(int32_t clientId, +- const std::vector& tags, const std::vector& configs, const std::string& msg); +- +- /** +- * @brief Reset SocperfClient +- * +- */ +- void ResetClient(); +- +-private: +- SocPerfClient() {} +- ~SocPerfClient() {} +- +-private: +- bool CheckClientValid(); +- std::string AddPidAndTidInfo(const std::string& msg); +- +-private: +- class SocPerfDeathRecipient : public IRemoteObject::DeathRecipient { +- public: +- explicit SocPerfDeathRecipient(SocPerfClient &socPerfClient); +- +- ~SocPerfDeathRecipient(); +- +- void OnRemoteDied(const wptr &object) override; +- +- private: +- SocPerfClient &socPerfClient_; +- }; +- +-private: +- std::mutex mutex_; +- sptr client; +- sptr recipient_; +-}; +-} // namespace SOCPERF +-} // namespace OHOS +- +-#endif // SOC_PERF_INTERFACES_INNER_API_SOCPERF_CLIENT_INCLUDE_SOCPERF_CLIENT_H +diff --git a/soc_perf/interfaces/inner_api/socperf_client/include/socperf_proxy.h b/soc_perf/interfaces/inner_api/socperf_client/include/socperf_proxy.h +deleted file mode 100644 +index 67f3faa..0000000 +--- a/soc_perf/interfaces/inner_api/socperf_client/include/socperf_proxy.h ++++ /dev/null +@@ -1,90 +0,0 @@ +-/* +- * Copyright (c) 2022-2023 Huawei Device Co., Ltd. +- * Licensed under the Apache License, Version 2.0 (the "License"); +- * you may not use this file except in compliance with the License. +- * You may obtain a copy of the License at +- * +- * http://www.apache.org/licenses/LICENSE-2.0 +- * +- * Unless required by applicable law or agreed to in writing, software +- * distributed under the License is distributed on an "AS IS" BASIS, +- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +- * See the License for the specific language governing permissions and +- * limitations under the License. +- */ +- +-#ifndef SOC_PERF_INTERFACES_INNER_API_SOCPERF_CLIENT_INCLUDE_SOCPERF_PROXY_H +-#define SOC_PERF_INTERFACES_INNER_API_SOCPERF_CLIENT_INCLUDE_SOCPERF_PROXY_H +- +-#include "i_socperf_service.h" +- +-namespace OHOS { +-namespace SOCPERF { +-class SocPerfProxy : public IRemoteProxy { +-public: +- /** +- * @brief Sending a performance request. +- * +- * @param cmdId Scene id defined in config file. +- * @param msg Additional string info, which is used for other extensions. +- */ +- void PerfRequest(int32_t cmdId, const std::string& msg) override; +- +- /** +- * @brief Sending a performance request. +- * +- * @param cmdId Scene id defined in config file. +- * @param onOffTag Indicates the start of end of a long-term frequency increase event. +- * @param msg Additional string info, which is used for other extensions. +- */ +- void PerfRequestEx(int32_t cmdId, bool onOffTag, const std::string& msg) override; +- +- /** +- * @brief Sending a power limit boost request. +- * +- * @param onOffTag Indicates the start of end of a power limit boost event. +- * @param msg Additional string info, which is used for other extensions. +- */ +- void PowerLimitBoost(bool onOffTag, const std::string& msg) override; +- +- /** +- * @brief Sending a thermal limit boost request. +- * +- * @param onOffTag Indicates the start of end of a thermal limit boost event. +- * @param msg Additional string info, which is used for other extensions. +- */ +- void ThermalLimitBoost(bool onOffTag, const std::string& msg) override; +- +- /** +- * @brief Sending a limit request. +- * +- * @param clientId Used to indentify the caller of frequency limiting, such as +- * the thermal module or power consumption module. +- * @param configs Indicates the specific value to be limited. +- * @param msg Additional string info, which is used for other extensions. +- */ +- void LimitRequest(int32_t clientId, +- const std::vector& tags, const std::vector& configs, const std::string& msg) override; +- +-public: +- /** +- * @brief Construct a new SocPerfProxy object. +- * +- * @param impl RemoteObject. +- */ +- explicit SocPerfProxy(const sptr &impl) +- : IRemoteProxy(impl) {} +- +- /** +- * @brief Destroy the SocPerfProxy object. +- * +- */ +- virtual ~SocPerfProxy() {} +- +-private: +- static inline BrokerDelegator delegator_; +-}; +-} // namespace SOCPERF +-} // namespace OHOS +- +-#endif // SOC_PERF_INTERFACES_INNER_API_SOCPERF_CLIENT_INCLUDE_SOCPERF_PROXY_H +diff --git a/soc_perf/interfaces/inner_api/socperf_client/libsocperf_client.versionscript b/soc_perf/interfaces/inner_api/socperf_client/libsocperf_client.versionscript +deleted file mode 100644 +index d870698..0000000 +--- a/soc_perf/interfaces/inner_api/socperf_client/libsocperf_client.versionscript ++++ /dev/null +@@ -1,27 +0,0 @@ +-# Copyright (c) 2023 Huawei Device Co., Ltd. +-# Licensed under the Apache License, Version 2.0 (the "License"); +-# you may not use this file except in compliance with the License. +-# You may obtain a copy of the License at +-# +-# http://www.apache.org/licenses/LICENSE-2.0 +-# +-# Unless required by applicable law or agreed to in writing, software +-# distributed under the License is distributed on an "AS IS" BASIS, +-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-# See the License for the specific language governing permissions and +-# limitations under the License. +- +-1.0 { +- global: +- *ISocPerfService*; +- *SocPerfClient*GetInstance*; +- *SocPerfClient*PerfRequest*; +- *SocPerfClient*PerfRequestEx*; +- *SocPerfClient*PowerLimitBoost*; +- *SocPerfClient*ThermalLimitBoost*; +- *SocPerfClient*LimitRequest*; +- *SocPerfClient*ResetClient*; +- *SocPerfProxy*; +- local: +- *; +-}; +diff --git a/soc_perf/interfaces/inner_api/socperf_client/src/socperf_client.cpp b/soc_perf/interfaces/inner_api/socperf_client/src/socperf_client.cpp +deleted file mode 100644 +index d70f7f2..0000000 +--- a/soc_perf/interfaces/inner_api/socperf_client/src/socperf_client.cpp ++++ /dev/null +@@ -1,141 +0,0 @@ +-/* +- * Copyright (c) 2022-2023 Huawei Device Co., Ltd. +- * Licensed under the Apache License, Version 2.0 (the "License"); +- * you may not use this file except in compliance with the License. +- * You may obtain a copy of the License at +- * +- * http://www.apache.org/licenses/LICENSE-2.0 +- * +- * Unless required by applicable law or agreed to in writing, software +- * distributed under the License is distributed on an "AS IS" BASIS, +- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +- * See the License for the specific language governing permissions and +- * limitations under the License. +- */ +- +-#include "socperf_client.h" +-#include // for basic_string, to_string +-#include // for getpid, gettid +-#include "socperf_log.h" +- +-namespace OHOS { +-namespace SOCPERF { +-SocPerfClient& SocPerfClient::GetInstance() +-{ +- static SocPerfClient instance; +- return instance; +-} +- +-bool SocPerfClient::CheckClientValid() +-{ +- std::lock_guard lock(mutex_); +- if (client) { +- return true; +- } +- +- sptr samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); +- if (!samgr) { +- SOC_PERF_LOGE("Failed to get SystemAbilityManager."); +- return false; +- } +- +- sptr object = samgr->CheckSystemAbility(SOC_PERF_SERVICE_SA_ID); +- if (!object) { +- SOC_PERF_LOGE("Failed to get SystemAbility[1906]."); +- return false; +- } +- +- client = iface_cast(object); +- if (!client || !client->AsObject()) { +- SOC_PERF_LOGE("Failed to get SocPerfClient."); +- return false; +- } +- +- recipient_ = new (std::nothrow) SocPerfDeathRecipient(*this); +- if (!recipient_) { +- return false; +- } +- client->AsObject()->AddDeathRecipient(recipient_); +- +- return true; +-} +- +-void SocPerfClient::ResetClient() +-{ +- std::lock_guard lock(mutex_); +- if (client && client->AsObject()) { +- client->AsObject()->RemoveDeathRecipient(recipient_); +- } +- client = nullptr; +-} +- +-SocPerfClient::SocPerfDeathRecipient::SocPerfDeathRecipient(SocPerfClient &socPerfClient) +- : socPerfClient_(socPerfClient) {} +- +-SocPerfClient::SocPerfDeathRecipient::~SocPerfDeathRecipient() {} +- +-void SocPerfClient::SocPerfDeathRecipient::OnRemoteDied(const wptr &remote) +-{ +- socPerfClient_.ResetClient(); +-} +- +-std::string SocPerfClient::AddPidAndTidInfo(const std::string& msg) +-{ +- std::string str; +- int32_t pid = getpid(); +- int32_t tid = gettid(); +- str.append("pid=").append(std::to_string(pid)).append("|"); +- str.append("tid=").append(std::to_string(tid)); +- if (msg.size() > 0) { +- str.append("|").append(msg); +- } +- return str; +-} +- +-void SocPerfClient::PerfRequest(int32_t cmdId, const std::string& msg) +-{ +- if (!CheckClientValid()) { +- return; +- } +- std::string newMsg = AddPidAndTidInfo(msg); +- client->PerfRequest(cmdId, newMsg); +-} +- +-void SocPerfClient::PerfRequestEx(int32_t cmdId, bool onOffTag, const std::string& msg) +-{ +- if (!CheckClientValid()) { +- return; +- } +- std::string newMsg = AddPidAndTidInfo(msg); +- client->PerfRequestEx(cmdId, onOffTag, newMsg); +-} +- +-void SocPerfClient::PowerLimitBoost(bool onOffTag, const std::string& msg) +-{ +- if (!CheckClientValid()) { +- return; +- } +- std::string newMsg = AddPidAndTidInfo(msg); +- client->PowerLimitBoost(onOffTag, newMsg); +-} +- +-void SocPerfClient::ThermalLimitBoost(bool onOffTag, const std::string& msg) +-{ +- if (!CheckClientValid()) { +- return; +- } +- std::string newMsg = AddPidAndTidInfo(msg); +- client->ThermalLimitBoost(onOffTag, newMsg); +-} +- +-void SocPerfClient::LimitRequest(int32_t clientId, +- const std::vector& tags, const std::vector& configs, const std::string& msg) +-{ +- if (!CheckClientValid()) { +- return; +- } +- std::string newMsg = AddPidAndTidInfo(msg); +- client->LimitRequest(clientId, tags, configs, newMsg); +-} +-} // namespace SOCPERF +-} // namespace OHOS +diff --git a/soc_perf/interfaces/inner_api/socperf_client/src/socperf_proxy.cpp b/soc_perf/interfaces/inner_api/socperf_client/src/socperf_proxy.cpp +deleted file mode 100644 +index afb44dd..0000000 +--- a/soc_perf/interfaces/inner_api/socperf_client/src/socperf_proxy.cpp ++++ /dev/null +@@ -1,89 +0,0 @@ +-/* +- * Copyright (c) 2022 Huawei Device Co., Ltd. +- * Licensed under the Apache License, Version 2.0 (the "License"); +- * you may not use this file except in compliance with the License. +- * You may obtain a copy of the License at +- * +- * http://www.apache.org/licenses/LICENSE-2.0 +- * +- * Unless required by applicable law or agreed to in writing, software +- * distributed under the License is distributed on an "AS IS" BASIS, +- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +- * See the License for the specific language governing permissions and +- * limitations under the License. +- */ +- +-#include "socperf_proxy.h" +- +-namespace OHOS { +-namespace SOCPERF { +-void SocPerfProxy::PerfRequest(int32_t cmdId, const std::string& msg) +-{ +- MessageParcel data; +- MessageParcel reply; +- MessageOption option = { MessageOption::TF_ASYNC }; +- if (!data.WriteInterfaceToken(GetDescriptor())) { +- return; +- } +- data.WriteInt32(cmdId); +- data.WriteString(msg); +- Remote()->SendRequest(TRANS_IPC_ID_PERF_REQUEST, data, reply, option); +-} +- +-void SocPerfProxy::PerfRequestEx(int32_t cmdId, bool onOffTag, const std::string& msg) +-{ +- MessageParcel data; +- MessageParcel reply; +- MessageOption option = { MessageOption::TF_ASYNC }; +- if (!data.WriteInterfaceToken(GetDescriptor())) { +- return; +- } +- data.WriteInt32(cmdId); +- data.WriteBool(onOffTag); +- data.WriteString(msg); +- Remote()->SendRequest(TRANS_IPC_ID_PERF_REQUEST_EX, data, reply, option); +-} +- +-void SocPerfProxy::PowerLimitBoost(bool onOffTag, const std::string& msg) +-{ +- MessageParcel data; +- MessageParcel reply; +- MessageOption option = { MessageOption::TF_ASYNC }; +- if (!data.WriteInterfaceToken(GetDescriptor())) { +- return; +- } +- data.WriteBool(onOffTag); +- data.WriteString(msg); +- Remote()->SendRequest(TRANS_IPC_ID_POWER_LIMIT_BOOST_FREQ, data, reply, option); +-} +- +-void SocPerfProxy::ThermalLimitBoost(bool onOffTag, const std::string& msg) +-{ +- MessageParcel data; +- MessageParcel reply; +- MessageOption option = { MessageOption::TF_ASYNC }; +- if (!data.WriteInterfaceToken(GetDescriptor())) { +- return; +- } +- data.WriteBool(onOffTag); +- data.WriteString(msg); +- Remote()->SendRequest(TRANS_IPC_ID_THERMAL_LIMIT_BOOST_FREQ, data, reply, option); +-} +- +-void SocPerfProxy::LimitRequest(int32_t clientId, +- const std::vector& tags, const std::vector& configs, const std::string& msg) +-{ +- MessageParcel data; +- MessageParcel reply; +- MessageOption option = { MessageOption::TF_ASYNC }; +- if (!data.WriteInterfaceToken(GetDescriptor())) { +- return; +- } +- data.WriteInt32(clientId); +- data.WriteInt32Vector(tags); +- data.WriteInt64Vector(configs); +- data.WriteString(msg); +- Remote()->SendRequest(TRANS_IPC_ID_LIMIT_REQUEST, data, reply, option); +-} +-} // namespace SOCPERF +-} // namespace OHOS +diff --git a/soc_perf/profile/BUILD.gn b/soc_perf/profile/BUILD.gn +deleted file mode 100644 +index d5b9789..0000000 +--- a/soc_perf/profile/BUILD.gn ++++ /dev/null +@@ -1,36 +0,0 @@ +-# Copyright (c) 2023 Huawei Device Co., Ltd. +-# Licensed under the Apache License, Version 2.0 (the "License"); +-# you may not use this file except in compliance with the License. +-# You may obtain a copy of the License at +-# +-# http://www.apache.org/licenses/LICENSE-2.0 +-# +-# Unless required by applicable law or agreed to in writing, software +-# distributed under the License is distributed on an "AS IS" BASIS, +-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-# See the License for the specific language governing permissions and +-# limitations under the License. +- +-import("//build/ohos.gni") +- +-ohos_prebuilt_etc("socperf_resource_config") { +- source = "socperf_resource_config.xml" +- install_enable = true +- module_install_dir = "etc/soc_perf" +- part_name = "soc_perf" +- subsystem_name = "resourceschedule" +-} +-ohos_prebuilt_etc("socperf_boost_config") { +- source = "socperf_boost_config.xml" +- install_enable = true +- module_install_dir = "etc/soc_perf" +- part_name = "soc_perf" +- subsystem_name = "resourceschedule" +-} +- +-group("socperf_config") { +- deps = [ +- ":socperf_boost_config", +- ":socperf_resource_config", +- ] +-} +diff --git a/soc_perf/profile/socperf_boost_config.xml b/soc_perf/profile/socperf_boost_config.xml +deleted file mode 100644 +index 4fdf3be..0000000 +--- a/soc_perf/profile/socperf_boost_config.xml ++++ /dev/null +@@ -1,17 +0,0 @@ +- +- +- +- +\ No newline at end of file +diff --git a/soc_perf/profile/socperf_resource_config.xml b/soc_perf/profile/socperf_resource_config.xml +deleted file mode 100644 +index 4fdf3be..0000000 +--- a/soc_perf/profile/socperf_resource_config.xml ++++ /dev/null +@@ -1,17 +0,0 @@ +- +- +- +- +\ No newline at end of file +diff --git a/soc_perf/sa_profile/1906.json b/soc_perf/sa_profile/1906.json +deleted file mode 100644 +index 12cf53a..0000000 +--- a/soc_perf/sa_profile/1906.json ++++ /dev/null +@@ -1,12 +0,0 @@ +-{ +- "process": "resource_schedule_service", +- "systemability": [ +- { +- "name": 1906, +- "libpath": "libsocperf_server.z.so", +- "run-on-create": true, +- "distributed": false, +- "dump_level": 1 +- } +- ] +-} +\ No newline at end of file +diff --git a/soc_perf/sa_profile/BUILD.gn b/soc_perf/sa_profile/BUILD.gn +deleted file mode 100644 +index ef1bab8..0000000 +--- a/soc_perf/sa_profile/BUILD.gn ++++ /dev/null +@@ -1,19 +0,0 @@ +-# Copyright (c) 2023 Huawei Device Co., Ltd. +-# Licensed under the Apache License, Version 2.0 (the "License"); +-# you may not use this file except in compliance with the License. +-# You may obtain a copy of the License at +-# +-# http://www.apache.org/licenses/LICENSE-2.0 +-# +-# Unless required by applicable law or agreed to in writing, software +-# distributed under the License is distributed on an "AS IS" BASIS, +-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-# See the License for the specific language governing permissions and +-# limitations under the License. +- +-import("//build/ohos/sa_profile/sa_profile.gni") +- +-ohos_sa_profile("socperf_sa_profile") { +- sources = [ "1906.json" ] +- part_name = "soc_perf" +-} +diff --git a/soc_perf/services/BUILD.gn b/soc_perf/services/BUILD.gn +deleted file mode 100644 +index 934b1ab..0000000 +--- a/soc_perf/services/BUILD.gn ++++ /dev/null +@@ -1,91 +0,0 @@ +-# Copyright (c) 2022-2023 Huawei Device Co., Ltd. +-# Licensed under the Apache License, Version 2.0 (the "License"); +-# you may not use this file except in compliance with the License. +-# You may obtain a copy of the License at +-# +-# http://www.apache.org/licenses/LICENSE-2.0 +-# +-# Unless required by applicable law or agreed to in writing, software +-# distributed under the License is distributed on an "AS IS" BASIS, +-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-# See the License for the specific language governing permissions and +-# limitations under the License. +- +-import("//build/ohos.gni") +-import("../soc_perf.gni") +- +-config("socperf_server_config") { +- include_dirs = [ +- "core/include", +- "server/include", +- "${socperf_common}/include", +- "${socperf_interfaces}/inner_api/socperf_client/include", +- ] +-} +- +-ohos_shared_library("socperf_server") { +- configs = [ ":socperf_server_config" ] +- +- sources = [ +- "${socperf_common}/src/socperf_log.cpp", +- "core/src/socperf.cpp", +- "core/src/socperf_handler.cpp", +- "server/src/socperf_server.cpp", +- "server/src/socperf_stub.cpp", +- ] +- +- deps = [ "//third_party/libxml2:xml2" ] +- +- external_deps = [ +- "c_utils:utils", +- "eventhandler:libeventhandler", +- "hitrace_native:hitrace_meter", +- "hiviewdfx_hilog_native:libhilog", +- "ipc:ipc_single", +- "safwk:system_ability_fwk", +- "samgr:samgr_proxy", +- ] +- +- defines = [] +- if (customization_config_policy_enable) { +- external_deps += [ "config_policy:configpolicy_util" ] +- defines += [ "CUSTOMIZATION_CONFIG_POLICY_ENABLE" ] +- } +- +- shlib_type = "sa" +- part_name = "soc_perf" +- subsystem_name = "resourceschedule" +-} +- +-ohos_static_library("socperf_server_static") { +- configs = [ ":socperf_server_config" ] +- +- sources = [ +- "${socperf_common}/src/socperf_log.cpp", +- "core/src/socperf.cpp", +- "core/src/socperf_handler.cpp", +- "server/src/socperf_server.cpp", +- "server/src/socperf_stub.cpp", +- ] +- +- deps = [ "//third_party/libxml2:xml2" ] +- +- external_deps = [ +- "c_utils:utils", +- "eventhandler:libeventhandler", +- "hitrace_native:hitrace_meter", +- "hiviewdfx_hilog_native:libhilog", +- "ipc:ipc_single", +- "safwk:system_ability_fwk", +- "samgr:samgr_proxy", +- ] +- +- defines = [] +- if (customization_config_policy_enable) { +- external_deps += [ "config_policy:configpolicy_util" ] +- defines += [ "CUSTOMIZATION_CONFIG_POLICY_ENABLE" ] +- } +- +- part_name = "soc_perf" +- subsystem_name = "resourceschedule" +-} +diff --git a/soc_perf/services/core/include/socperf.h b/soc_perf/services/core/include/socperf.h +deleted file mode 100644 +index f36070c..0000000 +--- a/soc_perf/services/core/include/socperf.h ++++ /dev/null +@@ -1,85 +0,0 @@ +-/* +- * Copyright (c) 2022-2023 Huawei Device Co., Ltd. +- * Licensed under the Apache License, Version 2.0 (the "License"); +- * you may not use this file except in compliance with the License. +- * You may obtain a copy of the License at +- * +- * http://www.apache.org/licenses/LICENSE-2.0 +- * +- * Unless required by applicable law or agreed to in writing, software +- * distributed under the License is distributed on an "AS IS" BASIS, +- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +- * See the License for the specific language governing permissions and +- * limitations under the License. +- */ +- +-#ifndef SOC_PERF_SERVICES_CORE_INCLUDE_SOCPERF_H +-#define SOC_PERF_SERVICES_CORE_INCLUDE_SOCPERF_H +- +-#include +-#include +-#include +-#include +-#include "libxml/parser.h" +-#include "libxml/tree.h" +-#include "socperf_common.h" +-#include "socperf_handler.h" +- +-namespace OHOS { +-namespace SOCPERF { +-class SocPerf { +-public: +- bool Init(); +- void PerfRequest(int32_t cmdId, const std::string& msg); +- void PerfRequestEx(int32_t cmdId, bool onOffTag, const std::string& msg); +- void PowerLimitBoost(bool onOffTag, const std::string& msg); +- void ThermalLimitBoost(bool onOffTag, const std::string& msg); +- void LimitRequest(int32_t clientId, +- const std::vector& tags, const std::vector& configs, const std::string& msg); +- +-public: +- SocPerf(); +- ~SocPerf(); +- +-private: +- std::unordered_map> perfActionsInfo; +- std::vector> handlers; +- bool handlerSwitch[MAX_HANDLER_THREADS] = { false }; +- bool enabled = false; +- +- std::unordered_map> resNodeInfo; +- std::unordered_map> govResNodeInfo; +- std::unordered_map resStrToIdInfo; +- std::vector> limitRequest; +- +-private: +- std::mutex mutex_; +- std::string GetRealConfigPath(const std::string configFile); +- std::shared_ptr GetHandlerByResId(int32_t resId); +- bool LoadConfigXmlFile(std::string configFile); +- bool CreateHandlers(); +- void InitHandlerThreads(); +- bool LoadResource(xmlNode* rootNode, std::string configFile); +- bool LoadGovResource(xmlNode* rootNode, std::string configFile); +- bool LoadCmd(xmlNode* rootNode, std::string configFile); +- bool CheckResourceTag(char* id, char* name, char* pair, char* mode, std::string configFile); +- bool CheckResourceTag(char* def, char* path, std::string configFile); +- bool LoadResourceAvailable(std::shared_ptr resNode, char* node); +- bool CheckPairResIdValid(); +- bool CheckResDefValid(); +- bool CheckGovResourceTag(char* id, char* name, std::string configFile); +- bool LoadGovResourceAvailable(std::shared_ptr govResNode, char* level, char* node); +- bool CheckGovResDefValid(); +- bool CheckCmdTag(char* id, char* name, std::string configFile); +- bool CheckActionResIdAndValueValid(std::string configFile); +- void DoFreqActions(std::shared_ptr actions, int32_t onOff, int32_t actionType); +- void PrintCachedInfo(); +- void SendLimitRequestEvent(int32_t clientId, int32_t resId, int64_t resValue); +- void SendLimitRequestEventOff(std::shared_ptr handler, +- int32_t clientId, int32_t resId, int32_t eventId); +- void SendLimitRequestEventOn(std::shared_ptr handler, +- int32_t clientId, int32_t resId, int64_t resValue, int32_t eventId); +-}; +-} // namespace SOCPERF +-} // namespace OHOS +-#endif // SOC_PERF_SERVICES_CORE_INCLUDE_SOCPERF_H +diff --git a/soc_perf/services/core/include/socperf_common.h b/soc_perf/services/core/include/socperf_common.h +deleted file mode 100644 +index 74b6598..0000000 +--- a/soc_perf/services/core/include/socperf_common.h ++++ /dev/null +@@ -1,367 +0,0 @@ +-/* +- * Copyright (c) 2022-2023 Huawei Device Co., Ltd. +- * Licensed under the Apache License, Version 2.0 (the "License"); +- * you may not use this file except in compliance with the License. +- * You may obtain a copy of the License at +- * +- * http://www.apache.org/licenses/LICENSE-2.0 +- * +- * Unless required by applicable law or agreed to in writing, software +- * distributed under the License is distributed on an "AS IS" BASIS, +- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +- * See the License for the specific language governing permissions and +- * limitations under the License. +- */ +- +-#ifndef SOC_PERF_SERVICES_CORE_INCLUDE_SOCPERF_COMMON_H +-#define SOC_PERF_SERVICES_CORE_INCLUDE_SOCPERF_COMMON_H +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include "socperf_log.h" +-#include "socperf_action_type.h" +- +-namespace OHOS { +-namespace SOCPERF { +-enum EventType { +- EVENT_INVALID = -1, +- EVENT_OFF, +- EVENT_ON +-}; +- +-const std::string SOCPERF_RESOURCE_CONFIG_XML = "etc/soc_perf/socperf_resource_config.xml"; +-const std::string SOCPERF_BOOST_CONFIG_XML = "etc/soc_perf/socperf_boost_config.xml"; +-const int64_t MAX_INT_VALUE = 0x7FFFFFFFFFFFFFFF; +-const int64_t MIN_INT_VALUE = 0x8000000000000000; +-const int32_t INVALID_VALUE = INT_MIN; +-const int32_t RESET_VALUE = -1; +-/* +- * Divide all resource id into five sections, resource of each section is processed in an individual handler thread. +- * handlerId = resourceId / RES_ID_NUMS_PER_TYPE - 1 +- * Resource section: [1000, 1999] [2000, 2999] [3000, 3999] [4000, 4999] [5000, 5999] +- * Handler Thread: handlers[0] handlers[1] handlers[2] handlers[3] handlers[4] +- */ +-const int32_t MAX_HANDLER_THREADS = 5; +-const int32_t MIN_RESOURCE_ID = 1000; +-const int32_t MAX_RESOURCE_ID = 5999; +-const int32_t RES_ID_ADDITION = 10000; +-const int32_t RES_ID_AND_VALUE_PAIR = 2; +-const int32_t RES_ID_NUMS_PER_TYPE = 1000; +- +-class ResNode { +-public: +- int32_t id; +- std::string name; +- int64_t def; +- std::string path; +- int32_t mode; +- int32_t pair; +- std::unordered_set available; +- +-public: +- ResNode(int32_t resId, std::string resName, int32_t resMode, int32_t resPair) +- { +- id = resId; +- name = resName; +- mode = resMode; +- pair = resPair; +- def = INVALID_VALUE; +- } +- ~ResNode() {} +- +- void PrintString() +- { +- SOC_PERF_LOGD("resNode-> id: [%{public}d], name: [%{public}s]", id, name.c_str()); +- SOC_PERF_LOGD(" path: [%{public}s]", path.c_str()); +- SOC_PERF_LOGD(" def: [%{public}lld], mode: [%{public}d], pair: [%{public}d]", +- (long long)def, mode, pair); +- std::string str; +- str.append("available(").append(std::to_string((int32_t)available.size())).append("): "); +- str.append("["); +- for (auto validValue : available) { +- str.append(std::to_string(validValue)).append(","); +- } +- if (!available.empty()) { +- str.pop_back(); +- } +- str.append("]"); +- SOC_PERF_LOGD(" %{public}s", str.c_str()); +- } +-}; +- +-class GovResNode { +-public: +- int32_t id; +- std::string name; +- int64_t def; +- std::vector paths; +- std::unordered_set available; +- std::unordered_map> levelToStr; +- +-public: +- GovResNode(int32_t govResId, std::string govResName) +- { +- id = govResId; +- name = govResName; +- def = INVALID_VALUE; +- } +- ~GovResNode() {} +- +- void PrintString() +- { +- SOC_PERF_LOGD("govResNode-> id: [%{public}d], name: [%{public}s]", id, name.c_str()); +- SOC_PERF_LOGD(" def: [%{public}lld]", (long long)def); +- for (auto path : paths) { +- SOC_PERF_LOGD(" path: [%{public}s]", path.c_str()); +- } +- std::string str; +- str.append("available(").append(std::to_string((int32_t)available.size())).append("): "); +- str.append("["); +- for (auto validValue : available) { +- str.append(std::to_string(validValue)).append(","); +- } +- if (!available.empty()) { +- str.pop_back(); +- } +- str.append("]"); +- SOC_PERF_LOGD(" %{public}s", str.c_str()); +- for (auto iter = levelToStr.begin(); iter != levelToStr.end(); ++iter) { +- std::string str2; +- int64_t level = iter->first; +- std::vector result = iter->second; +- for (int32_t i = 0; i < (int32_t)result.size(); i++) { +- str2.append(result[i]).append(","); +- } +- if (!result.empty()) { +- str2.pop_back(); +- } +- SOC_PERF_LOGD(" %{public}lld: [%{public}s]", (long long)level, str2.c_str()); +- } +- } +-}; +- +-class Action { +-public: +- int32_t duration; +- std::vector variable; +- +-public: +- Action() {} +- ~Action() {} +-}; +- +-class Actions { +-public: +- int32_t id; +- std::string name; +- std::list> actionList; +- +-public: +- Actions(int32_t cmdId, std::string cmdName) +- { +- id = cmdId; +- name = cmdName; +- } +- ~Actions() {} +- +- void PrintString() +- { +- SOC_PERF_LOGD("Actions-> id: [%{public}d], name: [%{public}s]", id, name.c_str()); +- for (auto iter = actionList.begin(); iter != actionList.end(); iter++) { +- std::shared_ptr action = *iter; +- std::string str; +- str.append("variable(").append(std::to_string((int32_t)action->variable.size())).append("): ["); +- for (int32_t i = 0; i < (int32_t)action->variable.size(); i++) { +- str.append(std::to_string(action->variable[i])).append(","); +- } +- if (!action->variable.empty()) { +- str.pop_back(); +- } +- str.append("]"); +- SOC_PERF_LOGD(" duration: [%{public}d], %{public}s", action->duration, str.c_str()); +- } +- } +-}; +- +-class ResAction { +-public: +- int64_t value; +- int32_t duration; +- int32_t type; +- int32_t onOff; +- +-public: +- ResAction(int64_t resActionValue, int32_t resActionDuration, int32_t resActionType, int32_t resActionOnOff) +- { +- value = resActionValue; +- duration = resActionDuration; +- type = resActionType; +- onOff = resActionOnOff; +- } +- ~ResAction() {} +- +- bool TotalSame(std::shared_ptr resAction) +- { +- if (value == resAction->value +- && duration == resAction->duration +- && type == resAction->type +- && onOff == resAction->onOff) { +- return true; +- } +- return false; +- } +- +- bool PartSame(std::shared_ptr resAction) +- { +- if (value == resAction->value +- && duration == resAction->duration +- && type == resAction->type) { +- return true; +- } +- return false; +- } +-}; +- +-class ResActionItem { +-public: +- ResActionItem(int32_t id) +- { +- resId = id; +- } +- +- ~ResActionItem() = default; +- +- int32_t resId; +- std::shared_ptr resAction = nullptr; +- std::shared_ptr next = nullptr; +-}; +- +-class ResStatus { +-public: +- std::vector>> resActionList; +- std::vector candidates; +- int64_t candidate; +- int64_t current; +- +-public: +- explicit ResStatus(int64_t val) +- { +- resActionList = std::vector>>(ACTION_TYPE_MAX); +- candidates = std::vector(ACTION_TYPE_MAX); +- candidates[ACTION_TYPE_PERF] = INVALID_VALUE; +- candidates[ACTION_TYPE_POWER] = INVALID_VALUE; +- candidates[ACTION_TYPE_THERMAL] = INVALID_VALUE; +- candidate = val; +- current = val; +- } +- ~ResStatus() {} +- +- std::string ToString() +- { +- std::string str; +- str.append("perf:["); +- for (auto iter = resActionList[ACTION_TYPE_PERF].begin(); +- iter != resActionList[ACTION_TYPE_PERF].end(); ++iter) { +- str.append(std::to_string((*iter)->value)).append(","); +- } +- if (!resActionList[ACTION_TYPE_PERF].empty()) { +- str.pop_back(); +- } +- str.append("]power:["); +- for (auto iter = resActionList[ACTION_TYPE_POWER].begin(); +- iter != resActionList[ACTION_TYPE_POWER].end(); ++iter) { +- str.append(std::to_string((*iter)->value)).append(","); +- } +- if (!resActionList[ACTION_TYPE_POWER].empty()) { +- str.pop_back(); +- } +- str.append("]thermal:["); +- for (auto iter = resActionList[ACTION_TYPE_THERMAL].begin(); +- iter != resActionList[ACTION_TYPE_THERMAL].end(); ++iter) { +- str.append(std::to_string((*iter)->value)).append(","); +- } +- if (!resActionList[ACTION_TYPE_THERMAL].empty()) { +- str.pop_back(); +- } +- str.append("]candidates["); +- for (auto iter = candidates.begin(); iter != candidates.end(); ++iter) { +- str.append(std::to_string(*iter)).append(","); +- } +- str.pop_back(); +- str.append("]candidate[").append(std::to_string(candidate)); +- str.append("]current[").append(std::to_string(current)).append("]"); +- return str; +- } +-}; +- +-static inline int64_t Max(int64_t num1, int64_t num2) +-{ +- if (num1 >= num2) { +- return num1; +- } +- return num2; +-} +- +-static inline int64_t Max(int64_t num1, int64_t num2, int64_t num3) +-{ +- return Max(Max(num1, num2), num3); +-} +- +-static inline int64_t Min(int64_t num1, int64_t num2) +-{ +- if (num1 <= num2) { +- return num1; +- } +- return num2; +-} +- +-static inline int64_t Min(int64_t num1, int64_t num2, int64_t num3) +-{ +- return Min(Min(num1, num2), num3); +-} +- +-static inline bool IsNumber(std::string str) +-{ +- for (int32_t i = 0; i < (int32_t)str.size(); i++) { +- if (i == 0 && str.at(i) == '-') { +- continue; +- } +- if (str.at(i) < '0' || str.at(i) > '9') { +- return false; +- } +- } +- return true; +-} +- +-static inline bool IsValidResId(int32_t id) +-{ +- if (id < MIN_RESOURCE_ID || id > MAX_RESOURCE_ID) { +- return false; +- } +- return true; +-} +- +-static inline std::vector Split(std::string str, std::string pattern) +-{ +- int32_t position; +- std::vector result; +- str += pattern; +- int32_t length = (int32_t)str.size(); +- for (int32_t i = 0; i < length; i++) { +- position = (int32_t)str.find(pattern, i); +- if (position < length) { +- std::string tmp = str.substr(i, position - i); +- result.push_back(tmp); +- i = position + (int32_t)pattern.size() - 1; +- } +- } +- return result; +-} +-} // namespace SOCPERF +-} // namespace OHOS +- +-#endif // SOC_PERF_SERVICES_CORE_INCLUDE_COMMON_H +diff --git a/soc_perf/services/core/include/socperf_handler.h b/soc_perf/services/core/include/socperf_handler.h +deleted file mode 100644 +index 414e02e..0000000 +--- a/soc_perf/services/core/include/socperf_handler.h ++++ /dev/null +@@ -1,79 +0,0 @@ +-/* +- * Copyright (c) 2022-2023 Huawei Device Co., Ltd. +- * Licensed under the Apache License, Version 2.0 (the "License"); +- * you may not use this file except in compliance with the License. +- * You may obtain a copy of the License at +- * +- * http://www.apache.org/licenses/LICENSE-2.0 +- * +- * Unless required by applicable law or agreed to in writing, software +- * distributed under the License is distributed on an "AS IS" BASIS, +- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +- * See the License for the specific language governing permissions and +- * limitations under the License. +- */ +- +-#ifndef SOC_PERF_SERVICES_CORE_INCLUDE_SOCPERF_HANDLER_H +-#define SOC_PERF_SERVICES_CORE_INCLUDE_SOCPERF_HANDLER_H +- +- +-#include // for shared_ptr +-#include // for string +-#include // for unordered_map +-#include // for uint32_t +-#include "event_handler.h" // for EventHandler +-#include "event_runner.h" +-#include "inner_event.h" // for InnerEvent, InnerEvent::Pointer +-namespace OHOS { namespace SOCPERF { class GovResNode; } } +-namespace OHOS { namespace SOCPERF { class ResAction; } } +-namespace OHOS { namespace SOCPERF { class ResNode; } } +-namespace OHOS { namespace SOCPERF { class ResStatus; } } +- +-namespace OHOS { +-namespace SOCPERF { +-enum SocPerfInnerEvent : uint32_t { +- INNER_EVENT_ID_INIT_RES_NODE_INFO = 0, +- INNER_EVENT_ID_INIT_GOV_RES_NODE_INFO, +- INNER_EVENT_ID_DO_FREQ_ACTION, +- INNER_EVENT_ID_DO_FREQ_ACTION_PACK, +- INNER_EVENT_ID_DO_FREQ_ACTION_DELAYED, +- INNER_EVENT_ID_POWER_LIMIT_BOOST_FREQ, +- INNER_EVENT_ID_THERMAL_LIMIT_BOOST_FREQ, +- INNER_EVENT_ID_DO_FREQ_ACTION_LEVEL, +-}; +- +-class SocPerfHandler : public AppExecFwk::EventHandler { +-public: +- explicit SocPerfHandler(const std::shared_ptr& runner); +- ~SocPerfHandler() override; +- void ProcessEvent(const AppExecFwk::InnerEvent::Pointer& event) override; +- +-private: +- std::unordered_map> resNodeInfo; +- std::unordered_map> govResNodeInfo; +- std::unordered_map> resStatusInfo; +- std::unordered_map fdInfo; +- bool powerLimitBoost = false; +- bool thermalLimitBoost = false; +- +-private: +- void HandleDoFreqActionLevel(int32_t resId, std::shared_ptr resAction); +- bool GetResValueByLevel(int32_t resId, int32_t level, int64_t& resValue); +- void UpdateResActionList(int32_t resId, std::shared_ptr resAction, bool delayed); +- void UpdateCandidatesValue(int32_t resId, int32_t type); +- void ArbitrateCandidate(int32_t resId); +- void ArbitratePairRes(int32_t resId); +- void UpdatePairResValue(int32_t minResId, int64_t minResValue, int32_t maxResId, int64_t maxResValue); +- void UpdateCurrentValue(int32_t resId, int64_t value); +- void WriteNode(std::string path, std::string value); +- bool ExistNoCandidate( +- int32_t resId, std::shared_ptr resStatus, int64_t perf, int64_t power, int64_t thermal); +- bool IsGovResId(int32_t resId); +- bool IsResId(int32_t resId); +- bool IsValidResId(int32_t resId); +- int32_t GetFdForFilePath(std::string filePath); +-}; +-} // namespace SOCPERF +-} // namespace OHOS +- +-#endif // SOC_PERF_SERVICES_CORE_INCLUDE_SOCPERF_HANDLER_H +diff --git a/soc_perf/services/core/src/socperf.cpp b/soc_perf/services/core/src/socperf.cpp +deleted file mode 100644 +index 03f006c..0000000 +--- a/soc_perf/services/core/src/socperf.cpp ++++ /dev/null +@@ -1,752 +0,0 @@ +-/* +- * Copyright (c) 2022-2023 Huawei Device Co., Ltd. +- * Licensed under the Apache License, Version 2.0 (the "License"); +- * you may not use this file except in compliance with the License. +- * You may obtain a copy of the License at +- * +- * http://www.apache.org/licenses/LICENSE-2.0 +- * +- * Unless required by applicable law or agreed to in writing, software +- * distributed under the License is distributed on an "AS IS" BASIS, +- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +- * See the License for the specific language governing permissions and +- * limitations under the License. +- */ +- +- +-#include "socperf.h" +- +-#ifdef CUSTOMIZATION_CONFIG_POLICY_ENABLE +-#include "config_policy_utils.h" +-#endif // CUSTOMIZATION_CONFIG_POLICY_ENABLE +- +-#include "hitrace_meter.h" +- +-namespace OHOS { +-namespace SOCPERF { +-SocPerf::SocPerf() +-{ +-} +- +-SocPerf::~SocPerf() +-{ +-} +- +-bool SocPerf::Init() +-{ +-#ifdef CUSTOMIZATION_CONFIG_POLICY_ENABLE +- if (!LoadConfigXmlFile(SOCPERF_RESOURCE_CONFIG_XML)) { +- SOC_PERF_LOGE("Failed to load %{public}s", SOCPERF_RESOURCE_CONFIG_XML.c_str()); +- return false; +- } +- +- if (!LoadConfigXmlFile(SOCPERF_BOOST_CONFIG_XML)) { +- SOC_PERF_LOGE("Failed to load %{public}s", SOCPERF_BOOST_CONFIG_XML.c_str()); +- return false; +- } +-#endif // CUSTOMIZATION_CONFIG_POLICY_ENABLE +- +- PrintCachedInfo(); +- +- if (!CreateHandlers()) { +- SOC_PERF_LOGE("Failed to create handler threads"); +- return false; +- } +- +- InitHandlerThreads(); +- +- resNodeInfo.clear(); +- govResNodeInfo.clear(); +- resStrToIdInfo.clear(); +- limitRequest = std::vector>(ACTION_TYPE_MAX); +- +- enabled = true; +- +- SOC_PERF_LOGD("SocPerf Init SUCCESS!"); +- +- return true; +-} +- +-void SocPerf::PerfRequest(int32_t cmdId, const std::string& msg) +-{ +- if (!enabled) { +- SOC_PERF_LOGE("SocPerf disabled!"); +- return; +- } +- if (perfActionsInfo.find(cmdId) == perfActionsInfo.end()) { +- SOC_PERF_LOGE("Invalid PerfRequest cmdId[%{public}d]", cmdId); +- return; +- } +- SOC_PERF_LOGD("cmdId[%{public}d]msg[%{public}s]", cmdId, msg.c_str()); +- +- std::string trace_str(__func__); +- trace_str.append(",cmdId[").append(std::to_string(cmdId)).append("]"); +- trace_str.append(",msg[").append(msg).append("]"); +- StartTrace(HITRACE_TAG_OHOS, trace_str, -1); +- DoFreqActions(perfActionsInfo[cmdId], EVENT_INVALID, ACTION_TYPE_PERF); +- FinishTrace(HITRACE_TAG_OHOS); +-} +- +-void SocPerf::PerfRequestEx(int32_t cmdId, bool onOffTag, const std::string& msg) +-{ +- if (!enabled) { +- SOC_PERF_LOGE("SocPerf disabled!"); +- return; +- } +- if (perfActionsInfo.find(cmdId) == perfActionsInfo.end()) { +- SOC_PERF_LOGE("Invalid PerfRequestEx cmdId[%{public}d]", cmdId); +- return; +- } +- SOC_PERF_LOGD("cmdId[%{public}d]onOffTag[%{public}d]msg[%{public}s]", +- cmdId, onOffTag, msg.c_str()); +- +- std::string trace_str(__func__); +- trace_str.append(",cmdId[").append(std::to_string(cmdId)).append("]"); +- trace_str.append(",onOff[").append(std::to_string(onOffTag)).append("]"); +- trace_str.append(",msg[").append(msg).append("]"); +- StartTrace(HITRACE_TAG_OHOS, trace_str, -1); +- DoFreqActions(perfActionsInfo[cmdId], onOffTag ? EVENT_ON : EVENT_OFF, ACTION_TYPE_PERF); +- FinishTrace(HITRACE_TAG_OHOS); +-} +- +-void SocPerf::PowerLimitBoost(bool onOffTag, const std::string& msg) +-{ +- if (!enabled) { +- SOC_PERF_LOGE("SocPerf disabled!"); +- return; +- } +- SOC_PERF_LOGD("onOffTag[%{public}d]msg[%{public}s]", onOffTag, msg.c_str()); +- +- std::string trace_str(__func__); +- trace_str.append(",onOff[").append(std::to_string(onOffTag)).append("]"); +- trace_str.append(",msg[").append(msg).append("]"); +- StartTrace(HITRACE_TAG_OHOS, trace_str, -1); +- for (auto handler : handlers) { +- if (handler) { +- auto event = AppExecFwk::InnerEvent::Get(INNER_EVENT_ID_POWER_LIMIT_BOOST_FREQ, onOffTag ? 1 : 0); +- handler->SendEvent(event); +- } +- } +- FinishTrace(HITRACE_TAG_OHOS); +-} +- +-void SocPerf::ThermalLimitBoost(bool onOffTag, const std::string& msg) +-{ +- if (!enabled) { +- SOC_PERF_LOGE("SocPerf disabled!"); +- return; +- } +- SOC_PERF_LOGD("onOffTag[%{public}d]msg[%{public}s]", onOffTag, msg.c_str()); +- std::string trace_str(__func__); +- trace_str.append(",onOff[").append(std::to_string(onOffTag)).append("]"); +- trace_str.append(",msg[").append(msg).append("]"); +- StartTrace(HITRACE_TAG_OHOS, trace_str, -1); +- for (auto handler : handlers) { +- if (handler) { +- auto event = AppExecFwk::InnerEvent::Get(INNER_EVENT_ID_THERMAL_LIMIT_BOOST_FREQ, onOffTag ? 1 : 0); +- handler->SendEvent(event); +- } +- } +- FinishTrace(HITRACE_TAG_OHOS); +-} +- +-void SocPerf::SendLimitRequestEventOff(std::shared_ptr handler, +- int32_t clientId, int32_t resId, int32_t eventId) +-{ +- auto iter = limitRequest[clientId].find(resId); +- if (iter != limitRequest[clientId].end() +- && limitRequest[clientId][resId] != INVALID_VALUE) { +- auto resAction = std::make_shared( +- limitRequest[clientId][resId], 0, clientId, EVENT_OFF); +- auto event = AppExecFwk::InnerEvent::Get(eventId, resAction, resId); +- handler->SendEvent(event); +- limitRequest[clientId].erase(iter); +- } +-} +- +-void SocPerf::SendLimitRequestEventOn(std::shared_ptr handler, +- int32_t clientId, int32_t resId, int64_t resValue, int32_t eventId) +-{ +- if (resValue != INVALID_VALUE && resValue != RESET_VALUE) { +- auto resAction = std::make_shared(resValue, 0, clientId, EVENT_ON); +- auto event = AppExecFwk::InnerEvent::Get(eventId, resAction, resId); +- handler->SendEvent(event); +- limitRequest[clientId].insert(std::pair(resId, resValue)); +- } +-} +- +-void SocPerf::SendLimitRequestEvent(int32_t clientId, int32_t resId, int64_t resValue) +-{ +- int32_t eventId, realResId, levelResId; +- if (resId > RES_ID_ADDITION) { +- realResId = resId - RES_ID_ADDITION; +- levelResId = resId; +- eventId = INNER_EVENT_ID_DO_FREQ_ACTION_LEVEL; +- } else { +- realResId = resId; +- levelResId = resId + RES_ID_ADDITION; +- eventId = INNER_EVENT_ID_DO_FREQ_ACTION; +- } +- +- auto handler = GetHandlerByResId(realResId); +- if (!handler) { +- return; +- } +- std::lock_guard lock(mutex_); +- SendLimitRequestEventOff(handler, clientId, realResId, INNER_EVENT_ID_DO_FREQ_ACTION); +- SendLimitRequestEventOff(handler, clientId, levelResId, INNER_EVENT_ID_DO_FREQ_ACTION_LEVEL); +- SendLimitRequestEventOn(handler, clientId, resId, resValue, eventId); +-} +- +-void SocPerf::LimitRequest(int32_t clientId, +- const std::vector& tags, const std::vector& configs, const std::string& msg) +-{ +- if (!enabled) { +- SOC_PERF_LOGE("SocPerf disabled!"); +- return; +- } +- if (tags.size() != configs.size()) { +- SOC_PERF_LOGE("tags'size and configs' size must be the same!"); +- return; +- } +- if (clientId <= (int32_t)ACTION_TYPE_PERF || clientId >= (int32_t)ACTION_TYPE_MAX) { +- SOC_PERF_LOGE("clientId must be between ACTION_TYPE_PERF and ACTION_TYPE_MAX!"); +- return; +- } +- for (int32_t i = 0; i < (int32_t)tags.size(); i++) { +- SOC_PERF_LOGD("clientId[%{public}d],tags[%{public}d],configs[%{public}lld],msg[%{public}s]", +- clientId, tags[i], (long long)configs[i], msg.c_str()); +- SendLimitRequestEvent(clientId, tags[i], configs[i]); +- } +-} +- +-void SocPerf::DoFreqActions(std::shared_ptr actions, int32_t onOff, int32_t actionType) +-{ +- std::shared_ptr header[MAX_HANDLER_THREADS] = { nullptr }; +- std::shared_ptr curItem[MAX_HANDLER_THREADS] = { nullptr }; +- for (auto iter = actions->actionList.begin(); iter != actions->actionList.end(); iter++) { +- std::shared_ptr action = *iter; +- for (int32_t i = 0; i < (int32_t)action->variable.size() - 1; i += RES_ID_AND_VALUE_PAIR) { +- if (!IsValidResId(action->variable[i])) { +- continue; +- } +- auto resActionItem = std::make_shared(action->variable[i]); +- resActionItem->resAction = +- std::make_shared(action->variable[i + 1], action->duration, actionType, onOff); +- int32_t id = action->variable[i] / RES_ID_NUMS_PER_TYPE - 1; +- if (curItem[id]) { +- curItem[id]->next = resActionItem; +- } else { +- header[id] = resActionItem; +- } +- curItem[id] = resActionItem; +- } +- } +- for (int32_t i = 0; i < MAX_HANDLER_THREADS; ++i) { +- if (!handlers[i] || !header[i]) { +- continue; +- } +- auto event = AppExecFwk::InnerEvent::Get(INNER_EVENT_ID_DO_FREQ_ACTION_PACK, header[i]); +- handlers[i]->SendEvent(event); +- } +-} +- +-#ifdef CUSTOMIZATION_CONFIG_POLICY_ENABLE +-std::string SocPerf::GetRealConfigPath(const std::string configFile) +-{ +- char buf[PATH_MAX + 1]; +- char* configFilePath = GetOneCfgFile(configFile.c_str(), buf, PATH_MAX + 1); +- char tmpPath[PATH_MAX + 1] = {0}; +- if (!configFilePath || strlen(configFilePath) == 0 || strlen(configFilePath) > PATH_MAX || +- !realpath(configFilePath, tmpPath)) { +- SOC_PERF_LOGE("load %{public}s file fail", configFile.c_str()); +- return ""; +- } +- return std::string(tmpPath); +-} +-#endif // CUSTOMIZATION_CONFIG_POLICY_ENABLE +- +-std::shared_ptr SocPerf::GetHandlerByResId(int32_t resId) +-{ +- if (!IsValidResId(resId)) { +- return nullptr; +- } +- return handlers[resId / RES_ID_NUMS_PER_TYPE - 1]; +-} +- +-#ifdef CUSTOMIZATION_CONFIG_POLICY_ENABLE +-bool SocPerf::LoadConfigXmlFile(std::string configFile) +-{ +- std::string realConfigFile = GetRealConfigPath(configFile); +- if (realConfigFile.size() <= 0) { +- return false; +- } +- xmlKeepBlanksDefault(0); +- xmlDoc* file = xmlReadFile(realConfigFile.c_str(), nullptr, XML_PARSE_NOERROR | XML_PARSE_NOWARNING); +- if (!file) { +- SOC_PERF_LOGE("Failed to open xml file"); +- return false; +- } +- xmlNode* rootNode = xmlDocGetRootElement(file); +- if (!rootNode) { +- SOC_PERF_LOGE("Failed to get xml file's RootNode"); +- xmlFreeDoc(file); +- return false; +- } +- if (!xmlStrcmp(rootNode->name, reinterpret_cast("Configs"))) { +- if (realConfigFile.find(SOCPERF_RESOURCE_CONFIG_XML) != std::string::npos) { +- xmlNode* child = rootNode->children; +- for (; child; child = child->next) { +- if (!xmlStrcmp(child->name, reinterpret_cast("Resource"))) { +- if (!LoadResource(child, realConfigFile)) { +- xmlFreeDoc(file); +- return false; +- } +- } else if (!xmlStrcmp(child->name, reinterpret_cast("GovResource"))) { +- if (!LoadGovResource(child, realConfigFile)) { +- xmlFreeDoc(file); +- return false; +- } +- } +- } +- } else { +- if (!LoadCmd(rootNode, realConfigFile)) { +- xmlFreeDoc(file); +- return false; +- } +- } +- } else { +- SOC_PERF_LOGE("Wrong format for xml file"); +- xmlFreeDoc(file); +- return false; +- } +- xmlFreeDoc(file); +- SOC_PERF_LOGD("Success to Load %{public}s", configFile.c_str()); +- return true; +-} +-#endif // CUSTOMIZATION_CONFIG_POLICY_ENABLE +- +-bool SocPerf::CreateHandlers() +-{ +- handlers = std::vector>(MAX_HANDLER_THREADS); +- std::string threadName = "socperf#"; +- for (int32_t i = 0; i < (int32_t)handlers.size(); i++) { +- if (!handlerSwitch[i]) { +- handlers[i] = nullptr; +- continue; +- } +- auto runner = AppExecFwk::EventRunner::Create(threadName + std::to_string(i)); +- if (!runner) { +- SOC_PERF_LOGE("Failed to Create EventRunner"); +- return false; +- } +- handlers[i] = std::make_shared(runner); +- } +- SOC_PERF_LOGD("Success to Create All Handler threads"); +- return true; +-} +- +-void SocPerf::InitHandlerThreads() +-{ +- for (auto iter = resNodeInfo.begin(); iter != resNodeInfo.end(); ++iter) { +- std::shared_ptr resNode = iter->second; +- auto handler = GetHandlerByResId(resNode->id); +- if (!handler) { +- continue; +- } +- auto event = AppExecFwk::InnerEvent::Get(INNER_EVENT_ID_INIT_RES_NODE_INFO, resNode); +- handler->SendEvent(event); +- } +- for (auto iter = govResNodeInfo.begin(); iter != govResNodeInfo.end(); ++iter) { +- std::shared_ptr govResNode = iter->second; +- auto handler = GetHandlerByResId(govResNode->id); +- if (!handler) { +- continue; +- } +- auto event = AppExecFwk::InnerEvent::Get(INNER_EVENT_ID_INIT_GOV_RES_NODE_INFO, govResNode); +- handler->SendEvent(event); +- } +-} +- +-bool SocPerf::LoadResource(xmlNode* child, std::string configFile) +-{ +- xmlNode* grandson = child->children; +- for (; grandson; grandson = grandson->next) { +- if (!xmlStrcmp(grandson->name, reinterpret_cast("res"))) { +- char* id = reinterpret_cast(xmlGetProp(grandson, reinterpret_cast("id"))); +- char* name = reinterpret_cast(xmlGetProp(grandson, reinterpret_cast("name"))); +- char* pair = reinterpret_cast(xmlGetProp(grandson, reinterpret_cast("pair"))); +- char* mode = reinterpret_cast(xmlGetProp(grandson, reinterpret_cast("mode"))); +- if (!CheckResourceTag(id, name, pair, mode, configFile)) { +- xmlFree(id); +- xmlFree(name); +- xmlFree(pair); +- xmlFree(mode); +- return false; +- } +- xmlNode* greatGrandson = grandson->children; +- std::shared_ptr resNode = std::make_shared( +- atoi(id), name, mode ? atoi(mode) : 0, pair ? atoi(pair) : INVALID_VALUE); +- xmlFree(id); +- xmlFree(name); +- xmlFree(pair); +- xmlFree(mode); +- char *def = nullptr; +- char *path = nullptr; +- char *node = nullptr; +- for (; greatGrandson; greatGrandson = greatGrandson->next) { +- if (!xmlStrcmp(greatGrandson->name, reinterpret_cast("default"))) { +- xmlFree(def); +- def = reinterpret_cast(xmlNodeGetContent(greatGrandson)); +- } else if (!xmlStrcmp(greatGrandson->name, reinterpret_cast("path"))) { +- xmlFree(path); +- path = reinterpret_cast(xmlNodeGetContent(greatGrandson)); +- } else if (!xmlStrcmp(greatGrandson->name, reinterpret_cast("node"))) { +- xmlFree(node); +- node = reinterpret_cast(xmlNodeGetContent(greatGrandson)); +- } +- } +- if (!CheckResourceTag(def, path, configFile)) { +- xmlFree(def); +- xmlFree(path); +- xmlFree(node); +- return false; +- } +- resNode->def = atoll(def); +- resNode->path = path; +- xmlFree(def); +- xmlFree(path); +- if (node && !LoadResourceAvailable(resNode, node)) { +- SOC_PERF_LOGE("Invalid resource node for %{public}s", configFile.c_str()); +- xmlFree(node); +- return false; +- } +- xmlFree(node); +- +- resStrToIdInfo.insert(std::pair(resNode->name, resNode->id)); +- resNodeInfo.insert(std::pair>(resNode->id, resNode)); +- handlerSwitch[resNode->id / RES_ID_NUMS_PER_TYPE - 1] = true; +- } +- } +- +- if (!CheckPairResIdValid() || !CheckResDefValid()) { +- return false; +- } +- +- return true; +-} +- +-bool SocPerf::LoadGovResource(xmlNode* child, std::string configFile) +-{ +- xmlNode* grandson = child->children; +- for (; grandson; grandson = grandson->next) { +- if (xmlStrcmp(grandson->name, reinterpret_cast("res"))) { +- continue; +- } +- char* id = reinterpret_cast(xmlGetProp(grandson, reinterpret_cast("id"))); +- char* name = reinterpret_cast(xmlGetProp(grandson, reinterpret_cast("name"))); +- if (!CheckGovResourceTag(id, name, configFile)) { +- xmlFree(id); +- xmlFree(name); +- return false; +- } +- xmlNode* greatGrandson = grandson->children; +- std::shared_ptr govResNode = std::make_shared(atoi(id), name); +- xmlFree(id); +- xmlFree(name); +- handlerSwitch[govResNode->id / RES_ID_NUMS_PER_TYPE - 1] = true; +- for (; greatGrandson; greatGrandson = greatGrandson->next) { +- if (!xmlStrcmp(greatGrandson->name, reinterpret_cast("default"))) { +- char* def = reinterpret_cast(xmlNodeGetContent(greatGrandson)); +- if (!def || !IsNumber(def)) { +- SOC_PERF_LOGE("Invalid governor resource default for %{public}s", configFile.c_str()); +- xmlFree(def); +- return false; +- } +- govResNode->def = atoll(def); +- xmlFree(def); +- } else if (!xmlStrcmp(greatGrandson->name, reinterpret_cast("path"))) { +- char* path = reinterpret_cast(xmlNodeGetContent(greatGrandson)); +- if (!path) { +- SOC_PERF_LOGE("Invalid governor resource path for %{public}s", configFile.c_str()); +- return false; +- } +- govResNode->paths.push_back(path); +- xmlFree(path); +- } else if (!xmlStrcmp(greatGrandson->name, reinterpret_cast("node"))) { +- char* level = reinterpret_cast( +- xmlGetProp(greatGrandson, reinterpret_cast("level"))); +- char* node = reinterpret_cast(xmlNodeGetContent(greatGrandson)); +- if (!level || !IsNumber(level) || !node +- || !LoadGovResourceAvailable(govResNode, level, node)) { +- SOC_PERF_LOGE("Invalid governor resource node for %{public}s", configFile.c_str()); +- xmlFree(level); +- xmlFree(node); +- return false; +- } +- xmlFree(level); +- xmlFree(node); +- } +- } +- +- resStrToIdInfo.insert(std::pair(govResNode->name, govResNode->id)); +- govResNodeInfo.insert(std::pair>(govResNode->id, govResNode)); +- } +- +- if (!CheckGovResDefValid()) { +- return false; +- } +- +- return true; +-} +- +-bool SocPerf::LoadCmd(xmlNode* rootNode, std::string configFile) +-{ +- xmlNode* child = rootNode->children; +- for (; child; child = child->next) { // Iterate all cmdID +- if (xmlStrcmp(child->name, reinterpret_cast("cmd"))) { +- continue; +- } +- char* id = reinterpret_cast(xmlGetProp(child, reinterpret_cast("id"))); +- char* name = reinterpret_cast(xmlGetProp(child, reinterpret_cast("name"))); +- if (!CheckCmdTag(id, name, configFile)) { +- xmlFree(id); +- xmlFree(name); +- return false; +- } +- xmlNode* grandson = child->children; +- std::shared_ptr actions = std::make_shared(atoi(id), name); +- xmlFree(id); +- xmlFree(name); +- for (; grandson; grandson = grandson->next) { // Iterate all Action +- std::shared_ptr action = std::make_shared(); +- xmlNode* greatGrandson = grandson->children; +- for (; greatGrandson; greatGrandson = greatGrandson->next) { // Iterate duration and all res +- if (!xmlStrcmp(greatGrandson->name, reinterpret_cast("duration"))) { +- char* duration = reinterpret_cast(xmlNodeGetContent(greatGrandson)); +- if (!duration || !IsNumber(duration)) { +- SOC_PERF_LOGE("Invalid cmd duration for %{public}s", configFile.c_str()); +- xmlFree(duration); +- return false; +- } +- action->duration = atoi(duration); +- xmlFree(duration); +- } else { +- char* resStr = reinterpret_cast(const_cast(greatGrandson->name)); +- char* resValue = reinterpret_cast(xmlNodeGetContent(greatGrandson)); +- if (!resStr || resStrToIdInfo.find(resStr) == resStrToIdInfo.end() +- || !resValue || !IsNumber(resValue)) { +- SOC_PERF_LOGE("Invalid cmd resource(%{public}s) for %{public}s", resStr, configFile.c_str()); +- xmlFree(resValue); +- return false; +- } +- action->variable.push_back(resStrToIdInfo[resStr]); +- action->variable.push_back(atoll(resValue)); +- xmlFree(resValue); +- } +- } +- actions->actionList.push_back(action); +- } +- +- if (configFile.find(SOCPERF_BOOST_CONFIG_XML) != std::string::npos) { +- perfActionsInfo.insert(std::pair>(actions->id, actions)); +- } +- } +- +- if (!CheckActionResIdAndValueValid(configFile)) { +- return false; +- } +- +- return true; +-} +- +-bool SocPerf::CheckResourceTag(char* id, char* name, char* pair, char* mode, std::string configFile) +-{ +- if (!id || !IsNumber(id) || !IsValidResId(atoi(id))) { +- SOC_PERF_LOGE("Invalid resource id for %{public}s", configFile.c_str()); +- return false; +- } +- if (!name) { +- SOC_PERF_LOGE("Invalid resource name for %{public}s", configFile.c_str()); +- return false; +- } +- if (pair && (!IsNumber(pair) || !IsValidResId(atoi(pair)))) { +- SOC_PERF_LOGE("Invalid resource pair for %{public}s", configFile.c_str()); +- return false; +- } +- if (mode && !IsNumber(mode)) { +- SOC_PERF_LOGE("Invalid resource mode for %{public}s", configFile.c_str()); +- return false; +- } +- return true; +-} +- +-bool SocPerf::CheckResourceTag(char* def, char* path, std::string configFile) +-{ +- if (!def || !IsNumber(def)) { +- SOC_PERF_LOGE("Invalid resource default for %{public}s", configFile.c_str()); +- return false; +- } +- if (!path) { +- SOC_PERF_LOGE("Invalid resource path for %{public}s", configFile.c_str()); +- return false; +- } +- return true; +-} +- +-bool SocPerf::LoadResourceAvailable(std::shared_ptr resNode, char* node) +-{ +- std::string nodeStr = node; +- std::vector result = Split(nodeStr, " "); +- for (auto str : result) { +- if (IsNumber(str)) { +- resNode->available.insert(stoll(str)); +- } else { +- return false; +- } +- } +- return true; +-} +- +-bool SocPerf::CheckPairResIdValid() +-{ +- for (auto iter = resNodeInfo.begin(); iter != resNodeInfo.end(); ++iter) { +- int32_t resId = iter->first; +- std::shared_ptr resNode = iter->second; +- int32_t pairResId = resNode->pair; +- if (pairResId != INVALID_VALUE && resNodeInfo.find(pairResId) == resNodeInfo.end()) { +- SOC_PERF_LOGE("resId[%{public}d]'s pairResId[%{public}d] is not valid", resId, pairResId); +- return false; +- } +- } +- return true; +-} +- +-bool SocPerf::CheckResDefValid() +-{ +- for (auto iter = resNodeInfo.begin(); iter != resNodeInfo.end(); ++iter) { +- int32_t resId = iter->first; +- std::shared_ptr resNode = iter->second; +- int64_t def = resNode->def; +- if (!resNode->available.empty() && resNode->available.find(def) == resNode->available.end()) { +- SOC_PERF_LOGE("resId[%{public}d]'s def[%{public}lld] is not valid", resId, (long long)def); +- return false; +- } +- } +- return true; +-} +- +-bool SocPerf::CheckGovResourceTag(char* id, char* name, std::string configFile) +-{ +- if (!id || !IsNumber(id) || !IsValidResId(atoi(id))) { +- SOC_PERF_LOGE("Invalid governor resource id for %{public}s", configFile.c_str()); +- return false; +- } +- if (!name) { +- SOC_PERF_LOGE("Invalid governor resource name for %{public}s", configFile.c_str()); +- return false; +- } +- return true; +-} +- +-bool SocPerf::LoadGovResourceAvailable(std::shared_ptr govResNode, char* level, char* node) +-{ +- govResNode->available.insert(atoll(level)); +- std::string nodeStr = node; +- std::vector result = Split(nodeStr, "|"); +- if (result.size() != govResNode->paths.size()) { +- SOC_PERF_LOGE("Invalid governor resource node matches paths"); +- return false; +- } +- govResNode->levelToStr.insert(std::pair>(atoll(level), result)); +- return true; +-} +- +-bool SocPerf::CheckGovResDefValid() +-{ +- for (auto iter = govResNodeInfo.begin(); iter != govResNodeInfo.end(); ++iter) { +- int32_t govResId = iter->first; +- std::shared_ptr govResNode = iter->second; +- int32_t def = govResNode->def; +- if (govResNode->available.find(def) == govResNode->available.end()) { +- SOC_PERF_LOGE("govResId[%{public}d]'s def[%{public}d] is not valid", govResId, def); +- return false; +- } +- } +- return true; +-} +- +-bool SocPerf::CheckCmdTag(char* id, char* name, std::string configFile) +-{ +- if (!id || !IsNumber(id)) { +- SOC_PERF_LOGE("Invalid cmd id for %{public}s", configFile.c_str()); +- return false; +- } +- if (!name) { +- SOC_PERF_LOGE("Invalid cmd name for %{public}s", configFile.c_str()); +- return false; +- } +- return true; +-} +- +-bool SocPerf::CheckActionResIdAndValueValid(std::string configFile) +-{ +- std::unordered_map> actionsInfo; +- if (configFile.find(SOCPERF_BOOST_CONFIG_XML) != std::string::npos) { +- actionsInfo = perfActionsInfo; +- } +- for (auto actionsIter = actionsInfo.begin(); actionsIter != actionsInfo.end(); ++actionsIter) { +- int32_t actionId = actionsIter->first; +- std::shared_ptr actions = actionsIter->second; +- for (auto actionIter = actions->actionList.begin(); actionIter != actions->actionList.end(); ++actionIter) { +- std::shared_ptr action = *actionIter; +- for (int32_t i = 0; i < (int32_t)action->variable.size() - 1; i += RES_ID_AND_VALUE_PAIR) { +- int32_t resId = action->variable[i]; +- int64_t resValue = action->variable[i + 1]; +- if (resNodeInfo.find(resId) != resNodeInfo.end()) { +- if (!resNodeInfo[resId]->available.empty() +- && resNodeInfo[resId]->available.find(resValue) == resNodeInfo[resId]->available.end()) { +- SOC_PERF_LOGE("action[%{public}d]'s resValue[%{public}lld] is not valid", +- actionId, (long long)resValue); +- return false; +- } +- } else if (govResNodeInfo.find(resId) != govResNodeInfo.end()) { +- if (govResNodeInfo[resId]->available.find(resValue) == govResNodeInfo[resId]->available.end()) { +- SOC_PERF_LOGE("action[%{public}d]'s resValue[%{public}lld] is not valid", +- actionId, (long long)resValue); +- return false; +- } +- } else { +- SOC_PERF_LOGE("action[%{public}d]'s resId[%{public}d] is not valid", actionId, resId); +- return false; +- } +- } +- } +- } +- return true; +-} +- +-void SocPerf::PrintCachedInfo() +-{ +- SOC_PERF_LOGD("------------------------------------"); +- SOC_PERF_LOGD("resNodeInfo(%{public}d)", (int32_t)resNodeInfo.size()); +- for (auto iter = resNodeInfo.begin(); iter != resNodeInfo.end(); ++iter) { +- std::shared_ptr resNode = iter->second; +- resNode->PrintString(); +- } +- SOC_PERF_LOGD("------------------------------------"); +- SOC_PERF_LOGD("govResNodeInfo(%{public}d)", (int32_t)govResNodeInfo.size()); +- for (auto iter = govResNodeInfo.begin(); iter != govResNodeInfo.end(); ++iter) { +- std::shared_ptr govResNode = iter->second; +- govResNode->PrintString(); +- } +- SOC_PERF_LOGD("------------------------------------"); +- SOC_PERF_LOGD("perfActionsInfo(%{public}d)", (int32_t)perfActionsInfo.size()); +- for (auto iter = perfActionsInfo.begin(); iter != perfActionsInfo.end(); ++iter) { +- std::shared_ptr actions = iter->second; +- actions->PrintString(); +- } +- SOC_PERF_LOGD("------------------------------------"); +-} +-} // namespace SOCPERF +-} // namespace OHOS +diff --git a/soc_perf/services/core/src/socperf_handler.cpp b/soc_perf/services/core/src/socperf_handler.cpp +deleted file mode 100644 +index a63e94e..0000000 +--- a/soc_perf/services/core/src/socperf_handler.cpp ++++ /dev/null +@@ -1,431 +0,0 @@ +-/* +- * Copyright (c) 2022 Huawei Device Co., Ltd. +- * Licensed under the Apache License, Version 2.0 (the "License"); +- * you may not use this file except in compliance with the License. +- * You may obtain a copy of the License at +- * +- * http://www.apache.org/licenses/LICENSE-2.0 +- * +- * Unless required by applicable law or agreed to in writing, software +- * distributed under the License is distributed on an "AS IS" BASIS, +- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +- * See the License for the specific language governing permissions and +- * limitations under the License. +- */ +-#include "socperf_handler.h" +-#include // for FILE +-#include // for int32_t +-#include // for PATH_MAX +-#include // for list, __list_iterator, operator!= +-#include // for operator delete, operator new +-#include // for realpath +-#include // for set +-#include // for basic_string, to_string +-#include // for unordered_map, operator==, operator!= +-#include // for pair +-#include // for vector +-#include // for open, write +-#include // for O_RDWR, O_CLOEXEC +-#include "socperf_common.h" // for ResStatus, ResAction, ResNode, INVALID_V... +- +-namespace OHOS { +-namespace SOCPERF { +-SocPerfHandler::SocPerfHandler( +- const std::shared_ptr& runner) : AppExecFwk::EventHandler(runner) +-{ +-} +- +-SocPerfHandler::~SocPerfHandler() +-{ +-} +- +-void SocPerfHandler::ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event) +-{ +- if (event == nullptr) { +- return; +- } +- switch (event->GetInnerEventId()) { +- case INNER_EVENT_ID_INIT_RES_NODE_INFO: { +- auto resNode = event->GetSharedObject(); +- if (resNode != nullptr) { +- resNodeInfo.insert(std::pair>(resNode->id, resNode)); +- WriteNode(resNode->path, std::to_string(resNode->def)); +- auto resStatus = std::make_shared(resNode->def); +- resStatusInfo.insert(std::pair>(resNode->id, resStatus)); +- } +- break; +- } +- case INNER_EVENT_ID_INIT_GOV_RES_NODE_INFO: { +- auto govResNode = event->GetSharedObject(); +- if (govResNode != nullptr) { +- govResNodeInfo.insert(std::pair>(govResNode->id, govResNode)); +- for (int32_t i = 0; i < (int32_t)govResNode->paths.size(); i++) { +- WriteNode(govResNode->paths[i], govResNode->levelToStr[govResNode->def][i]); +- } +- auto resStatus = std::make_shared(govResNode->def); +- resStatusInfo.insert(std::pair>(govResNode->id, resStatus)); +- } +- break; +- } +- case INNER_EVENT_ID_DO_FREQ_ACTION: { +- int32_t resId = event->GetParam(); +- if (!IsValidResId(resId)) { +- return; +- } +- std::shared_ptr resAction = event->GetSharedObject(); +- if (resAction != nullptr) { +- UpdateResActionList(resId, resAction, false); +- } +- break; +- } +- case INNER_EVENT_ID_DO_FREQ_ACTION_PACK: { +- std::shared_ptr head = event->GetSharedObject(); +- while (head) { +- if (IsValidResId(head->resId)) { +- UpdateResActionList(head->resId, head->resAction, false); +- } +- auto temp = head->next; +- head->next = nullptr; +- head = temp; +- } +- break; +- } +- case INNER_EVENT_ID_DO_FREQ_ACTION_DELAYED: { +- int32_t resId = event->GetParam(); +- if (!IsValidResId(resId)) { +- return; +- } +- std::shared_ptr resAction = event->GetSharedObject(); +- if (resAction != nullptr) { +- UpdateResActionList(resId, resAction, true); +- } +- break; +- } +- case INNER_EVENT_ID_POWER_LIMIT_BOOST_FREQ: { +- powerLimitBoost = event->GetParam() == 1; +- for (auto iter = resStatusInfo.begin(); iter != resStatusInfo.end(); ++iter) { +- ArbitrateCandidate(iter->first); +- } +- break; +- } +- case INNER_EVENT_ID_THERMAL_LIMIT_BOOST_FREQ: { +- thermalLimitBoost = event->GetParam() == 1; +- for (auto iter = resStatusInfo.begin(); iter != resStatusInfo.end(); ++iter) { +- ArbitrateCandidate(iter->first); +- } +- break; +- } +- case INNER_EVENT_ID_DO_FREQ_ACTION_LEVEL: { +- HandleDoFreqActionLevel(event->GetParam(), event->GetSharedObject()); +- break; +- } +- default: { +- break; +- } +- } +-} +- +-void SocPerfHandler::HandleDoFreqActionLevel(int32_t resId, std::shared_ptr resAction) +-{ +- int32_t realResId = resId - RES_ID_ADDITION; +- if (!IsValidResId(realResId) || !resAction) { +- return; +- } +- int32_t level = (int32_t)resAction->value; +- if (!GetResValueByLevel(realResId, level, resAction->value)) { +- return; +- } +- UpdateResActionList(realResId, resAction, false); +-} +- +-bool SocPerfHandler::GetResValueByLevel(int32_t resId, int32_t level, int64_t& resValue) +-{ +- if (resNodeInfo.find(resId) == resNodeInfo.end() +- || resNodeInfo[resId]->available.empty()) { +- SOC_PERF_LOGE("resId[%{public}d] is not valid.", resId); +- return false; +- } +- if (level < 0) { +- return false; +- } +- +- std::set available; +- for (auto a : resNodeInfo[resId]->available) { +- available.insert(a); +- } +- int32_t len = (int32_t)available.size(); +- auto iter = available.begin(); +- if (level < len) { +- std::advance(iter, len - 1 - level); +- } +- resValue = *iter; +- return true; +-} +- +-void SocPerfHandler::UpdateResActionList(int32_t resId, std::shared_ptr resAction, bool delayed) +-{ +- std::shared_ptr resStatus = resStatusInfo[resId]; +- int32_t type = resAction->type; +- +- if (delayed) { +- for (auto iter = resStatus->resActionList[type].begin(); +- iter != resStatus->resActionList[type].end(); ++iter) { +- if (resAction == *iter) { +- resStatus->resActionList[type].erase(iter); +- UpdateCandidatesValue(resId, type); +- break; +- } +- } +- } else { +- switch (resAction->onOff) { +- case EVENT_INVALID: { +- resStatus->resActionList[type].push_back(resAction); +- UpdateCandidatesValue(resId, type); +- auto event = AppExecFwk::InnerEvent::Get( +- INNER_EVENT_ID_DO_FREQ_ACTION_DELAYED, resAction, resId); +- this->SendEvent(event, resAction->duration); +- break; +- } +- case EVENT_ON: { +- if (resAction->duration == 0) { +- for (auto iter = resStatus->resActionList[type].begin(); +- iter != resStatus->resActionList[type].end(); ++iter) { +- if (resAction->TotalSame(*iter)) { +- resStatus->resActionList[type].erase(iter); +- break; +- } +- } +- resStatus->resActionList[type].push_back(resAction); +- UpdateCandidatesValue(resId, type); +- } else { +- resStatus->resActionList[type].push_back(resAction); +- UpdateCandidatesValue(resId, type); +- auto event = AppExecFwk::InnerEvent::Get( +- INNER_EVENT_ID_DO_FREQ_ACTION_DELAYED, resAction, resId); +- this->SendEvent(event, resAction->duration); +- } +- break; +- } +- case EVENT_OFF: { +- for (auto iter = resStatus->resActionList[type].begin(); +- iter != resStatus->resActionList[type].end(); ++iter) { +- if (resAction->PartSame(*iter) && (*iter)->onOff == EVENT_ON) { +- resStatus->resActionList[type].erase(iter); +- UpdateCandidatesValue(resId, type); +- break; +- } +- } +- break; +- } +- default: { +- break; +- } +- } +- } +-} +- +-void SocPerfHandler::UpdateCandidatesValue(int32_t resId, int32_t type) +-{ +- std::shared_ptr resStatus = resStatusInfo[resId]; +- int64_t prev = resStatus->candidates[type]; +- +- if (resStatus->resActionList[type].empty()) { +- resStatus->candidates[type] = INVALID_VALUE; +- } else { +- if (type == ACTION_TYPE_PERF) { +- int64_t res = MIN_INT_VALUE; +- for (auto iter = resStatus->resActionList[type].begin(); +- iter != resStatus->resActionList[type].end(); ++iter) { +- res = Max(res, (*iter)->value); +- } +- resStatus->candidates[type] = res; +- } else { +- int64_t res = MAX_INT_VALUE; +- for (auto iter = resStatus->resActionList[type].begin(); +- iter != resStatus->resActionList[type].end(); ++iter) { +- res = Min(res, (*iter)->value); +- } +- resStatus->candidates[type] = res; +- } +- } +- +- if (resStatus->candidates[type] != prev) { +- ArbitrateCandidate(resId); +- } +-} +- +-void SocPerfHandler::ArbitrateCandidate(int32_t resId) +-{ +- std::shared_ptr resStatus = resStatusInfo[resId]; +- int64_t candidatePerf = resStatus->candidates[ACTION_TYPE_PERF]; +- int64_t candidatePower = resStatus->candidates[ACTION_TYPE_POWER]; +- int64_t candidateThermal = resStatus->candidates[ACTION_TYPE_THERMAL]; +- +- if (ExistNoCandidate(resId, resStatus, candidatePerf, candidatePower, candidateThermal)) { +- return; +- } +- +- if (!powerLimitBoost && !thermalLimitBoost) { +- if (candidatePerf != INVALID_VALUE) { +- resStatus->candidate = Max(candidatePerf, candidatePower, candidateThermal); +- } else { +- resStatus->candidate = +- (candidatePower == INVALID_VALUE) ? candidateThermal : +- ((candidateThermal == INVALID_VALUE) ? candidatePower : Min(candidatePower, candidateThermal)); +- } +- } else if (!powerLimitBoost && thermalLimitBoost) { +- resStatus->candidate = +- (candidateThermal != INVALID_VALUE) ? candidateThermal : Max(candidatePerf, candidatePower); +- } else if (powerLimitBoost && !thermalLimitBoost) { +- resStatus->candidate = +- (candidatePower != INVALID_VALUE) ? candidatePower : Max(candidatePerf, candidateThermal); +- } else { +- if (candidatePower == INVALID_VALUE && candidateThermal == INVALID_VALUE) { +- resStatus->candidate = candidatePerf; +- } else { +- resStatus->candidate = +- (candidatePower == INVALID_VALUE) ? candidateThermal : +- ((candidateThermal == INVALID_VALUE) ? candidatePower : Min(candidatePower, candidateThermal)); +- } +- } +- +- ArbitratePairRes(resId); +-} +- +-void SocPerfHandler::ArbitratePairRes(int32_t resId) +-{ +- if (IsGovResId(resId)) { +- UpdateCurrentValue(resId, resStatusInfo[resId]->candidate); +- return; +- } +- +- int32_t pairResId = resNodeInfo[resId]->pair; +- if (pairResId == INVALID_VALUE) { +- UpdateCurrentValue(resId, resStatusInfo[resId]->candidate); +- return; +- } +- +- if (resNodeInfo[resId]->mode == 1) { +- if (resStatusInfo[resId]->candidate < resStatusInfo[pairResId]->candidate) { +- if (powerLimitBoost || thermalLimitBoost) { +- UpdatePairResValue(pairResId, +- resStatusInfo[resId]->candidate, resId, resStatusInfo[resId]->candidate); +- } else { +- UpdatePairResValue(pairResId, +- resStatusInfo[pairResId]->candidate, resId, resStatusInfo[pairResId]->candidate); +- } +- } else { +- UpdatePairResValue(pairResId, +- resStatusInfo[pairResId]->candidate, resId, resStatusInfo[resId]->candidate); +- } +- } else { +- if (resStatusInfo[resId]->candidate > resStatusInfo[pairResId]->candidate) { +- if (powerLimitBoost || thermalLimitBoost) { +- UpdatePairResValue(resId, +- resStatusInfo[pairResId]->candidate, pairResId, resStatusInfo[pairResId]->candidate); +- } else { +- UpdatePairResValue(resId, +- resStatusInfo[resId]->candidate, pairResId, resStatusInfo[resId]->candidate); +- } +- } else { +- UpdatePairResValue(resId, +- resStatusInfo[resId]->candidate, pairResId, resStatusInfo[pairResId]->candidate); +- } +- } +-} +- +-void SocPerfHandler::UpdatePairResValue(int32_t minResId, int64_t minResValue, int32_t maxResId, int64_t maxResValue) +-{ +- WriteNode(resNodeInfo[minResId]->path, std::to_string(resNodeInfo[minResId]->def)); +- WriteNode(resNodeInfo[maxResId]->path, std::to_string(resNodeInfo[maxResId]->def)); +- UpdateCurrentValue(minResId, minResValue); +- UpdateCurrentValue(maxResId, maxResValue); +-} +- +-void SocPerfHandler::UpdateCurrentValue(int32_t resId, int64_t currValue) +-{ +- resStatusInfo[resId]->current = currValue; +- if (IsGovResId(resId)) { +- if (govResNodeInfo[resId]->levelToStr.find(currValue) != govResNodeInfo[resId]->levelToStr.end()) { +- std::vector targetStrs = govResNodeInfo[resId]->levelToStr[resStatusInfo[resId]->current]; +- for (int32_t i = 0; i < (int32_t)govResNodeInfo[resId]->paths.size(); i++) { +- WriteNode(govResNodeInfo[resId]->paths[i], targetStrs[i]); +- } +- } +- } else if (IsResId(resId)) { +- WriteNode(resNodeInfo[resId]->path, std::to_string(resStatusInfo[resId]->current)); +- } +-} +- +-void SocPerfHandler::WriteNode(std::string filePath, std::string value) +-{ +- int32_t fd = GetFdForFilePath(filePath); +- if (fd < 0) { +- return; +- } +- write(fd, value.c_str(), value.size()); +-} +- +-int32_t SocPerfHandler::GetFdForFilePath(std::string filePath) +-{ +- if (fdInfo.find(filePath) != fdInfo.end()) { +- return fdInfo[filePath]; +- } +- char path[PATH_MAX + 1] = {0}; +- if (filePath.size() == 0 || filePath.size() > PATH_MAX || !realpath(filePath.c_str(), path)) { +- return -1; +- } +- int32_t fd = open(path, O_RDWR | O_CLOEXEC); +- if (fd < 0) { +- return fd; +- } +- fdInfo.insert(std::pair(filePath, fd)); +- return fdInfo[filePath]; +-} +- +-bool SocPerfHandler::ExistNoCandidate( +- int32_t resId, std::shared_ptr resStatus, int64_t perf, int64_t power, int64_t thermal) +-{ +- if (perf == INVALID_VALUE && power == INVALID_VALUE && thermal == INVALID_VALUE) { +- if (IsGovResId(resId)) { +- resStatus->candidate = govResNodeInfo[resId]->def; +- } else if (IsResId(resId)) { +- resStatus->candidate = resNodeInfo[resId]->def; +- } +- ArbitratePairRes(resId); +- return true; +- } +- return false; +-} +- +-bool SocPerfHandler::IsGovResId(int32_t resId) +-{ +- if (resNodeInfo.find(resId) == resNodeInfo.end() +- && govResNodeInfo.find(resId) != govResNodeInfo.end()) { +- return true; +- } +- return false; +-} +- +-bool SocPerfHandler::IsResId(int32_t resId) +-{ +- if (govResNodeInfo.find(resId) == govResNodeInfo.end() +- && resNodeInfo.find(resId) != resNodeInfo.end()) { +- return true; +- } +- return false; +-} +- +-bool SocPerfHandler::IsValidResId(int32_t resId) +-{ +- if (resNodeInfo.find(resId) == resNodeInfo.end() +- && govResNodeInfo.find(resId) == govResNodeInfo.end()) { +- return false; +- } +- if (resStatusInfo.find(resId) == resStatusInfo.end()) { +- return false; +- } +- return true; +-} +-} // namespace SOCPERF +-} // namespace OHOS +diff --git a/soc_perf/services/server/include/socperf_server.h b/soc_perf/services/server/include/socperf_server.h +deleted file mode 100644 +index 7af60a2..0000000 +--- a/soc_perf/services/server/include/socperf_server.h ++++ /dev/null +@@ -1,56 +0,0 @@ +-/* +- * Copyright (c) 2022-2023 Huawei Device Co., Ltd. +- * Licensed under the Apache License, Version 2.0 (the "License"); +- * you may not use this file except in compliance with the License. +- * You may obtain a copy of the License at +- * +- * http://www.apache.org/licenses/LICENSE-2.0 +- * +- * Unless required by applicable law or agreed to in writing, software +- * distributed under the License is distributed on an "AS IS" BASIS, +- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +- * See the License for the specific language governing permissions and +- * limitations under the License. +- */ +- +-#ifndef SOC_PERF_SERVICES_SERVER_INCLUDE_SOCPERF_SERVER_H +-#define SOC_PERF_SERVICES_SERVER_INCLUDE_SOCPERF_SERVER_H +- +-#include +-#include +-#include "i_socperf_service.h" +-#include "singleton.h" +-#include "socperf_stub.h" +-#include "socperf.h" +- +-namespace OHOS { +-namespace SOCPERF { +-class SocPerfServer : public SystemAbility, public SocPerfStub, +- public std::enable_shared_from_this { +-DISALLOW_COPY_AND_MOVE(SocPerfServer); +-DECLARE_SYSTEM_ABILITY(SocPerfServer); +-DECLARE_DELAYED_SINGLETON(SocPerfServer); +- +-public: +- void PerfRequest(int32_t cmdId, const std::string& msg) override; +- void PerfRequestEx(int32_t cmdId, bool onOffTag, const std::string& msg) override; +- void PowerLimitBoost(bool onOffTag, const std::string& msg) override; +- void ThermalLimitBoost(bool onOffTag, const std::string& msg) override; +- void LimitRequest(int32_t clientId, +- const std::vector& tags, const std::vector& configs, const std::string& msg) override; +- int32_t Dump(int32_t fd, const std::vector& args) override; +- +-public: +- SocPerfServer(int32_t systemAbilityId, bool runOnCreate); +- +-protected: +- void OnStart() override; +- void OnStop() override; +- +-private: +- SocPerf socPerf; +-}; +-} // namespace SOCPERF +-} // namespace OHOS +- +-#endif // SOC_PERF_SERVICES_SERVER_INCLUDE_SOCPERF_SERVER_H +diff --git a/soc_perf/services/server/include/socperf_stub.h b/soc_perf/services/server/include/socperf_stub.h +deleted file mode 100644 +index cf1e10d..0000000 +--- a/soc_perf/services/server/include/socperf_stub.h ++++ /dev/null +@@ -1,36 +0,0 @@ +-/* +- * Copyright (c) 2022-2023 Huawei Device Co., Ltd. +- * Licensed under the Apache License, Version 2.0 (the "License"); +- * you may not use this file except in compliance with the License. +- * You may obtain a copy of the License at +- * +- * http://www.apache.org/licenses/LICENSE-2.0 +- * +- * Unless required by applicable law or agreed to in writing, software +- * distributed under the License is distributed on an "AS IS" BASIS, +- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +- * See the License for the specific language governing permissions and +- * limitations under the License. +- */ +- +-#ifndef SOC_PERF_SERVICES_SERVER_INCLUDE_SOCPERF_STUB_H +-#define SOC_PERF_SERVICES_SERVER_INCLUDE_SOCPERF_STUB_H +- +-#include // for int32_t, uint32_t +-#include "i_socperf_service.h" +- +-namespace OHOS { +-namespace SOCPERF { +-class SocPerfStub : public IRemoteStub { +-public: +- SocPerfStub() = default; +- ~SocPerfStub() override = default; +- DISALLOW_COPY_AND_MOVE(SocPerfStub); +- +- int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, +- MessageParcel &reply, MessageOption &option) override; +-}; +-} // namespace SOCPERF +-} // namespace OHOS +- +-#endif // SOC_PERF_SERVICES_SERVER_INCLUDE_SOCPERF_STUB_H +diff --git a/soc_perf/services/server/src/socperf_server.cpp b/soc_perf/services/server/src/socperf_server.cpp +deleted file mode 100644 +index 6f5aa78..0000000 +--- a/soc_perf/services/server/src/socperf_server.cpp ++++ /dev/null +@@ -1,93 +0,0 @@ +-/* +- * Copyright (c) 2022 Huawei Device Co., Ltd. +- * Licensed under the Apache License, Version 2.0 (the "License"); +- * you may not use this file except in compliance with the License. +- * You may obtain a copy of the License at +- * +- * http://www.apache.org/licenses/LICENSE-2.0 +- * +- * Unless required by applicable law or agreed to in writing, software +- * distributed under the License is distributed on an "AS IS" BASIS, +- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +- * See the License for the specific language governing permissions and +- * limitations under the License. +- */ +- +-#include "socperf_server.h" +- +-namespace OHOS { +-namespace SOCPERF { +-const bool REGISTER_RESULT = +- SystemAbility::MakeAndRegisterAbility(DelayedSingleton::GetInstance().get()); +- +-SocPerfServer::SocPerfServer() : SystemAbility(SOC_PERF_SERVICE_SA_ID, true) +-{ +-} +- +-SocPerfServer::~SocPerfServer() +-{ +-} +- +-void SocPerfServer::OnStart() +-{ +- if (!Publish(DelayedSingleton::GetInstance().get())) { +- SOC_PERF_LOGE("Register SystemAbility for SocPerf FAILED."); +- return; +- } +- if (!socPerf.Init()) { +- SOC_PERF_LOGE("SocPerf Init FAILED"); +- return; +- } +-} +- +-void SocPerfServer::OnStop() +-{ +-} +- +-int32_t SocPerfServer::Dump(int32_t fd, const std::vector& args) +-{ +- std::vector argsInStr; +- std::transform(args.begin(), args.end(), std::back_inserter(argsInStr), +- [](const std::u16string &arg) { +- return Str16ToStr8(arg); +- }); +- std::string result; +- result.append("usage: soc_perf service dump []\n") +- .append(" 1. PerfRequest(cmdId, msg)\n") +- .append(" 2. PerfRequestEx(cmdId, onOffTag, msg)\n") +- .append(" 3. LimitRequest(clientId, tags, configs, msg)\n") +- .append(" -h: show the help.\n") +- .append(" -a: show all info.\n"); +- if (!SaveStringToFd(fd, result)) { +- SOC_PERF_LOGE("Dump FAILED"); +- } +- return ERR_OK; +-} +- +-void SocPerfServer::PerfRequest(int32_t cmdId, const std::string& msg) +-{ +- socPerf.PerfRequest(cmdId, msg); +-} +- +-void SocPerfServer::PerfRequestEx(int32_t cmdId, bool onOffTag, const std::string& msg) +-{ +- socPerf.PerfRequestEx(cmdId, onOffTag, msg); +-} +- +-void SocPerfServer::PowerLimitBoost(bool onOffTag, const std::string& msg) +-{ +- socPerf.PowerLimitBoost(onOffTag, msg); +-} +- +-void SocPerfServer::ThermalLimitBoost(bool onOffTag, const std::string& msg) +-{ +- socPerf.ThermalLimitBoost(onOffTag, msg); +-} +- +-void SocPerfServer::LimitRequest(int32_t clientId, +- const std::vector& tags, const std::vector& configs, const std::string& msg) +-{ +- socPerf.LimitRequest(clientId, tags, configs, msg); +-} +-} // namespace SOCPERF +-} // namespace OHOS +diff --git a/soc_perf/services/server/src/socperf_stub.cpp b/soc_perf/services/server/src/socperf_stub.cpp +deleted file mode 100644 +index 413f6ae..0000000 +--- a/soc_perf/services/server/src/socperf_stub.cpp ++++ /dev/null +@@ -1,73 +0,0 @@ +-/* +- * Copyright (c) 2022 Huawei Device Co., Ltd. +- * Licensed under the Apache License, Version 2.0 (the "License"); +- * you may not use this file except in compliance with the License. +- * You may obtain a copy of the License at +- * +- * http://www.apache.org/licenses/LICENSE-2.0 +- * +- * Unless required by applicable law or agreed to in writing, software +- * distributed under the License is distributed on an "AS IS" BASIS, +- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +- * See the License for the specific language governing permissions and +- * limitations under the License. +- */ +- +-#include "socperf_stub.h" +-#include // for int32_t +-#include // for string +-#include // for basic_string, operator!=, u16string +-#include // for vector +- +- +-namespace OHOS { +-namespace SOCPERF { +-int32_t SocPerfStub::OnRemoteRequest(uint32_t code, MessageParcel &data, +- MessageParcel &reply, MessageOption &option) +-{ +- auto remoteDescriptor = data.ReadInterfaceToken(); +- if (GetDescriptor() != remoteDescriptor) { +- return ERR_INVALID_STATE; +- } +- switch (code) { +- case TRANS_IPC_ID_PERF_REQUEST: { +- int32_t cmdId = data.ReadInt32(); +- std::string msg = data.ReadString(); +- PerfRequest(cmdId, msg); +- return 0; +- } +- case TRANS_IPC_ID_PERF_REQUEST_EX: { +- int32_t cmdId = data.ReadInt32(); +- bool onOffTag = data.ReadBool(); +- std::string msg = data.ReadString(); +- PerfRequestEx(cmdId, onOffTag, msg); +- return 0; +- } +- case TRANS_IPC_ID_POWER_LIMIT_BOOST_FREQ: { +- bool onOffTag = data.ReadBool(); +- std::string msg = data.ReadString(); +- PowerLimitBoost(onOffTag, msg); +- return 0; +- } +- case TRANS_IPC_ID_THERMAL_LIMIT_BOOST_FREQ: { +- bool onOffTag = data.ReadBool(); +- std::string msg = data.ReadString(); +- ThermalLimitBoost(onOffTag, msg); +- return 0; +- } +- case TRANS_IPC_ID_LIMIT_REQUEST: { +- int32_t clientId = data.ReadInt32(); +- std::vector tags; +- data.ReadInt32Vector(&tags); +- std::vector configs; +- data.ReadInt64Vector(&configs); +- std::string msg = data.ReadString(); +- LimitRequest(clientId, tags, configs, msg); +- return 0; +- } +- default: +- return IPCObjectStub::OnRemoteRequest(code, data, reply, option); +- } +-} +-} // namespace SOCPERF +-} // namespace OHOS +diff --git a/soc_perf/soc_perf.gni b/soc_perf/soc_perf.gni +deleted file mode 100644 +index 9bd7ce5..0000000 +--- a/soc_perf/soc_perf.gni ++++ /dev/null +@@ -1,31 +0,0 @@ +-# Copyright (C) 2023 Huawei Device Co., Ltd. +-# Licensed under the Apache License, Version 2.0 (the "License"); +-# you may not use this file except in compliance with the License. +-# You may obtain a copy of the License at +-# +-# http://www.apache.org/licenses/LICENSE-2.0 +-# +-# Unless required by applicable law or agreed to in writing, software +-# distributed under the License is distributed on an "AS IS" BASIS, +-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-# See the License for the specific language governing permissions and +-# limitations under the License. +- +-socperf_path = +- "//foundation/resourceschedule/resource_schedule_service/soc_perf" +- +-socperf_services = "${socperf_path}/services" +- +-socperf_common = "${socperf_path}/common" +- +-socperf_interfaces = "${socperf_path}/interfaces" +- +-socperf_test = "${socperf_path}/test" +- +-declare_args() { +- customization_config_policy_enable = true +- if (defined(global_parts_info) && +- !defined(global_parts_info.customization_config_policy)) { +- customization_config_policy_enable = false +- } +-} +diff --git a/soc_perf/test/fuzztest/BUILD.gn b/soc_perf/test/fuzztest/BUILD.gn +deleted file mode 100644 +index e857064..0000000 +--- a/soc_perf/test/fuzztest/BUILD.gn ++++ /dev/null +@@ -1,22 +0,0 @@ +-# Copyright (c) 2022 Huawei Device Co., Ltd. +-# Licensed under the Apache License, Version 2.0 (the "License"); +-# you may not use this file except in compliance with the License. +-# You may obtain a copy of the License at +-# +-# http://www.apache.org/licenses/LICENSE-2.0 +-# +-# Unless required by applicable law or agreed to in writing, software +-# distributed under the License is distributed on an "AS IS" BASIS, +-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-# See the License for the specific language governing permissions and +-# limitations under the License. +- +-group("fuzztest") { +- testonly = true +- +- deps = [ +- "loadconfigxmlfile_fuzzer:fuzztest", +- "perfrequest_fuzzer:fuzztest", +- "socperf_fuzzer:fuzztest", +- ] +-} +diff --git a/soc_perf/test/fuzztest/loadconfigxmlfile_fuzzer/BUILD.gn b/soc_perf/test/fuzztest/loadconfigxmlfile_fuzzer/BUILD.gn +deleted file mode 100644 +index c93ebb2..0000000 +--- a/soc_perf/test/fuzztest/loadconfigxmlfile_fuzzer/BUILD.gn ++++ /dev/null +@@ -1,60 +0,0 @@ +-# Copyright (c) 2022-2023 Huawei Device Co., Ltd. +-# Licensed under the Apache License, Version 2.0 (the "License"); +-# you may not use this file except in compliance with the License. +-# You may obtain a copy of the License at +-# +-# http://www.apache.org/licenses/LICENSE-2.0 +-# +-# Unless required by applicable law or agreed to in writing, software +-# distributed under the License is distributed on an "AS IS" BASIS, +-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-# See the License for the specific language governing permissions and +-# limitations under the License. +- +-#####################hydra-fuzz################### +-import("//build/config/features.gni") +-import("//build/test.gni") +-import("../../../soc_perf.gni") +-module_output_path = "resource_schedule_service/soc_perf" +- +-##############################fuzztest########################################## +-config("module_private_config") { +- include_dirs = [ +- "${socperf_common}/include", +- "${socperf_interfaces}/inner_api/socperf_client/include", +- "${socperf_services}/core/include", +- "${socperf_services}/server/include", +- ] +-} +- +-ohos_fuzztest("LoadConfigXmlFileFuzzTest") { +- module_out_path = module_output_path +- fuzz_config_file = "${socperf_test}/fuzztest/loadconfigxmlfile_fuzzer" +- configs = [ ":module_private_config" ] +- +- cflags = [ +- "-g", +- "-O0", +- "-Wno-unused-variable", +- "-fno-omit-frame-pointer", +- ] +- +- sources = [ "loadconfigxmlfile_fuzzer.cpp" ] +- +- deps = [ "${socperf_services}:socperf_server_static" ] +- +- external_deps = [ +- "c_utils:utils", +- "hiviewdfx_hilog_native:libhilog", +- ] +-} +- +-############################################################################### +-group("fuzztest") { +- testonly = true +- deps = [ +- # deps file +- ":LoadConfigXmlFileFuzzTest", +- ] +-} +-############################################################################### +diff --git a/soc_perf/test/fuzztest/loadconfigxmlfile_fuzzer/corpus/init b/soc_perf/test/fuzztest/loadconfigxmlfile_fuzzer/corpus/init +deleted file mode 100644 +index 415fc33..0000000 +--- a/soc_perf/test/fuzztest/loadconfigxmlfile_fuzzer/corpus/init ++++ /dev/null +@@ -1,28 +0,0 @@ +- +- +- +- +- +- 408000 +- /sys/devices/system/cpu/cpufreq/policy0/scaling_min_freq +- 408000 600000 816000 1104000 1416000 1608000 1800000 1992000 +- +- +- 1992000 +- /sys/devices/system/cpu/cpufreq/policy0/scaling_max_freq +- 408000 600000 816000 1104000 1416000 1608000 1800000 1992000 +- +- +- +\ No newline at end of file +diff --git a/soc_perf/test/fuzztest/loadconfigxmlfile_fuzzer/loadconfigxmlfile_fuzzer.cpp b/soc_perf/test/fuzztest/loadconfigxmlfile_fuzzer/loadconfigxmlfile_fuzzer.cpp +deleted file mode 100644 +index 933451d..0000000 +--- a/soc_perf/test/fuzztest/loadconfigxmlfile_fuzzer/loadconfigxmlfile_fuzzer.cpp ++++ /dev/null +@@ -1,70 +0,0 @@ +-/* +- * Copyright (c) 2022-2023 Huawei Device Co., Ltd. +- * Licensed under the Apache License, Version 2.0 (the "License"); +- * you may not use this file except in compliance with the License. +- * You may obtain a copy of the License at +- * +- * http://www.apache.org/licenses/LICENSE-2.0 +- * +- * Unless required by applicable law or agreed to in writing, software +- * distributed under the License is distributed on an "AS IS" BASIS, +- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +- * See the License for the specific language governing permissions and +- * limitations under the License. +- */ +- +-#include "loadconfigxmlfile_fuzzer.h" +- +-#define private public +-#include "socperf.h" +- +-namespace OHOS { +-namespace SOCPERF { +- const std::string fuzzedFile = "myFuzzed.xml"; +- const int32_t FILE_RETURN_SUCCESS = 1; +- std::mutex mutexLock; +- std::unique_ptr socPerf = nullptr; +- +- bool DoInit() +- { +- std::lock_guard lock(mutexLock); +- if (socPerf) { +- return true; +- } +- socPerf = std::make_unique(); +- return socPerf != nullptr; +- } +- +- void DoSomethingInterestingWithMyAPI(const uint8_t* data, size_t size) +- { +- if (!DoInit()) { +- return; +- } +- +- // generate fuzzed xml +- FILE *pFile = fopen(fuzzedFile.c_str(), "wb"); +- if (!pFile) { +- return; +- } +- +- int32_t retCode = fwrite(reinterpret_cast(data), size, 1, pFile); // 1 means count=1 +- if (retCode < FILE_RETURN_SUCCESS) { +- (void)fclose(pFile); +- pFile = nullptr; +- return; +- } +- +- (void)fclose(pFile); +- pFile = nullptr; +- socPerf->LoadConfigXmlFile(fuzzedFile); +- } +-} // namespace SOCPERF +-} // namespace OHOS +- +-/* Fuzzer entry point */ +-extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) +-{ +- /* Run your code on data */ +- OHOS::SOCPERF::DoSomethingInterestingWithMyAPI(data, size); +- return 0; +-} +diff --git a/soc_perf/test/fuzztest/loadconfigxmlfile_fuzzer/loadconfigxmlfile_fuzzer.h b/soc_perf/test/fuzztest/loadconfigxmlfile_fuzzer/loadconfigxmlfile_fuzzer.h +deleted file mode 100644 +index 9f20ca2..0000000 +--- a/soc_perf/test/fuzztest/loadconfigxmlfile_fuzzer/loadconfigxmlfile_fuzzer.h ++++ /dev/null +@@ -1,21 +0,0 @@ +-/* +- * Copyright (c) 2022 Huawei Device Co., Ltd. +- * Licensed under the Apache License, Version 2.0 (the "License"); +- * you may not use this file except in compliance with the License. +- * You may obtain a copy of the License at +- * +- * http://www.apache.org/licenses/LICENSE-2.0 +- * +- * Unless required by applicable law or agreed to in writing, software +- * distributed under the License is distributed on an "AS IS" BASIS, +- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +- * See the License for the specific language governing permissions and +- * limitations under the License. +- */ +- +-#ifndef TEST_FUZZTEST_LOADCONFIGXMLFILE_FUZZER_H +-#define TEST_FUZZTEST_LOADCONFIGXMLFILE_FUZZER_H +- +-#define FUZZ_PROJECT_NAME "loadconfigxmlfile_fuzzer" +- +-#endif +\ No newline at end of file +diff --git a/soc_perf/test/fuzztest/loadconfigxmlfile_fuzzer/project.xml b/soc_perf/test/fuzztest/loadconfigxmlfile_fuzzer/project.xml +deleted file mode 100644 +index c2b6907..0000000 +--- a/soc_perf/test/fuzztest/loadconfigxmlfile_fuzzer/project.xml ++++ /dev/null +@@ -1,24 +0,0 @@ +- +- +- +- +- +- 1000 +- +- 300 +- +- 4096 +- +- +diff --git a/soc_perf/test/fuzztest/perfrequest_fuzzer/BUILD.gn b/soc_perf/test/fuzztest/perfrequest_fuzzer/BUILD.gn +deleted file mode 100644 +index 87ec5dd..0000000 +--- a/soc_perf/test/fuzztest/perfrequest_fuzzer/BUILD.gn ++++ /dev/null +@@ -1,60 +0,0 @@ +-# Copyright (c) 2022-2023 Huawei Device Co., Ltd. +-# Licensed under the Apache License, Version 2.0 (the "License"); +-# you may not use this file except in compliance with the License. +-# You may obtain a copy of the License at +-# +-# http://www.apache.org/licenses/LICENSE-2.0 +-# +-# Unless required by applicable law or agreed to in writing, software +-# distributed under the License is distributed on an "AS IS" BASIS, +-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-# See the License for the specific language governing permissions and +-# limitations under the License. +- +-#####################hydra-fuzz################### +-import("//build/config/features.gni") +-import("//build/test.gni") +-import("../../../soc_perf.gni") +- +-##############################fuzztest########################################## +-ohos_fuzztest("PerfRequestFuzzTest") { +- module_out_path = "soc_perf/socperftest" +- fuzz_config_file = "${socperf_test}/fuzztest/perfrequest_fuzzer" +- +- include_dirs = [ +- "${socperf_common}/include", +- "${socperf_interfaces}/inner_api/socperf_client:socperf_client", +- "${socperf_services}/core/include", +- ] +- +- cflags = [ +- "-g", +- "-O0", +- "-Wno-unused-variable", +- "-fno-omit-frame-pointer", +- ] +- +- sources = [ "perfrequest_fuzzer.cpp" ] +- +- deps = [ "${socperf_interfaces}/inner_api/socperf_client:socperf_client" ] +- +- external_deps = [ +- "c_utils:utils", +- "eventhandler:libeventhandler", +- "hiviewdfx_hilog_native:libhilog", +- "ipc:ipc_single", +- "safwk:system_ability_fwk", +- "samgr:samgr_proxy", +- ] +-} +- +-############################################################################### +-group("fuzztest") { +- testonly = true +- deps = [] +- deps += [ +- # deps file +- ":PerfRequestFuzzTest", +- ] +-} +-############################################################################### +diff --git a/soc_perf/test/fuzztest/perfrequest_fuzzer/corpus/init b/soc_perf/test/fuzztest/perfrequest_fuzzer/corpus/init +deleted file mode 100644 +index f812823..0000000 +--- a/soc_perf/test/fuzztest/perfrequest_fuzzer/corpus/init ++++ /dev/null +@@ -1,14 +0,0 @@ +-# Copyright (c) 2023 Huawei Device Co., Ltd. +-# Licensed under the Apache License, Version 2.0 (the "License"); +-# you may not use this file except in compliance with the License. +-# You may obtain a copy of the License at +-# +-# http://www.apache.org/licenses/LICENSE-2.0 +-# +-# Unless required by applicable law or agreed to in writing, software +-# distributed under the License is distributed on an "AS IS" BASIS, +-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-# See the License for the specific language governing permissions and +-# limitations under the License. +- +-FUZZ +\ No newline at end of file +diff --git a/soc_perf/test/fuzztest/perfrequest_fuzzer/perfrequest_fuzzer.cpp b/soc_perf/test/fuzztest/perfrequest_fuzzer/perfrequest_fuzzer.cpp +deleted file mode 100644 +index 896269d..0000000 +--- a/soc_perf/test/fuzztest/perfrequest_fuzzer/perfrequest_fuzzer.cpp ++++ /dev/null +@@ -1,198 +0,0 @@ +-/* +- * Copyright (c) 2022-2023 Huawei Device Co., Ltd. +- * Licensed under the Apache License, Version 2.0 (the "License"); +- * you may not use this file except in compliance with the License. +- * You may obtain a copy of the License at +- * +- * http://www.apache.org/licenses/LICENSE-2.0 +- * +- * Unless required by applicable law or agreed to in writing, software +- * distributed under the License is distributed on an "AS IS" BASIS, +- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +- * See the License for the specific language governing permissions and +- * limitations under the License. +- */ +- +-#include "perfrequest_fuzzer.h" +-#include "socperf_client.h" +- +-#include +-#include +-#include +-#include +- +-#ifndef errno_t +-typedef int errno_t; +-#endif +- +-#ifndef EOK +-#define EOK 0 +-#endif +- +-namespace OHOS { +-namespace SOCPERF { +- const uint8_t* g_data = nullptr; +- size_t g_size = 0; +- size_t g_pos; +- +- /* +- * describe: get data from outside untrusted data(g_data) which size is according to sizeof(T) +- * tips: only support basic type +- */ +- template +- T GetData() +- { +- T object {}; +- size_t objectSize = sizeof(object); +- if (g_data == nullptr || objectSize > g_size - g_pos) { +- return object; +- } +- errno_t ret = memcpy_s(&object, objectSize, g_data + g_pos, objectSize); +- if (ret != EOK) { +- return {}; +- } +- g_pos += objectSize; +- return object; +- } +- +- /* +- * get a string from g_data +- */ +- std::string GetStringFromData(int strlen) +- { +- if (strlen <= 0) { +- return ""; +- } +- char cstr[strlen]; +- cstr[strlen - 1] = '\0'; +- for (int i = 0; i < strlen - 1; i++) { +- char tmp = GetData(); +- if (tmp == '\0') { +- tmp = '1'; +- } +- cstr[i] = tmp; +- } +- std::string str(cstr); +- return str; +- } +- +- bool PerfRequestFuzzTest(const uint8_t* data, size_t size) +- { +- if (data == nullptr) { +- return false; +- } +- +- // initialize +- g_data = data; +- g_size = size; +- g_pos = 0; +- +- // getdata +- std::string msg; +- int32_t cmdId = GetData(); +- msg = GetStringFromData(int(size) - sizeof(int32_t)); +- OHOS::SOCPERF::SocPerfClient::GetInstance().PerfRequest(cmdId, msg); +- +- return true; +- } +- +- bool PerfRequestExFuzzTest(const uint8_t* data, size_t size) +- { +- if (data == nullptr) { +- return false; +- } +- +- // initialize +- g_data = data; +- g_size = size; +- g_pos = 0; +- +- // getdata +- std::string msg; +- int32_t cmdId = GetData(); +- bool onOffTag = GetData(); +- msg = GetStringFromData(int(size) - sizeof(int32_t) - sizeof(bool)); +- OHOS::SOCPERF::SocPerfClient::GetInstance().PerfRequestEx(cmdId, onOffTag, msg); +- +- return true; +- } +- +- bool PowerLimitBoostFuzzTest(const uint8_t* data, size_t size) +- { +- if (data == nullptr) { +- return false; +- } +- +- // initialize +- g_data = data; +- g_size = size; +- g_pos = 0; +- +- // getdata +- std::string msg; +- bool onOffTag = GetData(); +- msg = GetStringFromData(int(size) - sizeof(bool)); +- OHOS::SOCPERF::SocPerfClient::GetInstance().PowerLimitBoost(onOffTag, msg); +- +- return true; +- } +- +- bool ThermalLimitBoostFuzzTest(const uint8_t* data, size_t size) +- { +- if (data == nullptr) { +- return false; +- } +- +- // initialize +- g_data = data; +- g_size = size; +- g_pos = 0; +- +- // getdata +- std::string msg; +- bool onOffTag = GetData(); +- msg = GetStringFromData(int(size) - sizeof(bool)); +- OHOS::SOCPERF::SocPerfClient::GetInstance().ThermalLimitBoost(onOffTag, msg); +- +- return true; +- } +- +- bool LimitRequestFuzzTest(const uint8_t* data, size_t size) +- { +- if (data == nullptr) { +- return false; +- } +- +- // initialize +- g_data = data; +- g_size = size; +- g_pos = 0; +- +- // getdata +- std::vector tags; +- std::vector configs; +- std::string msg; +- int32_t tagsNumber = GetData(); +- int64_t configsNumber = GetData(); +- int32_t clientId = GetData(); +- tags.push_back(tagsNumber); +- configs.push_back(configsNumber); +- msg = GetStringFromData(int(size) - sizeof(int32_t) - sizeof(int32_t) - sizeof(int64_t)); +- OHOS::SOCPERF::SocPerfClient::GetInstance().LimitRequest(clientId, tags, configs, msg); +- +- return true; +- } +-} // namespace SOCPERF +-} // namespace OHOS +- +-/* Fuzzer entry point */ +-extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) +-{ +- /* Run your code on data */ +- OHOS::SOCPERF::PerfRequestFuzzTest(data, size); +- OHOS::SOCPERF::PerfRequestExFuzzTest(data, size); +- OHOS::SOCPERF::PowerLimitBoostFuzzTest(data, size); +- OHOS::SOCPERF::ThermalLimitBoostFuzzTest(data, size); +- OHOS::SOCPERF::LimitRequestFuzzTest(data, size); +- return 0; +-} +\ No newline at end of file +diff --git a/soc_perf/test/fuzztest/perfrequest_fuzzer/perfrequest_fuzzer.h b/soc_perf/test/fuzztest/perfrequest_fuzzer/perfrequest_fuzzer.h +deleted file mode 100644 +index 5343b90..0000000 +--- a/soc_perf/test/fuzztest/perfrequest_fuzzer/perfrequest_fuzzer.h ++++ /dev/null +@@ -1,28 +0,0 @@ +-/* +- * Copyright (c) 2023 Huawei Device Co., Ltd. +- * Licensed under the Apache License, Version 2.0 (the "License"); +- * you may not use this file except in compliance with the License. +- * You may obtain a copy of the License at +- * +- * http://www.apache.org/licenses/LICENSE-2.0 +- * +- * Unless required by applicable law or agreed to in writing, software +- * distributed under the License is distributed on an "AS IS" BASIS, +- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +- * See the License for the specific language governing permissions and +- * limitations under the License. +- */ +- +-#ifndef PERFREQUEST_FUZZER_H +-#define PERFREQUEST_FUZZER_H +- +-#include +-#include +-#include +-#include +-#include +-#include +- +-#define FUZZ_PROJECT_NAME "perfrequest_fuzzer" +- +-#endif +\ No newline at end of file +diff --git a/soc_perf/test/fuzztest/perfrequest_fuzzer/project.xml b/soc_perf/test/fuzztest/perfrequest_fuzzer/project.xml +deleted file mode 100644 +index f881f69..0000000 +--- a/soc_perf/test/fuzztest/perfrequest_fuzzer/project.xml ++++ /dev/null +@@ -1,24 +0,0 @@ +- +- +- +- +- +- 1000 +- +- 300 +- +- 4096 +- +- +diff --git a/soc_perf/test/fuzztest/socperf_fuzzer/BUILD.gn b/soc_perf/test/fuzztest/socperf_fuzzer/BUILD.gn +deleted file mode 100644 +index 70e73e6..0000000 +--- a/soc_perf/test/fuzztest/socperf_fuzzer/BUILD.gn ++++ /dev/null +@@ -1,55 +0,0 @@ +-# Copyright (c) 2022-2023 Huawei Device Co., Ltd. +-# Licensed under the Apache License, Version 2.0 (the "License"); +-# you may not use this file except in compliance with the License. +-# You may obtain a copy of the License at +-# +-# http://www.apache.org/licenses/LICENSE-2.0 +-# +-# Unless required by applicable law or agreed to in writing, software +-# distributed under the License is distributed on an "AS IS" BASIS, +-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-# See the License for the specific language governing permissions and +-# limitations under the License. +- +-#####################hydra-fuzz################### +-import("//build/config/features.gni") +-import("//build/test.gni") +-import("../../../soc_perf.gni") +-module_output_path = "resource_schedule_service/soc_perf" +- +-##############################fuzztest########################################## +-ohos_fuzztest("SocPerfFuzzTest") { +- module_out_path = module_output_path +- fuzz_config_file = "${socperf_test}/fuzztest/socperf_fuzzer" +- include_dirs = [] +- +- cflags = [ +- "-g", +- "-O0", +- "-Wno-unused-variable", +- "-fno-omit-frame-pointer", +- ] +- +- sources = [ "socperf_fuzzer.cpp" ] +- +- deps = [ "${socperf_interfaces}/inner_api/socperf_client:socperf_client" ] +- +- external_deps = [ +- "c_utils:utils", +- "hiviewdfx_hilog_native:libhilog", +- "ipc:ipc_single", +- "safwk:system_ability_fwk", +- "samgr:samgr_proxy", +- ] +-} +- +-############################################################################### +-group("fuzztest") { +- testonly = true +- deps = [] +- deps += [ +- # deps file +- ":SocPerfFuzzTest", +- ] +-} +-############################################################################### +diff --git a/soc_perf/test/fuzztest/socperf_fuzzer/corpus/init b/soc_perf/test/fuzztest/socperf_fuzzer/corpus/init +deleted file mode 100644 +index bc977bd..0000000 +--- a/soc_perf/test/fuzztest/socperf_fuzzer/corpus/init ++++ /dev/null +@@ -1,14 +0,0 @@ +-# Copyright (c) 2022 Huawei Device Co., Ltd. +-# Licensed under the Apache License, Version 2.0 (the "License"); +-# you may not use this file except in compliance with the License. +-# You may obtain a copy of the License at +-# +-# http://www.apache.org/licenses/LICENSE-2.0 +-# +-# Unless required by applicable law or agreed to in writing, software +-# distributed under the License is distributed on an "AS IS" BASIS, +-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-# See the License for the specific language governing permissions and +-# limitations under the License. +- +-FUZZ +\ No newline at end of file +diff --git a/soc_perf/test/fuzztest/socperf_fuzzer/project.xml b/soc_perf/test/fuzztest/socperf_fuzzer/project.xml +deleted file mode 100644 +index c2b6907..0000000 +--- a/soc_perf/test/fuzztest/socperf_fuzzer/project.xml ++++ /dev/null +@@ -1,24 +0,0 @@ +- +- +- +- +- +- 1000 +- +- 300 +- +- 4096 +- +- +diff --git a/soc_perf/test/fuzztest/socperf_fuzzer/socperf_fuzzer.cpp b/soc_perf/test/fuzztest/socperf_fuzzer/socperf_fuzzer.cpp +deleted file mode 100644 +index 8c05f42..0000000 +--- a/soc_perf/test/fuzztest/socperf_fuzzer/socperf_fuzzer.cpp ++++ /dev/null +@@ -1,87 +0,0 @@ +-/* +- * Copyright (c) 2022-2023 Huawei Device Co., Ltd. +- * Licensed under the Apache License, Version 2.0 (the "License"); +- * you may not use this file except in compliance with the License. +- * You may obtain a copy of the License at +- * +- * http://www.apache.org/licenses/LICENSE-2.0 +- * +- * Unless required by applicable law or agreed to in writing, software +- * distributed under the License is distributed on an "AS IS" BASIS, +- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +- * See the License for the specific language governing permissions and +- * limitations under the License. +- */ +- +-#include "socperf_fuzzer.h" +- +-#include "iservice_registry.h" +-#include "system_ability_definition.h" +- +-#include "i_socperf_service.h" +-#include "socperf_log.h" +- +-namespace OHOS { +-namespace SOCPERF { +- constexpr int32_t MIN_LEN = 4; +- std::mutex mutexLock; +- sptr remoteObj = nullptr; +- +- bool DoInit() +- { +- std::lock_guard lock(mutexLock); +- if (remoteObj) { +- return true; +- } +- auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); +- if (!samgr) { +- return false; +- } +- remoteObj = samgr->GetSystemAbility(SOC_PERF_SERVICE_SA_ID); +- if (!remoteObj) { +- return false; +- } +- return true; +- } +- +- int32_t onRemoteRequest(uint32_t code, MessageParcel& data) +- { +- if (!DoInit()) { +- return -1; +- } +- MessageParcel reply; +- MessageOption option; +- return remoteObj->SendRequest(code, data, reply, option); +- } +- +- bool DoSomethingInterestingWithMyAPI(const uint8_t* data, size_t size) +- { +- if (size <= MIN_LEN) { +- return false; +- } +- +- MessageParcel dataMessageParcel; +- if (!dataMessageParcel.WriteInterfaceToken(IRemoteStub::GetDescriptor())) { +- return false; +- } +- +- uint32_t code = *(reinterpret_cast(data)); +- size -= sizeof(uint32_t); +- +- dataMessageParcel.WriteBuffer(data + sizeof(uint32_t), size); +- dataMessageParcel.RewindRead(0); +- +- onRemoteRequest(code, dataMessageParcel); +- return true; +- } +-} // namespace SOCPERF +-} // namespace OHOS +- +-/* Fuzzer entry point */ +-extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) +-{ +- /* Run your code on data */ +- OHOS::SOCPERF::DoSomethingInterestingWithMyAPI(data, size); +- return 0; +-} +- +diff --git a/soc_perf/test/fuzztest/socperf_fuzzer/socperf_fuzzer.h b/soc_perf/test/fuzztest/socperf_fuzzer/socperf_fuzzer.h +deleted file mode 100644 +index cfd3fb6..0000000 +--- a/soc_perf/test/fuzztest/socperf_fuzzer/socperf_fuzzer.h ++++ /dev/null +@@ -1,21 +0,0 @@ +-/* +- * Copyright (c) 2022 Huawei Device Co., Ltd. +- * Licensed under the Apache License, Version 2.0 (the "License"); +- * you may not use this file except in compliance with the License. +- * You may obtain a copy of the License at +- * +- * http://www.apache.org/licenses/LICENSE-2.0 +- * +- * Unless required by applicable law or agreed to in writing, software +- * distributed under the License is distributed on an "AS IS" BASIS, +- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +- * See the License for the specific language governing permissions and +- * limitations under the License. +- */ +- +-#ifndef TEST_FUZZTEST_SOCPERF_FUZZER_H +-#define TEST_FUZZTEST_SOCPERF_FUZZER_H +- +-#define FUZZ_PROJECT_NAME "socperf_fuzzer" +- +-#endif +\ No newline at end of file +diff --git a/soc_perf/test/testutil/BUILD.gn b/soc_perf/test/testutil/BUILD.gn +deleted file mode 100644 +index a5c9041..0000000 +--- a/soc_perf/test/testutil/BUILD.gn ++++ /dev/null +@@ -1,33 +0,0 @@ +-# Copyright (c) 2022-2023 Huawei Device Co., Ltd. +-# Licensed under the Apache License, Version 2.0 (the "License"); +-# you may not use this file except in compliance with the License. +-# You may obtain a copy of the License at +-# +-# http://www.apache.org/licenses/LICENSE-2.0 +-# +-# Unless required by applicable law or agreed to in writing, software +-# distributed under the License is distributed on an "AS IS" BASIS, +-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-# See the License for the specific language governing permissions and +-# limitations under the License. +- +-import("//build/test.gni") +-import("../../soc_perf.gni") +- +-ohos_executable("socperf_test") { +- sources = [ "socperf_test.cpp" ] +- +- deps = [ "${socperf_interfaces}/inner_api/socperf_client:socperf_client" ] +- +- external_deps = [ +- "c_utils:utils", +- "eventhandler:libeventhandler", +- "hiviewdfx_hilog_native:libhilog", +- "ipc:ipc_single", +- "safwk:system_ability_fwk", +- "samgr:samgr_proxy", +- ] +- +- part_name = "soc_perf" +- subsystem_name = "resourceschedule" +-} +diff --git a/soc_perf/test/testutil/socperf_test.cpp b/soc_perf/test/testutil/socperf_test.cpp +deleted file mode 100644 +index 2ea5559..0000000 +--- a/soc_perf/test/testutil/socperf_test.cpp ++++ /dev/null +@@ -1,110 +0,0 @@ +-/* +- * Copyright (c) 2022-2023 Huawei Device Co., Ltd. +- * Licensed under the Apache License, Version 2.0 (the "License"); +- * you may not use this file except in compliance with the License. +- * You may obtain a copy of the License at +- * +- * http://www.apache.org/licenses/LICENSE-2.0 +- * +- * Unless required by applicable law or agreed to in writing, software +- * distributed under the License is distributed on an "AS IS" BASIS, +- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +- * See the License for the specific language governing permissions and +- * limitations under the License. +- */ +- +- +-#include // for int32_t +-#include // for atoi +-#include // for vector +-#include // for strcmp +-#include "socperf_client.h" // for SocPerfClient +- +-const static int32_t PARAMETERS_NUM_MIN = 2; +-const static int32_t PARAMETERS_NUM_WITHOUT_EX = 3; +-const static int32_t PARAMETERS_NUM_WITH_EX = 4; +-const static int32_t PARAMETERS_NUM_LIMIT = 5; +- +-static void PerfRequest(int32_t argc, char *argv[]) +-{ +- if (argc == PARAMETERS_NUM_WITHOUT_EX) { +- char* cmdId = argv[2]; +- if (cmdId) { +- OHOS::SOCPERF::SocPerfClient::GetInstance().PerfRequest(atoi(cmdId), ""); +- } +- } +-} +- +-static void PerfRequestEx(int32_t argc, char *argv[]) +-{ +- if (argc == PARAMETERS_NUM_WITH_EX) { +- char* cmdId = argv[2]; +- char* onOffTag = argv[3]; +- if (cmdId && onOffTag) { +- if (strcmp(onOffTag, "true") == 0) { +- OHOS::SOCPERF::SocPerfClient::GetInstance().PerfRequestEx(atoi(cmdId), true, ""); +- } else if (strcmp(onOffTag, "false") == 0) { +- OHOS::SOCPERF::SocPerfClient::GetInstance().PerfRequestEx(atoi(cmdId), false, ""); +- } +- } +- } +-} +- +-static void PowerLimitBoost(int32_t argc, char *argv[]) +-{ +- if (argc == PARAMETERS_NUM_WITHOUT_EX) { +- char* onOffTag = argv[2]; +- if (onOffTag) { +- if (strcmp(onOffTag, "true") == 0) { +- OHOS::SOCPERF::SocPerfClient::GetInstance().PowerLimitBoost(true, ""); +- } else if (strcmp(onOffTag, "false") == 0) { +- OHOS::SOCPERF::SocPerfClient::GetInstance().PowerLimitBoost(false, ""); +- } +- } +- } +-} +- +-static void ThermalLimitBoost(int32_t argc, char *argv[]) +-{ +- if (argc == PARAMETERS_NUM_WITHOUT_EX) { +- char* onOffTag = argv[2]; +- if (onOffTag) { +- if (strcmp(onOffTag, "true") == 0) { +- OHOS::SOCPERF::SocPerfClient::GetInstance().ThermalLimitBoost(true, ""); +- } else if (strcmp(onOffTag, "false") == 0) { +- OHOS::SOCPERF::SocPerfClient::GetInstance().ThermalLimitBoost(false, ""); +- } +- } +- } +-} +- +-static void LimitRequest(int32_t argc, char *argv[]) +-{ +- if (argc == PARAMETERS_NUM_LIMIT) { +- char* clientId = argv[2]; +- char* tags = argv[3]; +- char* configs = argv[4]; +- std::vector tagsVector = { atoi(tags) }; +- std::vector configsVector = { atoll(configs) }; +- OHOS::SOCPERF::SocPerfClient::GetInstance().LimitRequest(atoi(clientId), tagsVector, configsVector, ""); +- } +-} +- +-int32_t main(int32_t argc, char *argv[]) +-{ +- if (argc >= PARAMETERS_NUM_MIN && argv) { +- char* function = argv[1]; +- if (strcmp(function, "PerfRequest") == 0) { +- PerfRequest(argc, argv); +- } else if (strcmp(function, "PerfRequestEx") == 0) { +- PerfRequestEx(argc, argv); +- } else if (strcmp(function, "PowerLimitBoost") == 0) { +- PowerLimitBoost(argc, argv); +- } else if (strcmp(function, "ThermalLimitBoost") == 0) { +- ThermalLimitBoost(argc, argv); +- } else if (strcmp(function, "LimitRequest") == 0) { +- LimitRequest(argc, argv); +- } +- } +- return 0; +-} +diff --git a/soc_perf/test/unittest/BUILD.gn b/soc_perf/test/unittest/BUILD.gn +deleted file mode 100644 +index 6540071..0000000 +--- a/soc_perf/test/unittest/BUILD.gn ++++ /dev/null +@@ -1,84 +0,0 @@ +-# Copyright (c) 2022-2023 Huawei Device Co., Ltd. +-# Licensed under the Apache License, Version 2.0 (the "License"); +-# you may not use this file except in compliance with the License. +-# You may obtain a copy of the License at +-# +-# http://www.apache.org/licenses/LICENSE-2.0 +-# +-# Unless required by applicable law or agreed to in writing, software +-# distributed under the License is distributed on an "AS IS" BASIS, +-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-# See the License for the specific language governing permissions and +-# limitations under the License. +- +-import("//build/test.gni") +-import("../../soc_perf.gni") +- +-module_output_path = "soc_perf/socperftest" +- +-config("module_private_config") { +- visibility = [ ":*" ] +- +- include_dirs = [ +- "${socperf_common}/include", +- "${socperf_interfaces}/inner_api/socperf_client/include", +- "${socperf_services}/core/include", +- ] +-} +- +-ohos_unittest("SocPerfSubTest") { +- module_out_path = module_output_path +- +- sources = [ "socperf_sub_test.cpp" ] +- +- configs = [ ":module_private_config" ] +- +- deps = [ +- "${socperf_interfaces}/inner_api/socperf_client:socperf_client", +- "//third_party/googletest:gtest_main", +- "//third_party/libxml2:xml2", +- ] +- +- external_deps = [ +- "c_utils:utils", +- "eventhandler:libeventhandler", +- "hiviewdfx_hilog_native:libhilog", +- "ipc:ipc_single", +- "safwk:system_ability_fwk", +- "samgr:samgr_proxy", +- ] +-} +- +-ohos_unittest("SocPerfSubMockTest") { +- module_out_path = module_output_path +- +- sources = [ +- "mock/mock_socperf_client.cpp", +- "socperf_sub_mock_test.cpp", +- ] +- +- configs = [ ":module_private_config" ] +- +- deps = [ +- "${socperf_interfaces}/inner_api/socperf_client:socperf_client", +- "//third_party/googletest:gtest_main", +- "//third_party/libxml2:xml2", +- ] +- +- external_deps = [ +- "c_utils:utils", +- "eventhandler:libeventhandler", +- "hiviewdfx_hilog_native:libhilog", +- "ipc:ipc_single", +- "safwk:system_ability_fwk", +- "samgr:samgr_proxy", +- ] +-} +- +-group("unittest") { +- testonly = true +- deps = [ +- ":SocPerfSubMockTest", +- ":SocPerfSubTest", +- ] +-} +diff --git a/soc_perf/test/unittest/mock/mock_socperf_client.cpp b/soc_perf/test/unittest/mock/mock_socperf_client.cpp +deleted file mode 100644 +index 4081bc9..0000000 +--- a/soc_perf/test/unittest/mock/mock_socperf_client.cpp ++++ /dev/null +@@ -1,25 +0,0 @@ +-/* +- * Copyright (c) 2022 Huawei Device Co., Ltd. +- * Licensed under the Apache License, Version 2.0 (the "License"); +- * you may not use this file except in compliance with the License. +- * You may obtain a copy of the License at +- * +- * http://www.apache.org/licenses/LICENSE-2.0 +- * +- * Unless required by applicable law or agreed to in writing, software +- * distributed under the License is distributed on an "AS IS" BASIS, +- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +- * See the License for the specific language governing permissions and +- * limitations under the License. +- */ +- +-#define private public +-#include "socperf_client.h" +-namespace OHOS { +-namespace SOCPERF { +-bool SocPerfClient::CheckClientValid() +-{ +- return false; +-} +-} // namespace SOCPERF +-} // namespace OHOS +\ No newline at end of file +diff --git a/soc_perf/test/unittest/socperf_sub_mock_test.cpp b/soc_perf/test/unittest/socperf_sub_mock_test.cpp +deleted file mode 100644 +index 1da0c75..0000000 +--- a/soc_perf/test/unittest/socperf_sub_mock_test.cpp ++++ /dev/null +@@ -1,139 +0,0 @@ +-/* +- * Copyright (c) 2022 Huawei Device Co., Ltd. +- * Licensed under the Apache License, Version 2.0 (the "License"); +- * you may not use this file except in compliance with the License. +- * You may obtain a copy of the License at +- * +- * http://www.apache.org/licenses/LICENSE-2.0 +- * +- * Unless required by applicable law or agreed to in writing, software +- * distributed under the License is distributed on an "AS IS" BASIS, +- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +- * See the License for the specific language governing permissions and +- * limitations under the License. +- */ +- +-#define private public +-#define protected public +-#undef private +-#undef protected +- +-#include +-#include "socperf_client.h" +-#include "socperf.h" +-#include "iservice_registry.h" +-#include "system_ability_definition.h" +- +-using namespace testing::ext; +- +-namespace OHOS { +-namespace SOCPERF { +-class SocPerfSubTest : public testing::Test { +-public: +- static void SetUpTestCase(void); +- static void TearDownTestCase(void); +- void SetUp(); +- void TearDown(); +-}; +- +-void SocPerfSubTest::SetUpTestCase(void) +-{ +-} +- +-void SocPerfSubTest::TearDownTestCase(void) +-{ +-} +- +-void SocPerfSubTest::SetUp(void) +-{ +-} +- +-void SocPerfSubTest::TearDown(void) +-{ +-} +- +-/* +- * @tc.name: SocPerfSubTest_PerfRequest_001 +- * @tc.desc: PerfRequest +- * @tc.type FUNC +- * @tc.require: issueI78T3V +- */ +-HWTEST_F(SocPerfSubTest, SocPerfSubTest_PerfRequest_001, Function | MediumTest | Level0) +-{ +- OHOS::SOCPERF::SocPerfClient::GetInstance().PerfRequest(10000, ""); +- OHOS::SOCPERF::SocPerfClient::GetInstance().PerfRequest(10000, "123"); +-} +- +-/* +- * @tc.name: SocPerfSubTest_PerfRequest_002 +- * @tc.desc: PerfRequestEx ON +- * @tc.type FUNC +- * @tc.require: issueI78T3V +- */ +-HWTEST_F(SocPerfSubTest, SocPerfSubTest_PerfRequest_002, Function | MediumTest | Level0) +-{ +- OHOS::SOCPERF::SocPerfClient::GetInstance().PerfRequestEx(10000, true, ""); +- OHOS::SOCPERF::SocPerfClient::GetInstance().PerfRequestEx(10000, true, "123"); +-} +- +-/* +- * @tc.name: SocPerfSubTest_PerfRequest_003 +- * @tc.desc: PerfRequestEx OFF +- * @tc.type FUNC +- * @tc.require: issueI78T3V +- */ +-HWTEST_F(SocPerfSubTest, SocPerfSubTest_PerfRequest_003, Function | MediumTest | Level0) +-{ +- OHOS::SOCPERF::SocPerfClient::GetInstance().PerfRequestEx(10000, false, ""); +- OHOS::SOCPERF::SocPerfClient::GetInstance().PerfRequestEx(10000, false, "123"); +-} +- +-/* +- * @tc.name: SocPerfSubTest_PowerLimitBoost_001 +- * @tc.desc: PowerLimitBoost ON +- * @tc.type FUNC +- * @tc.require: issueI78T3V +- */ +-HWTEST_F(SocPerfSubTest, SocPerfSubTest_PowerLimitBoost_001, Function | MediumTest | Level0) +-{ +- OHOS::SOCPERF::SocPerfClient::GetInstance().PowerLimitBoost(true, ""); +- OHOS::SOCPERF::SocPerfClient::GetInstance().PowerLimitBoost(true, "123"); +-} +- +-/* +- * @tc.name: SocPerfSubTest_PowerLimitBoost_001 +- * @tc.desc: PowerLimitBoost OFF +- * @tc.type FUNC +- * @tc.require: issueI78T3V +- */ +-HWTEST_F(SocPerfSubTest, SocPerfSubTest_PowerLimitBoost_002, Function | MediumTest | Level0) +-{ +- OHOS::SOCPERF::SocPerfClient::GetInstance().PowerLimitBoost(false, ""); +- OHOS::SOCPERF::SocPerfClient::GetInstance().PowerLimitBoost(false, "123"); +-} +- +-/* +- * @tc.name: SocPerfSubTest_ThermalLimitBoost_001 +- * @tc.desc: ThermalLimitBoost ON +- * @tc.type FUNC +- * @tc.require: issueI78T3V +- */ +-HWTEST_F(SocPerfSubTest, SocPerfSubTest_ThermalLimitBoost_001, Function | MediumTest | Level0) +-{ +- OHOS::SOCPERF::SocPerfClient::GetInstance().ThermalLimitBoost(true, ""); +- OHOS::SOCPERF::SocPerfClient::GetInstance().ThermalLimitBoost(true, "123"); +-} +- +-/* +- * @tc.name: SocPerfSubTest_ThermalLimitBoost_002 +- * @tc.desc: ThermalLimitBoost OFF +- * @tc.type FUNC +- * @tc.require: issueI78T3V +- */ +-HWTEST_F(SocPerfSubTest, SocPerfSubTest_ThermalLimitBoost_002, Function | MediumTest | Level0) +-{ +- OHOS::SOCPERF::SocPerfClient::GetInstance().ThermalLimitBoost(false, ""); +- OHOS::SOCPERF::SocPerfClient::GetInstance().ThermalLimitBoost(false, "123"); +-} +-} // namespace SOCPERF +-} // namespace OHOS +\ No newline at end of file +diff --git a/soc_perf/test/unittest/socperf_sub_test.cpp b/soc_perf/test/unittest/socperf_sub_test.cpp +deleted file mode 100644 +index 9312e64..0000000 +--- a/soc_perf/test/unittest/socperf_sub_test.cpp ++++ /dev/null +@@ -1,361 +0,0 @@ +-/* +- * Copyright (c) 2022 Huawei Device Co., Ltd. +- * Licensed under the Apache License, Version 2.0 (the "License"); +- * you may not use this file except in compliance with the License. +- * You may obtain a copy of the License at +- * +- * http://www.apache.org/licenses/LICENSE-2.0 +- * +- * Unless required by applicable law or agreed to in writing, software +- * distributed under the License is distributed on an "AS IS" BASIS, +- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +- * See the License for the specific language governing permissions and +- * limitations under the License. +- */ +- +-#define private public +-#define protected public +-#undef private +-#undef protected +- +-#include +-#include "socperf_client.h" +-#include "socperf.h" +-#include "iservice_registry.h" +-#include "system_ability_definition.h" +- +-using namespace testing::ext; +- +-namespace OHOS { +-namespace SOCPERF { +-class SocPerfSubTest : public testing::Test { +-public: +- static void SetUpTestCase(void); +- static void TearDownTestCase(void); +- void SetUp(); +- void TearDown(); +-}; +- +-void SocPerfSubTest::SetUpTestCase(void) +-{ +-} +- +-void SocPerfSubTest::TearDownTestCase(void) +-{ +-} +- +-void SocPerfSubTest::SetUp(void) +-{ +-} +- +-void SocPerfSubTest::TearDown(void) +-{ +-} +- +-/* +- * @tc.name: SocPerfSubTest_ActionType_001 +- * @tc.desc: action type perf +- * @tc.type FUNC +- * @tc.require: issueI78T3V +- */ +-HWTEST_F(SocPerfSubTest, SocPerfSubTest_ActionType_001, Function | MediumTest | Level0) +-{ +- EXPECT_EQ(OHOS::SOCPERF::ActionType::ACTION_TYPE_PERF, 0); +-} +- +-/* +- * @tc.name: SocPerfSubTest_ActionType_002 +- * @tc.desc: action type power +- * @tc.type FUNC +- * @tc.require: issueI78T3V +- */ +-HWTEST_F(SocPerfSubTest, SocPerfSubTest_ActionType_002, Function | MediumTest | Level0) +-{ +- EXPECT_EQ(OHOS::SOCPERF::ActionType::ACTION_TYPE_POWER, 1); +-} +- +-/* +- * @tc.name: SocPerfSubTest_ActionType_003 +- * @tc.desc: action type THERMAL +- * @tc.type FUNC +- * @tc.require: issueI78T3V +- */ +-HWTEST_F(SocPerfSubTest, SocPerfSubTest_ActionType_003, Function | MediumTest | Level0) +-{ +- EXPECT_EQ(OHOS::SOCPERF::ActionType::ACTION_TYPE_THERMAL, 2); +-} +- +-/* +- * @tc.name: SocPerfSubTest_ActionType_004 +- * @tc.desc: action type max +- * @tc.type FUNC +- * @tc.require: issueI78T3V +- */ +-HWTEST_F(SocPerfSubTest, SocPerfSubTest_ActionType_004, Function | MediumTest | Level0) +-{ +- EXPECT_EQ(OHOS::SOCPERF::ActionType::ACTION_TYPE_MAX, 3); +-} +- +-/* +- * @tc.name: SocPerfSubTest_EventType_001 +- * @tc.desc: event type off +- * @tc.type FUNC +- * @tc.require: issueI78T3V +- */ +-HWTEST_F(SocPerfSubTest, SocPerfSubTest_EventType_001, Function | MediumTest | Level0) +-{ +- EXPECT_EQ(OHOS::SOCPERF::EventType::EVENT_OFF, 0); +-} +- +-/* +- * @tc.name: SocPerfSubTest_EventType_002 +- * @tc.desc: event type on +- * @tc.type FUNC +- * @tc.require: issueI78T3V +- */ +-HWTEST_F(SocPerfSubTest, SocPerfSubTest_EventType_002, Function | MediumTest | Level0) +-{ +- EXPECT_EQ(OHOS::SOCPERF::EventType::EVENT_ON, 1); +-} +- +-/* +- * @tc.name: SocPerfSubTest_EventType_003 +- * @tc.desc: event type invalid +- * @tc.type FUNC +- * @tc.require: issueI78T3V +- */ +-HWTEST_F(SocPerfSubTest, SocPerfSubTest_EventType_003, Function | MediumTest | Level0) +-{ +- EXPECT_EQ(OHOS::SOCPERF::EventType::EVENT_INVALID, -1); +-} +- +-/* +- * @tc.name: SocPerfSubTest_InnerEventId_001 +- * @tc.desc: init res node info +- * @tc.type FUNC +- * @tc.require: issueI78T3V +- */ +-HWTEST_F(SocPerfSubTest, SocPerfSubTest_InnerEventId_001, Function | MediumTest | Level0) +-{ +- EXPECT_EQ(INNER_EVENT_ID_INIT_RES_NODE_INFO, 0); +-} +- +-/* +- * @tc.name: SocPerfSubTest_InnerEventId_002 +- * @tc.desc: init gov res node info +- * @tc.type FUNC +- * @tc.require: issueI78T3V +- */ +-HWTEST_F(SocPerfSubTest, SocPerfSubTest_InnerEventId_002, Function | MediumTest | Level0) +-{ +- EXPECT_EQ(INNER_EVENT_ID_INIT_GOV_RES_NODE_INFO, 1); +-} +- +-/* +- * @tc.name: SocPerfSubTest_InnerEventId_003 +- * @tc.desc: do freq action +- * @tc.type FUNC +- * @tc.require: issueI78T3V +- */ +-HWTEST_F(SocPerfSubTest, SocPerfSubTest_InnerEventId_003, Function | MediumTest | Level0) +-{ +- EXPECT_EQ(INNER_EVENT_ID_DO_FREQ_ACTION, 2); +-} +- +-/* +- * @tc.name: SocPerfSubTest_InnerEventId_004 +- * @tc.desc: do freq action delayed +- * @tc.type FUNC +- * @tc.require: issueI78T3V +- */ +-HWTEST_F(SocPerfSubTest, SocPerfSubTest_InnerEventId_004, Function | MediumTest | Level0) +-{ +- EXPECT_EQ(INNER_EVENT_ID_DO_FREQ_ACTION_DELAYED, 4); +-} +- +-/* +- * @tc.name: SocPerfSubTest_InnerEventId_005 +- * @tc.desc: power limit boost freq +- * @tc.type FUNC +- * @tc.require: issueI78T3V +- */ +-HWTEST_F(SocPerfSubTest, SocPerfSubTest_InnerEventId_005, Function | MediumTest | Level0) +-{ +- EXPECT_EQ(INNER_EVENT_ID_POWER_LIMIT_BOOST_FREQ, 5); +-} +- +-/* +- * @tc.name: SocPerfSubTest_InnerEventId_006 +- * @tc.desc: thermal limit boost freq +- * @tc.type FUNC +- * @tc.require: issueI78T3V +- */ +-HWTEST_F(SocPerfSubTest, SocPerfSubTest_InnerEventId_006, Function | MediumTest | Level0) +-{ +- EXPECT_EQ(INNER_EVENT_ID_THERMAL_LIMIT_BOOST_FREQ, 6); +-} +- +-/* +- * @tc.name: SocPerfSubTest_GetService_001 +- * @tc.desc: get socperf service +- * @tc.type FUNC +- * @tc.require: issueI78T3V +- */ +-HWTEST_F(SocPerfSubTest, SocPerfSubTest_GetService_001, Function | MediumTest | Level0) +-{ +- sptr samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); +- EXPECT_NE(samgr, nullptr); +- +- sptr object = samgr->GetSystemAbility(SOC_PERF_SERVICE_SA_ID); +- EXPECT_NE(object, nullptr); +-} +- +-/* +- * @tc.name: SocPerfSubTest_GetService_002 +- * @tc.desc: get socperf service +- * @tc.type FUNC +- * @tc.require: issueI78T3V +- */ +-HWTEST_F(SocPerfSubTest, SocPerfSubTest_GetService_002, Function | MediumTest | Level0) +-{ +- sptr samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); +- EXPECT_NE(samgr, nullptr); +- +- sptr object = samgr->GetSystemAbility(RES_SCHED_SYS_ABILITY_ID); +- EXPECT_NE(object, nullptr); +-} +- +-/* +- * @tc.name: SocPerfSubTest_PerfRequest_001 +- * @tc.desc: PerfRequest +- * @tc.type FUNC +- * @tc.require: issueI78T3V +- */ +-HWTEST_F(SocPerfSubTest, SocPerfSubTest_PerfRequest_001, Function | MediumTest | Level0) +-{ +- OHOS::SOCPERF::SocPerfClient::GetInstance().PerfRequest(10000, ""); +-} +- +-/* +- * @tc.name: SocPerfSubTest_PerfRequest_002 +- * @tc.desc: PerfRequestEx ON +- * @tc.type FUNC +- * @tc.require: issueI78T3V +- */ +-HWTEST_F(SocPerfSubTest, SocPerfSubTest_PerfRequest_002, Function | MediumTest | Level0) +-{ +- OHOS::SOCPERF::SocPerfClient::GetInstance().PerfRequestEx(10000, true, ""); +-} +- +-/* +- * @tc.name: SocPerfSubTest_PerfRequest_003 +- * @tc.desc: PerfRequestEx OFF +- * @tc.type FUNC +- * @tc.require: issueI78T3V +- */ +-HWTEST_F(SocPerfSubTest, SocPerfSubTest_PerfRequest_003, Function | MediumTest | Level0) +-{ +- OHOS::SOCPERF::SocPerfClient::GetInstance().PerfRequestEx(10000, false, ""); +-} +- +-/* +- * @tc.name: SocPerfSubTest_PowerLimitBoost_001 +- * @tc.desc: PowerLimitBoost ON +- * @tc.type FUNC +- * @tc.require: issueI78T3V +- */ +-HWTEST_F(SocPerfSubTest, SocPerfSubTest_PowerLimitBoost_001, Function | MediumTest | Level0) +-{ +- OHOS::SOCPERF::SocPerfClient::GetInstance().PowerLimitBoost(true, ""); +-} +- +-/* +- * @tc.name: SocPerfSubTest_PowerLimitBoost_001 +- * @tc.desc: PowerLimitBoost OFF +- * @tc.type FUNC +- * @tc.require: issueI78T3V +- */ +-HWTEST_F(SocPerfSubTest, SocPerfSubTest_PowerLimitBoost_002, Function | MediumTest | Level0) +-{ +- OHOS::SOCPERF::SocPerfClient::GetInstance().PowerLimitBoost(false, ""); +-} +- +-/* +- * @tc.name: SocPerfSubTest_ThermalLimitBoost_001 +- * @tc.desc: ThermalLimitBoost ON +- * @tc.type FUNC +- * @tc.require: issueI78T3V +- */ +-HWTEST_F(SocPerfSubTest, SocPerfSubTest_ThermalLimitBoost_001, Function | MediumTest | Level0) +-{ +- OHOS::SOCPERF::SocPerfClient::GetInstance().ThermalLimitBoost(true, ""); +-} +- +-/* +- * @tc.name: SocPerfSubTest_ThermalLimitBoost_002 +- * @tc.desc: ThermalLimitBoost OFF +- * @tc.type FUNC +- * @tc.require: issueI78T3V +- */ +-HWTEST_F(SocPerfSubTest, SocPerfSubTest_ThermalLimitBoost_002, Function | MediumTest | Level0) +-{ +- OHOS::SOCPERF::SocPerfClient::GetInstance().ThermalLimitBoost(false, ""); +-} +- +-/* +- * @tc.name: SocPerfSubTest_LimitRequest_001 +- * @tc.desc: LimitRequest thermal +- * @tc.type FUNC +- * @tc.require: issueI78T3V +- */ +-HWTEST_F(SocPerfSubTest, SocPerfSubTest_LimitRequest_001, Function | MediumTest | Level0) +-{ +- int32_t clientId_power = ACTION_TYPE_POWER; +- std::vector tags; +- tags.push_back(1001); +- std::vector configs; +- EXPECT_NE(tags.size(), configs.size()); +- configs.push_back(1608000); +- EXPECT_EQ(tags.size(), configs.size()); +- OHOS::SOCPERF::SocPerfClient::GetInstance().LimitRequest(clientId_power, tags, configs, ""); +-} +- +-/* +- * @tc.name: SocPerfSubTest_LimitRequest_002 +- * @tc.desc: LimitRequest thermal +- * @tc.type FUNC +- * @tc.require: issueI78T3V +- */ +-HWTEST_F(SocPerfSubTest, SocPerfSubTest_LimitRequest_002, Function | MediumTest | Level0) +-{ +- int32_t clientId_thermal = ACTION_TYPE_THERMAL; +- std::vector tags; +- tags.push_back(1000); +- tags.push_back(1001); +- std::vector configs; +- EXPECT_NE(tags.size(), configs.size()); +- configs.push_back(1800000); +- configs.push_back(1992000); +- EXPECT_EQ(tags.size(), configs.size()); +- OHOS::SOCPERF::SocPerfClient::GetInstance().LimitRequest(clientId_thermal, tags, configs, ""); +-} +- +-/* +- * @tc.name: SocPerfSubTest_ResetClient_001 +- * @tc.desc: ResetClient +- * @tc.type FUNC +- * @tc.require: issueI78T3V +- */ +-HWTEST_F(SocPerfSubTest, SocPerfSubTest_ResetClient_001, Function | MediumTest | Level0) +-{ +- OHOS::SOCPERF::SocPerfClient::GetInstance().PerfRequest(10000, ""); +- OHOS::SOCPERF::SocPerfClient::GetInstance().PerfRequestEx(10000, true, ""); +- OHOS::SOCPERF::SocPerfClient::GetInstance().PerfRequestEx(10000, false, ""); +- OHOS::SOCPERF::SocPerfClient::GetInstance().PowerLimitBoost(true, ""); +- OHOS::SOCPERF::SocPerfClient::GetInstance().PowerLimitBoost(false, ""); +- OHOS::SOCPERF::SocPerfClient::GetInstance().ThermalLimitBoost(true, ""); +- OHOS::SOCPERF::SocPerfClient::GetInstance().ThermalLimitBoost(false, ""); +- OHOS::SOCPERF::SocPerfClient::GetInstance().ResetClient(); +-} +-} // namespace SOCPERF +-} // namespace OHOS