diff --git a/application/protector/include/thermal_sensor_provider.h b/application/protector/include/thermal_sensor_provider.h index ef75ecbd7430b5c5cfbbe693d80b16cc62f7acb2..1a4619c1f5efac036f0c34e58b6d4c3a824194ff 100644 --- a/application/protector/include/thermal_sensor_provider.h +++ b/application/protector/include/thermal_sensor_provider.h @@ -23,11 +23,11 @@ #include "thermal_zone_manager.h" #include "thermal_simulation_node.h" -#include "v1_0/thermal_types.h" +#include "v1_1/thermal_types.h" namespace OHOS { namespace PowerMgr { -using namespace OHOS::HDI::Thermal::V1_0; +using namespace OHOS::HDI::Thermal::V1_1; using SensorsMap = std::map; enum EventType { EVENT_UEVENT_FD, diff --git a/services/BUILD.gn b/services/BUILD.gn index 6c51f80d2170d6bfc0d7c44e04c39434fb194e3a..ed2f86f30128a7c6625e226ba4cef9077230c41c 100644 --- a/services/BUILD.gn +++ b/services/BUILD.gn @@ -32,6 +32,7 @@ config("thermalsrv_public_config") { ohos_shared_library("thermalservice") { sources = [ + "native/src/fan_callback.cpp", "native/src/thermal_action/action/action_application_process.cpp", "native/src/thermal_action/action/action_charger.cpp", "native/src/thermal_action/action/action_display.cpp", @@ -39,6 +40,7 @@ ohos_shared_library("thermalservice") { "native/src/thermal_action/action/action_shutdown.cpp", "native/src/thermal_action/action/action_soc/action_cpu_big.cpp", "native/src/thermal_action/action/action_soc/action_cpu_boost.cpp", + "native/src/thermal_action/action/action_soc/action_cpu_isolate.cpp", "native/src/thermal_action/action/action_soc/action_cpu_lit.cpp", "native/src/thermal_action/action/action_soc/action_cpu_med.cpp", "native/src/thermal_action/action/action_soc/action_gpu.cpp", @@ -60,6 +62,7 @@ ohos_shared_library("thermalservice") { "native/src/thermal_observer/thermal_observer.cpp", "native/src/thermal_observer/thermal_sensor_info.cpp", "native/src/thermal_observer/thermal_service_subscriber.cpp", + "native/src/thermal_policy/fan_fault_detect.cpp", "native/src/thermal_policy/thermal_config_base_info.cpp", "native/src/thermal_policy/thermal_config_sensor_cluster.cpp", "native/src/thermal_policy/thermal_policy.cpp", @@ -99,7 +102,7 @@ ohos_shared_library("thermalservice") { "config_policy:configpolicy_util", "display_manager:displaymgr", "drivers_interface_battery:libbattery_proxy_1.2", - "drivers_interface_thermal:libthermal_proxy_1.0", + "drivers_interface_thermal:libthermal_proxy_1.1", "ffrt:libffrt", "hdf_core:libhdi", "hdf_core:libpub_utils", diff --git a/services/native/include/fan_callback.h b/services/native/include/fan_callback.h new file mode 100644 index 0000000000000000000000000000000000000000..339e60d6803f36c6c04bbaa7381169ce1403de8c --- /dev/null +++ b/services/native/include/fan_callback.h @@ -0,0 +1,37 @@ +/* + * 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 FAN_CALLBACK_H +#define FAN_CALLBACK_H + +#include +#include "v1_1/ifan_callback.h" +#include "v1_1/thermal_types.h" + +namespace OHOS { +namespace PowerMgr { +using namespace OHOS::HDI::Thermal::V1_1; +class FanCallback : public IFanCallback { +public: + virtual ~FanCallback() {} + using FanEventCallback = std::function; + static int32_t RegisterFanEvent(const FanEventCallback &eventCb); + int32_t OnFanDataEvent(const HdfThermalCallbackInfo& event) override; +private: + static FanEventCallback eventCb_; +}; +} // OHOS +} // PowerMgr +#endif // FAN_CALLBACK_H diff --git a/services/native/include/thermal_action/action/action_cpu_isolate.h b/services/native/include/thermal_action/action/action_cpu_isolate.h new file mode 100644 index 0000000000000000000000000000000000000000..bc893e55b0b6c8befc3ac00b8f98e946f12713a5 --- /dev/null +++ b/services/native/include/thermal_action/action/action_cpu_isolate.h @@ -0,0 +1,42 @@ +/* + * 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 ACTION_CPU_ISOLATE_H +#define ACTION_CPU_ISOLATE_H + +#include "soc_action_base.h" + +namespace OHOS { +namespace PowerMgr { +class ActionCpuIsolate : public IThermalAction { +public: + ActionCpuIsolate(const std::string& actionName); + ~ActionCpuIsolate() = default; + + void InitParams(const std::string& params) override; + void SetStrict(bool enable) override; + void SetEnableEvent(bool enable) override; + void AddActionValue(std::string value) override; + void Execute() override; + +private: + void RequestCpuIsolate(uint32_t isolateNum); + uint32_t GetActionValue(); + uint32_t lastValue_ {0}; + std::vector valueList_; +}; +} // namespace PowerMgr +} // namespace OHOS +#endif // ACTION_CPU_ISOLATE_H diff --git a/services/native/include/thermal_action/action/action_soc/action_cpu_isolate.h b/services/native/include/thermal_action/action/action_soc/action_cpu_isolate.h new file mode 100644 index 0000000000000000000000000000000000000000..bc893e55b0b6c8befc3ac00b8f98e946f12713a5 --- /dev/null +++ b/services/native/include/thermal_action/action/action_soc/action_cpu_isolate.h @@ -0,0 +1,42 @@ +/* + * 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 ACTION_CPU_ISOLATE_H +#define ACTION_CPU_ISOLATE_H + +#include "soc_action_base.h" + +namespace OHOS { +namespace PowerMgr { +class ActionCpuIsolate : public IThermalAction { +public: + ActionCpuIsolate(const std::string& actionName); + ~ActionCpuIsolate() = default; + + void InitParams(const std::string& params) override; + void SetStrict(bool enable) override; + void SetEnableEvent(bool enable) override; + void AddActionValue(std::string value) override; + void Execute() override; + +private: + void RequestCpuIsolate(uint32_t isolateNum); + uint32_t GetActionValue(); + uint32_t lastValue_ {0}; + std::vector valueList_; +}; +} // namespace PowerMgr +} // namespace OHOS +#endif // ACTION_CPU_ISOLATE_H diff --git a/services/native/include/thermal_callback.h b/services/native/include/thermal_callback.h index c0e8c592228270e2470a2404c530da906e4df55c..60ea80f398b7c56bf9cbe9d8f99ad8fa8094f530 100644 --- a/services/native/include/thermal_callback.h +++ b/services/native/include/thermal_callback.h @@ -17,12 +17,12 @@ #define POWERMGR_THERMAL_MANAGER_THERMAL_CALLBACK_H #include -#include "v1_0/ithermal_callback.h" -#include "v1_0/thermal_types.h" +#include "v1_1/ithermal_callback.h" +#include "v1_1/thermal_types.h" namespace OHOS { namespace PowerMgr { -using namespace OHOS::HDI::Thermal::V1_0; +using namespace OHOS::HDI::Thermal::V1_1; class ThermalCallback : public IThermalCallback { public: virtual ~ThermalCallback() {} diff --git a/services/native/include/thermal_policy/fan_fault_detect.h b/services/native/include/thermal_policy/fan_fault_detect.h new file mode 100644 index 0000000000000000000000000000000000000000..b20f9ade1a5c35ca181b642d87777d2fd6106be0 --- /dev/null +++ b/services/native/include/thermal_policy/fan_fault_detect.h @@ -0,0 +1,56 @@ +/* + * 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 FAN_FAULT_DETECT_H +#define FAN_FAULT_DETECT_H + +#include +#include +#include + +namespace OHOS { +namespace PowerMgr { + +enum { + FAN_FAULT_OK = 0, + FAN_FAULT_TOO_SLOW, + FAN_FAULT_TOO_FAST, +}; + +using FanSensorInfo = std::map; +using FanFaultInfoMap = std::map; + +class FanFaultDetect { +public: + FanFaultDetect() = default; + ~FanFaultDetect() = default; + + void OnFanSensorInfoChanged(const FanSensorInfo& report); + void SetFaultInfoMap(FanFaultInfoMap& map); + bool HasFanConfig(); + +private: + void CheckFanFault(const FanSensorInfo& report); + void CheckFanTooSlow(const FanSensorInfo& report, const FanSensorInfo& config); + void CheckFanTooFast(const FanSensorInfo& report, const FanSensorInfo& config); + bool CheckFanSensorInfo(const FanSensorInfo& report, const FanSensorInfo& config); + int32_t GetSensorValue(const FanSensorInfo& map, const std::string& name); + std::string FormatReportInfo(const FanSensorInfo& report, const FanSensorInfo& config); + + FanFaultInfoMap fanFaultInfoMap_; +}; +} // namespace PowerMgr +} // namespace OHOS +#endif // FAN_FAULT_DETECT_H diff --git a/services/native/include/thermal_policy/thermal_srv_config_parser.h b/services/native/include/thermal_policy/thermal_srv_config_parser.h index 56ce00a6b4eb797f4808c2727cfb6bea74a0de8b..3565bfc6faf1662d5b712c699f46d4778b3c4308 100644 --- a/services/native/include/thermal_policy/thermal_srv_config_parser.h +++ b/services/native/include/thermal_policy/thermal_srv_config_parser.h @@ -19,6 +19,7 @@ #include #include #include +#include "fan_fault_detect.h" #include "thermal_action_manager.h" #include "thermal_config_sensor_cluster.h" #include "thermal_policy.h" @@ -55,6 +56,9 @@ private: std::vector& sensors, const uint32_t sensorIdx); bool ParseActionInfo(const xmlNodePtr& cur, ActionItem& ai); bool ParsePolicyActionInfo(const xmlNodePtr& cur, PolicyConfig& policyConfig); + bool ParseFanNode(const xmlNodePtr& cur); + bool ParseFanFaultInfo(const xmlNodePtr& cur, + std::vector &sensors, FanFaultInfoMap &fanFaultInfoMap); }; } // namespace PowerMgr } // namespace OHOS diff --git a/services/native/include/thermal_service.h b/services/native/include/thermal_service.h index 12fdb3731d08cdedbc723935c36ec49c83122848..ea5a9d6af6b11e6654fb9cd1246a4b2b7a48025b 100644 --- a/services/native/include/thermal_service.h +++ b/services/native/include/thermal_service.h @@ -23,6 +23,8 @@ #include "system_ability.h" #include "action_popup.h" +#include "fan_callback.h" +#include "fan_fault_detect.h" #include "ithermal_level_callback.h" #include "ithermal_temp_callback.h" #include "thermal_srv_sensor_info.h" @@ -37,13 +39,13 @@ #include "thermal_policy.h" #include "thermal_sensor_info.h" #include "thermal_service_subscriber.h" -#include "v1_0/ithermal_interface.h" -#include "v1_0/thermal_types.h" +#include "v1_1/ithermal_interface.h" +#include "v1_1/thermal_types.h" namespace OHOS { namespace PowerMgr { using TypeTempMap = std::map; -using namespace OHOS::HDI::Thermal::V1_0; +using namespace OHOS::HDI::Thermal::V1_1; using namespace OHOS::HDI::ServiceManager::V1_0; class ThermalService final : public SystemAbility, public ThermalSrvStub { DECLARE_SYSTEM_ABILITY(ThermalService); @@ -69,6 +71,7 @@ public: virtual std::string ShellDump(const std::vector& args, uint32_t argc) override; int32_t HandleThermalCallbackEvent(const HdfThermalCallbackInfo& event); + int32_t HandleFanCallbackEvent(const HdfThermalCallbackInfo& event); void SetFlag(bool flag) { @@ -134,6 +137,11 @@ public: isSimulation_ = isSimulation; } + std::shared_ptr GetFanFaultDetect() const + { + return fanFaultDetect_; + } + std::string GetScene() { return scene_; @@ -159,6 +167,7 @@ private: bool CreateConfigModule(); void RegisterHdiStatusListener(); void RegisterThermalHdiCallback(); + void RegisterFanHdiCallback(); void RegisterBootCompletedCallback(); bool ready_ {false}; static std::atomic_bool isBootCompleted_; @@ -171,6 +180,7 @@ private: std::shared_ptr baseInfo_ {nullptr}; std::shared_ptr state_ {nullptr}; std::shared_ptr actionMgr_ {nullptr}; + std::shared_ptr fanFaultDetect_ {nullptr}; bool flag_ {false}; sptr thermalInterface_ {nullptr}; sptr hdiServiceMgr_ {nullptr}; diff --git a/services/native/profile/thermal_service_config.xml b/services/native/profile/thermal_service_config.xml index 89ab992d5ce816a00e00a95f78fb81a11a0d27e9..d5ba2bc722776e0ffc3876ec24040edd37b3beee 100644 --- a/services/native/profile/thermal_service_config.xml +++ b/services/native/profile/thermal_service_config.xml @@ -61,6 +61,7 @@ + @@ -96,6 +97,7 @@ 3000 1.0 1 + 0 0.90 @@ -118,6 +120,7 @@ 2000 0.8 1 + 1 0.80 @@ -141,6 +144,7 @@ 0.7 1 0 + 2 0.70 @@ -171,6 +175,13 @@ + + + + + + + 1 80 diff --git a/services/native/src/fan_callback.cpp b/services/native/src/fan_callback.cpp new file mode 100644 index 0000000000000000000000000000000000000000..871f2acf195e43d8dfc71390de14163d60e91eab --- /dev/null +++ b/services/native/src/fan_callback.cpp @@ -0,0 +1,37 @@ +/* + * 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 "fan_callback.h" + +#include "hdf_base.h" + +namespace OHOS { +namespace PowerMgr { +FanCallback::FanEventCallback FanCallback::eventCb_ = nullptr; +int32_t FanCallback::OnFanDataEvent(const HdfThermalCallbackInfo& event) +{ + if (eventCb_ == nullptr) { + return HDF_FAILURE; + } + return eventCb_(event); +} + +int32_t FanCallback::RegisterFanEvent(const FanEventCallback &eventCb) +{ + eventCb_ = eventCb; + return HDF_SUCCESS; +} +} // OHOS +} // PowerMgr diff --git a/services/native/src/thermal_action/action/action_soc/action_cpu_isolate.cpp b/services/native/src/thermal_action/action/action_soc/action_cpu_isolate.cpp new file mode 100644 index 0000000000000000000000000000000000000000..cf5000d04837e5902b7a5269864b5539af3e14bf --- /dev/null +++ b/services/native/src/thermal_action/action/action_soc/action_cpu_isolate.cpp @@ -0,0 +1,101 @@ +/* + * 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 "action_cpu_isolate.h" + +#include "constants.h" +#include "thermal_hisysevent.h" +#include "thermal_service.h" + +namespace OHOS { +namespace PowerMgr { +namespace { +auto g_service = DelayedSpSingleton::GetInstance(); +} + +ActionCpuIsolate::ActionCpuIsolate(const std::string& actionName) +{ + actionName_ = actionName; +} + +void ActionCpuIsolate::InitParams(const std::string& params) +{ + (void)params; +} + +void ActionCpuIsolate::SetStrict(bool enable) +{ + isStrict_ = enable; +} + +void ActionCpuIsolate::SetEnableEvent(bool enable) +{ + enableEvent_ = enable; +} + +void ActionCpuIsolate::AddActionValue(std::string value) +{ + if (value.empty()) { + return; + } + valueList_.push_back(static_cast(strtol(value.c_str(), nullptr, STRTOL_FORMART_DEC))); +} + +void ActionCpuIsolate::Execute() +{ + THERMAL_RETURN_IF (g_service == nullptr); + uint32_t value = GetActionValue(); + if (value != lastValue_) { + RequestCpuIsolate(value); + WriteActionTriggeredHiSysEvent(enableEvent_, actionName_, value); + g_service->GetObserver()->SetDecisionValue(actionName_, std::to_string(value)); + lastValue_ = value; + THERMAL_HILOGD(COMP_SVC, "action execute: {%{public}s = %{public}u}", actionName_.c_str(), lastValue_); + } + valueList_.clear(); +} + +uint32_t ActionCpuIsolate::GetActionValue() +{ + std::string scene = g_service->GetScene(); + auto iter = g_sceneMap.find(scene); + if (iter != g_sceneMap.end()) { + return static_cast(strtol(iter->second.c_str(), nullptr, STRTOL_FORMART_DEC)); + } + uint32_t value = FALLBACK_VALUE_UINT_ZERO; + if (!valueList_.empty()) { + if (isStrict_) { + value = *min_element(valueList_.begin(), valueList_.end()); + } else { + value = *max_element(valueList_.begin(), valueList_.end()); + } + } + return value; +} + +void ActionCpuIsolate::RequestCpuIsolate(uint32_t isolateNum) +{ + auto thermalInterface = g_service->GetThermalInterface(); + if (thermalInterface != nullptr) { + int32_t ret = thermalInterface->IsolateCpu(isolateNum); + if (ret != ERR_OK) { + THERMAL_HILOGE(COMP_SVC, "failed to isolate cpu %u to thermal hdi", isolateNum); + return; + } + } + return; +} +} // namespace PowerMgr +} // namespace OHOS diff --git a/services/native/src/thermal_action/thermal_action_factory.cpp b/services/native/src/thermal_action/thermal_action_factory.cpp index cdb5c64a1c5fdb9e1bf95643888ff37e5279e1a4..32caca6ac755d90a3d7e084c722cbde2c33bb241 100644 --- a/services/native/src/thermal_action/thermal_action_factory.cpp +++ b/services/native/src/thermal_action/thermal_action_factory.cpp @@ -19,6 +19,7 @@ #include "action_charger.h" #include "action_cpu_big.h" #include "action_cpu_boost.h" +#include "action_cpu_isolate.h" #include "action_cpu_med.h" #include "action_cpu_lit.h" #include "action_gpu.h" @@ -57,6 +58,8 @@ void ThermalActionFactory::InitFactory() g_actionMap.insert( std::make_pair(VOLATAGE_BUCK_ACTION_NAME, std::make_shared(VOLATAGE_BUCK_ACTION_NAME))); g_actionMap.insert(std::make_pair(CPU_BOOST_ACTION_NAME, std::make_shared(CPU_BOOST_ACTION_NAME))); + g_actionMap.insert(std::make_pair(CPU_ISOLATE_ACTION_NAME, + std::make_shared(CPU_ISOLATE_ACTION_NAME))); std::shared_ptr actionAppProcess = std::make_shared(PROCESS_ACTION_NAME); actionAppProcess->Init(); diff --git a/services/native/src/thermal_policy/fan_fault_detect.cpp b/services/native/src/thermal_policy/fan_fault_detect.cpp new file mode 100644 index 0000000000000000000000000000000000000000..03adf1ca38437dd721ced4bc3a29e3a4d7e9740e --- /dev/null +++ b/services/native/src/thermal_policy/fan_fault_detect.cpp @@ -0,0 +1,140 @@ +/* + * 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 "fan_fault_detect.h" +#include "thermal_hisysevent.h" +#include "thermal_log.h" + +namespace OHOS { +namespace PowerMgr { + +const int32_t SENSOR_INVALID_VALUE = -1; +const std::string FAN = "fan"; + +void FanFaultDetect::OnFanSensorInfoChanged(const FanSensorInfo& report) +{ + CheckFanFault(report); +} + +void FanFaultDetect::CheckFanFault(const FanSensorInfo& report) +{ + for (auto &faultInfo : fanFaultInfoMap_) { + if (faultInfo.first == FAN_FAULT_TOO_SLOW) { + CheckFanTooSlow(report, faultInfo.second); + } else if (faultInfo.first == FAN_FAULT_TOO_FAST) { + CheckFanTooFast(report, faultInfo.second); + } + } +} + +void FanFaultDetect::CheckFanTooSlow(const FanSensorInfo& report, const FanSensorInfo& config) +{ + if (!CheckFanSensorInfo(report, config)) { + return; + } + + bool tempHigh = false; + for (auto &sensorInfo : config) { + if (sensorInfo.first == "fan") { + continue; + } + if (report.at(sensorInfo.first) > sensorInfo.second) { + tempHigh = true; + break; + } + } + if (report.at(FAN) < config.at(FAN) && tempHigh) { + std::string reportInfo = FormatReportInfo(report, config); + THERMAL_HILOGE(COMP_SVC, "fan is slow, %{public}s", reportInfo.c_str()); + WriteFanFaultEvent(FAN_FAULT_TOO_SLOW, reportInfo); + } +} + +void FanFaultDetect::CheckFanTooFast(const FanSensorInfo& report, const FanSensorInfo& config) +{ + if (!CheckFanSensorInfo(report, config)) { + return; + } + + bool tempLow = true; + for (auto &sensorInfo : config) { + if (sensorInfo.first == "fan") { + continue; + } + if (report.at(sensorInfo.first) > sensorInfo.second) { + tempLow = false; + break; + } + } + if ((report.at(FAN) > config.at(FAN)) && tempLow) { + std::string reportInfo = FormatReportInfo(report, config); + THERMAL_HILOGE(COMP_SVC, "fan is fast, %{public}s", reportInfo.c_str()); + WriteFanFaultEvent(FAN_FAULT_TOO_FAST, reportInfo); + } +} + +bool FanFaultDetect::CheckFanSensorInfo(const FanSensorInfo& report, const FanSensorInfo& config) +{ + // must config and report fan speed + if (GetSensorValue(report, "fan") < 0 || GetSensorValue(config, "fan") < 0) { + return false; + } + + for (auto &sensorInfo : config) { + if (sensorInfo.second < 0) { + return false; + } + // config and report info must match + if (GetSensorValue(report, sensorInfo.first) < 0) { + return false; + } + } + + return true; +} + +int32_t FanFaultDetect::GetSensorValue(const FanSensorInfo& map, const std::string& name) +{ + auto iter = map.find(name); + if (iter == map.end()) { + return SENSOR_INVALID_VALUE; + } + + return iter->second; +} + +std::string FanFaultDetect::FormatReportInfo(const FanSensorInfo& report, const FanSensorInfo& config) +{ + std::string reportInfo = "Report"; + for (auto &sensorInfo : config) { + reportInfo += " "; + reportInfo += sensorInfo.first; + reportInfo += ":"; + reportInfo += std::to_string(report.at(sensorInfo.first)); + } + return reportInfo; +} + +bool FanFaultDetect::HasFanConfig() +{ + return !fanFaultInfoMap_.empty(); +} + +void FanFaultDetect::SetFaultInfoMap(FanFaultInfoMap& map) +{ + fanFaultInfoMap_ = map; +} +} // namespace PowerMgr +} // namespace OHOS diff --git a/services/native/src/thermal_policy/thermal_srv_config_parser.cpp b/services/native/src/thermal_policy/thermal_srv_config_parser.cpp index c4eab4ab716fa7b6269efa5f24f6f6d282672553..7b8f709e77175a2a7029bd8323e0d5c389305b58 100644 --- a/services/native/src/thermal_policy/thermal_srv_config_parser.cpp +++ b/services/native/src/thermal_policy/thermal_srv_config_parser.cpp @@ -82,6 +82,8 @@ bool ThermalSrvConfigParser::ParseRootNode(const xmlNodePtr& node) ret = ParsePolicyNode(node); } else if (!xmlStrcmp(node->name, BAD_CAST"idle")) { ret = ParseIdleNode(node); + } else if (!xmlStrcmp(node->name, BAD_CAST"fan")) { + ret = ParseFanNode(node); } else if (!xmlStrcmp(node->name, BAD_CAST"comment")) { ret = true; } else { @@ -611,5 +613,77 @@ bool ThermalSrvConfigParser::ParseIdleNode(const xmlNodePtr& node) g_service->GetStateMachineObj()->SetIdleStateConfig(idleState); return true; } + +bool ThermalSrvConfigParser::ParseFanNode(const xmlNodePtr &node) +{ + FanFaultInfoMap fanFaultInfoMap; + xmlNodePtr cur = node->xmlChildrenNode; + + while (cur != nullptr) { + if (xmlStrcmp(cur->name, BAD_CAST"sensor_cluster")) { + cur = cur->next; + continue; + } + xmlChar* xmlSensor = xmlGetProp(cur, BAD_CAST"sensor"); + if (xmlSensor == nullptr) { + return false; + } + std::vector sensors; + std::string sensorStr = reinterpret_cast(xmlSensor); + StringOperation::SplitString(sensorStr, sensors, ","); + xmlFree(xmlSensor); + if (!ParseFanFaultInfo(cur, sensors, fanFaultInfoMap)) { + THERMAL_HILOGE(COMP_SVC, "ParseFanFaultInfo failed"); + return false; + } + cur = cur->next; + } + + g_service->GetFanFaultDetect()->SetFaultInfoMap(fanFaultInfoMap); + return true; +} + +bool ThermalSrvConfigParser::ParseFanFaultInfo(const xmlNodePtr& node, + std::vector &sensors, FanFaultInfoMap &fanFaultInfoMap) +{ + uint32_t sensorNum = sensors.size(); + xmlNodePtr cur = node->xmlChildrenNode; + + while (cur != nullptr) { + if (xmlStrcmp(cur->name, BAD_CAST"item")) { + cur = cur->next; + continue; + } + FanSensorInfo fanSensorInfo; + xmlChar* xmlFault = xmlGetProp(cur, BAD_CAST"fault"); + if (xmlFault == nullptr) { + return false; + } + std::string faultStr = reinterpret_cast(xmlFault); + xmlFree(xmlFault); + int32_t faultNum; + StrToInt(faultStr, faultNum); + xmlChar* xmlThreshold = xmlGetProp(cur, BAD_CAST"threshold"); + if (xmlThreshold == nullptr) { + return false; + } + std::string thresholdStr = reinterpret_cast(xmlThreshold); + std::vector thresholds; + StringOperation::SplitString(thresholdStr, thresholds, ","); + xmlFree(xmlThreshold); + if (thresholds.size() != sensorNum) { + return false; + } + for (uint32_t i = 0; i < sensorNum; i++) { + int32_t value; + StrToInt(thresholds[i], value); + fanSensorInfo.insert(std::make_pair(sensors[i], value)); + } + fanFaultInfoMap.insert(std::make_pair(faultNum, fanSensorInfo)); + cur = cur->next; + } + + return true; +} } // namespace PowerMgr } // namespace OHOS diff --git a/services/native/src/thermal_service.cpp b/services/native/src/thermal_service.cpp index 9559fb938f0e6cfa0e0c0e2977d110789c60ae08..59576d010e4aac4344286b51ecfae5099add6d2c 100644 --- a/services/native/src/thermal_service.cpp +++ b/services/native/src/thermal_service.cpp @@ -101,11 +101,10 @@ bool ThermalService::Init() if (!CreateConfigModule()) { return false; } - - RegisterHdiStatusListener(); if (!InitModules()) { return false; } + RegisterHdiStatusListener(); THERMAL_HILOGD(COMP_SVC, "Init success"); return true; } @@ -143,6 +142,15 @@ bool ThermalService::CreateConfigModule() return false; } } + + if (!fanFaultDetect_) { + fanFaultDetect_ = std::make_shared(); + if (fanFaultDetect_ == nullptr) { + THERMAL_HILOGE(COMP_SVC, "failed to create fan fault detect"); + return false; + } + } + return true; } @@ -286,6 +294,7 @@ void ThermalService::OnStop() RemoveSystemAbilityListener(COMMON_EVENT_SERVICE_ID); if (thermalInterface_) { thermalInterface_->Unregister(); + thermalInterface_->UnregisterFanCallback(); thermalInterface_ = nullptr; } if (hdiServiceMgr_) { @@ -434,12 +443,14 @@ void ThermalService::RegisterHdiStatusListener() if (status.status == SERVIE_STATUS_START) { FFRTTask task = [this] { - return RegisterThermalHdiCallback(); + RegisterThermalHdiCallback(); + RegisterFanHdiCallback(); }; FFRTUtils::SubmitTask(task); THERMAL_HILOGD(COMP_SVC, "thermal interface service start"); } else if (status.status == SERVIE_STATUS_STOP && thermalInterface_) { thermalInterface_->Unregister(); + thermalInterface_->UnregisterFanCallback(); thermalInterface_ = nullptr; THERMAL_HILOGW(COMP_SVC, "thermal interface service, unregister interface"); } @@ -489,6 +500,40 @@ int32_t ThermalService::HandleThermalCallbackEvent(const HdfThermalCallbackInfo& return ERR_OK; } +void ThermalService::RegisterFanHdiCallback() +{ + if (!fanFaultDetect_->HasFanConfig()) { + return; + } + + if (thermalInterface_ == nullptr) { + thermalInterface_ = IThermalInterface::Get(); + THERMAL_RETURN_IF_WITH_LOG(thermalInterface_ == nullptr, "failed to get thermal hdi interface"); + } + + sptr callback = new FanCallback(); + FanCallback::FanEventCallback eventCb = + std::bind(&ThermalService::HandleFanCallbackEvent, this, std::placeholders::_1); + FanCallback::RegisterFanEvent(eventCb); + int32_t ret = thermalInterface_->RegisterFanCallback(callback); + THERMAL_HILOGI(COMP_SVC, "register fan hdi callback end, ret: %{public}d", ret); + + return; +} + +int32_t ThermalService::HandleFanCallbackEvent(const HdfThermalCallbackInfo& event) +{ + FanSensorInfo report; + if (!event.info.empty()) { + for (auto iter = event.info.begin(); iter != event.info.end(); iter++) { + report.insert(std::make_pair(iter->type, iter->temp)); + } + } + + fanFaultDetect_->OnFanSensorInfoChanged(report); + return ERR_OK; +} + std::string ThermalService::ShellDump(const std::vector& args, uint32_t argc) { if (!Permission::IsSystem() || !isBootCompleted_) { diff --git a/test/fuzztest/thermal_fuzzer/BUILD.gn b/test/fuzztest/thermal_fuzzer/BUILD.gn index 47966d1e19d4be84e147fb172972130a0701dc9c..215fe80ff20f315479b67614f4f59ab36f260421 100644 --- a/test/fuzztest/thermal_fuzzer/BUILD.gn +++ b/test/fuzztest/thermal_fuzzer/BUILD.gn @@ -25,7 +25,7 @@ deps_ex = [ "c_utils:utils", "hdf_core:libhdi", "hdf_core:libpub_utils", - "drivers_interface_thermal:libthermal_proxy_1.0", + "drivers_interface_thermal:libthermal_proxy_1.1", ] ##############################fuzztest########################################## diff --git a/test/systemtest/BUILD.gn b/test/systemtest/BUILD.gn index dd55336c8c0adaa442ea1db0a28bb47445ee5ee2..bdc132f59be95110cd53478710a116bd369cbc40 100644 --- a/test/systemtest/BUILD.gn +++ b/test/systemtest/BUILD.gn @@ -35,7 +35,7 @@ deps_ex = [ "bundle_framework:appexecfwk_base", "common_event_service:cesfwk_innerkits", "c_utils:utils", - "drivers_interface_thermal:libthermal_proxy_1.0", + "drivers_interface_thermal:libthermal_proxy_1.1", "hilog:libhilog", "ipc:ipc_core", "power_manager:powermgr_client", diff --git a/test/unittest/BUILD.gn b/test/unittest/BUILD.gn index db32f27d0b81b5e15aafc5db7240f799e6c007c1..d105927bb7a2a119aa440da7f6387ec6fd8f87a1 100644 --- a/test/unittest/BUILD.gn +++ b/test/unittest/BUILD.gn @@ -52,7 +52,7 @@ deps_ex = [ "appspawn:appspawn_socket_client", "window_manager:libwm", "drivers_interface_battery:libbattery_proxy_1.2", - "drivers_interface_thermal:libthermal_proxy_1.0", + "drivers_interface_thermal:libthermal_proxy_1.1", "time_service:time_client", ] @@ -496,7 +496,7 @@ ohos_unittest("ThermalClientTest") { "bundle_framework:appexecfwk_base", "c_utils:utils", "common_event_service:cesfwk_innerkits", - "drivers_interface_thermal:libthermal_proxy_1.0", + "drivers_interface_thermal:libthermal_proxy_1.1", "hdf_core:libhdi", "hdf_core:libpub_utils", "hilog:libhilog", diff --git a/test/unittest/include/thermal_action_hub_test.h b/test/unittest/include/thermal_action_hub_test.h index 407cd56952120e2027289e209b7d4f1b196dfd4c..ff41bc80b5179e2b738a5ebb47cd067f4f50bd36 100644 --- a/test/unittest/include/thermal_action_hub_test.h +++ b/test/unittest/include/thermal_action_hub_test.h @@ -78,6 +78,13 @@ public: virtual ~ThermalActionTest7Callback() = default; virtual bool OnThermalActionChanged(ActionCallbackMap& actionCbMap) override; }; + + class ThermalActionTest8Callback : public ThermalActionCallbackStub { + public: + ThermalActionTest8Callback() = default; + virtual ~ThermalActionTest8Callback() = default; + virtual bool OnThermalActionChanged(ActionCallbackMap& actionCbMap) override; + }; }; } // namespace PowerMgr } // namespace OHOS diff --git a/test/unittest/src/thermal_action_hub_test.cpp b/test/unittest/src/thermal_action_hub_test.cpp index 584fc586b50d11f2d86e2eec1fca4c39671c4c11..b4acbb3a2f01c3c948e21965734568da94e5b48c 100644 --- a/test/unittest/src/thermal_action_hub_test.cpp +++ b/test/unittest/src/thermal_action_hub_test.cpp @@ -197,6 +197,22 @@ bool ThermalActionHubTest::ThermalActionTest7Callback::OnThermalActionChanged(Ac return true; } +bool ThermalActionHubTest::ThermalActionTest8Callback::OnThermalActionChanged(ActionCallbackMap& actionCbMap) +{ + THERMAL_HILOGD(LABEL_TEST, "ThermalActionTest8Callback::OnThermalActionChanged Enter"); + bool isFind = false; + for (auto iter : actionCbMap) { + if (iter.first == "isolate") { + EXPECT_TRUE(static_cast(iter.second)); + isFind = true; + } + GTEST_LOG_(INFO) << "actionName: " << iter.first << " actionValue: " << iter.second; + } + EXPECT_TRUE(isFind); + Notify(); + return true; +} + namespace { /** * @tc.name: ThermalActionHubTest001 @@ -418,4 +434,35 @@ HWTEST_F(ThermalActionHubTest, ThermalActionHubTest007, TestSize.Level0) thermalMgrClient.UnSubscribeThermalActionCallback(cbBoost); THERMAL_HILOGD(LABEL_TEST, "ThermalActionHubTest001 end"); } + +/** + * @tc.name: ThermalActionHubTest008 + * @tc.desc: register action is isolate cpu test + * @tc.type: FUNC + */ +HWTEST_F(ThermalActionHubTest, ThermalActionHubTest008, TestSize.Level0) +{ + THERMAL_HILOGD(LABEL_TEST, "ThermalActionHubTest008 start"); + if (!IsMock(BATTERY_PATH) || IsVendor()) { + return; + } + std::vector actionList; + actionList.push_back("isolate"); + + std::string desc = ""; + InitData(); + auto& thermalMgrClient = ThermalMgrClient::GetInstance(); + const sptr cbIsolateCpu = new ThermalActionTest8Callback(); + + THERMAL_HILOGD(LABEL_TEST, "ThermalActionHubTest008 start register"); + thermalMgrClient.SubscribeThermalActionCallback(actionList, desc, cbIsolateCpu); + + int32_t batteryTemp = 43100; + SetNodeValue(batteryTemp, BATTERY_PATH); + + MockThermalMgrClient::GetInstance().GetThermalInfo(); + Wait(); + thermalMgrClient.UnSubscribeThermalActionCallback(cbIsolateCpu); + THERMAL_HILOGD(LABEL_TEST, "ThermalActionHubTest008 end"); +} } // namespace diff --git a/test/unittest/src/thermal_action_test.cpp b/test/unittest/src/thermal_action_test.cpp index b900d121a7bf28e38523e67d4ae87e02300de6f4..40c3c0b0b1a49d0443e5606859a7084b753e7474 100644 --- a/test/unittest/src/thermal_action_test.cpp +++ b/test/unittest/src/thermal_action_test.cpp @@ -26,6 +26,7 @@ #include "action_cpu_big.h" #include "action_cpu_med.h" #include "action_cpu_lit.h" +#include "action_cpu_isolate.h" #include "action_display.h" #include "action_gpu.h" #include "action_shutdown.h" @@ -50,6 +51,7 @@ std::shared_ptr g_actionCharger = std::make_shared std::shared_ptr g_actionCpuBig = std::make_shared("cpu_big"); std::shared_ptr g_actionCpuMed = std::make_shared("cpu_med"); std::shared_ptr g_actionCpuLit = std::make_shared("cpu_lit"); +std::shared_ptr g_actionCpuIsolate = std::make_shared("isolate"); std::shared_ptr g_actionDisplay = std::make_shared("lcd"); std::shared_ptr g_actionGpu = std::make_shared("gpu"); std::shared_ptr g_actionPopup = std::make_shared("popup"); @@ -261,4 +263,17 @@ HWTEST_F(ThermalActionTest, ThermalActionTest011, TestSize.Level0) g_actionGpu->Execute(); EXPECT_TRUE(g_actionGpu->valueList_.empty()); } + +/** + * @tc.name: ThermalActionTest012 + * @tc.desc: Action Isolate CPU Test + * @tc.type: FUNC + */ +HWTEST_F(ThermalActionTest, ThermalActionTest012, TestSize.Level0) +{ + g_actionCpuIsolate->AddActionValue(""); + g_actionCpuIsolate->AddActionValue("1.0"); + g_actionCpuIsolate->Execute(); + EXPECT_TRUE(g_actionCpuIsolate->valueList_.empty()); +} } // namespace diff --git a/thermalmgr.yaml b/thermalmgr.yaml index 031a73037dbaf6f849529bea8619b2e3bcd0caee..4d4fffc4c7dd6fae72b84f59d00d9c900f1433cd 100644 --- a/thermalmgr.yaml +++ b/thermalmgr.yaml @@ -27,3 +27,8 @@ ACTION_TRIGGERED: ACTION: {type: STRING, desc: action name} VALUE: {type: INT32, desc: action value} RATIO: {type: FLOAT, desc: action ration value} + +FAN_FAULT: + __BASE: {type: FAULT, level: MINOR, tag: PowerStats, desc: fan fault information} + ID: {type: INT32, desc: fault id} + MSG: {type: STRING, desc: fan speed and temprature of hardwares} diff --git a/utils/native/include/constants.h b/utils/native/include/constants.h index e784d93d526a8301897aeaa482348b6d8ed80b5b..38d1438e023f08923c2d719c64cd0c9aaa341cf2 100644 --- a/utils/native/include/constants.h +++ b/utils/native/include/constants.h @@ -25,6 +25,7 @@ namespace PowerMgr { constexpr const char* CPU_MED_ACTION_NAME = "cpu_med"; constexpr const char* CPU_LIT_ACTION_NAME = "cpu_lit"; constexpr const char* CPU_BOOST_ACTION_NAME = "boost"; + constexpr const char* CPU_ISOLATE_ACTION_NAME = "isolate"; constexpr const char* GPU_ACTION_NAME = "gpu"; constexpr const char* LCD_ACTION_NAME = "lcd"; constexpr const char* VOLUME_ACTION_NAME = "volume"; diff --git a/utils/native/include/thermal_hisysevent.h b/utils/native/include/thermal_hisysevent.h index b8eece05187a8a80053e5582d7c9af2bac44bc6a..4d3d968330f2d5bc6402e2099a0647a2ebd7c899 100644 --- a/utils/native/include/thermal_hisysevent.h +++ b/utils/native/include/thermal_hisysevent.h @@ -23,6 +23,7 @@ namespace PowerMgr { void WriteLevelChangedHiSysEvent(bool enableEvent, int32_t level); void WriteActionTriggeredHiSysEvent(bool enableEvent, const std::string& actionName, int32_t value); void WriteActionTriggeredHiSysEventWithRatio(bool enableEvent, const std::string& actionName, float value); +void WriteFanFaultEvent(int32_t faultId, std::string msg); } // namespace PowerMgr } // namespace OHOS #endif // THERMAL_HISYSEVENT_H diff --git a/utils/native/src/thermal_hisysevent.cpp b/utils/native/src/thermal_hisysevent.cpp index bc7de9d33c308a50b5768f5ec34055e523a9b779..e59f05b193f8677b2dcbc29571948d7250386b00 100644 --- a/utils/native/src/thermal_hisysevent.cpp +++ b/utils/native/src/thermal_hisysevent.cpp @@ -52,5 +52,21 @@ void WriteActionTriggeredHiSysEventWithRatio(bool enableEvent, const std::string WriteEvent("ACTION_TRIGGERED", "ACTION", actionName, "RATIO", value); } } + +template +static void WriteFaultEvent(const std::string& eventType, Types... args) +{ + int ret = HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::THERMAL, eventType, + HiviewDFX::HiSysEvent::EventType::FAULT, args...); + if (ret != 0) { + THERMAL_HILOGE(COMP_SVC, "Write fault event fail: %{public}s", eventType.c_str()); + } +} + +void WriteFanFaultEvent(int32_t faultId, std::string msg) +{ + WriteFaultEvent("FAN_FAULT", "ID", faultId, "MSG", msg); +} + } // namespace PowerMgr -} // namespace OHOS \ No newline at end of file +} // namespace OHOS