diff options
author | Maggie White <maggiewhite@google.com> | 2018-09-28 16:18:35 -0700 |
---|---|---|
committer | Maggie White <maggiewhite@google.com> | 2018-10-01 18:29:25 -0700 |
commit | 8c72de9446b713eae311bb125983a8293f55d487 (patch) | |
tree | 273563044a6f90564537ab32bdd6fb4a4d3c65d3 /health | |
parent | 7640c2489408063953b0f5cab47ae706de949b15 (diff) | |
download | pixel-8c72de9446b713eae311bb125983a8293f55d487.tar.gz |
health HAL: Add device-agnostic tools from P18
Bug: 116825947
Test: Tested battery metrics and shutdown logging on P18
Change-Id: Icf955bb955a0791bb3e49fcb77eed77616bec8b8
Signed-off-by: Maggie White <maggiewhite@google.com>
Diffstat (limited to 'health')
-rw-r--r-- | health/Android.bp | 31 | ||||
-rw-r--r-- | health/BatteryMetricsLogger.cpp | 202 | ||||
-rw-r--r-- | health/CycleCountBackupRestore.cpp | 148 | ||||
-rw-r--r-- | health/DeviceHealth.cpp | 44 | ||||
-rw-r--r-- | health/LowBatteryShutdownMetrics.cpp | 105 | ||||
-rw-r--r-- | health/include/pixelhealth/BatteryMetricsLogger.h | 97 | ||||
-rw-r--r-- | health/include/pixelhealth/CycleCountBackupRestore.h | 60 | ||||
-rw-r--r-- | health/include/pixelhealth/DeviceHealth.h | 40 | ||||
-rw-r--r-- | health/include/pixelhealth/LowBatteryShutdownMetrics.h | 63 |
9 files changed, 790 insertions, 0 deletions
diff --git a/health/Android.bp b/health/Android.bp new file mode 100644 index 00000000..76b0df66 --- /dev/null +++ b/health/Android.bp @@ -0,0 +1,31 @@ +cc_library_static { + name: "libpixelhealth", + vendor_available: true, + export_include_dirs: ["include"], + + srcs: [ + "LowBatteryShutdownMetrics.cpp", + "CycleCountBackupRestore.cpp", + "DeviceHealth.cpp", + "BatteryMetricsLogger.cpp", + ], + + cflags: [ + "-Wall", + "-Werror", + ], + + static_libs: [ + "libbatterymonitor", + ], + + shared_libs: [ + "hardware.google.pixelstats@1.0", + "libbase", + "libcutils", + "libhidlbase", + "libhidltransport", + "libhwbinder", + "libutils", + ], +} diff --git a/health/BatteryMetricsLogger.cpp b/health/BatteryMetricsLogger.cpp new file mode 100644 index 00000000..e226e1ce --- /dev/null +++ b/health/BatteryMetricsLogger.cpp @@ -0,0 +1,202 @@ + +/* + * 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 <pixelhealth/BatteryMetricsLogger.h> + +namespace hardware { +namespace google { +namespace pixel { +namespace health { + +using ::hardware::google::pixelstats::V1_0::IPixelStats; +using BatteryHealthSnapshotArgs = + ::hardware::google::pixelstats::V1_0::IPixelStats::BatteryHealthSnapshotArgs; +using android::sp; + +BatteryMetricsLogger::BatteryMetricsLogger(const char *const batt_res, const char *const batt_ocv, + int sample_period, int upload_period) + : kBatteryResistance(batt_res), + kBatteryOCV(batt_ocv), + kSamplePeriod(sample_period), + kUploadPeriod(upload_period), + kMaxSamples(upload_period / sample_period) { + last_sample_ = 0; + last_upload_ = 0; + num_res_samples_ = 0; + num_samples_ = 0; + memset(min_, 0, sizeof(min_)); + memset(max_, 0, sizeof(max_)); + accum_resistance_ = 0; +} + +int64_t BatteryMetricsLogger::getTime(void) { + return nanoseconds_to_seconds(systemTime(SYSTEM_TIME_BOOTTIME)); +} + +bool BatteryMetricsLogger::uploadOutlierMetric(sp<IPixelStats> client, sampleType type) { + BatteryHealthSnapshotArgs min_ss = {static_cast<BatterySnapshotType>(0), + min_[type][TEMP], + min_[type][VOLT], + min_[type][CURR], + min_[type][OCV], + min_[type][RES], + min_[type][SOC]}; + BatteryHealthSnapshotArgs max_ss = {static_cast<BatterySnapshotType>(0), + max_[type][TEMP], + max_[type][VOLT], + max_[type][CURR], + max_[type][OCV], + max_[type][RES], + max_[type][SOC]}; + + if (kSnapshotType[type] < 0) + return false; + + min_ss.type = (BatterySnapshotType)kSnapshotType[type]; + max_ss.type = (BatterySnapshotType)(kSnapshotType[type] + 1); + + client->reportBatteryHealthSnapshot(min_ss); + client->reportBatteryHealthSnapshot(max_ss); + return true; +} + +bool BatteryMetricsLogger::uploadMetrics(void) { + int64_t time = getTime(); + int32_t avg_resistance = 0; + + if (last_sample_ == 0) + return false; + + LOG(INFO) << "Uploading metrics at time " << std::to_string(time) << " w/ " + << std::to_string(num_samples_) << " samples"; + + if (num_res_samples_) + avg_resistance = accum_resistance_ / num_res_samples_; + + LOG(INFO) << "Logging metrics to tron"; + + sp<IPixelStats> client = IPixelStats::tryGetService(); + if (!client) { + LOG(ERROR) << "Unable to connect to PixelStats service"; + return false; + } + + // Only log and upload the min and max for metric types we want to upload + for (int metric = 0; metric < NUM_FIELDS; metric++) { + if ((metric == RES && num_res_samples_ == 0) || kSnapshotType[metric] < 0) + continue; + std::string log_min = "min-" + std::to_string(metric) + " "; + std::string log_max = "max-" + std::to_string(metric) + " "; + for (int j = 0; j < NUM_FIELDS; j++) { + log_min += std::to_string(min_[metric][j]) + " "; + log_max += std::to_string(max_[metric][j]) + " "; + } + LOG(INFO) << log_min; + LOG(INFO) << log_max; + // Upload min/max metrics + uploadOutlierMetric(client, static_cast<sampleType>(metric)); + } + + // Upload average metric + BatteryHealthSnapshotArgs avg_res_ss = { + BatterySnapshotType::AVG_RESISTANCE, 0, 0, 0, 0, avg_resistance, 0}; + if (num_res_samples_) + client->reportBatteryHealthSnapshot(avg_res_ss); + + // Clear existing data + memset(min_, 0, sizeof(min_)); + memset(max_, 0, sizeof(max_)); + num_res_samples_ = 0; + num_samples_ = 0; + last_upload_ = time; + accum_resistance_ = 0; + LOG(INFO) << "Finished uploading to tron"; + return true; +} + +bool BatteryMetricsLogger::recordSample(struct android::BatteryProperties *props) { + std::string resistance_str, ocv_str; + int32_t resistance, ocv; + int32_t time = getTime(); + + LOG(INFO) << "Recording a sample at time " << std::to_string(time); + + if (!android::base::ReadFileToString(kBatteryResistance, &resistance_str)) { + LOG(ERROR) << "Can't read the battery resistance"; + resistance = 0; + } else if (!(resistance = stoi(resistance_str))) { + LOG(ERROR) << "Can't parse battery resistance value " << resistance_str; + } + + if (!android::base::ReadFileToString(kBatteryOCV, &ocv_str)) { + LOG(ERROR) << "Can't read the open-circuit voltage (ocv) value"; + ocv = 0; + } else if (!(ocv = stoi(ocv_str))) { + LOG(ERROR) << "Can't parse open-circuit voltage (ocv) value " << ocv_str; + } + + int32_t sample[NUM_FIELDS] = {time, + resistance, + props->batteryCurrent, + props->batteryVoltage, + props->batteryTemperature, + props->batteryLevel, + ocv}; + if (props->batteryStatus != android::BATTERY_STATUS_CHARGING) { + accum_resistance_ += resistance; + num_res_samples_++; + } + + // Only calculate the min and max for metric types we want to upload + for (int metric = 0; metric < NUM_FIELDS; metric++) { + // Discard resistance min/max when charging + if ((metric == RES && props->batteryStatus == android::BATTERY_STATUS_CHARGING) || + kSnapshotType[metric] < 0) + continue; + if (num_samples_ == 0 || (metric == RES && num_res_samples_ == 0) || + sample[metric] < min_[metric][metric]) { + for (int i = 0; i < NUM_FIELDS; i++) { // update new min with current sample + min_[metric][i] = sample[i]; + } + } + if (num_samples_ == 0 || (metric == RES && num_res_samples_ == 0) || + sample[metric] > max_[metric][metric]) { + for (int i = 0; i < NUM_FIELDS; i++) { // update new max with current sample + max_[metric][i] = sample[i]; + } + } + } + + num_samples_++; + last_sample_ = time; + return true; +} + +void BatteryMetricsLogger::logBatteryProperties(struct android::BatteryProperties *props) { + int32_t time = getTime(); + if (last_sample_ == 0 || time - last_sample_ >= kSamplePeriod) + recordSample(props); + if (last_sample_ - last_upload_ > kUploadPeriod || num_samples_ >= kMaxSamples) + uploadMetrics(); + + return; +} + +} // namespace health +} // namespace pixel +} // namespace google +} // namespace hardware diff --git a/health/CycleCountBackupRestore.cpp b/health/CycleCountBackupRestore.cpp new file mode 100644 index 00000000..9b5b1006 --- /dev/null +++ b/health/CycleCountBackupRestore.cpp @@ -0,0 +1,148 @@ +/* + * 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 <pixelhealth/CycleCountBackupRestore.h> + +namespace hardware { +namespace google { +namespace pixel { +namespace health { + +static constexpr int kBackupTrigger = 20; + +CycleCountBackupRestore::CycleCountBackupRestore(int nb_buckets, const char *sysfs_path, + const char *persist_path, const char *serial_path) + : nb_buckets_(nb_buckets), + saved_soc_(-1), + soc_inc_(0), + sysfs_path_(sysfs_path), + persist_path_(persist_path), + serial_path_(serial_path) { + sw_bins_ = new int[nb_buckets](); + hw_bins_ = new int[nb_buckets](); +} + +void CycleCountBackupRestore::Restore() { + if (CheckSerial()) { + Read(persist_path_, sw_bins_); + } + Read(sysfs_path_, hw_bins_); + UpdateAndSave(); +} + +bool CycleCountBackupRestore::CheckSerial() { + std::string device_battery_serial; + std::string persist_battery_serial; + + if (serial_path_.empty()) + return true; + + if (!android::base::ReadFileToString(serial_path_, &device_battery_serial)) { + LOG(ERROR) << "Failed to read " << serial_path_; + return true; + } + + if (!android::base::ReadFileToString(kPersistSerial, &persist_battery_serial)) { + LOG(ERROR) << "Failed to read " << kPersistSerial; + } + + if (device_battery_serial != persist_battery_serial) { + // Battery pack has been changed or first time, + // cycle counts on the pack are the ones to save + if (!android::base::WriteStringToFile(device_battery_serial, kPersistSerial)) { + LOG(ERROR) << "Write to " << kPersistSerial << " error: " << strerror(errno); + } + return false; + } + + return true; +} + +void CycleCountBackupRestore::Backup(int battery_level) { + if (saved_soc_ == -1) { + saved_soc_ = battery_level; + return; + } + // Cycle counts only increases on increasing level + if (battery_level > saved_soc_) { + soc_inc_ += battery_level - saved_soc_; + } + saved_soc_ = battery_level; + // To avoid writting file too often just rate limit it + if (soc_inc_ >= kBackupTrigger) { + Read(sysfs_path_, hw_bins_); + UpdateAndSave(); + soc_inc_ = 0; + } +} + +void CycleCountBackupRestore::Read(const std::string &path, int *bins) { + std::string buffer; + + if (!android::base::ReadFileToString(path, &buffer)) { + LOG(ERROR) << "Failed to read " << path; + return; + } + + buffer = ::android::base::Trim(buffer); + std::vector<std::string> counts = android::base::Split(buffer, " "); + if (counts.size() != (size_t)nb_buckets_) { + LOG(ERROR) << "data format \"" << buffer << "\" is wrong in " << path; + } else { + LOG(INFO) << "Read: \"" << buffer << "\" from " << path; + for (int i = 0; i < nb_buckets_; ++i) { + bins[i] = std::stoi(counts[i]); + } + } +} + +void CycleCountBackupRestore::Write(int *bins, const std::string &path) { + std::string str_data = ""; + + for (int i = 0; i < nb_buckets_; ++i) { + if (i) { + str_data += " "; + } + str_data += std::to_string(bins[i]); + } + + LOG(INFO) << "Write: \"" << str_data << "\" to " << path; + if (!android::base::WriteStringToFile(str_data, path)) + LOG(ERROR) << "Write to " << path << " error: " << strerror(errno); +} + +void CycleCountBackupRestore::UpdateAndSave() { + bool backup = false; + bool restore = false; + for (int i = 0; i < nb_buckets_; i++) { + if (hw_bins_[i] < sw_bins_[i]) { + hw_bins_[i] = sw_bins_[i]; + restore = true; + } else if (hw_bins_[i] > sw_bins_[i]) { + sw_bins_[i] = hw_bins_[i]; + backup = true; + } + } + if (restore) + Write(hw_bins_, sysfs_path_); + if (backup) + Write(sw_bins_, persist_path_); +} + +} // namespace health +} // namespace pixel +} // namespace google +} // namespace hardware diff --git a/health/DeviceHealth.cpp b/health/DeviceHealth.cpp new file mode 100644 index 00000000..7054b2d9 --- /dev/null +++ b/health/DeviceHealth.cpp @@ -0,0 +1,44 @@ +/* + * 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. + */ + +#define LOG_TAG "dhealth" + +#include <pixelhealth/DeviceHealth.h> + +#include <android-base/properties.h> +#include <cutils/klog.h> + +namespace hardware { +namespace google { +namespace pixel { +namespace health { + +DeviceHealth::DeviceHealth() { + is_user_build_ = android::base::GetProperty("ro.build.type", "") == "user"; +} + +void DeviceHealth::update(struct android::BatteryProperties *props) { + if (!is_user_build_ && + (android::base::GetProperty("persist.vendor.disable.thermal.control", "") == "1" || + android::base::GetProperty("persist.vendor.fake.battery.temperature", "") == "1")) { + props->batteryTemperature = 200; + } +} + +} // namespace health +} // namespace pixel +} // namespace google +} // namespace hardware diff --git a/health/LowBatteryShutdownMetrics.cpp b/health/LowBatteryShutdownMetrics.cpp new file mode 100644 index 00000000..68645eb6 --- /dev/null +++ b/health/LowBatteryShutdownMetrics.cpp @@ -0,0 +1,105 @@ + +/* + * 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 <pixelhealth/LowBatteryShutdownMetrics.h> + +namespace hardware { +namespace google { +namespace pixel { +namespace health { + +using android::BATTERY_STATUS_DISCHARGING; +using android::sp; +using android::base::GetProperty; +using android::base::ReadFileToString; +using android::base::SetProperty; +using ::hardware::google::pixelstats::V1_0::IPixelStats; + +LowBatteryShutdownMetrics::LowBatteryShutdownMetrics(const char *const voltage_avg, + const char *const persist_prop) + : kVoltageAvg(voltage_avg), kPersistProp(persist_prop) { + prop_written_ = false; + prop_empty_ = false; +} + +bool LowBatteryShutdownMetrics::uploadVoltageAvg(void) { + std::string prop_contents = GetProperty(kPersistProp, ""); + LOG(INFO) << kPersistProp << " property contents: " << prop_contents; + if (prop_contents.size() == 0) { // we don't have anything to upload + prop_empty_ = true; + return false; + } + + sp<IPixelStats> client = IPixelStats::tryGetService(); + if (!client) { + LOG(ERROR) << "Unable to connect to PixelStats service"; + return false; + } + + // Process and upload comma-delimited last voltage values + int32_t voltage_avg; + for (const auto &item : android::base::Split(prop_contents, ",")) { + if (!(voltage_avg = stoi(item))) { + LOG(ERROR) << "Couldn't process voltage value " << item; + continue; + } + LOG(INFO) << "Uploading voltage_avg: " << std::to_string(voltage_avg); + client->reportBatteryCausedShutdown(voltage_avg); + } + + // Clear property now that we've uploaded its contents + SetProperty(kPersistProp, ""); + return true; +} + +bool LowBatteryShutdownMetrics::saveVoltageAvg(void) { + std::string voltage_avg; + std::string prop_contents; + + if (!ReadFileToString(kVoltageAvg, &voltage_avg)) { + LOG(ERROR) << "Can't read the Maxim fuel gauge average voltage value"; + return false; + } + voltage_avg = ::android::base::Trim(voltage_avg); + prop_contents = GetProperty(kPersistProp, ""); + + // Comma delimit additional values + if (prop_contents.size() > 0) + prop_contents += ","; + prop_contents += voltage_avg; + + LOG(INFO) << "Saving \"" << prop_contents << "\" to " << kPersistProp; + + return SetProperty(kPersistProp, prop_contents); +} + +void LowBatteryShutdownMetrics::logShutdownVoltage(struct android::BatteryProperties *props) { + // If we're about to shut down due to low battery, save voltage_avg + if (!prop_written_ && props->batteryLevel == 0 && + props->batteryStatus == android::BATTERY_STATUS_DISCHARGING) { + prop_written_ = saveVoltageAvg(); + } else if (!prop_empty_) { // We have data to upload + uploadVoltageAvg(); + } + + return; +} + +} // namespace health +} // namespace pixel +} // namespace google +} // namespace hardware diff --git a/health/include/pixelhealth/BatteryMetricsLogger.h b/health/include/pixelhealth/BatteryMetricsLogger.h new file mode 100644 index 00000000..2c760474 --- /dev/null +++ b/health/include/pixelhealth/BatteryMetricsLogger.h @@ -0,0 +1,97 @@ +/* + * 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. + */ + +#ifndef HARDWARE_GOOGLE_PIXEL_HEALTH_BATTERYMETRICSLOGGER_H +#define HARDWARE_GOOGLE_PIXEL_HEALTH_BATTERYMETRICSLOGGER_H + +#include <android-base/file.h> +#include <android-base/logging.h> +#include <android-base/strings.h> +#include <batteryservice/BatteryService.h> +#include <math.h> +#include <time.h> +#include <utils/Timers.h> +#include <string> + +#include <hardware/google/pixelstats/1.0/IPixelStats.h> + +namespace hardware { +namespace google { +namespace pixel { +namespace health { + +using BatterySnapshotType = ::hardware::google::pixelstats::V1_0::IPixelStats::BatterySnapshotType; + +class BatteryMetricsLogger { + public: + BatteryMetricsLogger(const char *const batt_res, const char *const batt_ocv, + int sample_period = TEN_MINUTES_SEC, int upload_period = ONE_DAY_SEC); + void logBatteryProperties(struct android::BatteryProperties *props); + + private: + enum sampleType { + TIME, // time in seconds + CURR, // current in mA + VOLT, // voltage in mV + TEMP, // temp in deci-degC + SOC, // SoC in % battery level + RES, // resistance in milli-ohms + OCV, // open-circuit voltage in mV + NUM_FIELDS, // do not reference + }; + + const int kSnapshotType[NUM_FIELDS] = { + -1, + (int)BatterySnapshotType::MIN_CURRENT, + (int)BatterySnapshotType::MIN_VOLTAGE, + (int)BatterySnapshotType::MIN_TEMP, + (int)BatterySnapshotType::MIN_BATT_LEVEL, + (int)BatterySnapshotType::MIN_RESISTANCE, + -1, + }; + + const char *const kBatteryResistance; + const char *const kBatteryOCV; + const int kSamplePeriod; + const int kUploadPeriod; + const int kMaxSamples; + static constexpr int TEN_MINUTES_SEC = 10 * 60; + static constexpr int ONE_DAY_SEC = 24 * 60 * 60; + + // min and max are referenced by type in both the X and Y axes + // i.e. min[TYPE] is the event where the minimum of that type occurred, and + // min[TYPE][TYPE] is the reading of that type at that minimum event + int32_t min_[NUM_FIELDS][NUM_FIELDS]; + int32_t max_[NUM_FIELDS][NUM_FIELDS]; + int32_t num_res_samples_; // number of res samples since last upload + int32_t num_samples_; // number of min/max samples since last upload + int64_t accum_resistance_; // accumulative resistance + int64_t last_sample_; // time in seconds since boot of last sample + int64_t last_upload_; // time in seconds since boot of last upload + + int64_t getTime(); + bool recordSample(struct android::BatteryProperties *props); + bool uploadMetrics(); + bool uploadOutlierMetric(android::sp<::hardware::google::pixelstats::V1_0::IPixelStats> client, + sampleType type); +}; + +} // namespace health +} // namespace pixel +} // namespace google +} // namespace hardware + +#endif diff --git a/health/include/pixelhealth/CycleCountBackupRestore.h b/health/include/pixelhealth/CycleCountBackupRestore.h new file mode 100644 index 00000000..bdac8899 --- /dev/null +++ b/health/include/pixelhealth/CycleCountBackupRestore.h @@ -0,0 +1,60 @@ +/* + * 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. + */ + +#ifndef HARDWARE_GOOGLE_PIXEL_HEALTH_CYCLECOUNTBACKUPRESTORE_H +#define HARDWARE_GOOGLE_PIXEL_HEALTH_CYCLECOUNTBACKUPRESTORE_H + +#include <android-base/file.h> +#include <android-base/logging.h> +#include <android-base/strings.h> +#include <string> + +namespace hardware { +namespace google { +namespace pixel { +namespace health { + +class CycleCountBackupRestore { + public: + CycleCountBackupRestore(int nb_buckets, const char *sysfs_path, const char *persist_path, + const char *serial_path = ""); + void Restore(); + void Backup(int battery_level); + + private: + const char *kPersistSerial = "/persist/battery/serial_number"; + + int nb_buckets_; + int *sw_bins_; + int *hw_bins_; + int saved_soc_; + int soc_inc_; + std::string sysfs_path_; + std::string persist_path_; + std::string serial_path_; + + void Read(const std::string &path, int *bins); + void Write(int *bins, const std::string &path); + void UpdateAndSave(); + bool CheckSerial(); +}; + +} // namespace health +} // namespace pixel +} // namespace google +} // namespace hardware + +#endif // #ifndef HARDWARE_GOOGLE_PIXEL_HEALTH_CYCLECOUNTBACKUPRESTORE_H diff --git a/health/include/pixelhealth/DeviceHealth.h b/health/include/pixelhealth/DeviceHealth.h new file mode 100644 index 00000000..037a9aca --- /dev/null +++ b/health/include/pixelhealth/DeviceHealth.h @@ -0,0 +1,40 @@ +/* + * 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. + */ + +#ifndef HARDWARE_GOOGLE_PIXEL_HEALTH_DEVICEHEALTH_H + +#include <batteryservice/BatteryService.h> + +namespace hardware { +namespace google { +namespace pixel { +namespace health { + +class DeviceHealth { + public: + DeviceHealth(); + void update(struct android::BatteryProperties *props); + + private: + bool is_user_build_; +}; + +} // namespace health +} // namespace pixel +} // namespace google +} // namespace hardware + +#endif diff --git a/health/include/pixelhealth/LowBatteryShutdownMetrics.h b/health/include/pixelhealth/LowBatteryShutdownMetrics.h new file mode 100644 index 00000000..2fa7e4b0 --- /dev/null +++ b/health/include/pixelhealth/LowBatteryShutdownMetrics.h @@ -0,0 +1,63 @@ +/* + * 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. + */ + +#ifndef HARDWARE_GOOGLE_PIXEL_HEALTH_LOWBATTERYSHUTDOWNMETRICS_H +#define HARDWARE_GOOGLE_PIXEL_HEALTH_LOWBATTERYSHUTDOWNMETRICS_H + +#include <android-base/file.h> +#include <android-base/logging.h> +#include <android-base/properties.h> +#include <android-base/strings.h> +#include <batteryservice/BatteryService.h> +#include <math.h> +#include <time.h> +#include <utils/Timers.h> +#include <string> + +#include <hardware/google/pixelstats/1.0/IPixelStats.h> + +namespace hardware { +namespace google { +namespace pixel { +namespace health { + +class LowBatteryShutdownMetrics { + public: + LowBatteryShutdownMetrics( + const char *const voltage_avg, + const char *const persist_prop = "persist.vendor.shutdown.voltage_avg"); + void logShutdownVoltage(struct android::BatteryProperties *props); + + private: + const char *const kVoltageAvg; + const char *const kPersistProp; + + // Helps enforce that we only record kVoltageAvg once per boot cycle + bool prop_written_; + // Help us avoid polling kPersistProp if it's empty + bool prop_empty_; + + bool saveVoltageAvg(); + void readStatus(); + bool uploadVoltageAvg(); +}; + +} // namespace health +} // namespace pixel +} // namespace google +} // namespace hardware + +#endif |