summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2020-10-20 23:04:10 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2020-10-20 23:04:10 +0000
commit6a92d6dce908dca21d072ccd5b15ebdea1220359 (patch)
tree94b4810048f92401be660693d75823038ad80864
parent02b687328f0f3a97adadac16d9fa83c212f563e9 (diff)
parent95ebbcfe7361fa2fd1ad6931312a05136492cf23 (diff)
downloadpixel-6a92d6dce908dca21d072ccd5b15ebdea1220359.tar.gz
Snap for 6918817 from 95ebbcfe7361fa2fd1ad6931312a05136492cf23 to rvc-qpr2-release
Change-Id: I8b80f2fd385d7b69bdf02e1e21101ab1d63b0418
-rw-r--r--pixelstats/Android.bp1
-rw-r--r--pixelstats/BatteryEEPROMReporter.cpp210
-rw-r--r--pixelstats/SysfsCollector.cpp16
-rw-r--r--pixelstats/include/pixelstats/BatteryEEPROMReporter.h106
-rw-r--r--pixelstats/include/pixelstats/SysfsCollector.h7
-rw-r--r--pixelstats/pixelatoms.proto50
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;
+}