diff options
author | Kyle Lin <kylelin@google.com> | 2020-08-07 17:02:55 +0800 |
---|---|---|
committer | Wei Wang <wvw@google.com> | 2020-08-19 00:14:17 +0000 |
commit | 7c8556bf9a436ff0eaf4601ed74e86aa05f7afbf (patch) | |
tree | a9b464f8f92f5a28a46573d2393c34eaf2c23818 /thermal | |
parent | 35e110fe669a7d2996ce503d7e31204554f972e3 (diff) | |
download | pixel-7c8556bf9a436ff0eaf4601ed74e86aa05f7afbf.tar.gz |
thermal: notify perfmgr current thermal status
Bug: 72471476
Bug: 162791243
Test: build and using emul temp/running burn8 to verify it
Change-Id: If0fd7d5a877f172562eed406a0a39cfa120e6961
Diffstat (limited to 'thermal')
-rw-r--r-- | thermal/Android.bp | 3 | ||||
-rw-r--r-- | thermal/Thermal.cpp | 20 | ||||
-rw-r--r-- | thermal/thermal-helper.cpp | 152 | ||||
-rw-r--r-- | thermal/thermal-helper.h | 35 | ||||
-rw-r--r-- | thermal/utils/config_parser.cpp | 10 | ||||
-rw-r--r-- | thermal/utils/config_parser.h | 1 |
6 files changed, 221 insertions, 0 deletions
diff --git a/thermal/Android.bp b/thermal/Android.bp index 7875ea40..a3055211 100644 --- a/thermal/Android.bp +++ b/thermal/Android.bp @@ -23,8 +23,11 @@ cc_binary { "libhidlbase", "libjsoncpp", "libutils", + "libbinder_ndk", "android.hardware.thermal@1.0", "android.hardware.thermal@2.0", + "android.hardware.power-ndk_platform", + "pixel-power-ext-ndk_platform" ], cflags: [ "-Wall", diff --git a/thermal/Thermal.cpp b/thermal/Thermal.cpp index bd47f6eb..ada526fe 100644 --- a/thermal/Thermal.cpp +++ b/thermal/Thermal.cpp @@ -241,6 +241,8 @@ void Thermal::sendThermalChangedCallback(const std::vector<Temperature_2_0> &tem << " Type: " << android::hardware::thermal::V2_0::toString(t.type) << " Name: " << t.name << " CurrentValue: " << t.value << " ThrottlingStatus: " << android::hardware::thermal::V2_0::toString(t.throttlingStatus); + + thermal_helper_.sendPowerExtHint(t); callbacks_.erase( std::remove_if(callbacks_.begin(), callbacks_.end(), [&](const CallbackSetting &c) { @@ -377,6 +379,24 @@ Return<void> Thermal::debug(const hidl_handle &handle, const hidl_vec<hidl_strin << std::noboolalpha << std::endl; } } + { + dump_buf << "SendPowerHint:" << std::endl; + const auto &map = thermal_helper_.GetSensorInfoMap(); + for (const auto &name_info_pair : map) { + dump_buf << " Name: " << name_info_pair.first; + dump_buf << " SendPowerHint: " << std::boolalpha + << name_info_pair.second.send_powerhint << std::noboolalpha + << std::endl; + } + } + { + dump_buf << "AIDL Power Hal exist: " << std::boolalpha + << thermal_helper_.isAidlPowerHalExist() << std::endl; + dump_buf << "AIDL Power Hal connected: " << std::boolalpha + << thermal_helper_.isPowerHalConnected() << std::endl; + dump_buf << "AIDL Power Hal Ext connected: " << std::boolalpha + << thermal_helper_.isPowerHalExtConnected() << std::endl; + } } std::string buf = dump_buf.str(); if (!android::base::WriteStringToFd(buf, fd)) { diff --git a/thermal/thermal-helper.cpp b/thermal/thermal-helper.cpp index 725578da..43f0d924 100644 --- a/thermal/thermal-helper.cpp +++ b/thermal/thermal-helper.cpp @@ -25,6 +25,7 @@ #include <android-base/properties.h> #include <android-base/stringprintf.h> #include <android-base/strings.h> +#include <android/binder_manager.h> #include <hidl/HidlTransportSupport.h> #include "thermal-helper.h" @@ -54,6 +55,7 @@ constexpr std::string_view kConfigDefaultFileName("thermal_info_config.json"); namespace { using android::base::StringPrintf; +using android::hardware::thermal::V2_0::toString; /* * Pixel don't offline CPU, so std::thread::hardware_concurrency(); should work. @@ -167,6 +169,91 @@ std::map<std::string, std::string> parseThermalPathMap(std::string_view prefix) } } // namespace +PowerHalService::PowerHalService() + : power_hal_aidl_exist_(true), power_hal_aidl_(nullptr), power_hal_ext_aidl_(nullptr) { + connect(); +} + +bool PowerHalService::connect() { + std::lock_guard<std::mutex> lock(lock_); + if (!power_hal_aidl_exist_) + return false; + + if (power_hal_aidl_ != nullptr) + return true; + + const std::string kInstance = std::string(IPower::descriptor) + "/default"; + ndk::SpAIBinder power_binder = ndk::SpAIBinder(AServiceManager_getService(kInstance.c_str())); + ndk::SpAIBinder ext_power_binder; + + if (power_binder.get() == nullptr) { + LOG(ERROR) << "Cannot get Power Hal Binder"; + power_hal_aidl_exist_ = false; + return false; + } + + power_hal_aidl_ = IPower::fromBinder(power_binder); + + if (power_hal_aidl_ == nullptr) { + power_hal_aidl_exist_ = false; + LOG(ERROR) << "Cannot get Power Hal AIDL" << kInstance.c_str(); + return false; + } + + if (STATUS_OK != AIBinder_getExtension(power_binder.get(), ext_power_binder.getR()) || + ext_power_binder.get() == nullptr) { + LOG(ERROR) << "Cannot get Power Hal Extension Binder"; + power_hal_aidl_exist_ = false; + return false; + } + + power_hal_ext_aidl_ = IPowerExt::fromBinder(ext_power_binder); + if (power_hal_ext_aidl_ == nullptr) { + LOG(ERROR) << "Cannot get Power Hal Extension AIDL"; + power_hal_aidl_exist_ = false; + } + + return true; +} + +bool PowerHalService::isModeSupported(const std::string &type, const ThrottlingSeverity &t) { + bool isSupported = false; + if (!isPowerHalConnected()) { + return false; + } + std::string power_hint = StringPrintf("THERMAL_%s_%s", type.c_str(), toString(t).c_str()); + lock_.lock(); + if (!power_hal_ext_aidl_->isModeSupported(power_hint, &isSupported).isOk()) { + LOG(ERROR) << "Fail to check supported mode, Hint: " << power_hint; + power_hal_aidl_exist_ = false; + power_hal_ext_aidl_ = nullptr; + power_hal_aidl_ = nullptr; + lock_.unlock(); + return false; + } + lock_.unlock(); + return isSupported; +} + +void PowerHalService::setMode(const std::string &type, const ThrottlingSeverity &t, + const bool &enable) { + if (!isPowerHalConnected()) { + return; + } + + std::string power_hint = StringPrintf("THERMAL_%s_%s", type.c_str(), toString(t).c_str()); + LOG(INFO) << "Send Hint " << power_hint << " Enable: " << std::boolalpha << enable; + lock_.lock(); + if (!power_hal_ext_aidl_->setMode(power_hint, enable).isOk()) { + LOG(ERROR) << "Fail to set mode, Hint: " << power_hint; + power_hal_aidl_exist_ = false; + power_hal_ext_aidl_ = nullptr; + power_hal_aidl_ = nullptr; + lock_.unlock(); + return; + } + lock_.unlock(); +} /* * Populate the sensor_name_to_file_map_ map by walking through the file tree, @@ -188,6 +275,7 @@ ThermalHelper::ThermalHelper(const NotificationCallback &cb) .severity = ThrottlingSeverity::NONE, .prev_hot_severity = ThrottlingSeverity::NONE, .prev_cold_severity = ThrottlingSeverity::NONE, + .prev_hint_severity = ThrottlingSeverity::NONE, }; } @@ -215,6 +303,12 @@ ThermalHelper::ThermalHelper(const NotificationCallback &cb) if (!is_initialized_) { LOG(FATAL) << "ThermalHAL could not start watching thread properly."; } + + if (!connectToPowerHal()) { + LOG(ERROR) << "Fail to connect to Power Hal"; + } else { + updateSupportedPowerHints(); + } } bool ThermalHelper::readCoolingDevice(std::string_view cooling_device, @@ -614,6 +708,64 @@ bool ThermalHelper::thermalWatcherCallbackFunc(const std::set<std::string> &ueve return thermal_triggered; } +bool ThermalHelper::connectToPowerHal() { + return power_hal_service_.connect(); +} + +void ThermalHelper::updateSupportedPowerHints() { + for (auto const &name_status_pair : sensor_info_map_) { + if (!name_status_pair.second.send_powerhint) { + continue; + } + ThrottlingSeverity current_severity = ThrottlingSeverity::NONE; + for (const auto &severity : hidl_enum_range<ThrottlingSeverity>()) { + LOG(ERROR) << "sensor: " << name_status_pair.first + << " current_severity :" << toString(current_severity) << " severity " + << toString(severity); + if (severity == ThrottlingSeverity::NONE) { + supported_powerhint_map_[name_status_pair.first][ThrottlingSeverity::NONE] = + ThrottlingSeverity::NONE; + continue; + } + + bool isSupported = false; + ndk::ScopedAStatus isSupportedResult; + + if (power_hal_service_.isPowerHalExtConnected()) { + isSupported = power_hal_service_.isModeSupported(name_status_pair.first, severity); + } + if (isSupported) + current_severity = severity; + supported_powerhint_map_[name_status_pair.first][severity] = current_severity; + } + } +} + +void ThermalHelper::sendPowerExtHint(const Temperature_2_0 &t) { + std::lock_guard<std::shared_mutex> lock(sensor_status_map_mutex_); + if (!isAidlPowerHalExist()) + return; + + if (!sensor_info_map_.at(t.name).send_powerhint) + return; + + ThrottlingSeverity prev_hint_severity; + prev_hint_severity = sensor_status_map_.at(t.name).prev_hint_severity; + ThrottlingSeverity current_hint_severity = supported_powerhint_map_[t.name][t.throttlingStatus]; + + if (prev_hint_severity == current_hint_severity) + return; + + if (prev_hint_severity != ThrottlingSeverity::NONE) { + power_hal_service_.setMode(t.name, prev_hint_severity, false); + } + + if (current_hint_severity != ThrottlingSeverity::NONE) { + power_hal_service_.setMode(t.name, current_hint_severity, true); + } + + sensor_status_map_[t.name].prev_hint_severity = current_hint_severity; +} } // namespace implementation } // namespace V2_0 } // namespace thermal diff --git a/thermal/thermal-helper.h b/thermal/thermal-helper.h index 5eb389ee..37a2dea3 100644 --- a/thermal/thermal-helper.h +++ b/thermal/thermal-helper.h @@ -40,6 +40,8 @@ #include <unordered_map> #include <vector> +#include <aidl/android/hardware/power/IPower.h> +#include <aidl/google/hardware/power/extension/pixel/IPowerExt.h> #include <android/hardware/thermal/2.0/IThermal.h> #include "utils/config_parser.h" @@ -52,6 +54,8 @@ namespace thermal { namespace V2_0 { namespace implementation { +using ::aidl::android::hardware::power::IPower; +using ::aidl::google::hardware::power::extension::pixel::IPowerExt; using ::android::hardware::hidl_vec; using ::android::hardware::thermal::V1_0::CpuUsage; using ::android::hardware::thermal::V2_0::CoolingType; @@ -72,6 +76,25 @@ struct SensorStatus { ThrottlingSeverity severity; ThrottlingSeverity prev_hot_severity; ThrottlingSeverity prev_cold_severity; + ThrottlingSeverity prev_hint_severity; +}; + +class PowerHalService { + public: + PowerHalService(); + ~PowerHalService() = default; + bool connect(); + bool isAidlPowerHalExist() { return power_hal_aidl_exist_; } + bool isModeSupported(const std::string &type, const ThrottlingSeverity &t); + bool isPowerHalConnected() { return power_hal_aidl_ != nullptr; } + bool isPowerHalExtConnected() { return power_hal_ext_aidl_ != nullptr; } + void setMode(const std::string &type, const ThrottlingSeverity &t, const bool &enable); + + private: + bool power_hal_aidl_exist_; + std::shared_ptr<IPower> power_hal_aidl_; + std::shared_ptr<IPowerExt> power_hal_ext_aidl_; + std::mutex lock_; }; class ThermalHelper { @@ -105,6 +128,12 @@ class ThermalHelper { // Get SensorInfo Map const std::map<std::string, SensorInfo> &GetSensorInfoMap() const { return sensor_info_map_; } + void sendPowerExtHint(const Temperature_2_0 &t); + + bool isAidlPowerHalExist() { return power_hal_service_.isAidlPowerHalExist(); } + bool isPowerHalConnected() { return power_hal_service_.isPowerHalConnected(); } + bool isPowerHalExtConnected() { return power_hal_service_.isPowerHalExtConnected(); } + private: bool initializeSensorMap(const std::map<std::string, std::string> &path_map); bool initializeCoolingDevices(const std::map<std::string, std::string> &path_map); @@ -119,6 +148,9 @@ class ThermalHelper { ThrottlingSeverity prev_hot_severity, ThrottlingSeverity prev_cold_severity, float value) const; + bool connectToPowerHal(); + void updateSupportedPowerHints(); + sp<ThermalWatcher> thermal_watcher_; ThermalFiles thermal_sensors_; ThermalFiles cooling_devices_; @@ -126,6 +158,9 @@ class ThermalHelper { const NotificationCallback cb_; const std::map<std::string, CoolingType> cooling_device_info_map_; const std::map<std::string, SensorInfo> sensor_info_map_; + std::map<std::string, std::map<ThrottlingSeverity, ThrottlingSeverity>> + supported_powerhint_map_; + PowerHalService power_hal_service_; mutable std::shared_mutex sensor_status_map_mutex_; std::map<std::string, SensorStatus> sensor_status_map_; diff --git a/thermal/utils/config_parser.cpp b/thermal/utils/config_parser.cpp index d74fd495..daba0ee3 100644 --- a/thermal/utils/config_parser.cpp +++ b/thermal/utils/config_parser.cpp @@ -217,6 +217,15 @@ std::map<std::string, SensorInfo> ParseSensorInfo(std::string_view config_path) LOG(INFO) << "Sensor[" << name << "]'s Monitor: " << std::boolalpha << is_monitor << std::noboolalpha; + bool send_powerhint = false; + if (sensors[i]["SendPowerHint"].empty() || !sensors[i]["SendPowerHint"].isBool()) { + LOG(INFO) << "Failed to read Sensor[" << name << "]'s SendPowerHint, set to 'false'"; + } else { + send_powerhint = sensors[i]["SendPowerHint"].asBool(); + } + LOG(INFO) << "Sensor[" << name << "]'s SendPowerHint: " << std::boolalpha << send_powerhint + << std::noboolalpha; + sensors_parsed[name] = { .type = sensor_type, .hot_thresholds = hot_thresholds, @@ -226,6 +235,7 @@ std::map<std::string, SensorInfo> ParseSensorInfo(std::string_view config_path) .vr_threshold = vr_threshold, .multiplier = multiplier, .is_monitor = is_monitor, + .send_powerhint = send_powerhint, }; ++total_parsed; } diff --git a/thermal/utils/config_parser.h b/thermal/utils/config_parser.h index fe43594f..399fef63 100644 --- a/thermal/utils/config_parser.h +++ b/thermal/utils/config_parser.h @@ -45,6 +45,7 @@ struct SensorInfo { float vr_threshold; float multiplier; bool is_monitor; + bool send_powerhint; }; std::map<std::string, SensorInfo> ParseSensorInfo(std::string_view config_path); |