diff options
author | android-build-team Robot <android-build-team-robot@google.com> | 2020-10-20 23:04:10 +0000 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2020-10-20 23:04:10 +0000 |
commit | 6a92d6dce908dca21d072ccd5b15ebdea1220359 (patch) | |
tree | 94b4810048f92401be660693d75823038ad80864 | |
parent | 02b687328f0f3a97adadac16d9fa83c212f563e9 (diff) | |
parent | 95ebbcfe7361fa2fd1ad6931312a05136492cf23 (diff) | |
download | pixel-6a92d6dce908dca21d072ccd5b15ebdea1220359.tar.gz |
Snap for 6918817 from 95ebbcfe7361fa2fd1ad6931312a05136492cf23 to rvc-qpr2-release
Change-Id: I8b80f2fd385d7b69bdf02e1e21101ab1d63b0418
-rw-r--r-- | pixelstats/Android.bp | 1 | ||||
-rw-r--r-- | pixelstats/BatteryEEPROMReporter.cpp | 210 | ||||
-rw-r--r-- | pixelstats/SysfsCollector.cpp | 16 | ||||
-rw-r--r-- | pixelstats/include/pixelstats/BatteryEEPROMReporter.h | 106 | ||||
-rw-r--r-- | pixelstats/include/pixelstats/SysfsCollector.h | 7 | ||||
-rw-r--r-- | pixelstats/pixelatoms.proto | 50 |
6 files changed, 389 insertions, 1 deletions
diff --git a/pixelstats/Android.bp b/pixelstats/Android.bp index 7f2ee61f..94fa064e 100644 --- a/pixelstats/Android.bp +++ b/pixelstats/Android.bp @@ -49,6 +49,7 @@ cc_library { "UeventListener.cpp", "WlcReporter.cpp", "BatteryCapacityReporter.cpp", + "BatteryEEPROMReporter.cpp", ], cflags: [ "-Wall", diff --git a/pixelstats/BatteryEEPROMReporter.cpp b/pixelstats/BatteryEEPROMReporter.cpp new file mode 100644 index 00000000..8bbfcf1f --- /dev/null +++ b/pixelstats/BatteryEEPROMReporter.cpp @@ -0,0 +1,210 @@ +/* + * Copyright (C) 2020 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 "pixelstats: BatteryEEPROM" + +#include <log/log.h> +#include <time.h> +#include <utils/Timers.h> +#include <cmath> +#include <inttypes.h> + +#include <android-base/file.h> + +#include <android/frameworks/stats/1.0/IStats.h> +#include <pixelstats/BatteryEEPROMReporter.h> + +#include <hardware/google/pixel/pixelstats/pixelatoms.pb.h> + +namespace android { +namespace hardware { +namespace google { +namespace pixel { + +using android::base::ReadFileToString; +using android::frameworks::stats::V1_0::IStats; +using android::frameworks::stats::V1_0::VendorAtom; +using android::hardware::google::pixel::PixelAtoms::BatteryEEPROM; + +#define LINESIZE 71 + +BatteryEEPROMReporter::BatteryEEPROMReporter() {} + +void BatteryEEPROMReporter::checkAndReport(const std::string &path) { + std::string file_contents; + std::string history_each; + + const int kSecondsPerMonth = 60 * 60 * 24 * 30; + int64_t now = getTimeSecs(); + + if ((report_time_ != 0) && (now - report_time_ < kSecondsPerMonth)) { + ALOGD("Not upload time. now:%ld, pre:%ld", now, report_time_); + return; + } + + if (!ReadFileToString(path.c_str(), &file_contents)) { + ALOGE("Unable to read %s - %s", path.c_str(), strerror(errno)); + return; + } + ALOGD("checkAndReport: %s", file_contents.c_str()); + + int16_t i, num; + struct BatteryHistory hist; + const int kHistTotalLen = strlen(file_contents.c_str()); + + for (i = 0; i < (LINESIZE * BATT_HIST_NUM_MAX); i = i + LINESIZE) { + if (i + LINESIZE > kHistTotalLen) + break; + history_each = file_contents.substr(i, LINESIZE); + num = sscanf(history_each.c_str(), + "%4" SCNx16 "%4" SCNx16 "%4" SCNx16 "%4" SCNx16 + "%2" SCNx8 "%2" SCNx8 " %2" SCNx8 "%2" SCNx8 + "%2" SCNx8 "%2" SCNx8 " %2" SCNx8 "%2" SCNx8 + "%2" SCNx8 "%2" SCNx8 " %4" SCNx16 "%4" SCNx16 + "%4" SCNx16 "%4" SCNx16 "%4" SCNx16, + &hist.cycle_cnt, &hist.full_cap, &hist.esr, + &hist.rslow, &hist.soh, &hist.batt_temp, + &hist.cutoff_soc, &hist.cc_soc, &hist.sys_soc, + &hist.msoc, &hist.batt_soc, &hist.reserve, + &hist.max_temp, &hist.min_temp, &hist.max_vbatt, + &hist.min_vbatt, &hist.max_ibatt, &hist.min_ibatt, + &hist.checksum); + + if (num != kNumBatteryHistoryFields) { + ALOGE("Couldn't process %s", history_each.c_str()); + continue; + } + + if (checkLogEvent(hist)) { + reportEvent(hist); + report_time_ = getTimeSecs(); + } + } +} + +int64_t BatteryEEPROMReporter::getTimeSecs(void) { + return nanoseconds_to_seconds(systemTime(SYSTEM_TIME_BOOTTIME)); +} + +/** + * @return true if a log should be reported, else false. + * Here we use checksum to confirm the data is usable or not. + * The checksum mismatch when storage data overflow or corrupt. + * We don't need data in such cases. + */ +bool BatteryEEPROMReporter::checkLogEvent(struct BatteryHistory hist) { + int checksum = 0; + + checksum = hist.cycle_cnt + hist.full_cap + hist.esr + hist.rslow + + hist.soh + hist.batt_temp + hist.cutoff_soc + hist.cc_soc + + hist.sys_soc + hist.msoc + hist.batt_soc + hist.reserve + + hist.max_temp + hist.min_temp + hist.max_vbatt + + hist.min_vbatt + hist.max_ibatt + hist.min_ibatt; + /* Compare with checksum data */ + if (checksum == hist.checksum) { + return true; + } else { + return false; + } +} + +void BatteryEEPROMReporter::reportEvent(struct BatteryHistory hist) { + sp<IStats> stats_client = IStats::tryGetService(); + // upload atom + std::vector<int> eeprom_history_fields = {BatteryEEPROM::kCycleCntFieldNumber, + BatteryEEPROM::kFullCapFieldNumber, + BatteryEEPROM::kEsrFieldNumber, + BatteryEEPROM::kRslowFieldNumber, + BatteryEEPROM::kSohFieldNumber, + BatteryEEPROM::kBattTempFieldNumber, + BatteryEEPROM::kCutoffSocFieldNumber, + BatteryEEPROM::kCcSocFieldNumber, + BatteryEEPROM::kSysSocFieldNumber, + BatteryEEPROM::kMsocFieldNumber, + BatteryEEPROM::kBattSocFieldNumber, + BatteryEEPROM::kReserveFieldNumber, + BatteryEEPROM::kMaxTempFieldNumber, + BatteryEEPROM::kMinTempFieldNumber, + BatteryEEPROM::kMaxVbattFieldNumber, + BatteryEEPROM::kMinVbattFieldNumber, + BatteryEEPROM::kMaxIbattFieldNumber, + BatteryEEPROM::kMinIbattFieldNumber, + BatteryEEPROM::kChecksumFieldNumber}; + std::vector<VendorAtom::Value> values(eeprom_history_fields.size()); + VendorAtom::Value val; + + ALOGD("reportEvent: cycle_cnt:%d, full_cap:%d, esr:%d, rslow:%d, soh:%d, " + "batt_temp:%d, cutoff_soc:%d, cc_soc:%d, sys_soc:%d, msoc:%d, " + "batt_soc:%d, reserve:%d, max_temp:%d, min_temp:%d, max_vbatt:%d, " + "min_vbatt:%d, max_ibatt:%d, min_ibatt:%d, checksum:%d", + hist.cycle_cnt, hist.full_cap, hist.esr, hist.rslow, hist.soh, + hist.batt_temp, hist.cutoff_soc, hist.cc_soc, hist.sys_soc, + hist.msoc, hist.batt_soc, hist.reserve, hist.max_temp, + hist.min_temp, hist.max_vbatt, hist.min_vbatt, hist.max_ibatt, + hist.min_ibatt, hist.checksum); + + val.intValue(hist.cycle_cnt); + values[BatteryEEPROM::kCycleCntFieldNumber - kVendorAtomOffset] = val; + val.intValue(hist.full_cap); + values[BatteryEEPROM::kFullCapFieldNumber - kVendorAtomOffset] = val; + val.intValue(hist.esr); + values[BatteryEEPROM::kEsrFieldNumber - kVendorAtomOffset] = val; + val.intValue(hist.rslow); + values[BatteryEEPROM::kRslowFieldNumber - kVendorAtomOffset] = val; + val.intValue(hist.soh); + values[BatteryEEPROM::kSohFieldNumber - kVendorAtomOffset] = val; + val.intValue(hist.batt_temp); + values[BatteryEEPROM::kBattTempFieldNumber - kVendorAtomOffset] = val; + val.intValue(hist.cutoff_soc); + values[BatteryEEPROM::kCutoffSocFieldNumber - kVendorAtomOffset] = val; + val.intValue(hist.cc_soc); + values[BatteryEEPROM::kCcSocFieldNumber - kVendorAtomOffset] = val; + val.intValue(hist.sys_soc); + values[BatteryEEPROM::kSysSocFieldNumber - kVendorAtomOffset] = val; + val.intValue(hist.msoc); + values[BatteryEEPROM::kMsocFieldNumber - kVendorAtomOffset] = val; + val.intValue(hist.batt_soc); + values[BatteryEEPROM::kBattSocFieldNumber - kVendorAtomOffset] = val; + val.intValue(hist.reserve); + values[BatteryEEPROM::kReserveFieldNumber - kVendorAtomOffset] = val; + val.intValue(hist.max_temp); + values[BatteryEEPROM::kMaxTempFieldNumber - kVendorAtomOffset] = val; + val.intValue(hist.min_temp); + values[BatteryEEPROM::kMinTempFieldNumber - kVendorAtomOffset] = val; + val.intValue(hist.max_vbatt); + values[BatteryEEPROM::kMaxVbattFieldNumber - kVendorAtomOffset] = val; + val.intValue(hist.min_vbatt); + values[BatteryEEPROM::kMinTempFieldNumber - kVendorAtomOffset] = val; + val.intValue(hist.max_ibatt); + values[BatteryEEPROM::kMaxIbattFieldNumber - kVendorAtomOffset] = val; + val.intValue(hist.min_ibatt); + values[BatteryEEPROM::kMinIbattFieldNumber - kVendorAtomOffset] = val; + val.intValue(hist.checksum); + values[BatteryEEPROM::kChecksumFieldNumber - kVendorAtomOffset] = val; + + VendorAtom event = {.reverseDomainName = PixelAtoms::ReverseDomainNames().pixel(), + .atomId = PixelAtoms::Ids::BATTERY_EEPROM, + .values = values}; + Return<void> ret = stats_client->reportVendorAtom(event); + if (!ret.isOk()) + ALOGE("Unable to report BatteryEEPROM to Stats service"); +} + + +} // namespace pixel +} // namespace google +} // namespace hardware +} // namespace android diff --git a/pixelstats/SysfsCollector.cpp b/pixelstats/SysfsCollector.cpp index bf1e3d56..29b35099 100644 --- a/pixelstats/SysfsCollector.cpp +++ b/pixelstats/SysfsCollector.cpp @@ -72,7 +72,8 @@ SysfsCollector::SysfsCollector(const struct SysfsPaths &sysfs_paths) kF2fsStatsPath(sysfs_paths.F2fsStatsPath), kUserdataBlockProp(sysfs_paths.UserdataBlockProp), kZramMmStatPath("/sys/block/zram0/mm_stat"), - kZramBdStatPath("/sys/block/zram0/bd_stat") {} + kZramBdStatPath("/sys/block/zram0/bd_stat"), + kEEPROMPath(sysfs_paths.EEPROMPath) {} bool SysfsCollector::ReadFileToInt(const std::string &path, int *val) { return ReadFileToInt(path.c_str(), val); @@ -126,6 +127,18 @@ void SysfsCollector::logBatteryChargeCycles() { } /** + * Read the contents of kEEPROMPath and report them. + */ +void SysfsCollector::logBatteryEEPROM() { + if (kEEPROMPath == nullptr || strlen(kEEPROMPath) == 0) { + ALOGV("Battery EEPROM path not specified"); + return; + } + + battery_EEPROM_reporter_.checkAndReport(kEEPROMPath); +} + +/** * Check the codec for failures over the past 24hr. */ void SysfsCollector::logCodecFailed() { @@ -599,6 +612,7 @@ void SysfsCollector::logAll() { logUFSLifetime(); logF2fsStats(); logZramStats(); + logBatteryEEPROM(); stats_.clear(); } diff --git a/pixelstats/include/pixelstats/BatteryEEPROMReporter.h b/pixelstats/include/pixelstats/BatteryEEPROMReporter.h new file mode 100644 index 00000000..e3ff997b --- /dev/null +++ b/pixelstats/include/pixelstats/BatteryEEPROMReporter.h @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2020 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_PIXELSTATS_BATTERYEEPROMREPORTER_H +#define HARDWARE_GOOGLE_PIXEL_PIXELSTATS_BATTERYEEPROMREPORTER_H + +namespace android { +namespace hardware { +namespace google { +namespace pixel { + +// The storage for save whole history is 928 byte +// each history contains 19 items with total size 28 byte +// hence the history number is 928/28~33 +#define BATT_HIST_NUM_MAX 33 + +/** + * A class to upload battery EEPROM metrics + */ +class BatteryEEPROMReporter { + public: + BatteryEEPROMReporter(); + void checkAndReport(const std::string &path); + + private: + // Proto messages are 1-indexed and VendorAtom field numbers start at 2, so + // store everything in the values array at the index of the field number + // -2. + const int kVendorAtomOffset = 2; + + struct BatteryHistory { + /* The cycle count number; record of charge/discharge times */ + uint16_t cycle_cnt; + /* The current full capacity of the battery under nominal conditions */ + uint16_t full_cap; + /* The battery equivalent series resistance */ + uint16_t esr; + /* Battery resistance related to temperature change */ + uint16_t rslow; + /* Battery health indicator reflecting the battery age state */ + uint8_t soh; + /* The battery temperature */ + int8_t batt_temp; + + /* Battery state of charge (SOC) shutdown point */ + uint8_t cutoff_soc; + /* Raw battery state of charge (SOC), based on battery current (CC = Coulomb Counter) */ + uint8_t cc_soc; + /* Estimated battery state of charge (SOC) from batt_soc with endpoint limiting (0% and 100%) */ + uint8_t sys_soc; + /* Filtered monotonic SOC, handles situations where the cutoff_soc is increased and + * then decreased from the battery physical properties + */ + uint8_t msoc; + /* Estimated SOC derived from cc_soc that provides voltage loop feedback correction using + * battery voltage, current, and status values + */ + uint8_t batt_soc; + + /* Field used for data padding in the EEPROM data */ + uint8_t reserve; + + /* The maximum battery temperature ever seen */ + int8_t max_temp; + /* The minimum battery temperature ever seen */ + int8_t min_temp; + /* The maximum battery voltage ever seen */ + uint16_t max_vbatt; + /* The minimum battery voltage ever seen */ + uint16_t min_vbatt; + /* The maximum battery current ever seen */ + int16_t max_ibatt; + /* The minimum battery current ever seen */ + int16_t min_ibatt; + /* Field used to verify the integrity of the EEPROM data */ + uint16_t checksum; + }; + /* The number of elements in struct BatteryHistory */ + const int kNumBatteryHistoryFields = 19; + + int64_t report_time_ = 0; + int64_t getTimeSecs(); + + bool checkLogEvent(struct BatteryHistory hist); + void reportEvent(struct BatteryHistory hist); +}; + +} // namespace pixel +} // namespace google +} // namespace hardware +} // namespace android + +#endif // HARDWARE_GOOGLE_PIXEL_PIXELSTATS_BATTERYEEPROMREPORTER_H diff --git a/pixelstats/include/pixelstats/SysfsCollector.h b/pixelstats/include/pixelstats/SysfsCollector.h index c6cc608c..bbe116f0 100644 --- a/pixelstats/include/pixelstats/SysfsCollector.h +++ b/pixelstats/include/pixelstats/SysfsCollector.h @@ -20,6 +20,8 @@ #include <android/frameworks/stats/1.0/IStats.h> #include <utils/StrongPointer.h> +#include "BatteryEEPROMReporter.h" + using android::sp; using android::frameworks::stats::V1_0::IStats; using android::frameworks::stats::V1_0::SlowIo; @@ -50,6 +52,7 @@ class SysfsCollector { const char *const UserdataBlockProp; const char *const ZramMmStatPath; const char *const ZramBdStatPath; + const char *const EEPROMPath; }; SysfsCollector(const struct SysfsPaths &paths); @@ -71,6 +74,7 @@ class SysfsCollector { void logF2fsStats(); void logZramStats(); void logBootStats(); + void logBatteryEEPROM(); void reportSlowIoFromFile(const char *path, const SlowIo::IoOperation &operation_s); void reportZramMmStat(); @@ -96,8 +100,11 @@ class SysfsCollector { const char *const kUserdataBlockProp; const char *const kZramMmStatPath; const char *const kZramBdStatPath; + const char *const kEEPROMPath; sp<IStats> stats_; + BatteryEEPROMReporter battery_EEPROM_reporter_; + // Proto messages are 1-indexed and VendorAtom field numbers start at 2, so // store everything in the values array at the index of the field number // -2. diff --git a/pixelstats/pixelatoms.proto b/pixelstats/pixelatoms.proto index 857e66fc..a920783e 100644 --- a/pixelstats/pixelatoms.proto +++ b/pixelstats/pixelatoms.proto @@ -46,6 +46,8 @@ enum Ids { DEVICE_ORIENTATION = 105009; FG_CAPACITY = 105010; PD_VID_PID = 105011; + BATTERY_EEPROM = 105012; + // AOSP atom ID range ends at 109999 } @@ -257,3 +259,51 @@ message PdVidPid { /* Product ID of wired charger */ optional int32 pid = 3; } + +message BatteryEEPROM { + /* The cycle count number; record of charge/discharge times */ + optional int32 cycle_cnt = 2; + /* The current full capacity of the battery under nominal conditions */ + optional int32 full_cap = 3; + /* The battery equivalent series resistance */ + optional int32 esr = 4; + /* Battery resistance related to temperature change */ + optional int32 rslow = 5; + /* Battery health indicator reflecting the battery age state */ + optional int32 soh = 6; + /* The battery temperature */ + optional int32 batt_temp = 7; + + /* Battery state of charge (SOC) shutdown point */ + optional int32 cutoff_soc = 8; + /* Raw battery state of charge (SOC), based on battery current (CC = Coulomb Counter) */ + optional int32 cc_soc = 9; + /* Estimated battery state of charge (SOC) from batt_soc with endpoint limiting (0% and 100%) */ + optional int32 sys_soc = 10; + /* Filtered monotonic SOC, handles situations where the cutoff_soc is increased and + * then decreased from the battery physical properties + */ + optional int32 msoc = 11; + /* Estimated SOC derived from cc_soc that provides voltage loop feedback correction using + * battery voltage, current, and status values + */ + optional int32 batt_soc = 12; + + /* Field used for data padding in the EEPROM data */ + optional int32 reserve = 13; + + /* The maximum battery temperature ever seen */ + optional int32 max_temp = 14; + /* The minimum battery temperature ever seen */ + optional int32 min_temp = 15; + /* The maximum battery voltage ever seen */ + optional int32 max_vbatt = 16; + /* The minimum battery voltage ever seen */ + optional int32 min_vbatt = 17; + /* The maximum battery current ever seen */ + optional int32 max_ibatt = 18; + /* The minimum battery current ever seen */ + optional int32 min_ibatt = 19; + /* Field used to verify the integrity of the EEPROM data */ + optional int32 checksum = 20; +} |