From 528ab4789f29d46a3601942f45248c3ff5fa7327 Mon Sep 17 00:00:00 2001 From: George Lee Date: Wed, 18 May 2022 19:44:15 -0700 Subject: bcl: Add Mitigation Logger - library Mitigation Logger logs battery related information for 1 second when it is triggered by under voltage or over current interrupts. Information collected is to help debug system brownout. Bug: 228383769 Test: Boot and Test Signed-off-by: George Lee Change-Id: If2e84c2bdbe2e613895c33831c7dc1695525dc0c --- battery_mitigation/Android.bp | 47 ++++++ battery_mitigation/BatteryMitigation.cpp | 32 ++++ battery_mitigation/MitigationThermalManager.cpp | 187 +++++++++++++++++++++ battery_mitigation/OWNERS | 2 + .../include/battery_mitigation/BatteryMitigation.h | 39 +++++ .../include/battery_mitigation/MitigationConfig.h | 48 ++++++ .../battery_mitigation/MitigationThermalManager.h | 125 ++++++++++++++ 7 files changed, 480 insertions(+) create mode 100644 battery_mitigation/Android.bp create mode 100644 battery_mitigation/BatteryMitigation.cpp create mode 100644 battery_mitigation/MitigationThermalManager.cpp create mode 100644 battery_mitigation/OWNERS create mode 100644 battery_mitigation/include/battery_mitigation/BatteryMitigation.h create mode 100644 battery_mitigation/include/battery_mitigation/MitigationConfig.h create mode 100644 battery_mitigation/include/battery_mitigation/MitigationThermalManager.h (limited to 'battery_mitigation') diff --git a/battery_mitigation/Android.bp b/battery_mitigation/Android.bp new file mode 100644 index 00000000..19d6c4dd --- /dev/null +++ b/battery_mitigation/Android.bp @@ -0,0 +1,47 @@ +// +// Copyright (C) 2022 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. +// + +package { + default_applicable_licenses: ["Android-Apache-2.0"], +} + +cc_library { + name: "libpixelmitigation", + export_include_dirs: ["include"], + vendor_available: true, + srcs: [ + "BatteryMitigation.cpp", + "MitigationThermalManager.cpp", + ], + static_libs: [ + "libmath", + ], + + shared_libs: [ + "libbase", + "libbinder_ndk", + "libcutils", + "libhardware", + "libhidlbase", + "liblog", + "libutils", + "android.hardware.thermal@2.0" + ], + cflags: [ + "-Wall", + "-Werror", + ], +} diff --git a/battery_mitigation/BatteryMitigation.cpp b/battery_mitigation/BatteryMitigation.cpp new file mode 100644 index 00000000..252b1eec --- /dev/null +++ b/battery_mitigation/BatteryMitigation.cpp @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2022 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 + +namespace android { +namespace hardware { +namespace google { +namespace pixel { + +BatteryMitigation::BatteryMitigation(const struct MitigationConfig::Config &cfg) { + mThermalMgr = &MitigationThermalManager::getInstance(); + mThermalMgr->updateConfig(cfg); +} + +} // namespace pixel +} // namespace google +} // namespace hardware +} // namespace android diff --git a/battery_mitigation/MitigationThermalManager.cpp b/battery_mitigation/MitigationThermalManager.cpp new file mode 100644 index 00000000..b1320e70 --- /dev/null +++ b/battery_mitigation/MitigationThermalManager.cpp @@ -0,0 +1,187 @@ +/* + * Copyright (C) 2022 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. + */ +#define LOG_TAG "mitigation-logger" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#define NUM_OF_SAMPLES 20 +#define CAPTURE_INTERVAL_S 2 /* 2 seconds between new capture */ + +namespace android { +namespace hardware { +namespace google { +namespace pixel { + +using android::hardware::thermal::V1_0::ThermalStatus; +using android::hardware::thermal::V1_0::ThermalStatusCode; + +MitigationThermalManager &MitigationThermalManager::getInstance() { + static MitigationThermalManager mitigationThermalManager; + return mitigationThermalManager; +} + +void MitigationThermalManager::remove() { + if (!thermal) { + return; + } + if (callback) { + ThermalStatus returnStatus; + auto ret = thermal->unregisterThermalChangedCallback( + callback, [&returnStatus](ThermalStatus status) { returnStatus = status; }); + if (!ret.isOk() || returnStatus.code != ThermalStatusCode::SUCCESS) { + LOG(ERROR) << "Failed to release thermal callback!"; + } + } + if (deathRecipient) { + auto ret = thermal->unlinkToDeath(deathRecipient); + if (!ret.isOk()) { + LOG(ERROR) << "Failed to release thermal death notification!"; + } + } +} + +MitigationThermalManager::MitigationThermalManager() { + if (!connectThermalHal()) { + remove(); + } +} + +MitigationThermalManager::~MitigationThermalManager() { + remove(); +} + +void MitigationThermalManager::updateConfig(const struct MitigationConfig::Config &cfg) { + kLogFilePath = std::string(cfg.LogFilePath); + kSystemPath = cfg.SystemPath; + kSystemName = cfg.SystemName; + kFilteredZones = cfg.FilteredZones; +} + +bool MitigationThermalManager::connectThermalHal() { + thermal = IThermal::getService(); + if (thermal) { + lastCapturedTime = ::android::base::boot_clock::now(); + registerCallback(); + return true; + } else { + LOG(ERROR) << "Cannot get IThermal service!"; + } + return false; +} + +bool MitigationThermalManager::isMitigationTemperature(const Temperature &temperature) { + if (std::find(kFilteredZones.begin(), kFilteredZones.end(), temperature.name) != + kFilteredZones.end()) { + return true; + } + return false; +} + +void MitigationThermalManager::thermalCb(const Temperature &temperature) { + if ((temperature.throttlingStatus == ThrottlingSeverity::NONE) || + (!isMitigationTemperature(temperature))) { + return; + } + auto currentTime = ::android::base::boot_clock::now(); + auto delta = + std::chrono::duration_cast(currentTime - lastCapturedTime); + if (delta.count() < CAPTURE_INTERVAL_S) { + /* Do not log if delta is within 2 seconds */ + return; + } + int flag = O_WRONLY | O_CREAT | O_NOFOLLOW | O_CLOEXEC | O_APPEND | O_TRUNC; + android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(kLogFilePath.c_str(), flag, 0644))); + lastCapturedTime = currentTime; + std::stringstream oss; + oss << temperature.name << " triggered at " << temperature.value << std::endl << std::flush; + android::base::WriteStringToFd(oss.str(), fd); + + for (int i = 0; i < NUM_OF_SAMPLES; i++) { + auto now = std::chrono::system_clock::now(); + auto time_sec = std::chrono::system_clock::to_time_t(now); + auto ms = std::chrono::duration_cast(now.time_since_epoch()) - + std::chrono::duration_cast(now.time_since_epoch()); + struct tm now_tm; + localtime_r(&time_sec, &now_tm); + oss << std::put_time(&now_tm, "%m-%d %H:%M:%S.") << std::setw(3) << std::setfill('0') + << ms.count() << std::endl << std::flush; + android::base::WriteStringToFd(oss.str(), fd); + oss.str(""); + /* log System info */ + for (int j = 0; j < kSystemName.size(); j++) { + std::string value; + bool result = android::base::ReadFileToString(kSystemPath[j], &value); + if (!result) { + LOG(ERROR) << "Could not read: " << kSystemName[j]; + } + android::base::WriteStringToFd(kSystemName[j] + ":" + value, fd); + } + } + fsync(fd); +} + +void MitigationThermalManager::registerCallback() { + if (!thermal) { + LOG(ERROR) << "Cannot register thermal callback!"; + return; + } + ThermalStatus returnStatus; + // Create thermal death recipient object. + if (deathRecipient == nullptr) { + deathRecipient = new MitigationThermalManager::ThermalDeathRecipient(); + } + // Create thermal callback recipient object. + if (callback == nullptr) { + callback = new MitigationThermalManager::ThermalCallback( + [this](const Temperature &temperature) { + std::lock_guard api_lock(mutex_); + thermalCb(temperature); + }); + } + // Register thermal callback SKIN to thermal hal to cover all. Cannot register twice. + auto ret_callback = thermal->registerThermalChangedCallback( + callback, false, TemperatureType::SKIN, + [&returnStatus](ThermalStatus status) { return returnStatus = status; }); + if (!ret_callback.isOk() || returnStatus.code != ThermalStatusCode::SUCCESS) { + LOG(ERROR) << "Failed to register thermal callback!"; + } + // Register thermal death notification to thermal hal. + auto retLink = thermal->linkToDeath(deathRecipient, 0); + if (!retLink.isOk()) { + LOG(ERROR) << "Failed to register thermal death notification!"; + } +} + +} // namespace pixel +} // namespace google +} // namespace hardware +} // namespace android diff --git a/battery_mitigation/OWNERS b/battery_mitigation/OWNERS new file mode 100644 index 00000000..363efac2 --- /dev/null +++ b/battery_mitigation/OWNERS @@ -0,0 +1,2 @@ +geolee@google.com +wvw@google.com diff --git a/battery_mitigation/include/battery_mitigation/BatteryMitigation.h b/battery_mitigation/include/battery_mitigation/BatteryMitigation.h new file mode 100644 index 00000000..86dda064 --- /dev/null +++ b/battery_mitigation/include/battery_mitigation/BatteryMitigation.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2022 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 "MitigationThermalManager.h" + +namespace android { +namespace hardware { +namespace google { +namespace pixel { + +using ::android::sp; + +class BatteryMitigation : public RefBase { + public: + BatteryMitigation(const struct MitigationConfig::Config &cfg); + + private: + MitigationThermalManager *mThermalMgr; +}; + +} // namespace pixel +} // namespace google +} // namespace hardware +} // namespace android diff --git a/battery_mitigation/include/battery_mitigation/MitigationConfig.h b/battery_mitigation/include/battery_mitigation/MitigationConfig.h new file mode 100644 index 00000000..36a4f5e6 --- /dev/null +++ b/battery_mitigation/include/battery_mitigation/MitigationConfig.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2022 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. + */ + +#ifndef HARDWARE_GOOGLE_PIXEL_BATTERY_MITIGATION_CONFIG_H +#define HARDWARE_GOOGLE_PIXEL_BATTERY_MITIGATION_CONFIG_H + +namespace android { +namespace hardware { +namespace google { +namespace pixel { + +class MitigationConfig { + public: + struct Config { + const std::vector SystemPath; + const std::vector FilteredZones; + const std::vector SystemName; + const char *const LogFilePath; + }; + + MitigationConfig(const struct Config &cfg); + + private: + const std::vector kSystemPath; + const std::vector kFilteredZones; + const std::vector kSystemName; + const char *const kLogFilePath; +}; + +} // namespace pixel +} // namespace google +} // namespace hardware +} // namespace android + +#endif // HARDWARE_GOOGLE_PIXEL_BATTERY_MITIGATION_CONFIG_H diff --git a/battery_mitigation/include/battery_mitigation/MitigationThermalManager.h b/battery_mitigation/include/battery_mitigation/MitigationThermalManager.h new file mode 100644 index 00000000..5c4ddbe7 --- /dev/null +++ b/battery_mitigation/include/battery_mitigation/MitigationThermalManager.h @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2022 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 + +#ifndef MITIGATION_THERMAL_MANAGER_H_ +#define MITIGATION_THERMAL_MANAGER_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "MitigationConfig.h" + +#include +#include + +namespace android { +namespace hardware { +namespace google { +namespace pixel { + +using android::hardware::google::pixel::MitigationConfig; +using android::hardware::hidl_death_recipient; +using android::hardware::hidl_string; +using android::hardware::Return; +using android::hardware::thermal::V2_0::IThermal; +using android::hardware::thermal::V2_0::IThermalChangedCallback; +using android::hardware::thermal::V2_0::Temperature; +using android::hardware::thermal::V2_0::TemperatureType; +using android::hardware::thermal::V2_0::ThrottlingSeverity; +using android::hardware::Void; + +class MitigationThermalManager { + public: + static MitigationThermalManager &getInstance(); + + // delete copy and move constructors and assign operators + MitigationThermalManager(MitigationThermalManager const &) = delete; + MitigationThermalManager(MitigationThermalManager &&) = delete; + MitigationThermalManager &operator=(MitigationThermalManager const &) = delete; + MitigationThermalManager &operator=(MitigationThermalManager &&) = delete; + + private: + // ThermalCallback implements the HIDL thermal changed callback + // interface, IThermalChangedCallback. + void thermalCb(const Temperature &temperature); + android::base::boot_clock::time_point lastCapturedTime; + + class ThermalCallback : public IThermalChangedCallback { + public: + ThermalCallback(std::function notify_function) + : notifyFunction(notify_function) {} + + // Callback function. thermal service will call this. + Return notifyThrottling(const Temperature &temperature) override { + if ((temperature.type == TemperatureType::BCL_VOLTAGE) || + (temperature.type == TemperatureType::BCL_CURRENT)) { + notifyFunction(temperature); + } + return ::android::hardware::Void(); + } + + private: + std::function notifyFunction; + }; + + class ThermalDeathRecipient : virtual public hidl_death_recipient { + public: + void serviceDied(uint64_t /*cookie*/, + const android::wp<::android::hidl::base::V1_0::IBase> & /*who*/) override { + MitigationThermalManager::getInstance().connectThermalHal(); + }; + }; + + public: + MitigationThermalManager(); + ~MitigationThermalManager(); + bool connectThermalHal(); + bool isMitigationTemperature(const Temperature &temperature); + void registerCallback(); + void remove(); + void updateConfig(const struct MitigationConfig::Config &cfg); + + + private: + std::mutex mutex_; + // Thermal hal interface. + android::sp thermal; + // Thermal hal callback object. + android::sp callback; + // Receiver when thermal hal restart. + android::sp deathRecipient; + std::vector kSystemPath; + std::vector kFilteredZones; + std::vector kSystemName; + std::string kLogFilePath; +}; + +} // namespace pixel +} // namespace google +} // namespace hardware +} // namespace android +#endif -- cgit v1.2.3 From 746d69597862271cabf99d3f3c60a34458e1970c Mon Sep 17 00:00:00 2001 From: George Lee Date: Tue, 16 Aug 2022 14:26:44 -0700 Subject: battery_mitigation. Early sync avoid corruption We want to make sure thismeal.txt contains legible content instead of corrupted characters. Added an early fsync before the SYSFS read to ensure interrupt name is logged. Bug: 242764069 Test: Confirm that thismeal.txt can be logged Signed-off-by: George Lee Change-Id: I323fa5ea73c455c2e00d204b1b0bb69bc56e2cb0 --- battery_mitigation/MitigationThermalManager.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'battery_mitigation') diff --git a/battery_mitigation/MitigationThermalManager.cpp b/battery_mitigation/MitigationThermalManager.cpp index b1320e70..833e294b 100644 --- a/battery_mitigation/MitigationThermalManager.cpp +++ b/battery_mitigation/MitigationThermalManager.cpp @@ -124,6 +124,7 @@ void MitigationThermalManager::thermalCb(const Temperature &temperature) { std::stringstream oss; oss << temperature.name << " triggered at " << temperature.value << std::endl << std::flush; android::base::WriteStringToFd(oss.str(), fd); + fsync(fd); for (int i = 0; i < NUM_OF_SAMPLES; i++) { auto now = std::chrono::system_clock::now(); @@ -135,6 +136,7 @@ void MitigationThermalManager::thermalCb(const Temperature &temperature) { oss << std::put_time(&now_tm, "%m-%d %H:%M:%S.") << std::setw(3) << std::setfill('0') << ms.count() << std::endl << std::flush; android::base::WriteStringToFd(oss.str(), fd); + fsync(fd); oss.str(""); /* log System info */ for (int j = 0; j < kSystemName.size(); j++) { -- cgit v1.2.3 From 7a231f06777384b6330bda9b393fbe0bce438364 Mon Sep 17 00:00:00 2001 From: George Lee Date: Tue, 11 Oct 2022 18:09:59 -0700 Subject: bcl: Add log check for real brownout. Adding year to the data capture for timestamp comparison during lastmeal.txt generation. Add check within Battery Mitigation to confirm lastmeal.txt contains information related to brownout and only generates if it does contain information about the brownout. Bug: 246817058 Test: Confirm proper lastmeal.txt generation Signed-off-by: George Lee Change-Id: Ie5efbfbdb86688231728056fa3254d698d63046b --- battery_mitigation/BatteryMitigation.cpp | 35 ++++++++++++++++++++++ battery_mitigation/MitigationThermalManager.cpp | 9 +++--- .../include/battery_mitigation/BatteryMitigation.h | 3 ++ .../include/battery_mitigation/MitigationConfig.h | 2 ++ .../battery_mitigation/MitigationThermalManager.h | 6 ++-- 5 files changed, 49 insertions(+), 6 deletions(-) (limited to 'battery_mitigation') diff --git a/battery_mitigation/BatteryMitigation.cpp b/battery_mitigation/BatteryMitigation.cpp index 252b1eec..98419fc5 100644 --- a/battery_mitigation/BatteryMitigation.cpp +++ b/battery_mitigation/BatteryMitigation.cpp @@ -16,6 +16,10 @@ #include +#include + +#define MAX_BROWNOUT_DATA_AGE_SECONDS 300 + namespace android { namespace hardware { namespace google { @@ -26,6 +30,37 @@ BatteryMitigation::BatteryMitigation(const struct MitigationConfig::Config &cfg) mThermalMgr->updateConfig(cfg); } +bool BatteryMitigation::isMitigationLogTimeValid(std::chrono::system_clock::time_point startTime, + const char *const logFilePath, + const char *const timestampFormat, + const std::regex pattern) { + std::string logFile; + if (!android::base::ReadFileToString(logFilePath, &logFile)) { + return false; + } + std::istringstream content(logFile); + std::string line; + int counter = 0; + std::smatch pattern_match; + while (std::getline(content, line)) { + if (std::regex_match(line, pattern_match, pattern)) { + std::tm triggeredTimestamp = {}; + std::istringstream ss(pattern_match.str()); + ss >> std::get_time(&triggeredTimestamp, timestampFormat); + auto logFileTime = std::chrono::system_clock::from_time_t(mktime(&triggeredTimestamp)); + auto delta = std::chrono::duration_cast(startTime - logFileTime); + if ((delta.count() < MAX_BROWNOUT_DATA_AGE_SECONDS) && (delta.count() > 0)) { + return true; + } + } + counter += 1; + if (counter > 5) { + break; + } + } + return false; +} + } // namespace pixel } // namespace google } // namespace hardware diff --git a/battery_mitigation/MitigationThermalManager.cpp b/battery_mitigation/MitigationThermalManager.cpp index 833e294b..c3049173 100644 --- a/battery_mitigation/MitigationThermalManager.cpp +++ b/battery_mitigation/MitigationThermalManager.cpp @@ -15,14 +15,13 @@ */ #define LOG_TAG "mitigation-logger" -#include - #include #include #include #include #include #include +#include #include #include @@ -84,6 +83,7 @@ void MitigationThermalManager::updateConfig(const struct MitigationConfig::Confi kSystemPath = cfg.SystemPath; kSystemName = cfg.SystemName; kFilteredZones = cfg.FilteredZones; + kTimestampFormat = cfg.TimestampFormat; } bool MitigationThermalManager::connectThermalHal() { @@ -133,8 +133,9 @@ void MitigationThermalManager::thermalCb(const Temperature &temperature) { std::chrono::duration_cast(now.time_since_epoch()); struct tm now_tm; localtime_r(&time_sec, &now_tm); - oss << std::put_time(&now_tm, "%m-%d %H:%M:%S.") << std::setw(3) << std::setfill('0') - << ms.count() << std::endl << std::flush; + oss << std::put_time(&now_tm, kTimestampFormat.c_str()) << "." << std::setw(3) + << std::setfill('0') << ms.count() << std::endl + << std::flush; android::base::WriteStringToFd(oss.str(), fd); fsync(fd); oss.str(""); diff --git a/battery_mitigation/include/battery_mitigation/BatteryMitigation.h b/battery_mitigation/include/battery_mitigation/BatteryMitigation.h index 86dda064..d3839699 100644 --- a/battery_mitigation/include/battery_mitigation/BatteryMitigation.h +++ b/battery_mitigation/include/battery_mitigation/BatteryMitigation.h @@ -28,6 +28,9 @@ using ::android::sp; class BatteryMitigation : public RefBase { public: BatteryMitigation(const struct MitigationConfig::Config &cfg); + bool isMitigationLogTimeValid(std::chrono::system_clock::time_point startTime, + const char *const logFilePath, const char *const timestampFormat, + const std::regex pattern); private: MitigationThermalManager *mThermalMgr; diff --git a/battery_mitigation/include/battery_mitigation/MitigationConfig.h b/battery_mitigation/include/battery_mitigation/MitigationConfig.h index 36a4f5e6..825e30c6 100644 --- a/battery_mitigation/include/battery_mitigation/MitigationConfig.h +++ b/battery_mitigation/include/battery_mitigation/MitigationConfig.h @@ -29,6 +29,7 @@ class MitigationConfig { const std::vector FilteredZones; const std::vector SystemName; const char *const LogFilePath; + const char *const TimestampFormat; }; MitigationConfig(const struct Config &cfg); @@ -38,6 +39,7 @@ class MitigationConfig { const std::vector kFilteredZones; const std::vector kSystemName; const char *const kLogFilePath; + const char *const kTimestampFormat; }; } // namespace pixel diff --git a/battery_mitigation/include/battery_mitigation/MitigationThermalManager.h b/battery_mitigation/include/battery_mitigation/MitigationThermalManager.h index 5c4ddbe7..688c5d89 100644 --- a/battery_mitigation/include/battery_mitigation/MitigationThermalManager.h +++ b/battery_mitigation/include/battery_mitigation/MitigationThermalManager.h @@ -31,10 +31,11 @@ #include #include -#include "MitigationConfig.h" - #include #include +#include + +#include "MitigationConfig.h" namespace android { namespace hardware { @@ -116,6 +117,7 @@ class MitigationThermalManager { std::vector kFilteredZones; std::vector kSystemName; std::string kLogFilePath; + std::string kTimestampFormat; }; } // namespace pixel -- cgit v1.2.3 From 58be52c9a64786acfe9b0a1ef4d2f9123208f722 Mon Sep 17 00:00:00 2001 From: Xiang Wang Date: Wed, 25 Jan 2023 13:46:48 -0800 Subject: Update MitigationThermalManager use Thermal HIDL wrapper This will try to connect to Thermal AIDL service and fall back to HIDL if not Bug: b/264595820 Test: Thermal AIDL service restart test + pmic file test Change-Id: I243da62d6a0fad5f1babefe11c6a70e8434e0429 --- battery_mitigation/Android.bp | 5 +- battery_mitigation/MitigationThermalManager.cpp | 81 ++++++++++++++++++---- .../battery_mitigation/MitigationThermalManager.h | 16 +++-- 3 files changed, 82 insertions(+), 20 deletions(-) (limited to 'battery_mitigation') diff --git a/battery_mitigation/Android.bp b/battery_mitigation/Android.bp index 19d6c4dd..3056ff29 100644 --- a/battery_mitigation/Android.bp +++ b/battery_mitigation/Android.bp @@ -28,6 +28,7 @@ cc_library { ], static_libs: [ "libmath", + "libpixelthermalwrapper", ], shared_libs: [ @@ -38,7 +39,9 @@ cc_library { "libhidlbase", "liblog", "libutils", - "android.hardware.thermal@2.0" + "android.hardware.thermal@1.0", + "android.hardware.thermal@2.0", + "android.hardware.thermal-V1-ndk" ], cflags: [ "-Wall", diff --git a/battery_mitigation/MitigationThermalManager.cpp b/battery_mitigation/MitigationThermalManager.cpp index c3049173..ff54952d 100644 --- a/battery_mitigation/MitigationThermalManager.cpp +++ b/battery_mitigation/MitigationThermalManager.cpp @@ -15,15 +15,20 @@ */ #define LOG_TAG "mitigation-logger" +#include #include #include #include #include #include #include +#include +#include #include #include +#include #include +#include #include #include @@ -31,6 +36,7 @@ #include #include #include +#include #define NUM_OF_SAMPLES 20 #define CAPTURE_INTERVAL_S 2 /* 2 seconds between new capture */ @@ -49,6 +55,7 @@ MitigationThermalManager &MitigationThermalManager::getInstance() { } void MitigationThermalManager::remove() { + const std::lock_guard lock(thermal_hal_mutex_); if (!thermal) { return; } @@ -60,8 +67,8 @@ void MitigationThermalManager::remove() { LOG(ERROR) << "Failed to release thermal callback!"; } } - if (deathRecipient) { - auto ret = thermal->unlinkToDeath(deathRecipient); + if (hidlDeathRecipient) { + auto ret = thermal->unlinkToDeath(hidlDeathRecipient); if (!ret.isOk()) { LOG(ERROR) << "Failed to release thermal death notification!"; } @@ -69,6 +76,13 @@ void MitigationThermalManager::remove() { } MitigationThermalManager::MitigationThermalManager() { + if (!ABinderProcess_isThreadPoolStarted()) { + std::thread([]() { + ABinderProcess_joinThreadPool(); + LOG(ERROR) << "SHOULD NOT EXIT"; + }).detach(); + LOG(ERROR) << "The user of MitigationThermalManager did not start a threadpool"; + } if (!connectThermalHal()) { remove(); } @@ -87,10 +101,34 @@ void MitigationThermalManager::updateConfig(const struct MitigationConfig::Confi } bool MitigationThermalManager::connectThermalHal() { - thermal = IThermal::getService(); + const std::string thermal_instance_name = + std::string(::aidl::android::hardware::thermal::IThermal::descriptor) + "/default"; + std::shared_ptr thermal_aidl_service; + const std::lock_guard lock(thermal_hal_mutex_); + if (AServiceManager_isDeclared(thermal_instance_name.c_str())) { + thermal_aidl_service = ::aidl::android::hardware::thermal::IThermal::fromBinder( + ndk::SpAIBinder(AServiceManager_waitForService(thermal_instance_name.c_str()))); + if (thermal_aidl_service) { + thermal = sp<::aidl::android::hardware::thermal::ThermalHidlWrapper>::make( + thermal_aidl_service); + } else { + LOG(ERROR) << "Unable to connect Thermal AIDL service, trying HIDL..."; + } + } else { + LOG(WARNING) << "Thermal AIDL service is not declared, trying HIDL..."; + } + + if (!thermal) { + thermal = IThermal::getService(); + } + if (thermal) { lastCapturedTime = ::android::base::boot_clock::now(); - registerCallback(); + if (thermal_aidl_service) { + registerCallback(thermal_aidl_service->asBinder().get()); + } else { + registerCallback(nullptr); + } return true; } else { LOG(ERROR) << "Cannot get IThermal service!"; @@ -152,35 +190,48 @@ void MitigationThermalManager::thermalCb(const Temperature &temperature) { fsync(fd); } -void MitigationThermalManager::registerCallback() { +void MitigationThermalManager::registerCallback(AIBinder *thermal_aidl_binder) { if (!thermal) { LOG(ERROR) << "Cannot register thermal callback!"; return; } ThermalStatus returnStatus; - // Create thermal death recipient object. - if (deathRecipient == nullptr) { - deathRecipient = new MitigationThermalManager::ThermalDeathRecipient(); - } // Create thermal callback recipient object. if (callback == nullptr) { callback = new MitigationThermalManager::ThermalCallback( [this](const Temperature &temperature) { - std::lock_guard api_lock(mutex_); + std::lock_guard api_lock(thermal_callback_mutex_); thermalCb(temperature); }); } - // Register thermal callback SKIN to thermal hal to cover all. Cannot register twice. + // Register thermal callback to thermal hal to cover all. Cannot register twice. auto ret_callback = thermal->registerThermalChangedCallback( - callback, false, TemperatureType::SKIN, + callback, false, TemperatureType::UNKNOWN, [&returnStatus](ThermalStatus status) { return returnStatus = status; }); if (!ret_callback.isOk() || returnStatus.code != ThermalStatusCode::SUCCESS) { LOG(ERROR) << "Failed to register thermal callback!"; } + // Register thermal death notification to thermal hal. - auto retLink = thermal->linkToDeath(deathRecipient, 0); - if (!retLink.isOk()) { - LOG(ERROR) << "Failed to register thermal death notification!"; + if (thermal_aidl_binder) { + // Create AIDL thermal death recipient object. + if (aidlDeathRecipient.get() == nullptr) { + aidlDeathRecipient = ndk::ScopedAIBinder_DeathRecipient( + AIBinder_DeathRecipient_new(onThermalAidlBinderDied)); + } + auto linked = AIBinder_linkToDeath(thermal_aidl_binder, aidlDeathRecipient.get(), this); + if (linked != STATUS_OK) { + LOG(ERROR) << "Failed to register AIDL thermal death notification!"; + } + } else { + // Create HIDL thermal death recipient object. + if (hidlDeathRecipient == nullptr) { + hidlDeathRecipient = new MitigationThermalManager::ThermalDeathRecipient(); + } + auto retLink = thermal->linkToDeath(hidlDeathRecipient, 0); + if (!retLink.isOk()) { + LOG(ERROR) << "Failed to register HIDL thermal death notification!"; + } } } diff --git a/battery_mitigation/include/battery_mitigation/MitigationThermalManager.h b/battery_mitigation/include/battery_mitigation/MitigationThermalManager.h index 688c5d89..9764b915 100644 --- a/battery_mitigation/include/battery_mitigation/MitigationThermalManager.h +++ b/battery_mitigation/include/battery_mitigation/MitigationThermalManager.h @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -94,25 +95,32 @@ class MitigationThermalManager { MitigationThermalManager::getInstance().connectThermalHal(); }; }; + static void onThermalAidlBinderDied(void *) { + LOG(ERROR) << "Thermal AIDL service died, trying to reconnect"; + MitigationThermalManager::getInstance().connectThermalHal(); + } public: MitigationThermalManager(); ~MitigationThermalManager(); bool connectThermalHal(); bool isMitigationTemperature(const Temperature &temperature); - void registerCallback(); + void registerCallback(AIBinder *thermal_aidl_binder); void remove(); void updateConfig(const struct MitigationConfig::Config &cfg); private: - std::mutex mutex_; + std::mutex thermal_callback_mutex_; + std::mutex thermal_hal_mutex_; // Thermal hal interface. android::sp thermal; // Thermal hal callback object. android::sp callback; - // Receiver when thermal hal restart. - android::sp deathRecipient; + // Receiver when HIDL thermal hal restart. + android::sp hidlDeathRecipient; + // Receiver when AIDL thermal hal restart. + ndk::ScopedAIBinder_DeathRecipient aidlDeathRecipient; std::vector kSystemPath; std::vector kFilteredZones; std::vector kSystemName; -- cgit v1.2.3 From 2ff32f4ca0ea7287f3bf5f9ce0d33ab4a1727fef Mon Sep 17 00:00:00 2001 From: Xiang Wang Date: Wed, 15 Feb 2023 15:26:17 -0800 Subject: Move thermal utils to hardware/interfaces Bug: b/269370789 Test: m Change-Id: Id20cf96441fca5f2fd9092481628f13d69ecabef Merged-In: Id20cf96441fca5f2fd9092481628f13d69ecabef --- battery_mitigation/Android.bp | 2 +- battery_mitigation/MitigationThermalManager.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'battery_mitigation') diff --git a/battery_mitigation/Android.bp b/battery_mitigation/Android.bp index 3056ff29..8dc8b9f5 100644 --- a/battery_mitigation/Android.bp +++ b/battery_mitigation/Android.bp @@ -28,7 +28,7 @@ cc_library { ], static_libs: [ "libmath", - "libpixelthermalwrapper", + "libthermalutils", ], shared_libs: [ diff --git a/battery_mitigation/MitigationThermalManager.cpp b/battery_mitigation/MitigationThermalManager.cpp index ff54952d..0297fcb6 100644 --- a/battery_mitigation/MitigationThermalManager.cpp +++ b/battery_mitigation/MitigationThermalManager.cpp @@ -26,8 +26,8 @@ #include #include #include -#include #include +#include #include #include -- cgit v1.2.3 From 356787f52e69d34c1da4ee93e4629222726da824 Mon Sep 17 00:00:00 2001 From: Xiang Wang Date: Tue, 21 Feb 2023 15:15:14 -0800 Subject: Migrate battery mitigation to Thermal AIDL Bug: b/269163592 Test: Thermal AIDL service restart test + pmic file test Change-Id: Ib5b4f4d803a3d7abcd538d8b338209f91595e045 --- battery_mitigation/Android.bp | 4 - battery_mitigation/MitigationThermalManager.cpp | 106 ++++++--------------- .../include/battery_mitigation/BatteryMitigation.h | 2 + .../battery_mitigation/MitigationThermalManager.h | 40 +++----- 4 files changed, 42 insertions(+), 110 deletions(-) (limited to 'battery_mitigation') diff --git a/battery_mitigation/Android.bp b/battery_mitigation/Android.bp index 8dc8b9f5..1a5d6c6e 100644 --- a/battery_mitigation/Android.bp +++ b/battery_mitigation/Android.bp @@ -28,7 +28,6 @@ cc_library { ], static_libs: [ "libmath", - "libthermalutils", ], shared_libs: [ @@ -36,11 +35,8 @@ cc_library { "libbinder_ndk", "libcutils", "libhardware", - "libhidlbase", "liblog", "libutils", - "android.hardware.thermal@1.0", - "android.hardware.thermal@2.0", "android.hardware.thermal-V1-ndk" ], cflags: [ diff --git a/battery_mitigation/MitigationThermalManager.cpp b/battery_mitigation/MitigationThermalManager.cpp index 0297fcb6..42e6e3cb 100644 --- a/battery_mitigation/MitigationThermalManager.cpp +++ b/battery_mitigation/MitigationThermalManager.cpp @@ -15,23 +15,16 @@ */ #define LOG_TAG "mitigation-logger" -#include #include #include #include -#include -#include -#include #include #include #include #include -#include -#include #include #include -#include #include #include #include @@ -46,9 +39,6 @@ namespace hardware { namespace google { namespace pixel { -using android::hardware::thermal::V1_0::ThermalStatus; -using android::hardware::thermal::V1_0::ThermalStatusCode; - MitigationThermalManager &MitigationThermalManager::getInstance() { static MitigationThermalManager mitigationThermalManager; return mitigationThermalManager; @@ -60,28 +50,18 @@ void MitigationThermalManager::remove() { return; } if (callback) { - ThermalStatus returnStatus; - auto ret = thermal->unregisterThermalChangedCallback( - callback, [&returnStatus](ThermalStatus status) { returnStatus = status; }); - if (!ret.isOk() || returnStatus.code != ThermalStatusCode::SUCCESS) { - LOG(ERROR) << "Failed to release thermal callback!"; - } - } - if (hidlDeathRecipient) { - auto ret = thermal->unlinkToDeath(hidlDeathRecipient); + auto ret = thermal->unregisterThermalChangedCallback(callback); if (!ret.isOk()) { - LOG(ERROR) << "Failed to release thermal death notification!"; + LOG(ERROR) << "Failed to release thermal callback! " << ret.getMessage(); } } } MitigationThermalManager::MitigationThermalManager() { if (!ABinderProcess_isThreadPoolStarted()) { - std::thread([]() { - ABinderProcess_joinThreadPool(); - LOG(ERROR) << "SHOULD NOT EXIT"; - }).detach(); - LOG(ERROR) << "The user of MitigationThermalManager did not start a threadpool"; + // if no thread pool then the thermal callback will not work, so abort + LOG(ERROR) << "The user of MitigationThermalManager did not start a thread pool!"; + return; } if (!connectThermalHal()) { remove(); @@ -106,32 +86,12 @@ bool MitigationThermalManager::connectThermalHal() { std::shared_ptr thermal_aidl_service; const std::lock_guard lock(thermal_hal_mutex_); if (AServiceManager_isDeclared(thermal_instance_name.c_str())) { - thermal_aidl_service = ::aidl::android::hardware::thermal::IThermal::fromBinder( + thermal = ::aidl::android::hardware::thermal::IThermal::fromBinder( ndk::SpAIBinder(AServiceManager_waitForService(thermal_instance_name.c_str()))); - if (thermal_aidl_service) { - thermal = sp<::aidl::android::hardware::thermal::ThermalHidlWrapper>::make( - thermal_aidl_service); - } else { - LOG(ERROR) << "Unable to connect Thermal AIDL service, trying HIDL..."; - } - } else { - LOG(WARNING) << "Thermal AIDL service is not declared, trying HIDL..."; - } - - if (!thermal) { - thermal = IThermal::getService(); - } - - if (thermal) { lastCapturedTime = ::android::base::boot_clock::now(); - if (thermal_aidl_service) { - registerCallback(thermal_aidl_service->asBinder().get()); - } else { - registerCallback(nullptr); - } - return true; + return registerCallback(); } else { - LOG(ERROR) << "Cannot get IThermal service!"; + LOG(ERROR) << "Thermal AIDL service is not declared"; } return false; } @@ -190,49 +150,37 @@ void MitigationThermalManager::thermalCb(const Temperature &temperature) { fsync(fd); } -void MitigationThermalManager::registerCallback(AIBinder *thermal_aidl_binder) { +bool MitigationThermalManager::registerCallback() { if (!thermal) { - LOG(ERROR) << "Cannot register thermal callback!"; - return; + LOG(ERROR) << "Unable to connect Thermal AIDL service"; + return false; } - ThermalStatus returnStatus; // Create thermal callback recipient object. if (callback == nullptr) { - callback = new MitigationThermalManager::ThermalCallback( - [this](const Temperature &temperature) { + callback = + ndk::SharedRefBase::make([this](const Temperature &temperature) { std::lock_guard api_lock(thermal_callback_mutex_); thermalCb(temperature); }); } // Register thermal callback to thermal hal to cover all. Cannot register twice. - auto ret_callback = thermal->registerThermalChangedCallback( - callback, false, TemperatureType::UNKNOWN, - [&returnStatus](ThermalStatus status) { return returnStatus = status; }); - if (!ret_callback.isOk() || returnStatus.code != ThermalStatusCode::SUCCESS) { - LOG(ERROR) << "Failed to register thermal callback!"; + auto ret_callback = thermal->registerThermalChangedCallback(callback); + if (!ret_callback.isOk()) { + LOG(ERROR) << "Failed to register thermal callback! " << ret_callback.getMessage(); + return false; } - // Register thermal death notification to thermal hal. - if (thermal_aidl_binder) { - // Create AIDL thermal death recipient object. - if (aidlDeathRecipient.get() == nullptr) { - aidlDeathRecipient = ndk::ScopedAIBinder_DeathRecipient( - AIBinder_DeathRecipient_new(onThermalAidlBinderDied)); - } - auto linked = AIBinder_linkToDeath(thermal_aidl_binder, aidlDeathRecipient.get(), this); - if (linked != STATUS_OK) { - LOG(ERROR) << "Failed to register AIDL thermal death notification!"; - } - } else { - // Create HIDL thermal death recipient object. - if (hidlDeathRecipient == nullptr) { - hidlDeathRecipient = new MitigationThermalManager::ThermalDeathRecipient(); - } - auto retLink = thermal->linkToDeath(hidlDeathRecipient, 0); - if (!retLink.isOk()) { - LOG(ERROR) << "Failed to register HIDL thermal death notification!"; - } + // Create AIDL thermal death recipient object. + if (aidlDeathRecipient.get() == nullptr) { + aidlDeathRecipient = ndk::ScopedAIBinder_DeathRecipient( + AIBinder_DeathRecipient_new(onThermalAidlBinderDied)); + } + auto linked = AIBinder_linkToDeath(thermal->asBinder().get(), aidlDeathRecipient.get(), this); + if (linked != STATUS_OK) { + // should we continue if the death recipient is not registered? + LOG(ERROR) << "Failed to register AIDL thermal death notification"; } + return true; } } // namespace pixel diff --git a/battery_mitigation/include/battery_mitigation/BatteryMitigation.h b/battery_mitigation/include/battery_mitigation/BatteryMitigation.h index d3839699..d3ce433d 100644 --- a/battery_mitigation/include/battery_mitigation/BatteryMitigation.h +++ b/battery_mitigation/include/battery_mitigation/BatteryMitigation.h @@ -16,6 +16,8 @@ #pragma once +#include + #include "MitigationThermalManager.h" namespace android { diff --git a/battery_mitigation/include/battery_mitigation/MitigationThermalManager.h b/battery_mitigation/include/battery_mitigation/MitigationThermalManager.h index 9764b915..5b5a3f0a 100644 --- a/battery_mitigation/include/battery_mitigation/MitigationThermalManager.h +++ b/battery_mitigation/include/battery_mitigation/MitigationThermalManager.h @@ -19,6 +19,8 @@ #ifndef MITIGATION_THERMAL_MANAGER_H_ #define MITIGATION_THERMAL_MANAGER_H_ +#include +#include #include #include #include @@ -26,9 +28,6 @@ #include #include #include -#include -#include -#include #include #include @@ -43,16 +42,12 @@ namespace hardware { namespace google { namespace pixel { +using ::aidl::android::hardware::thermal::BnThermalChangedCallback; +using ::aidl::android::hardware::thermal::IThermal; +using ::aidl::android::hardware::thermal::Temperature; +using ::aidl::android::hardware::thermal::TemperatureType; +using ::aidl::android::hardware::thermal::ThrottlingSeverity; using android::hardware::google::pixel::MitigationConfig; -using android::hardware::hidl_death_recipient; -using android::hardware::hidl_string; -using android::hardware::Return; -using android::hardware::thermal::V2_0::IThermal; -using android::hardware::thermal::V2_0::IThermalChangedCallback; -using android::hardware::thermal::V2_0::Temperature; -using android::hardware::thermal::V2_0::TemperatureType; -using android::hardware::thermal::V2_0::ThrottlingSeverity; -using android::hardware::Void; class MitigationThermalManager { public: @@ -70,31 +65,24 @@ class MitigationThermalManager { void thermalCb(const Temperature &temperature); android::base::boot_clock::time_point lastCapturedTime; - class ThermalCallback : public IThermalChangedCallback { + class ThermalCallback : public BnThermalChangedCallback { public: ThermalCallback(std::function notify_function) : notifyFunction(notify_function) {} // Callback function. thermal service will call this. - Return notifyThrottling(const Temperature &temperature) override { + ndk::ScopedAStatus notifyThrottling(const Temperature &temperature) override { if ((temperature.type == TemperatureType::BCL_VOLTAGE) || (temperature.type == TemperatureType::BCL_CURRENT)) { notifyFunction(temperature); } - return ::android::hardware::Void(); + return ndk::ScopedAStatus::ok(); } private: std::function notifyFunction; }; - class ThermalDeathRecipient : virtual public hidl_death_recipient { - public: - void serviceDied(uint64_t /*cookie*/, - const android::wp<::android::hidl::base::V1_0::IBase> & /*who*/) override { - MitigationThermalManager::getInstance().connectThermalHal(); - }; - }; static void onThermalAidlBinderDied(void *) { LOG(ERROR) << "Thermal AIDL service died, trying to reconnect"; MitigationThermalManager::getInstance().connectThermalHal(); @@ -105,7 +93,7 @@ class MitigationThermalManager { ~MitigationThermalManager(); bool connectThermalHal(); bool isMitigationTemperature(const Temperature &temperature); - void registerCallback(AIBinder *thermal_aidl_binder); + bool registerCallback(); void remove(); void updateConfig(const struct MitigationConfig::Config &cfg); @@ -114,11 +102,9 @@ class MitigationThermalManager { std::mutex thermal_callback_mutex_; std::mutex thermal_hal_mutex_; // Thermal hal interface. - android::sp thermal; + std::shared_ptr thermal; // Thermal hal callback object. - android::sp callback; - // Receiver when HIDL thermal hal restart. - android::sp hidlDeathRecipient; + std::shared_ptr callback; // Receiver when AIDL thermal hal restart. ndk::ScopedAIBinder_DeathRecipient aidlDeathRecipient; std::vector kSystemPath; -- cgit v1.2.3