diff --git a/hidl/thermal/Android.bp b/hidl/thermal/Android.bp deleted file mode 100644 index 5d6045b8..00000000 --- a/hidl/thermal/Android.bp +++ /dev/null @@ -1,52 +0,0 @@ -cc_binary { - name: "android.hardware.thermal@2.0-service.samsung", - defaults: [ - "hidl_defaults", - ], - vendor: true, - relative_install_path: "hw", - vintf_fragments: ["android.hardware.thermal@2.0-service.samsung.xml"], - init_rc: [ - "android.hardware.thermal@2.0-service.samsung.rc", - ], - srcs: [ - "service.cpp", - "Thermal.cpp", - "thermal-helper.cpp", - "utils/config_parser.cpp", - "utils/thermal_files.cpp", - "utils/thermal_watcher.cpp", - ], - static_libs: [ - "libjsoncpp", - ], - shared_libs: [ - "libbase", - "libcutils", - "libhidlbase", - "libutils", - "android.hardware.thermal@1.0", - "android.hardware.thermal@2.0", - ], - cflags: [ - "-Wall", - "-Werror", - "-Wextra", - "-Wunused", - ], - tidy: true, - tidy_checks_as_errors: [ - "android-*", - "cert-*", - "clang-analyzer-security*", - ], -} - -sh_binary { - name: "thermal_logd.samsung", - src: "init.thermal.logging.sh", - vendor: true, - init_rc: [ - "samsung-thermal-logd.rc", - ], -} diff --git a/hidl/thermal/README.md b/hidl/thermal/README.md deleted file mode 100644 index 61b82d58..00000000 --- a/hidl/thermal/README.md +++ /dev/null @@ -1,40 +0,0 @@ -# Samsung HIDL thermal HAL - -The HAL uses the standard linux thermal interface and can be configured by -adding thermal zones and cooling devices present on the device in a -`thermal_info_config.json` file. - -To probe them, just connect the phone via ADB and check the nodes available -under `/sys/class/thermal/`. The name of each thermal zone and cooling device -can be found in the type node, e.g. - - /sys/class/thermal/thermal_zone0/type - /sys/class/thermal/cooling_device0/type - -For each thermal device it is possible to configure a "Sensor" node in -`thermal_info_config.json`, and setting up to 7 throttling levels, from NONE to -SHUTDOWN. At each severity level, the hal send signals to throttle the device to the -framework, according to : https://source.android.com/devices/architecture/hidl/thermal-mitigation -In order to set temperature curve for the desired component you can -took as a refererence the kernel trip points temperatures, for the specific devices, -available in the thermal_zoneX sysfs. -Each sensor can be classified as *CPU*, *GPU*, *USB_PORT* or *BATTERY* type. -If you have a thermal monitor which does not belong to any of this categories you can -classify it as *UNKNOWN*. -You can specify hysteresis as well as if the interface should be monitored. -If you monitor the interface, the HAL takes action when the specifc treshold is passed. -You should not enable monitor if your kernel already implement thermal mitigatoin for -the specified component. -Since each device reports temperatures multiplied by different factor of 10, -you should set the Multipler field such as -`/sys/class/thermal/thermal_zoneX/temp` is reported in Celusis degrees (e.g. -25100 reported by sysfs, multiplied by 0.001 is 25.1). - -The same can be said for cooling devices. For each cooling devices can be -created a CoolingDevices node in `thermal_info_config.json`. -Each cooling interface can be classified as *CPU*, *GPU* or *BATTERY* type. -If you have a cooling device which does not belong to any of this categories you can -classify it as *COMPONENT*. -The `thermal_info_config.json` should be copied under /vendor/etc. - -For more details, refer on the sample config schema. diff --git a/hidl/thermal/Thermal.cpp b/hidl/thermal/Thermal.cpp deleted file mode 100644 index bd47f6eb..00000000 --- a/hidl/thermal/Thermal.cpp +++ /dev/null @@ -1,394 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include - -#include -#include -#include - -#include "Thermal.h" -#include "thermal-helper.h" - -namespace android { -namespace hardware { -namespace thermal { -namespace V2_0 { -namespace implementation { - -namespace { - -using ::android::hardware::interfacesEqual; -using ::android::hardware::thermal::V1_0::ThermalStatus; -using ::android::hardware::thermal::V1_0::ThermalStatusCode; -using ::android::hidl::base::V1_0::IBase; - -template -Return setFailureAndCallback(T _hidl_cb, hidl_vec data, std::string_view debug_msg) { - ThermalStatus status; - status.code = ThermalStatusCode::FAILURE; - status.debugMessage = debug_msg.data(); - _hidl_cb(status, data); - return Void(); -} - -template -Return setInitFailureAndCallback(T _hidl_cb, hidl_vec data) { - return setFailureAndCallback(_hidl_cb, data, "Failure initializing thermal HAL"); -} - -} // namespace - -// On init we will spawn a thread which will continually watch for -// throttling. When throttling is seen, if we have a callback registered -// the thread will call notifyThrottling() else it will log the dropped -// throttling event and do nothing. The thread is only killed when -// Thermal() is killed. -Thermal::Thermal() - : thermal_helper_( - std::bind(&Thermal::sendThermalChangedCallback, this, std::placeholders::_1)) {} - -// Methods from ::android::hardware::thermal::V1_0::IThermal. -Return Thermal::getTemperatures(getTemperatures_cb _hidl_cb) { - ThermalStatus status; - status.code = ThermalStatusCode::SUCCESS; - hidl_vec temperatures; - - if (!thermal_helper_.isInitializedOk()) { - LOG(ERROR) << "ThermalHAL not initialized properly."; - return setInitFailureAndCallback(_hidl_cb, temperatures); - } - - if (!thermal_helper_.fillTemperatures(&temperatures)) { - return setFailureAndCallback(_hidl_cb, temperatures, "Failed to read thermal sensors."); - } - - _hidl_cb(status, temperatures); - return Void(); -} - -Return Thermal::getCpuUsages(getCpuUsages_cb _hidl_cb) { - ThermalStatus status; - status.code = ThermalStatusCode::SUCCESS; - hidl_vec cpu_usages; - - if (!thermal_helper_.isInitializedOk()) { - return setInitFailureAndCallback(_hidl_cb, cpu_usages); - } - - if (!thermal_helper_.fillCpuUsages(&cpu_usages)) { - return setFailureAndCallback(_hidl_cb, cpu_usages, "Failed to get CPU usages."); - } - - _hidl_cb(status, cpu_usages); - return Void(); -} - -Return Thermal::getCoolingDevices(getCoolingDevices_cb _hidl_cb) { - ThermalStatus status; - status.code = ThermalStatusCode::SUCCESS; - hidl_vec cooling_devices; - - if (!thermal_helper_.isInitializedOk()) { - return setInitFailureAndCallback(_hidl_cb, cooling_devices); - } - _hidl_cb(status, cooling_devices); - return Void(); -} - -Return Thermal::getCurrentTemperatures(bool filterType, TemperatureType_2_0 type, - getCurrentTemperatures_cb _hidl_cb) { - ThermalStatus status; - status.code = ThermalStatusCode::SUCCESS; - hidl_vec temperatures; - - if (!thermal_helper_.isInitializedOk()) { - LOG(ERROR) << "ThermalHAL not initialized properly."; - return setInitFailureAndCallback(_hidl_cb, temperatures); - } - - if (!thermal_helper_.fillCurrentTemperatures(filterType, type, &temperatures)) { - return setFailureAndCallback(_hidl_cb, temperatures, "Failed to read thermal sensors."); - } - - _hidl_cb(status, temperatures); - return Void(); -} - -Return Thermal::getTemperatureThresholds(bool filterType, TemperatureType_2_0 type, - getTemperatureThresholds_cb _hidl_cb) { - ThermalStatus status; - status.code = ThermalStatusCode::SUCCESS; - hidl_vec temperatures; - - if (!thermal_helper_.isInitializedOk()) { - LOG(ERROR) << "ThermalHAL not initialized properly."; - return setInitFailureAndCallback(_hidl_cb, temperatures); - } - - if (!thermal_helper_.fillTemperatureThresholds(filterType, type, &temperatures)) { - return setFailureAndCallback(_hidl_cb, temperatures, "Failed to read thermal sensors."); - } - - _hidl_cb(status, temperatures); - return Void(); -} - -Return Thermal::getCurrentCoolingDevices(bool filterType, CoolingType type, - getCurrentCoolingDevices_cb _hidl_cb) { - ThermalStatus status; - status.code = ThermalStatusCode::SUCCESS; - hidl_vec cooling_devices; - - if (!thermal_helper_.isInitializedOk()) { - LOG(ERROR) << "ThermalHAL not initialized properly."; - return setInitFailureAndCallback(_hidl_cb, cooling_devices); - } - - if (!thermal_helper_.fillCurrentCoolingDevices(filterType, type, &cooling_devices)) { - return setFailureAndCallback(_hidl_cb, cooling_devices, "Failed to read thermal sensors."); - } - - _hidl_cb(status, cooling_devices); - return Void(); -} - -Return Thermal::registerThermalChangedCallback(const sp &callback, - bool filterType, TemperatureType_2_0 type, - registerThermalChangedCallback_cb _hidl_cb) { - ThermalStatus status; - if (callback == nullptr) { - status.code = ThermalStatusCode::FAILURE; - status.debugMessage = "Invalid nullptr callback"; - LOG(ERROR) << status.debugMessage; - _hidl_cb(status); - return Void(); - } else { - status.code = ThermalStatusCode::SUCCESS; - } - std::lock_guard _lock(thermal_callback_mutex_); - if (std::any_of(callbacks_.begin(), callbacks_.end(), [&](const CallbackSetting &c) { - return interfacesEqual(c.callback, callback); - })) { - status.code = ThermalStatusCode::FAILURE; - status.debugMessage = "Same callback registered already"; - LOG(ERROR) << status.debugMessage; - } else { - callbacks_.emplace_back(callback, filterType, type); - LOG(INFO) << "a callback has been registered to ThermalHAL, isFilter: " << filterType - << " Type: " << android::hardware::thermal::V2_0::toString(type); - } - _hidl_cb(status); - return Void(); -} - -Return Thermal::unregisterThermalChangedCallback( - const sp &callback, unregisterThermalChangedCallback_cb _hidl_cb) { - ThermalStatus status; - if (callback == nullptr) { - status.code = ThermalStatusCode::FAILURE; - status.debugMessage = "Invalid nullptr callback"; - LOG(ERROR) << status.debugMessage; - _hidl_cb(status); - return Void(); - } else { - status.code = ThermalStatusCode::SUCCESS; - } - bool removed = false; - std::lock_guard _lock(thermal_callback_mutex_); - callbacks_.erase( - std::remove_if(callbacks_.begin(), callbacks_.end(), - [&](const CallbackSetting &c) { - if (interfacesEqual(c.callback, callback)) { - LOG(INFO) - << "a callback has been unregistered to ThermalHAL, isFilter: " - << c.is_filter_type << " Type: " - << android::hardware::thermal::V2_0::toString(c.type); - removed = true; - return true; - } - return false; - }), - callbacks_.end()); - if (!removed) { - status.code = ThermalStatusCode::FAILURE; - status.debugMessage = "The callback was not registered before"; - LOG(ERROR) << status.debugMessage; - } - _hidl_cb(status); - return Void(); -} - -void Thermal::sendThermalChangedCallback(const std::vector &temps) { - std::lock_guard _lock(thermal_callback_mutex_); - for (auto &t : temps) { - LOG(INFO) << "Sending notification: " - << " Type: " << android::hardware::thermal::V2_0::toString(t.type) - << " Name: " << t.name << " CurrentValue: " << t.value << " ThrottlingStatus: " - << android::hardware::thermal::V2_0::toString(t.throttlingStatus); - callbacks_.erase( - std::remove_if(callbacks_.begin(), callbacks_.end(), - [&](const CallbackSetting &c) { - if (!c.is_filter_type || t.type == c.type) { - Return ret = c.callback->notifyThrottling(t); - return !ret.isOk(); - } - LOG(ERROR) - << "a Thermal callback is dead, removed from callback list."; - return false; - }), - callbacks_.end()); - } -} - -Return Thermal::debug(const hidl_handle &handle, const hidl_vec &) { - if (handle != nullptr && handle->numFds >= 1) { - int fd = handle->data[0]; - std::ostringstream dump_buf; - - if (!thermal_helper_.isInitializedOk()) { - dump_buf << "ThermalHAL not initialized properly." << std::endl; - } else { - { - hidl_vec temperatures; - dump_buf << "getTemperatures:" << std::endl; - if (!thermal_helper_.fillTemperatures(&temperatures)) { - dump_buf << "Failed to read thermal sensors." << std::endl; - } - - for (const auto &t : temperatures) { - dump_buf << " Type: " << android::hardware::thermal::V1_0::toString(t.type) - << " Name: " << t.name << " CurrentValue: " << t.currentValue - << " ThrottlingThreshold: " << t.throttlingThreshold - << " ShutdownThreshold: " << t.shutdownThreshold - << " VrThrottlingThreshold: " << t.vrThrottlingThreshold << std::endl; - } - } - { - hidl_vec cpu_usages; - dump_buf << "getCpuUsages:" << std::endl; - if (!thermal_helper_.fillCpuUsages(&cpu_usages)) { - dump_buf << "Failed to get CPU usages." << std::endl; - } - - for (const auto &usage : cpu_usages) { - dump_buf << " Name: " << usage.name << " Active: " << usage.active - << " Total: " << usage.total << " IsOnline: " << usage.isOnline - << std::endl; - } - } - { - dump_buf << "getCurrentTemperatures:" << std::endl; - hidl_vec temperatures; - if (!thermal_helper_.fillCurrentTemperatures(false, TemperatureType_2_0::SKIN, - &temperatures)) { - dump_buf << "Failed to getCurrentTemperatures." << std::endl; - } - - for (const auto &t : temperatures) { - dump_buf << " Type: " << android::hardware::thermal::V2_0::toString(t.type) - << " Name: " << t.name << " CurrentValue: " << t.value - << " ThrottlingStatus: " - << android::hardware::thermal::V2_0::toString(t.throttlingStatus) - << std::endl; - } - } - { - dump_buf << "getTemperatureThresholds:" << std::endl; - hidl_vec temperatures; - if (!thermal_helper_.fillTemperatureThresholds(false, TemperatureType_2_0::SKIN, - &temperatures)) { - dump_buf << "Failed to getTemperatureThresholds." << std::endl; - } - - for (const auto &t : temperatures) { - dump_buf << " Type: " << android::hardware::thermal::V2_0::toString(t.type) - << " Name: " << t.name; - dump_buf << " hotThrottlingThreshold: ["; - for (size_t i = 0; i < kThrottlingSeverityCount; ++i) { - dump_buf << t.hotThrottlingThresholds[i] << " "; - } - dump_buf << "] coldThrottlingThreshold: ["; - for (size_t i = 0; i < kThrottlingSeverityCount; ++i) { - dump_buf << t.coldThrottlingThresholds[i] << " "; - } - dump_buf << "] vrThrottlingThreshold: " << t.vrThrottlingThreshold; - dump_buf << std::endl; - } - } - { - dump_buf << "getCurrentCoolingDevices:" << std::endl; - hidl_vec cooling_devices; - if (!thermal_helper_.fillCurrentCoolingDevices(false, CoolingType::CPU, - &cooling_devices)) { - dump_buf << "Failed to getCurrentCoolingDevices." << std::endl; - } - - for (const auto &c : cooling_devices) { - dump_buf << " Type: " << android::hardware::thermal::V2_0::toString(c.type) - << " Name: " << c.name << " CurrentValue: " << c.value << std::endl; - } - } - { - dump_buf << "Callbacks: Total " << callbacks_.size() << std::endl; - for (const auto &c : callbacks_) { - dump_buf << " IsFilter: " << c.is_filter_type - << " Type: " << android::hardware::thermal::V2_0::toString(c.type) - << std::endl; - } - } - { - dump_buf << "getHysteresis:" << std::endl; - const auto &map = thermal_helper_.GetSensorInfoMap(); - for (const auto &name_info_pair : map) { - dump_buf << " Name: " << name_info_pair.first; - dump_buf << " hotHysteresis: ["; - for (size_t i = 0; i < kThrottlingSeverityCount; ++i) { - dump_buf << name_info_pair.second.hot_hysteresis[i] << " "; - } - dump_buf << "] coldHysteresis: ["; - for (size_t i = 0; i < kThrottlingSeverityCount; ++i) { - dump_buf << name_info_pair.second.cold_hysteresis[i] << " "; - } - dump_buf << "]" << std::endl; - } - } - { - dump_buf << "Monitor:" << std::endl; - const auto &map = thermal_helper_.GetSensorInfoMap(); - for (const auto &name_info_pair : map) { - dump_buf << " Name: " << name_info_pair.first; - dump_buf << " Monitor: " << std::boolalpha << name_info_pair.second.is_monitor - << std::noboolalpha << std::endl; - } - } - } - std::string buf = dump_buf.str(); - if (!android::base::WriteStringToFd(buf, fd)) { - PLOG(ERROR) << "Failed to dump state to fd"; - } - fsync(fd); - } - return Void(); -} - -} // namespace implementation -} // namespace V2_0 -} // namespace thermal -} // namespace hardware -} // namespace android diff --git a/hidl/thermal/Thermal.h b/hidl/thermal/Thermal.h deleted file mode 100644 index de17b17f..00000000 --- a/hidl/thermal/Thermal.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * 2022 The LineageOS Project - * - * 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. - */ - -#pragma once - -#include -#include - -#include -#include -#include - -#include "thermal-helper.h" - -namespace android { -namespace hardware { -namespace thermal { -namespace V2_0 { -namespace implementation { - -using ::android::sp; -using ::android::hardware::hidl_vec; -using ::android::hardware::Return; -using ::android::hardware::thermal::V2_0::IThermal; -using ::android::hardware::thermal::V2_0::IThermalChangedCallback; - -struct CallbackSetting { - CallbackSetting(sp callback, bool is_filter_type, - TemperatureType_2_0 type) - : callback(callback), is_filter_type(is_filter_type), type(type) {} - sp callback; - bool is_filter_type; - TemperatureType_2_0 type; -}; - -class Thermal : public IThermal { - public: - Thermal(); - ~Thermal() = default; - - // Disallow copy and assign. - Thermal(const Thermal &) = delete; - void operator=(const Thermal &) = delete; - - // Methods from ::android::hardware::thermal::V1_0::IThermal. - Return getTemperatures(getTemperatures_cb _hidl_cb) override; - Return getCpuUsages(getCpuUsages_cb _hidl_cb) override; - Return getCoolingDevices(getCoolingDevices_cb _hidl_cb) override; - - // Methods from ::android::hardware::thermal::V2_0::IThermal follow. - Return getCurrentTemperatures(bool filterType, TemperatureType_2_0 type, - getCurrentTemperatures_cb _hidl_cb) override; - Return getTemperatureThresholds(bool filterType, TemperatureType_2_0 type, - getTemperatureThresholds_cb _hidl_cb) override; - Return registerThermalChangedCallback(const sp &callback, - bool filterType, TemperatureType_2_0 type, - registerThermalChangedCallback_cb _hidl_cb) override; - Return unregisterThermalChangedCallback( - const sp &callback, - unregisterThermalChangedCallback_cb _hidl_cb) override; - Return getCurrentCoolingDevices(bool filterType, CoolingType type, - getCurrentCoolingDevices_cb _hidl_cb) override; - - // Methods from ::android::hidl::base::V1_0::IBase follow. - Return debug(const hidl_handle &fd, const hidl_vec &args) override; - - // Helper function for calling callbacks - void sendThermalChangedCallback(const std::vector &temps); - - private: - ThermalHelper thermal_helper_; - std::mutex thermal_callback_mutex_; - std::vector callbacks_; -}; - -} // namespace implementation -} // namespace V2_0 -} // namespace thermal -} // namespace hardware -} // namespace android diff --git a/hidl/thermal/android.hardware.thermal@2.0-service.samsung.rc b/hidl/thermal/android.hardware.thermal@2.0-service.samsung.rc deleted file mode 100644 index 17c14a5d..00000000 --- a/hidl/thermal/android.hardware.thermal@2.0-service.samsung.rc +++ /dev/null @@ -1,6 +0,0 @@ -service vendor.thermal-hal-2-0 /vendor/bin/hw/android.hardware.thermal@2.0-service.samsung - interface android.hardware.thermal@1.0::IThermal default - interface android.hardware.thermal@2.0::IThermal default - class hal - user system - group system diff --git a/hidl/thermal/android.hardware.thermal@2.0-service.samsung.xml b/hidl/thermal/android.hardware.thermal@2.0-service.samsung.xml deleted file mode 100644 index bcd6344b..00000000 --- a/hidl/thermal/android.hardware.thermal@2.0-service.samsung.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - android.hardware.thermal - hwbinder - 1.0 - 2.0 - - IThermal - default - - - diff --git a/hidl/thermal/init.thermal.logging.sh b/hidl/thermal/init.thermal.logging.sh deleted file mode 100755 index de385ab5..00000000 --- a/hidl/thermal/init.thermal.logging.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/vendor/bin/sh - -if [ $# -eq 1 ]; then - interval=$1 -else - exit 1 -fi - -while true -do - logline="tz:" - for f in /sys/class/thermal/thermal* - do - temp=`cat $f/temp` - logline+="|$temp" - done - logline+=" cdev:" - for f in /sys/class/thermal/cooling_device* - do - cur_state=`cat $f/cur_state` - logline+="|$cur_state" - done - log -p w -t THERMAL_LOG $logline - sleep $interval -done diff --git a/hidl/thermal/samsung-thermal-logd.rc b/hidl/thermal/samsung-thermal-logd.rc deleted file mode 100644 index f973cbc9..00000000 --- a/hidl/thermal/samsung-thermal-logd.rc +++ /dev/null @@ -1,14 +0,0 @@ -on property:persist.vendor.log.thermal=1 - start vendor.thermal.logd - -on property:persist.vendor.log.thermal=0 - stop vendor.thermal.logd - -on property:persist.vendor.log.thermal=1 && property:persist.vendor.log.thermal.interval=* - restart vendor.thermal.logd - -service vendor.thermal.logd /vendor/bin/thermal_logd.samsung ${persist.vendor.log.thermal.interval:-5} - class main - user root - group root system - disabled diff --git a/hidl/thermal/service.cpp b/hidl/thermal/service.cpp deleted file mode 100644 index 8c79920a..00000000 --- a/hidl/thermal/service.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include -#include -#include "Thermal.h" - -using ::android::OK; -using ::android::status_t; - -// libhwbinder: -using ::android::hardware::configureRpcThreadpool; -using ::android::hardware::joinRpcThreadpool; - -// Generated HIDL files: -using ::android::hardware::thermal::V2_0::IThermal; -using ::android::hardware::thermal::V2_0::implementation::Thermal; - -static int shutdown() { - LOG(ERROR) << "Samsung Thermal HAL Service is shutting down."; - return 1; -} - -int main(int /* argc */, char ** /* argv */) { - status_t status; - android::sp service = nullptr; - - LOG(INFO) << "Samsung Thermal HAL Service 2.0 starting..."; - - service = new Thermal(); - if (service == nullptr) { - LOG(ERROR) << "Error creating an instance of Thermal HAL. Exiting..."; - return shutdown(); - } - - configureRpcThreadpool(1, true /* callerWillJoin */); - - status = service->registerAsService(); - if (status != OK) { - LOG(ERROR) << "Could not register service for ThermalHAL (" << status << ")"; - return shutdown(); - } - - LOG(INFO) << "Samsung Thermal HAL Service 2.0 started successfully."; - joinRpcThreadpool(); - // We should not get past the joinRpcThreadpool(). - return shutdown(); -} diff --git a/hidl/thermal/thermal-helper.cpp b/hidl/thermal/thermal-helper.cpp deleted file mode 100644 index b84b1a9a..00000000 --- a/hidl/thermal/thermal-helper.cpp +++ /dev/null @@ -1,622 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "thermal-helper.h" - -namespace android { -namespace hardware { -namespace thermal { -namespace V2_0 { -namespace implementation { - -constexpr std::string_view kCpuOnlineRoot("/sys/devices/system/cpu"); -constexpr std::string_view kThermalSensorsRoot("/sys/devices/virtual/thermal"); -constexpr std::string_view kCpuUsageFile("/proc/stat"); -constexpr std::string_view kCpuOnlineFileSuffix("online"); -constexpr std::string_view kCpuPresentFile("/sys/devices/system/cpu/present"); -constexpr std::string_view kSensorPrefix("thermal_zone"); -constexpr std::string_view kCoolingDevicePrefix("cooling_device"); -constexpr std::string_view kThermalNameFile("type"); -constexpr std::string_view kSensorPolicyFile("policy"); -constexpr std::string_view kSensorTempSuffix("temp"); -constexpr std::string_view kSensorTripPointTempZeroFile("trip_point_0_temp"); -constexpr std::string_view kSensorTripPointHystZeroFile("trip_point_0_hyst"); -constexpr std::string_view kUserSpaceSuffix("user_space"); -constexpr std::string_view kCoolingDeviceCurStateSuffix("cur_state"); -constexpr std::string_view kConfigProperty("vendor.thermal.config"); -constexpr std::string_view kConfigDefaultFileName("thermal_info_config.json"); - -namespace { -using android::base::StringPrintf; - -/* - * The phone don't offline CPU, so std::thread::hardware_concurrency(); should - * work. - * However /sys/devices/system/cpu/present is preferred. - * The file is expected to contain single text line with two numbers %d-%d, - * which is a range of available cpu numbers, e.g. 0-7 would mean there - * are 8 cores number from 0 to 7. - * For Android systems this approach is safer than using cpufeatures, see bug - * b/36941727. - */ -std::size_t getNumberOfCores() { - std::string file; - if (!android::base::ReadFileToString(kCpuPresentFile.data(), &file)) { - LOG(ERROR) << "Error reading Cpu present file: " << kCpuPresentFile; - return 0; - } - std::vector pieces = android::base::Split(file, "-"); - if (pieces.size() != 2) { - LOG(ERROR) << "Error parsing Cpu present file content: " << file; - return 0; - } - auto min_core = std::stoul(pieces[0]); - auto max_core = std::stoul(pieces[1]); - if (max_core < min_core) { - LOG(ERROR) << "Error parsing Cpu present min and max: " << min_core << " - " << max_core; - return 0; - } - return static_cast(max_core - min_core + 1); -} -const std::size_t kMaxCpus = getNumberOfCores(); - -void parseCpuUsagesFileAndAssignUsages(hidl_vec *cpu_usages) { - uint64_t cpu_num, user, nice, system, idle; - std::string cpu_name; - std::string data; - if (!android::base::ReadFileToString(kCpuUsageFile.data(), &data)) { - LOG(ERROR) << "Error reading Cpu usage file: " << kCpuUsageFile; - return; - } - - std::istringstream stat_data(data); - std::string line; - while (std::getline(stat_data, line)) { - if (line.find("cpu") == 0 && isdigit(line[3])) { - // Split the string using spaces. - std::vector words = android::base::Split(line, " "); - cpu_name = words[0]; - cpu_num = std::stoi(cpu_name.substr(3)); - - if (cpu_num < kMaxCpus) { - user = std::stoi(words[1]); - nice = std::stoi(words[2]); - system = std::stoi(words[3]); - idle = std::stoi(words[4]); - - // Check if the CPU is online by reading the online file. - std::string cpu_online_path = - StringPrintf("%s/%s/%s", kCpuOnlineRoot.data(), cpu_name.c_str(), - kCpuOnlineFileSuffix.data()); - std::string is_online; - if (!android::base::ReadFileToString(cpu_online_path, &is_online)) { - LOG(ERROR) << "Could not open Cpu online file: " << cpu_online_path; - return; - } - is_online = android::base::Trim(is_online); - - (*cpu_usages)[cpu_num].name = cpu_name; - (*cpu_usages)[cpu_num].active = user + nice + system; - (*cpu_usages)[cpu_num].total = user + nice + system + idle; - (*cpu_usages)[cpu_num].isOnline = (is_online == "1") ? true : false; - } else { - LOG(ERROR) << "Unexpected cpu number: " << words[0]; - return; - } - } - } -} - -std::map parseThermalPathMap(std::string_view prefix) { - std::map path_map; - std::unique_ptr dir(opendir(kThermalSensorsRoot.data()), closedir); - if (!dir) { - return path_map; - } - - // std::filesystem is not available for vendor yet - // see discussion: aosp/894015 - while (struct dirent *dp = readdir(dir.get())) { - if (dp->d_type != DT_DIR) { - continue; - } - - if (!android::base::StartsWith(dp->d_name, prefix.data())) { - continue; - } - - std::string path = android::base::StringPrintf("%s/%s/%s", kThermalSensorsRoot.data(), - dp->d_name, kThermalNameFile.data()); - std::string name; - if (!android::base::ReadFileToString(path, &name)) { - PLOG(ERROR) << "Failed to read from " << path; - continue; - } - - path_map.emplace( - android::base::Trim(name), - android::base::StringPrintf("%s/%s", kThermalSensorsRoot.data(), dp->d_name)); - } - - return path_map; -} - -} // namespace - -/* - * Populate the sensor_name_to_file_map_ map by walking through the file tree, - * reading the type file and assigning the temp file path to the map. If we do - * not succeed, abort. - */ -ThermalHelper::ThermalHelper(const NotificationCallback &cb) - : thermal_watcher_(new ThermalWatcher( - std::bind(&ThermalHelper::thermalWatcherCallbackFunc, this, std::placeholders::_1))), - cb_(cb), - cooling_device_info_map_(ParseCoolingDevice( - "/vendor/etc/" + - android::base::GetProperty(kConfigProperty.data(), kConfigDefaultFileName.data()))), - sensor_info_map_(ParseSensorInfo( - "/vendor/etc/" + - android::base::GetProperty(kConfigProperty.data(), kConfigDefaultFileName.data()))) { - for (auto const &name_status_pair : sensor_info_map_) { - sensor_status_map_[name_status_pair.first] = { - .severity = ThrottlingSeverity::NONE, - .prev_hot_severity = ThrottlingSeverity::NONE, - .prev_cold_severity = ThrottlingSeverity::NONE, - }; - } - - auto tz_map = parseThermalPathMap(kSensorPrefix.data()); - auto cdev_map = parseThermalPathMap(kCoolingDevicePrefix.data()); - - is_initialized_ = initializeSensorMap(tz_map) && initializeCoolingDevices(cdev_map); - if (!is_initialized_) { - LOG(FATAL) << "ThermalHAL could not be initialized properly."; - } - std::set monitored_sensors; - std::transform(sensor_info_map_.cbegin(), sensor_info_map_.cend(), - std::inserter(monitored_sensors, monitored_sensors.begin()), - [](std::pair const &sensor) { - if (sensor.second.is_monitor) - return sensor.first; - else - return std::string(); - }); - - thermal_watcher_->registerFilesToWatch(monitored_sensors, initializeTrip(tz_map)); - - // Need start watching after status map initialized - is_initialized_ = thermal_watcher_->startWatchingDeviceFiles(); - if (!is_initialized_) { - LOG(FATAL) << "ThermalHAL could not start watching thread properly."; - } -} - -bool ThermalHelper::readCoolingDevice(std::string_view cooling_device, - CoolingDevice_2_0 *out) const { - // Read the file. If the file can't be read temp will be empty string. - std::string data; - - if (!cooling_devices_.readThermalFile(cooling_device, &data)) { - LOG(ERROR) << "readCoolingDevice: failed to read cooling_device: " << cooling_device; - return false; - } - - const CoolingType &type = cooling_device_info_map_.at(cooling_device.data()); - - out->type = type; - out->name = cooling_device.data(); - out->value = std::stoi(data); - - return true; -} - -bool ThermalHelper::readTemperature(std::string_view sensor_name, Temperature_1_0 *out) const { - // Read the file. If the file can't be read temp will be empty string. - std::string temp; - - if (!thermal_sensors_.readThermalFile(sensor_name, &temp)) { - LOG(ERROR) << "readTemperature: sensor not found: " << sensor_name; - return false; - } - - if (temp.empty()) { - LOG(ERROR) << "readTemperature: failed to read sensor: " << sensor_name; - return false; - } - - const SensorInfo &sensor_info = sensor_info_map_.at(sensor_name.data()); - TemperatureType_1_0 type = - (static_cast(sensor_info.type) > static_cast(TemperatureType_1_0::SKIN)) - ? TemperatureType_1_0::UNKNOWN - : static_cast(sensor_info.type); - out->type = type; - out->name = sensor_name.data(); - out->currentValue = std::stof(temp) * sensor_info.multiplier; - out->throttlingThreshold = - sensor_info.hot_thresholds[static_cast(ThrottlingSeverity::SEVERE)]; - out->shutdownThreshold = - sensor_info.hot_thresholds[static_cast(ThrottlingSeverity::SHUTDOWN)]; - out->vrThrottlingThreshold = sensor_info.vr_threshold; - - return true; -} - -bool ThermalHelper::readTemperature( - std::string_view sensor_name, Temperature_2_0 *out, - std::pair *throtting_status) const { - // Read the file. If the file can't be read temp will be empty string. - std::string temp; - - if (!thermal_sensors_.readThermalFile(sensor_name, &temp)) { - LOG(ERROR) << "readTemperature: sensor not found: " << sensor_name; - return false; - } - - if (temp.empty()) { - LOG(ERROR) << "readTemperature: failed to read sensor: " << sensor_name; - return false; - } - - const auto &sensor_info = sensor_info_map_.at(sensor_name.data()); - out->type = sensor_info.type; - out->name = sensor_name.data(); - out->value = std::stof(temp) * sensor_info.multiplier; - - std::pair status = - std::make_pair(ThrottlingSeverity::NONE, ThrottlingSeverity::NONE); - // Only update status if the thermal sensor is being monitored - if (sensor_info.is_monitor) { - ThrottlingSeverity prev_hot_severity, prev_cold_severity; - { - // reader lock, readTemperature will be called in Binder call and the watcher thread. - std::shared_lock _lock(sensor_status_map_mutex_); - prev_hot_severity = sensor_status_map_.at(sensor_name.data()).prev_hot_severity; - prev_cold_severity = sensor_status_map_.at(sensor_name.data()).prev_cold_severity; - } - status = getSeverityFromThresholds(sensor_info.hot_thresholds, sensor_info.cold_thresholds, - sensor_info.hot_hysteresis, sensor_info.cold_hysteresis, - prev_hot_severity, prev_cold_severity, out->value); - } - if (throtting_status) { - *throtting_status = status; - } - - out->throttlingStatus = static_cast(status.first) > static_cast(status.second) - ? status.first - : status.second; - - return true; -} - -bool ThermalHelper::readTemperatureThreshold(std::string_view sensor_name, - TemperatureThreshold *out) const { - // Read the file. If the file can't be read temp will be empty string. - std::string temp; - std::string path; - - if (!sensor_info_map_.count(sensor_name.data())) { - LOG(ERROR) << __func__ << ": sensor not found: " << sensor_name; - return false; - } - - const auto &sensor_info = sensor_info_map_.at(sensor_name.data()); - - out->type = sensor_info.type; - out->name = sensor_name.data(); - out->hotThrottlingThresholds = sensor_info.hot_thresholds; - out->coldThrottlingThresholds = sensor_info.cold_thresholds; - out->vrThrottlingThreshold = sensor_info.vr_threshold; - return true; -} - -std::pair ThermalHelper::getSeverityFromThresholds( - const ThrottlingArray &hot_thresholds, const ThrottlingArray &cold_thresholds, - const ThrottlingArray &hot_hysteresis, const ThrottlingArray &cold_hysteresis, - ThrottlingSeverity prev_hot_severity, ThrottlingSeverity prev_cold_severity, - float value) const { - ThrottlingSeverity ret_hot = ThrottlingSeverity::NONE; - ThrottlingSeverity ret_hot_hysteresis = ThrottlingSeverity::NONE; - ThrottlingSeverity ret_cold = ThrottlingSeverity::NONE; - ThrottlingSeverity ret_cold_hysteresis = ThrottlingSeverity::NONE; - - // Here we want to control the iteration from high to low, and hidl_enum_range doesn't support - // a reverse iterator yet. - for (size_t i = static_cast(ThrottlingSeverity::SHUTDOWN); - i > static_cast(ThrottlingSeverity::NONE); --i) { - if (!std::isnan(hot_thresholds[i]) && hot_thresholds[i] <= value && - ret_hot == ThrottlingSeverity::NONE) { - ret_hot = static_cast(i); - } - if (!std::isnan(hot_thresholds[i]) && (hot_thresholds[i] - hot_hysteresis[i]) < value && - ret_hot_hysteresis == ThrottlingSeverity::NONE) { - ret_hot_hysteresis = static_cast(i); - } - if (!std::isnan(cold_thresholds[i]) && cold_thresholds[i] >= value && - ret_cold == ThrottlingSeverity::NONE) { - ret_cold = static_cast(i); - } - if (!std::isnan(cold_thresholds[i]) && (cold_thresholds[i] + cold_hysteresis[i]) > value && - ret_cold_hysteresis == ThrottlingSeverity::NONE) { - ret_cold_hysteresis = static_cast(i); - } - } - if (static_cast(ret_hot) < static_cast(prev_hot_severity)) { - ret_hot = ret_hot_hysteresis; - } - if (static_cast(ret_cold) < static_cast(prev_cold_severity)) { - ret_cold = ret_cold_hysteresis; - } - - return std::make_pair(ret_hot, ret_cold); -} - -bool ThermalHelper::initializeSensorMap(const std::map &path_map) { - for (const auto &sensor_info_pair : sensor_info_map_) { - std::string_view sensor_name = sensor_info_pair.first; - if (!path_map.count(sensor_name.data())) { - LOG(ERROR) << "Could not find " << sensor_name << " in sysfs"; - continue; - } - std::string path = android::base::StringPrintf( - "%s/%s", path_map.at(sensor_name.data()).c_str(), kSensorTempSuffix.data()); - if (!thermal_sensors_.addThermalFile(sensor_name, path)) { - LOG(ERROR) << "Could not add " << sensor_name << "to sensors map"; - } - } - if (sensor_info_map_.size() == thermal_sensors_.getNumThermalFiles()) { - return true; - } - return false; -} - -bool ThermalHelper::initializeCoolingDevices(const std::map &path_map) { - for (const auto &cooling_device_info_pair : cooling_device_info_map_) { - std::string_view cooling_device_name = cooling_device_info_pair.first; - if (!path_map.count(cooling_device_name.data())) { - LOG(ERROR) << "Could not find " << cooling_device_name << " in sysfs"; - continue; - } - std::string path = android::base::StringPrintf( - "%s/%s", path_map.at(cooling_device_name.data()).c_str(), - kCoolingDeviceCurStateSuffix.data()); - if (!cooling_devices_.addThermalFile(cooling_device_name, path)) { - LOG(ERROR) << "Could not add " << cooling_device_name << "to cooling device map"; - continue; - } - } - - if (cooling_device_info_map_.size() == cooling_devices_.getNumThermalFiles()) { - return true; - } - return false; -} - -bool ThermalHelper::initializeTrip(const std::map &path_map) { - for (const auto &sensor_info : sensor_info_map_) { - if (sensor_info.second.is_monitor) { - std::string_view sensor_name = sensor_info.first; - std::string_view tz_path = path_map.at(sensor_name.data()); - std::string tz_policy; - std::string path = android::base::StringPrintf("%s/%s", (tz_path.data()), - kSensorPolicyFile.data()); - if (!android::base::ReadFileToString(path, &tz_policy)) { - LOG(ERROR) << sensor_name << " could not open tz policy file:" << path; - return false; - } - // Check if thermal zone support uevent notify - tz_policy = android::base::Trim(tz_policy); - if (tz_policy != kUserSpaceSuffix) { - LOG(ERROR) << sensor_name << " does not support uevent notify"; - return false; - } - - // Update thermal zone trip point - for (size_t i = 0; i < kThrottlingSeverityCount; ++i) { - if (!std::isnan(sensor_info.second.hot_thresholds[i]) && - !std::isnan(sensor_info.second.hot_hysteresis[i])) { - // Update trip_point_0_temp threshold - std::string threshold = std::to_string(static_cast( - sensor_info.second.hot_thresholds[i] / sensor_info.second.multiplier)); - path = android::base::StringPrintf("%s/%s", (tz_path.data()), - kSensorTripPointTempZeroFile.data()); - if (!android::base::WriteStringToFile(threshold, path)) { - LOG(ERROR) << "fail to update " << sensor_name - << " trip point: " << threshold << path; - return false; - } - // Update trip_point_0_hyst threshold - threshold = std::to_string(static_cast( - sensor_info.second.hot_hysteresis[i] / sensor_info.second.multiplier)); - path = android::base::StringPrintf("%s/%s", (tz_path.data()), - kSensorTripPointHystZeroFile.data()); - if (!android::base::WriteStringToFile(threshold, path)) { - LOG(ERROR) << "fail to update " << sensor_name << "trip hyst" << threshold - << path; - return false; - } - break; - } else if (i == kThrottlingSeverityCount - 1) { - LOG(ERROR) << sensor_name << ":all thresholds are NAN"; - return false; - } - } - } - } - return true; -} -bool ThermalHelper::fillTemperatures(hidl_vec *temperatures) const { - temperatures->resize(sensor_info_map_.size()); - int current_index = 0; - for (const auto &name_info_pair : sensor_info_map_) { - Temperature_1_0 temp; - - if (readTemperature(name_info_pair.first, &temp)) { - (*temperatures)[current_index] = temp; - } else { - LOG(ERROR) << __func__ - << ": error reading temperature for sensor: " << name_info_pair.first; - return false; - } - ++current_index; - } - return current_index > 0; -} - -bool ThermalHelper::fillCurrentTemperatures(bool filterType, TemperatureType_2_0 type, - hidl_vec *temperatures) const { - std::vector ret; - for (const auto &name_info_pair : sensor_info_map_) { - Temperature_2_0 temp; - if (filterType && name_info_pair.second.type != type) { - continue; - } - if (readTemperature(name_info_pair.first, &temp)) { - ret.emplace_back(std::move(temp)); - } else { - LOG(ERROR) << __func__ - << ": error reading temperature for sensor: " << name_info_pair.first; - return false; - } - } - *temperatures = ret; - return ret.size() > 0; -} - -bool ThermalHelper::fillTemperatureThresholds(bool filterType, TemperatureType_2_0 type, - hidl_vec *thresholds) const { - std::vector ret; - for (const auto &name_info_pair : sensor_info_map_) { - TemperatureThreshold temp; - if (filterType && name_info_pair.second.type != type) { - continue; - } - if (readTemperatureThreshold(name_info_pair.first, &temp)) { - ret.emplace_back(std::move(temp)); - } else { - LOG(ERROR) << __func__ << ": error reading temperature threshold for sensor: " - << name_info_pair.first; - return false; - } - } - *thresholds = ret; - return ret.size() > 0; -} - -bool ThermalHelper::fillCurrentCoolingDevices(bool filterType, CoolingType type, - hidl_vec *cooling_devices) const { - std::vector ret; - for (const auto &name_info_pair : cooling_device_info_map_) { - CoolingDevice_2_0 value; - if (filterType && name_info_pair.second != type) { - continue; - } - if (readCoolingDevice(name_info_pair.first, &value)) { - ret.emplace_back(std::move(value)); - } else { - LOG(ERROR) << __func__ << ": error reading cooling device: " << name_info_pair.first; - return false; - } - } - *cooling_devices = ret; - return ret.size() > 0; -} - -bool ThermalHelper::fillCpuUsages(hidl_vec *cpu_usages) const { - cpu_usages->resize(kMaxCpus); - parseCpuUsagesFileAndAssignUsages(cpu_usages); - return true; -} - -// This is called in the different thread context and will update sensor_status -// uevent_sensors is the set of sensors which trigger uevent from thermal core driver. -bool ThermalHelper::thermalWatcherCallbackFunc(const std::set &uevent_sensors) { - std::vector temps; - bool thermal_triggered = false; - for (auto &name_status_pair : sensor_status_map_) { - Temperature_2_0 temp; - TemperatureThreshold threshold; - SensorStatus &sensor_status = name_status_pair.second; - const SensorInfo &sensor_info = sensor_info_map_.at(name_status_pair.first); - // Only send notification on whitelisted sensors - if (!sensor_info.is_monitor) { - continue; - } - // If callback is triggered by uevent, only check the sensors within uevent_sensors - if (uevent_sensors.size() != 0 && - uevent_sensors.find(name_status_pair.first) == uevent_sensors.end()) { - if (sensor_status.severity != ThrottlingSeverity::NONE) { - thermal_triggered = true; - } - continue; - } - - std::pair throtting_status; - if (!readTemperature(name_status_pair.first, &temp, &throtting_status)) { - LOG(ERROR) << __func__ - << ": error reading temperature for sensor: " << name_status_pair.first; - continue; - } - if (!readTemperatureThreshold(name_status_pair.first, &threshold)) { - LOG(ERROR) << __func__ << ": error reading temperature threshold for sensor: " - << name_status_pair.first; - continue; - } - - { - // writer lock - std::unique_lock _lock(sensor_status_map_mutex_); - if (throtting_status.first != sensor_status.prev_hot_severity) { - sensor_status.prev_hot_severity = throtting_status.first; - } - if (throtting_status.second != sensor_status.prev_cold_severity) { - sensor_status.prev_cold_severity = throtting_status.second; - } - if (temp.throttlingStatus != sensor_status.severity) { - temps.push_back(temp); - sensor_status.severity = temp.throttlingStatus; - } - } - if (sensor_status.severity != ThrottlingSeverity::NONE) { - thermal_triggered = true; - LOG(INFO) << temp.name << ": " << temp.value; - } - } - if (!temps.empty() && cb_) { - cb_(temps); - } - - return thermal_triggered; -} - -} // namespace implementation -} // namespace V2_0 -} // namespace thermal -} // namespace hardware -} // namespace android diff --git a/hidl/thermal/thermal-helper.h b/hidl/thermal/thermal-helper.h deleted file mode 100644 index 52264942..00000000 --- a/hidl/thermal/thermal-helper.h +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (c) 2018, The Linux Foundation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * * Neither the name of The Linux Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "utils/config_parser.h" -#include "utils/thermal_files.h" -#include "utils/thermal_watcher.h" - -namespace android { -namespace hardware { -namespace thermal { -namespace V2_0 { -namespace implementation { - -using ::android::hardware::hidl_vec; -using ::android::hardware::thermal::V1_0::CpuUsage; -using ::android::hardware::thermal::V2_0::CoolingType; -using ::android::hardware::thermal::V2_0::IThermal; -using CoolingDevice_1_0 = ::android::hardware::thermal::V1_0::CoolingDevice; -using CoolingDevice_2_0 = ::android::hardware::thermal::V2_0::CoolingDevice; -using Temperature_1_0 = ::android::hardware::thermal::V1_0::Temperature; -using Temperature_2_0 = ::android::hardware::thermal::V2_0::Temperature; -using TemperatureType_1_0 = ::android::hardware::thermal::V1_0::TemperatureType; -using TemperatureType_2_0 = ::android::hardware::thermal::V2_0::TemperatureType; -using ::android::hardware::thermal::V2_0::TemperatureThreshold; -using ::android::hardware::thermal::V2_0::ThrottlingSeverity; - -using NotificationCallback = std::function &temps)>; -using NotificationTime = std::chrono::time_point; - -struct SensorStatus { - ThrottlingSeverity severity; - ThrottlingSeverity prev_hot_severity; - ThrottlingSeverity prev_cold_severity; -}; - -class ThermalHelper { - public: - ThermalHelper(const NotificationCallback &cb); - ~ThermalHelper() = default; - - bool fillTemperatures(hidl_vec *temperatures) const; - bool fillCurrentTemperatures(bool filterType, TemperatureType_2_0 type, - hidl_vec *temperatures) const; - bool fillTemperatureThresholds(bool filterType, TemperatureType_2_0 type, - hidl_vec *thresholds) const; - bool fillCurrentCoolingDevices(bool filterType, CoolingType type, - hidl_vec *coolingdevices) const; - bool fillCpuUsages(hidl_vec *cpu_usages) const; - - // Dissallow copy and assign. - ThermalHelper(const ThermalHelper &) = delete; - void operator=(const ThermalHelper &) = delete; - - bool isInitializedOk() const { return is_initialized_; } - - // Read the temperature of a single sensor. - bool readTemperature(std::string_view sensor_name, Temperature_1_0 *out) const; - bool readTemperature( - std::string_view sensor_name, Temperature_2_0 *out, - std::pair *throtting_status = nullptr) const; - bool readTemperatureThreshold(std::string_view sensor_name, TemperatureThreshold *out) const; - // Read the value of a single cooling device. - bool readCoolingDevice(std::string_view cooling_device, CoolingDevice_2_0 *out) const; - // Get SensorInfo Map - const std::map &GetSensorInfoMap() const { return sensor_info_map_; } - - private: - bool initializeSensorMap(const std::map &path_map); - bool initializeCoolingDevices(const std::map &path_map); - bool initializeTrip(const std::map &path_map); - - // For thermal_watcher_'s polling thread - bool thermalWatcherCallbackFunc(const std::set &uevent_sensors); - // Return hot and cold severity status as std::pair - std::pair getSeverityFromThresholds( - const ThrottlingArray &hot_thresholds, const ThrottlingArray &cold_thresholds, - const ThrottlingArray &hot_hysteresis, const ThrottlingArray &cold_hysteresis, - ThrottlingSeverity prev_hot_severity, ThrottlingSeverity prev_cold_severity, - float value) const; - - sp thermal_watcher_; - ThermalFiles thermal_sensors_; - ThermalFiles cooling_devices_; - bool is_initialized_; - const NotificationCallback cb_; - const std::map cooling_device_info_map_; - const std::map sensor_info_map_; - - mutable std::shared_mutex sensor_status_map_mutex_; - std::map sensor_status_map_; -}; - -} // namespace implementation -} // namespace V2_0 -} // namespace thermal -} // namespace hardware -} // namespace android diff --git a/hidl/thermal/thermal_info_config_template.json b/hidl/thermal/thermal_info_config_template.json deleted file mode 100644 index 084b06e5..00000000 --- a/hidl/thermal/thermal_info_config_template.json +++ /dev/null @@ -1,160 +0,0 @@ -{ - "Sensors":[ - { - "Name":"therm_zone0", - "Type":"CPU", - "HotThreshold":[ - "NAN", - 76.0, - 81.0, - 86.0, - 96.0, - 101.0, - 115.0 - ], - "VrThreshold":"NAN", - "Multiplier":0.001 - }, - { - "Name":"therm_zone1", - "Type":"CPU", - "HotThreshold":[ - "NAN", - 76.0, - 81.0, - 86.0, - 96.0, - 101.0, - 115.0 - ], - "VrThreshold":"NAN", - "Multiplier":0.001 - }, - { - "Name":"therm_zone2", - "Type":"CPU", - "HotThreshold":[ - "NAN", - 76.0, - 81.0, - 86.0, - 96.0, - 101.0, - 115.0 - ], - "VrThreshold":"NAN", - "Multiplier":0.001 - }, - { - "Name":"therm_zone3", - "Type":"CPU", - "HotThreshold":[ - "NAN", - 76.0, - 81.0, - 86.0, - 96.0, - 101.0, - 115.0 - ], - "VrThreshold":"NAN", - "Multiplier":0.001 - }, - { - "Name":"therm_zone4", - "Type":"CPU", - "HotThreshold":[ - "NAN", - 76.0, - 81.0, - 86.0, - 96.0, - 101.0, - 115.0 - ], - "VrThreshold":"NAN", - "Multiplier":0.001 - }, - { - "Name":"ac", - "Type":"USB_PORT", - "HotThreshold":[ - "NAN", - "NAN", - "NAN", - "NAN", - "NAN", - "60.0", - "NAN" - ], - "HotHysteresis":[ - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 5.0, - 0.0 - ], - "VrThreshold":"NAN", - "Multiplier":0.001, - "Monitor": true - }, - { - "Name":"max77854-fuelgauge", - "Type":"UNKNOWN", - "HotThreshold":[ - "NAN", - "NAN", - "NAN", - "NAN", - "NAN", - "NAN", - "NAN" - ], - "VrThreshold":"NAN", - "Multiplier":0.001 - }, - { - "Name":"battery", - "Type":"BATTERY", - "HotThreshold":[ - "NAN", - "NAN", - "NAN", - "NAN", - "NAN", - "NAN", - 60.0 - ], - "VrThreshold":"NAN", - "Multiplier":0.001 - } - ], - "CoolingDevices":[ - { - "Name":"thermal-cpufreq-0", - "Type":"CPU" - }, - { - "Name":"thermal-cpufreq-1", - "Type":"CPU" - }, - { - "Name":"thermal-cpufreq-2", - "Type":"CPU" - }, - { - "Name":"thermal-gpufreq-0", - "Type":"GPU" - }, - { - "Name":"thermal-isp-0", - "Type":"COMPONENT" - }, - { - "Name":"battery", - "Type":"BATTERY" - } - ] -} diff --git a/hidl/thermal/utils/config_parser.cpp b/hidl/thermal/utils/config_parser.cpp deleted file mode 100644 index 3933d9fe..00000000 --- a/hidl/thermal/utils/config_parser.cpp +++ /dev/null @@ -1,302 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include -#include -#include -#include -#include - -#include -#include - -#include "config_parser.h" - -namespace android { -namespace hardware { -namespace thermal { -namespace V2_0 { -namespace implementation { - -using ::android::hardware::hidl_enum_range; -using ::android::hardware::thermal::V2_0::toString; -using TemperatureType_2_0 = ::android::hardware::thermal::V2_0::TemperatureType; - -namespace { - -template -// Return false when failed parsing -bool getTypeFromString(std::string_view str, T *out) { - auto types = hidl_enum_range(); - for (const auto &type : types) { - if (toString(type) == str) { - *out = type; - return true; - } - } - return false; -} - -float getFloatFromValue(const Json::Value &value) { - if (value.isString()) { - return std::stof(value.asString()); - } else { - return value.asFloat(); - } -} - -} // namespace - -std::map ParseSensorInfo(std::string_view config_path) { - std::string json_doc; - std::map sensors_parsed; - if (!android::base::ReadFileToString(config_path.data(), &json_doc)) { - LOG(ERROR) << "Failed to read JSON config from " << config_path; - return sensors_parsed; - } - - Json::Value root; - Json::CharReaderBuilder builder; - std::unique_ptr reader(builder.newCharReader()); - std::string errorMessage; - - if (!reader->parse(&*json_doc.begin(), &*json_doc.end(), &root, &errorMessage)) { - LOG(ERROR) << "Failed to parse JSON config"; - return sensors_parsed; - } - - Json::Value sensors = root["Sensors"]; - std::size_t total_parsed = 0; - std::set sensors_name_parsed; - - for (Json::Value::ArrayIndex i = 0; i < sensors.size(); ++i) { - const std::string &name = sensors[i]["Name"].asString(); - LOG(INFO) << "Sensor[" << i << "]'s Name: " << name; - if (name.empty()) { - LOG(ERROR) << "Failed to read " - << "Sensor[" << i << "]'s Name"; - sensors_parsed.clear(); - return sensors_parsed; - } - - auto result = sensors_name_parsed.insert(name); - if (!result.second) { - LOG(ERROR) << "Duplicate Sensor[" << i << "]'s Name"; - sensors_parsed.clear(); - return sensors_parsed; - } - - std::string sensor_type_str = sensors[i]["Type"].asString(); - LOG(INFO) << "Sensor[" << name << "]'s Type: " << sensor_type_str; - TemperatureType_2_0 sensor_type; - - if (!getTypeFromString(sensor_type_str, &sensor_type)) { - LOG(ERROR) << "Invalid " - << "Sensor[" << name << "]'s Type: " << sensor_type_str; - sensors_parsed.clear(); - return sensors_parsed; - } - - std::array hot_thresholds; - hot_thresholds.fill(NAN); - std::array cold_thresholds; - cold_thresholds.fill(NAN); - std::array hot_hysteresis; - hot_hysteresis.fill(0.0); - std::array cold_hysteresis; - cold_hysteresis.fill(0.0); - - Json::Value values = sensors[i]["HotThreshold"]; - if (values.size() != kThrottlingSeverityCount) { - LOG(ERROR) << "Invalid " - << "Sensor[" << name << "]'s HotThreshold count" << values.size(); - sensors_parsed.clear(); - return sensors_parsed; - } else { - float min = std::numeric_limits::min(); - for (Json::Value::ArrayIndex j = 0; j < kThrottlingSeverityCount; ++j) { - hot_thresholds[j] = getFloatFromValue(values[j]); - if (!std::isnan(hot_thresholds[j])) { - if (hot_thresholds[j] < min) { - LOG(ERROR) << "Invalid " - << "Sensor[" << name << "]'s HotThreshold[j" << j - << "]: " << hot_thresholds[j] << " < " << min; - sensors_parsed.clear(); - return sensors_parsed; - } - min = hot_thresholds[j]; - } - LOG(INFO) << "Sensor[" << name << "]'s HotThreshold[" << j - << "]: " << hot_thresholds[j]; - } - } - - values = sensors[i]["HotHysteresis"]; - if (values.size() != kThrottlingSeverityCount) { - LOG(INFO) << "Cannot find valid " - << "Sensor[" << name << "]'s HotHysteresis, default all to 0.0"; - } else { - for (Json::Value::ArrayIndex j = 0; j < kThrottlingSeverityCount; ++j) { - hot_hysteresis[j] = getFloatFromValue(values[j]); - if (std::isnan(hot_hysteresis[j])) { - LOG(ERROR) << "Invalid " - << "Sensor[" << name << "]'s HotHysteresis: " << hot_hysteresis[j]; - sensors_parsed.clear(); - return sensors_parsed; - } - LOG(INFO) << "Sensor[" << name << "]'s HotHysteresis[" << j - << "]: " << hot_hysteresis[j]; - } - } - - values = sensors[i]["ColdThreshold"]; - if (values.size() != kThrottlingSeverityCount) { - LOG(INFO) << "Cannot find valid " - << "Sensor[" << name << "]'s ColdThreshold, default all to NAN"; - } else { - float max = std::numeric_limits::max(); - for (Json::Value::ArrayIndex j = 0; j < kThrottlingSeverityCount; ++j) { - cold_thresholds[j] = getFloatFromValue(values[j]); - if (!std::isnan(cold_thresholds[j])) { - if (cold_thresholds[j] > max) { - LOG(ERROR) << "Invalid " - << "Sensor[" << name << "]'s ColdThreshold[j" << j - << "]: " << cold_thresholds[j] << " > " << max; - sensors_parsed.clear(); - return sensors_parsed; - } - max = cold_thresholds[j]; - } - LOG(INFO) << "Sensor[" << name << "]'s ColdThreshold[" << j - << "]: " << cold_thresholds[j]; - } - } - - values = sensors[i]["ColdHysteresis"]; - if (values.size() != kThrottlingSeverityCount) { - LOG(INFO) << "Cannot find valid " - << "Sensor[" << name << "]'s ColdHysteresis, default all to 0.0"; - } else { - for (Json::Value::ArrayIndex j = 0; j < kThrottlingSeverityCount; ++j) { - cold_hysteresis[j] = getFloatFromValue(values[j]); - if (std::isnan(cold_hysteresis[j])) { - LOG(ERROR) << "Invalid " - << "Sensor[" << name - << "]'s ColdHysteresis: " << cold_hysteresis[j]; - sensors_parsed.clear(); - return sensors_parsed; - } - LOG(INFO) << "Sensor[" << name << "]'s ColdHysteresis[" << j - << "]: " << cold_hysteresis[j]; - } - } - - float vr_threshold = NAN; - vr_threshold = getFloatFromValue(sensors[i]["VrThreshold"]); - LOG(INFO) << "Sensor[" << name << "]'s VrThreshold: " << vr_threshold; - - float multiplier = sensors[i]["Multiplier"].asFloat(); - LOG(INFO) << "Sensor[" << name << "]'s Multiplier: " << multiplier; - - bool is_monitor = false; - if (sensors[i]["Monitor"].empty() || !sensors[i]["Monitor"].isBool()) { - LOG(INFO) << "Failed to read Sensor[" << name << "]'s Monitor, set to 'false'"; - } else { - is_monitor = sensors[i]["Monitor"].asBool(); - } - LOG(INFO) << "Sensor[" << name << "]'s Monitor: " << std::boolalpha << is_monitor - << std::noboolalpha; - - sensors_parsed[name] = { - .type = sensor_type, - .hot_thresholds = hot_thresholds, - .cold_thresholds = cold_thresholds, - .hot_hysteresis = hot_hysteresis, - .cold_hysteresis = cold_hysteresis, - .vr_threshold = vr_threshold, - .multiplier = multiplier, - .is_monitor = is_monitor, - }; - ++total_parsed; - } - - LOG(INFO) << total_parsed << " Sensors parsed successfully"; - return sensors_parsed; -} - -std::map ParseCoolingDevice(std::string_view config_path) { - std::string json_doc; - std::map cooling_devices_parsed; - if (!android::base::ReadFileToString(config_path.data(), &json_doc)) { - LOG(ERROR) << "Failed to read JSON config from " << config_path; - return cooling_devices_parsed; - } - - Json::Value root; - Json::CharReaderBuilder builder; - std::unique_ptr reader(builder.newCharReader()); - std::string errorMessage; - - if (!reader->parse(&*json_doc.begin(), &*json_doc.end(), &root, &errorMessage)) { - LOG(ERROR) << "Failed to parse JSON config"; - return cooling_devices_parsed; - } - - Json::Value cooling_devices = root["CoolingDevices"]; - std::size_t total_parsed = 0; - std::set cooling_devices_name_parsed; - - for (Json::Value::ArrayIndex i = 0; i < cooling_devices.size(); ++i) { - const std::string &name = cooling_devices[i]["Name"].asString(); - LOG(INFO) << "CoolingDevice[" << i << "]'s Name: " << name; - if (name.empty()) { - LOG(ERROR) << "Failed to read " - << "CoolingDevice[" << i << "]'s Name"; - cooling_devices_parsed.clear(); - return cooling_devices_parsed; - } - - auto result = cooling_devices_name_parsed.insert(name.data()); - if (!result.second) { - LOG(ERROR) << "Duplicate CoolingDevice[" << i << "]'s Name"; - cooling_devices_parsed.clear(); - return cooling_devices_parsed; - } - - std::string cooling_device_type_str = cooling_devices[i]["Type"].asString(); - LOG(INFO) << "CoolingDevice[" << name << "]'s Type: " << cooling_device_type_str; - CoolingType cooling_device_type; - - if (!getTypeFromString(cooling_device_type_str, &cooling_device_type)) { - LOG(ERROR) << "Invalid " - << "CoolingDevice[" << name << "]'s Type: " << cooling_device_type_str; - cooling_devices_parsed.clear(); - return cooling_devices_parsed; - } - - cooling_devices_parsed[name] = cooling_device_type; - - ++total_parsed; - } - - LOG(INFO) << total_parsed << " CoolingDevices parsed successfully"; - return cooling_devices_parsed; -} - -} // namespace implementation -} // namespace V2_0 -} // namespace thermal -} // namespace hardware -} // namespace android diff --git a/hidl/thermal/utils/config_parser.h b/hidl/thermal/utils/config_parser.h deleted file mode 100644 index 0dba9cfe..00000000 --- a/hidl/thermal/utils/config_parser.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * 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. - */ - -#pragma once - -#include -#include - -#include - -namespace android { -namespace hardware { -namespace thermal { -namespace V2_0 { -namespace implementation { - -using ::android::hardware::hidl_enum_range; -using ::android::hardware::thermal::V2_0::CoolingType; -using TemperatureType_2_0 = ::android::hardware::thermal::V2_0::TemperatureType; -using ::android::hardware::thermal::V2_0::ThrottlingSeverity; -constexpr size_t kThrottlingSeverityCount = std::distance( - hidl_enum_range().begin(), hidl_enum_range().end()); -using ThrottlingArray = std::array(kThrottlingSeverityCount)>; - -struct SensorInfo { - TemperatureType_2_0 type; - ThrottlingArray hot_thresholds; - ThrottlingArray cold_thresholds; - ThrottlingArray hot_hysteresis; - ThrottlingArray cold_hysteresis; - float vr_threshold; - float multiplier; - bool is_monitor; -}; - -std::map ParseSensorInfo(std::string_view config_path); -std::map ParseCoolingDevice(std::string_view config_path); - -} // namespace implementation -} // namespace V2_0 -} // namespace thermal -} // namespace hardware -} // namespace android diff --git a/hidl/thermal/utils/config_schema.json b/hidl/thermal/utils/config_schema.json deleted file mode 100644 index fd493e14..00000000 --- a/hidl/thermal/utils/config_schema.json +++ /dev/null @@ -1,219 +0,0 @@ -{ - "definitions":{ - - }, - "$schema":"http://json-schema.org/draft-07/schema#", - "$id":"http://example.com/root.json", - "type":"object", - "title":"The Root Schema", - "required":[ - "Sensors" - ], - "properties":{ - "Sensors":{ - "$id":"#/properties/Sensors", - "type":"array", - "title":"The Sensors Schema", - "items":{ - "$id":"#/properties/Sensors/items", - "type":"object", - "title":"The Items Schema", - "required":[ - "Name", - "Type", - "HotThreshold", - "VrThreshold", - "Multiplier" - ], - "properties":{ - "Name":{ - "$id":"#/properties/Sensors/items/properties/Name", - "type":"string", - "title":"The Name Schema", - "default":"", - "examples":[ - "cpu0-silver-usr" - ], - "pattern":"^(.+)$" - }, - "Type":{ - "$id":"#/properties/Sensors/items/properties/Type", - "type":"string", - "title":"The Type Schema", - "default":"", - "examples":[ - "CPU" - ], - "pattern":"^(.+)$" - }, - "HotThreshold":{ - "$id":"#/properties/Sensors/items/properties/HotThreshold", - "type":"array", - "title":"The hot threshold Schema, values are thresholds from ThrottlingSeverity::NONE to ThrottlingSeverity::SHUTDOWN", - "default":"NAN", - "maxItems":7, - "minItems":7, - "items":{ - "$id":"#/properties/Sensors/items/properties/HotThreshold/items", - "type":[ - "string", - "number" - ], - "title":"The Items Schema", - "default":"", - "examples":[ - "NAN", - "NAN", - "NAN", - 95, - "NAN", - "NAN", - 125 - ], - "pattern":"^([-+]?[0-9]*\\.?[0-9]+|NAN)$" - } - }, - "HotHysteresis":{ - "$id":"#/properties/Sensors/items/properties/HotHysteresis", - "type":"array", - "title":"The hot hysteresis Schema, values are thresholds from ThrottlingSeverity::NONE to ThrottlingSeverity::SHUTDOWN. Throttling status will be cleared HotThreshold - HotHysteresis.", - "default":null, - "maxItems":7, - "minItems":7, - "items":{ - "$id":"#/properties/Sensors/items/properties/HotHysteresis/items", - "type":[ - "number" - ], - "title":"The Items Schema", - "default":0.0, - "examples":[ - 0.0, - 0.0, - 0.0, - 1.0, - 1.5, - 1.0, - 2.0 - ] - } - }, - "ColdThreshold":{ - "$id":"#/properties/Sensors/items/properties/ColdThreshold", - "type":"array", - "title":"The cold threshold Schema, values are thresholds from ThrottlingSeverity::NONE to ThrottlingSeverity::SHUTDOWN, default to NAN", - "default":null, - "maxItems":7, - "minItems":7, - "items":{ - "$id":"#/properties/Sensors/items/properties/ColdThreshold/items", - "type":"string", - "title":"The Items Schema", - "default":"NAN", - "examples":[ - "NAN", - "NAN", - "NAN", - "NAN", - "NAN", - "NAN", - "NAN" - ], - "pattern":"^([-+]?[0-9]*\\.?[0-9]+|NAN)$" - } - }, - "ColdHysteresis":{ - "$id":"#/properties/Sensors/items/properties/ColdHysteresis", - "type":"array", - "title":"The cold hysteresis Schema, values are thresholds from ThrottlingSeverity::NONE to ThrottlingSeverity::SHUTDOWN. Throttling status will be cleared ColdThreshold + ColdHysteresis.", - "default":null, - "maxItems":7, - "minItems":7, - "items":{ - "$id":"#/properties/Sensors/items/properties/ColdHysteresis/items", - "type":[ - "number" - ], - "title":"The Items Schema", - "default":0.0, - "examples":[ - 0.0, - 0.0, - 0.0, - 1.0, - 1.5, - 1.0, - 2.0 - ] - } - }, - "VrThreshold":{ - "$id":"#/properties/Sensors/items/properties/VrThreshold", - "type":"string", - "title":"The Vrthreshold Schema", - "default":"", - "examples":[ - "NAN" - ], - "pattern":"^(.*)$" - }, - "Multiplier":{ - "$id":"#/properties/Sensors/items/properties/Multiplier", - "type":"number", - "title":"The Multiplier Schema", - "default":0.001, - "examples":[ - 0.001 - ], - "exclusiveMinimum":0.0 - }, - "Monitor":{ - "$id":"#/properties/Sensors/items/properties/Monitor", - "type":"boolean", - "title":"The Monitor Schema, if the sensor will be monitored and used to trigger throttling event", - "default":false, - "examples":[ - true - ] - } - } - } - }, - "CoolingDevices":{ - "$id":"#/properties/CoolingDevices", - "type":"array", - "title":"The Coolingdevices Schema", - "items":{ - "$id":"#/properties/CoolingDevices/items", - "type":"object", - "title":"The Items Schema", - "required":[ - "Name", - "Type" - ], - "properties":{ - "Name":{ - "$id":"#/properties/CoolingDevices/items/properties/Name", - "type":"string", - "title":"The Name Schema", - "default":"", - "examples":[ - "thermal-cpufreq-0" - ], - "pattern":"^(.+)$" - }, - "Type":{ - "$id":"#/properties/CoolingDevices/items/properties/Type", - "type":"string", - "title":"The Type Schema", - "default":"", - "examples":[ - "CPU" - ], - "pattern":"^(.+)$" - } - } - } - } - } -} diff --git a/hidl/thermal/utils/thermal_files.cpp b/hidl/thermal/utils/thermal_files.cpp deleted file mode 100644 index c3948165..00000000 --- a/hidl/thermal/utils/thermal_files.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include - -#include -#include -#include -#include "thermal_files.h" - -namespace android { -namespace hardware { -namespace thermal { -namespace V2_0 { -namespace implementation { - -std::string ThermalFiles::getThermalFilePath(std::string_view thermal_name) const { - auto sensor_itr = thermal_name_to_path_map_.find(thermal_name.data()); - if (sensor_itr == thermal_name_to_path_map_.end()) { - return ""; - } - return sensor_itr->second; -} - -bool ThermalFiles::addThermalFile(std::string_view thermal_name, std::string_view path) { - return thermal_name_to_path_map_.emplace(thermal_name, path).second; -} - -bool ThermalFiles::readThermalFile(std::string_view thermal_name, std::string *data) const { - std::string sensor_reading; - std::string file_path = getThermalFilePath(std::string_view(thermal_name)); - *data = ""; - if (file_path.empty()) { - return false; - } - - if (!::android::base::ReadFileToString(file_path, &sensor_reading)) { - PLOG(WARNING) << "Failed to read sensor: " << thermal_name; - return false; - } - - // Strip the newline. - *data = ::android::base::Trim(sensor_reading); - return true; -} - -} // namespace implementation -} // namespace V2_0 -} // namespace thermal -} // namespace hardware -} // namespace android diff --git a/hidl/thermal/utils/thermal_files.h b/hidl/thermal/utils/thermal_files.h deleted file mode 100644 index 42e3eb1a..00000000 --- a/hidl/thermal/utils/thermal_files.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * 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. - */ - -#pragma once - -#include -#include - -namespace android { -namespace hardware { -namespace thermal { -namespace V2_0 { -namespace implementation { - -class ThermalFiles { - public: - ThermalFiles() = default; - ~ThermalFiles() = default; - ThermalFiles(const ThermalFiles &) = delete; - void operator=(const ThermalFiles &) = delete; - - std::string getThermalFilePath(std::string_view thermal_name) const; - // Returns true if add was successful, false otherwise. - bool addThermalFile(std::string_view thermal_name, std::string_view path); - // If thermal_name is not found in the thermal names to path map, this will set - // data to empty and return false. If the thermal_name is found and its content - // is read, this function will fill in data accordingly then return true. - bool readThermalFile(std::string_view thermal_name, std::string *data) const; - size_t getNumThermalFiles() const { return thermal_name_to_path_map_.size(); } - - private: - std::unordered_map thermal_name_to_path_map_; -}; - -} // namespace implementation -} // namespace V2_0 -} // namespace thermal -} // namespace hardware -} // namespace android diff --git a/hidl/thermal/utils/thermal_watcher.cpp b/hidl/thermal/utils/thermal_watcher.cpp deleted file mode 100644 index 31a89a05..00000000 --- a/hidl/thermal/utils/thermal_watcher.cpp +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "thermal_watcher.h" - -namespace android { -namespace hardware { -namespace thermal { -namespace V2_0 { -namespace implementation { - -using std::chrono_literals::operator""ms; - -void ThermalWatcher::registerFilesToWatch(const std::set &sensors_to_watch, - bool uevent_monitor) { - monitored_sensors_.insert(sensors_to_watch.begin(), sensors_to_watch.end()); - if (!uevent_monitor) { - is_polling_ = true; - return; - } - uevent_fd_.reset((TEMP_FAILURE_RETRY(uevent_open_socket(64 * 1024, true)))); - if (uevent_fd_.get() < 0) { - LOG(ERROR) << "failed to open uevent socket"; - is_polling_ = true; - return; - } - - fcntl(uevent_fd_, F_SETFL, O_NONBLOCK); - - looper_->addFd(uevent_fd_.get(), 0, Looper::EVENT_INPUT, nullptr, nullptr); - is_polling_ = false; - thermal_triggered_ = true; - last_update_time_ = boot_clock::now(); -} - -bool ThermalWatcher::startWatchingDeviceFiles() { - if (cb_) { - auto ret = this->run("FileWatcherThread", PRIORITY_HIGHEST); - if (ret != NO_ERROR) { - LOG(ERROR) << "ThermalWatcherThread start fail"; - return false; - } else { - LOG(INFO) << "ThermalWatcherThread started"; - return true; - } - } - return false; -} -void ThermalWatcher::parseUevent(std::set *sensors_set) { - bool thermal_event = false; - constexpr int kUeventMsgLen = 2048; - char msg[kUeventMsgLen + 2]; - char *cp; - - while (true) { - int n = uevent_kernel_multicast_recv(uevent_fd_.get(), msg, kUeventMsgLen); - if (n <= 0) { - if (errno != EAGAIN && errno != EWOULDBLOCK) { - LOG(ERROR) << "Error reading from Uevent Fd"; - } - break; - } - - if (n >= kUeventMsgLen) { - LOG(ERROR) << "Uevent overflowed buffer, discarding"; - continue; - } - - msg[n] = '\0'; - msg[n + 1] = '\0'; - - cp = msg; - while (*cp) { - std::string uevent = cp; - if (!thermal_event) { - if (uevent.find("SUBSYSTEM=") == 0) { - if (uevent.find("SUBSYSTEM=thermal") != std::string::npos) { - thermal_event = true; - } else { - break; - } - } - } else { - auto start_pos = uevent.find("NAME="); - if (start_pos != std::string::npos) { - start_pos += 5; - std::string name = uevent.substr(start_pos); - if (std::find(monitored_sensors_.begin(), monitored_sensors_.end(), name) != - monitored_sensors_.end()) { - sensors_set->insert(name); - } - break; - } - } - while (*cp++) { - } - } - } -} - -void ThermalWatcher::wake() { - looper_->wake(); -} - -bool ThermalWatcher::threadLoop() { - LOG(VERBOSE) << "ThermalWatcher polling..."; - // Polling interval 2s - static constexpr int kMinPollIntervalMs = 2000; - // Max uevent timeout 5mins - static constexpr int kUeventPollTimeoutMs = 300000; - int fd; - std::set sensors; - - auto time_elapsed_ms = std::chrono::duration_cast(boot_clock::now() - - last_update_time_) - .count(); - int timeout = (thermal_triggered_ || is_polling_) ? kMinPollIntervalMs : kUeventPollTimeoutMs; - if (time_elapsed_ms < timeout && looper_->pollOnce(timeout, &fd, nullptr, nullptr) >= 0) { - if (fd != uevent_fd_.get()) { - return true; - } - parseUevent(&sensors); - // Ignore cb_ if uevent is not from monitored sensors - if (sensors.size() == 0) { - return true; - } - } - thermal_triggered_ = cb_(sensors); - last_update_time_ = boot_clock::now(); - return true; -} - -} // namespace implementation -} // namespace V2_0 -} // namespace thermal -} // namespace hardware -} // namespace android diff --git a/hidl/thermal/utils/thermal_watcher.h b/hidl/thermal/utils/thermal_watcher.h deleted file mode 100644 index ddfb46c9..00000000 --- a/hidl/thermal/utils/thermal_watcher.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * 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. - */ - -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -namespace android { -namespace hardware { -namespace thermal { -namespace V2_0 { -namespace implementation { - -using android::base::boot_clock; -using android::base::unique_fd; -using WatcherCallback = std::function &name)>; - -// A helper class for monitoring thermal files changes. -class ThermalWatcher : public ::android::Thread { - public: - ThermalWatcher(const WatcherCallback &cb) - : Thread(false), cb_(cb), looper_(new Looper(true)) {} - ~ThermalWatcher() = default; - - // Disallow copy and assign. - ThermalWatcher(const ThermalWatcher &) = delete; - void operator=(const ThermalWatcher &) = delete; - - // Start the thread and return true if it succeeds. - bool startWatchingDeviceFiles(); - // Give the file watcher a list of files to start watching. This helper - // class will by default wait for modifications to the file with a looper. - // This should be called before starting watcher thread. - void registerFilesToWatch(const std::set &sensors_to_watch, bool uevent_monitor); - // Wake up the looper thus the worker thread, immediately. This can be called - // in any thread. - void wake(); - - private: - // The work done by the watcher thread. This will use inotify to check for - // modifications to the files to watch. If any modification is seen this - // will callback the registered function with the new data read from the - // modified file. - bool threadLoop() override; - - // Parse uevent message - void parseUevent(std::set *sensor_name); - - // Maps watcher filer descriptor to watched file path. - std::unordered_map watch_to_file_path_map_; - - // The callback function. Called whenever thermal uevent is seen. - // The function passed in should expect a string in the form (type). - // Where type is the name of the thermal zone that trigger a uevent notification. - // Callback will return thermal trigger status for next polling decision. - const WatcherCallback cb_; - - sp looper_; - - // For uevent socket registration. - android::base::unique_fd uevent_fd_; - // Sensor list which monitor flag is enabled. - std::set monitored_sensors_; - // Flag to point out if any sensor across the first threshold. - bool thermal_triggered_; - // Flag to point out if device can support uevent notify. - bool is_polling_; - // Timestamp for last thermal update - boot_clock::time_point last_update_time_; -}; - -} // namespace implementation -} // namespace V2_0 -} // namespace thermal -} // namespace hardware -} // namespace android