summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJenny Ho <hsiufangho@google.com>2022-02-22 19:52:41 +0800
committerStephane Lee <stayfan@google.com>2022-05-06 16:12:02 -0700
commitce1277247a895da346783267d49ab16ce716319c (patch)
tree252da49715890a58d1c80996dde1c5d6a5b578bd
parent747d01f859591b59ec16867ea0780b4618450ae2 (diff)
pixelstats: Add battery usage stats
This sends accumulated time spent above different SOC and temperature levels on the device. This will sent a burst of events based on what the swelling_data sysfs node provides. eldar/142490839 Bug: 230501230 Test: logcat | grep pixelstats Signed-off-by: Jenny Ho <hsiufangho@google.com> Merged-In: If54a545503dcb47b9214ef0117acdf060c586035 Change-Id: I6358d02d8ae8a4c0c21b20cc04c2e75a46754e92
-rw-r--r--pixelstats/BatteryHealthReporter.cpp97
-rw-r--r--pixelstats/include/pixelstats/BatteryHealthReporter.h8
-rw-r--r--pixelstats/include/pixelstats/StatsHelper.h3
-rw-r--r--pixelstats/include/pixelstats/SysfsCollector.h2
-rw-r--r--pixelstats/pixelatoms.proto28
5 files changed, 124 insertions, 14 deletions
diff --git a/pixelstats/BatteryHealthReporter.cpp b/pixelstats/BatteryHealthReporter.cpp
index 027f7c4..66d6002 100644
--- a/pixelstats/BatteryHealthReporter.cpp
+++ b/pixelstats/BatteryHealthReporter.cpp
@@ -37,6 +37,7 @@ using aidl::android::frameworks::stats::VendorAtomValue;
using android::base::ReadFileToString;
using android::base::WriteStringToFile;
using android::hardware::google::pixel::PixelAtoms::BatteryHealthStatus;
+using android::hardware::google::pixel::PixelAtoms::BatteryHealthUsage;
const int SECONDS_PER_MONTH = 60 * 60 * 24 * 30;
@@ -46,8 +47,27 @@ int64_t BatteryHealthReporter::getTimeSecs(void) {
return nanoseconds_to_seconds(systemTime(SYSTEM_TIME_BOOTTIME));
}
-void BatteryHealthReporter::reportBatteryHealthStatus(const std::shared_ptr<IStats> &stats_client,
- const char *line) {
+bool BatteryHealthReporter::reportBatteryHealthStatus(const std::shared_ptr<IStats> &stats_client) {
+ std::string path = kBatteryHealthStatusPath;
+ std::string file_contents, line;
+ std::istringstream ss;
+
+ if (!ReadFileToString(path.c_str(), &file_contents)) {
+ ALOGD("Unsupported path %s - %s", path.c_str(), strerror(errno));
+ return false;
+ }
+
+ ss.str(file_contents);
+
+ while (std::getline(ss, line)) {
+ reportBatteryHealthStatusEvent(stats_client, line.c_str());
+ }
+
+ return true;
+}
+
+void BatteryHealthReporter::reportBatteryHealthStatusEvent(
+ const std::shared_ptr<IStats> &stats_client, const char *line) {
int health_status_stats_fields[] = {
BatteryHealthStatus::kHealthAlgorithmFieldNumber,
BatteryHealthStatus::kHealthStatusFieldNumber,
@@ -89,27 +109,78 @@ void BatteryHealthReporter::reportBatteryHealthStatus(const std::shared_ptr<ISta
ALOGE("Unable to report BatteryHealthStatus to Stats service");
}
-void BatteryHealthReporter::checkAndReportStatus(const std::shared_ptr<IStats> &stats_client) {
+bool BatteryHealthReporter::reportBatteryHealthUsage(const std::shared_ptr<IStats> &stats_client) {
+ std::string path = kBatteryHealthUsagePath;
std::string file_contents, line;
std::istringstream ss;
- std::string path = kBatteryHealthStatusPath;
- int64_t now = getTimeSecs();
- if ((report_time_ != 0) && (now - report_time_ < SECONDS_PER_MONTH)) {
- ALOGD("Do not upload yet. now: %" PRId64 ", pre: %" PRId64, now, report_time_);
+ if (!ReadFileToString(path.c_str(), &file_contents)) {
+ ALOGD("Unsupported path %s - %s", path.c_str(), strerror(errno));
+ return false;
+ }
+
+ ss.str(file_contents);
+
+ // skip first title line
+ if (!std::getline(ss, line)) {
+ ALOGE("Unable to read first line of: %s", path.c_str());
+ return false;
+ }
+
+ while (std::getline(ss, line)) {
+ reportBatteryHealthUsageEvent(stats_client, line.c_str());
+ }
+
+ return true;
+}
+
+void BatteryHealthReporter::reportBatteryHealthUsageEvent(
+ const std::shared_ptr<IStats> &stats_client, const char *line) {
+ int health_status_stats_fields[] = {
+ BatteryHealthUsage::kTemperatureLimitDeciCFieldNumber,
+ BatteryHealthUsage::kSocLimitFieldNumber,
+ BatteryHealthUsage::kChargeTimeSecsFieldNumber,
+ BatteryHealthUsage::kDischargeTimeSecsFieldNumber,
+ };
+
+ const int32_t vtier_fields_size = std::size(health_status_stats_fields);
+ static_assert(vtier_fields_size == 4, "Unexpected battery health status fields size");
+ std::vector<VendorAtomValue> values(vtier_fields_size);
+ VendorAtomValue val;
+ int32_t i = 0, tmp[vtier_fields_size] = {0};
+
+ // temp/soc charge(s) discharge(s)
+ if (sscanf(line, "%d/%d\t%d\t%d", &tmp[0], &tmp[1], &tmp[2], &tmp[3]) != vtier_fields_size) {
+ /* If format isn't as expected, then ignore line on purpose */
return;
}
- if (!ReadFileToString(path.c_str(), &file_contents)) {
- ALOGE("Unable to read %s - %s", path.c_str(), strerror(errno));
+ ALOGD("BatteryHealthUsage: processed %s", line);
+ for (i = 0; i < vtier_fields_size; i++) {
+ val.set<VendorAtomValue::intValue>(tmp[i]);
+ values[health_status_stats_fields[i] - kVendorAtomOffset] = val;
+ }
+
+ VendorAtom event = {.reverseDomainName = "",
+ .atomId = PixelAtoms::Atom::kBatteryHealthUsage,
+ .values = std::move(values)};
+ const ndk::ScopedAStatus ret = stats_client->reportVendorAtom(event);
+ if (!ret.isOk())
+ ALOGE("Unable to report BatteryHealthStatus to Stats service");
+}
+
+void BatteryHealthReporter::checkAndReportStatus(const std::shared_ptr<IStats> &stats_client) {
+ int64_t now = getTimeSecs();
+ if ((report_time_ != 0) && (now - report_time_ < SECONDS_PER_MONTH)) {
+ ALOGD("Do not upload yet. now: %" PRId64 ", pre: %" PRId64, now, report_time_);
return;
}
- ss.str(file_contents);
+ bool successStatus = reportBatteryHealthStatus(stats_client);
+ bool successUsage = reportBatteryHealthUsage(stats_client);
- report_time_ = now;
- while (std::getline(ss, line)) {
- reportBatteryHealthStatus(stats_client, line.c_str());
+ if (successStatus && successUsage) {
+ report_time_ = now;
}
}
diff --git a/pixelstats/include/pixelstats/BatteryHealthReporter.h b/pixelstats/include/pixelstats/BatteryHealthReporter.h
index 7c64f72..e6701c2 100644
--- a/pixelstats/include/pixelstats/BatteryHealthReporter.h
+++ b/pixelstats/include/pixelstats/BatteryHealthReporter.h
@@ -35,7 +35,12 @@ class BatteryHealthReporter {
void checkAndReportStatus(const std::shared_ptr<IStats> &stats_client);
private:
- void reportBatteryHealthStatus(const std::shared_ptr<IStats> &stats_client, const char *line);
+ bool reportBatteryHealthStatus(const std::shared_ptr<IStats> &stats_client);
+ void reportBatteryHealthStatusEvent(const std::shared_ptr<IStats> &stats_client,
+ const char *line);
+ bool reportBatteryHealthUsage(const std::shared_ptr<IStats> &stats_client);
+ void reportBatteryHealthUsageEvent(const std::shared_ptr<IStats> &stats_client,
+ const char *line);
int64_t report_time_ = 0;
int64_t getTimeSecs();
@@ -47,6 +52,7 @@ class BatteryHealthReporter {
const std::string kBatteryHealthStatusPath =
"/sys/class/power_supply/battery/health_index_stats";
+ const std::string kBatteryHealthUsagePath = "/sys/class/power_supply/battery/swelling_data";
};
} // namespace pixel
diff --git a/pixelstats/include/pixelstats/StatsHelper.h b/pixelstats/include/pixelstats/StatsHelper.h
index 7c79b6b..d6f8c72 100644
--- a/pixelstats/include/pixelstats/StatsHelper.h
+++ b/pixelstats/include/pixelstats/StatsHelper.h
@@ -38,6 +38,9 @@ void reportSlowIo(const std::shared_ptr<IStats> &stats_client,
void reportChargeCycles(const std::shared_ptr<IStats> &stats_client,
const std::vector<int32_t> &chargeCycles);
+void reportBatterySwelling(const std::shared_ptr<IStats> &stats_client,
+ const std::vector<int32_t> &swellingData);
+
void reportHardwareFailed(const std::shared_ptr<IStats> &stats_client,
const PixelAtoms::VendorHardwareFailed &failure);
diff --git a/pixelstats/include/pixelstats/SysfsCollector.h b/pixelstats/include/pixelstats/SysfsCollector.h
index 2baa53c..25a1072 100644
--- a/pixelstats/include/pixelstats/SysfsCollector.h
+++ b/pixelstats/include/pixelstats/SysfsCollector.h
@@ -41,6 +41,7 @@ class SysfsCollector {
const char *const SlowioUnmapCntPath;
const char *const SlowioSyncCntPath;
const char *const CycleCountBinsPath;
+ const char *const BatterySwellingPath;
const char *const ImpedancePath;
const char *const CodecPath;
const char *const Codec1Path;
@@ -88,6 +89,7 @@ class SysfsCollector {
void logBootStats(const std::shared_ptr<IStats> &stats_client);
void logBatteryEEPROM(const std::shared_ptr<IStats> &stats_client);
void logSpeakerHealthStats(const std::shared_ptr<IStats> &stats_client);
+ void logBatterySwelling(const std::shared_ptr<IStats> &stats_client);
void reportSlowIoFromFile(const std::shared_ptr<IStats> &stats_client, const char *path,
const VendorSlowIo::IoOperation &operation_s);
diff --git a/pixelstats/pixelatoms.proto b/pixelstats/pixelatoms.proto
index 2ef984c..38dc39a 100644
--- a/pixelstats/pixelatoms.proto
+++ b/pixelstats/pixelatoms.proto
@@ -78,6 +78,7 @@ message Atom {
ChreApWakeUpOccurred chre_ap_wake_up_occurred = 105036;
BatteryHealthStatus battery_health_status = 105037;
+ BatteryHealthUsage battery_health_usage = 105038;
}
// AOSP atom ID range ends at 109999
}
@@ -1068,3 +1069,30 @@ message BatteryHealthStatus {
// The cycle count at the time of the log event.
optional int32 cycle_count = 11;
}
+
+/**
+ * Log battery SOC/temperature usage data.
+ *
+ * Each data represents cumulative time of the battery
+ * spent over a specific SOC and over a specific temperature
+ * while charging and while discharging in seconds.
+ *
+ * Logged from:
+ * /sys/class/power_supply/battery/swelling_data, via Vendor.
+ */
+message BatteryHealthUsage {
+ // Vendor reverse domain name (expecting "com.google.pixel").
+ optional string reverse_domain_name = 1;
+
+ // The temperature limit (deg C) used to accumulate the time above this value.
+ optional int32 temperature_limit_deci_c = 2;
+
+ // The SOC limit (%) used to accumulate the time above this value.
+ optional int32 soc_limit = 3;
+
+ // Time (s) accumulated only during charge at the given thresholds.
+ optional int32 charge_time_secs = 4;
+
+ // Time (s) accumulated only during discharge at the given thresholds.
+ optional int32 discharge_time_secs = 5;
+}