statsd side implementation of Stats HAL
This change implements server-side of Stats HAL in statsd to be able to
receive loggings and parse them into LogEvent event before passing them to
StatsLogProcessor.
Bug: 114316519
Test: verified that statshal exists by calling 'adb shell lshal'
Change-Id: I43e7415a2d28e20af872049100cd6f2627cf3c02
diff --git a/cmds/statsd/Android.mk b/cmds/statsd/Android.mk
index d3496ed..e090ed1 100644
--- a/cmds/statsd/Android.mk
+++ b/cmds/statsd/Android.mk
@@ -99,6 +99,7 @@
libhidlbase \
libhidltransport \
libhwbinder \
+ android.frameworks.stats@1.0 \
android.hardware.health@2.0 \
android.hardware.power@1.0 \
android.hardware.power@1.1 \
diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp
index 2ef1169..8da2d44 100644
--- a/cmds/statsd/src/StatsService.cpp
+++ b/cmds/statsd/src/StatsService.cpp
@@ -992,6 +992,60 @@
return Status::ok();
}
+hardware::Return<void> StatsService::reportSpeakerImpedance(
+ const SpeakerImpedance& speakerImpedance) {
+ LogEvent event(getWallClockSec() * NS_PER_SEC, getElapsedRealtimeNs(), speakerImpedance);
+ mProcessor->OnLogEvent(&event);
+
+ return hardware::Void();
+}
+
+hardware::Return<void> StatsService::reportHardwareFailed(const HardwareFailed& hardwareFailed) {
+ LogEvent event(getWallClockSec() * NS_PER_SEC, getElapsedRealtimeNs(), hardwareFailed);
+ mProcessor->OnLogEvent(&event);
+
+ return hardware::Void();
+}
+
+hardware::Return<void> StatsService::reportPhysicalDropDetected(
+ const PhysicalDropDetected& physicalDropDetected) {
+ LogEvent event(getWallClockSec() * NS_PER_SEC, getElapsedRealtimeNs(), physicalDropDetected);
+ mProcessor->OnLogEvent(&event);
+
+ return hardware::Void();
+}
+
+hardware::Return<void> StatsService::reportChargeCycles(const ChargeCycles& chargeCycles) {
+ LogEvent event(getWallClockSec() * NS_PER_SEC, getElapsedRealtimeNs(), chargeCycles);
+ mProcessor->OnLogEvent(&event);
+
+ return hardware::Void();
+}
+
+hardware::Return<void> StatsService::reportBatteryHealthSnapshot(
+ const BatteryHealthSnapshotArgs& batteryHealthSnapshotArgs) {
+ LogEvent event(getWallClockSec() * NS_PER_SEC, getElapsedRealtimeNs(),
+ batteryHealthSnapshotArgs);
+ mProcessor->OnLogEvent(&event);
+
+ return hardware::Void();
+}
+
+hardware::Return<void> StatsService::reportSlowIo(const SlowIo& slowIo) {
+ LogEvent event(getWallClockSec() * NS_PER_SEC, getElapsedRealtimeNs(), slowIo);
+ mProcessor->OnLogEvent(&event);
+
+ return hardware::Void();
+}
+
+hardware::Return<void> StatsService::reportBatteryCausedShutdown(
+ const BatteryCausedShutdown& batteryCausedShutdown) {
+ LogEvent event(getWallClockSec() * NS_PER_SEC, getElapsedRealtimeNs(), batteryCausedShutdown);
+ mProcessor->OnLogEvent(&event);
+
+ return hardware::Void();
+}
+
void StatsService::binderDied(const wp <IBinder>& who) {
ALOGW("statscompanion service died");
StatsdStats::getInstance().noteSystemServerRestart(getWallClockSec());
diff --git a/cmds/statsd/src/StatsService.h b/cmds/statsd/src/StatsService.h
index 0618927..1f1d782 100644
--- a/cmds/statsd/src/StatsService.h
+++ b/cmds/statsd/src/StatsService.h
@@ -27,6 +27,8 @@
#include "shell/ShellSubscriber.h"
#include "statscompanion_util.h"
+#include <android/frameworks/stats/1.0/IStats.h>
+#include <android/frameworks/stats/1.0/types.h>
#include <android/os/BnStatsManager.h>
#include <android/os/IStatsCompanionService.h>
#include <binder/IResultReceiver.h>
@@ -38,6 +40,7 @@
using namespace android;
using namespace android::base;
using namespace android::binder;
+using namespace android::frameworks::stats::V1_0;
using namespace android::os;
using namespace std;
@@ -45,7 +48,12 @@
namespace os {
namespace statsd {
-class StatsService : public BnStatsManager, public LogListener, public IBinder::DeathRecipient {
+using android::hardware::Return;
+
+class StatsService : public BnStatsManager,
+ public LogListener,
+ public IStats,
+ public IBinder::DeathRecipient {
public:
StatsService(const sp<Looper>& handlerLooper);
virtual ~StatsService();
@@ -146,6 +154,44 @@
*/
virtual Status sendAppBreadcrumbAtom(int32_t label, int32_t state) override;
+ /**
+ * Binder call to get SpeakerImpedance atom.
+ */
+ virtual Return<void> reportSpeakerImpedance(const SpeakerImpedance& speakerImpedance) override;
+
+ /**
+ * Binder call to get HardwareFailed atom.
+ */
+ virtual Return<void> reportHardwareFailed(const HardwareFailed& hardwareFailed) override;
+
+ /**
+ * Binder call to get PhysicalDropDetected atom.
+ */
+ virtual Return<void> reportPhysicalDropDetected(
+ const PhysicalDropDetected& physicalDropDetected) override;
+
+ /**
+ * Binder call to get ChargeCyclesReported atom.
+ */
+ virtual Return<void> reportChargeCycles(const ChargeCycles& chargeCycles) override;
+
+ /**
+ * Binder call to get BatteryHealthSnapshot atom.
+ */
+ virtual Return<void> reportBatteryHealthSnapshot(
+ const BatteryHealthSnapshotArgs& batteryHealthSnapshotArgs) override;
+
+ /**
+ * Binder call to get SlowIo atom.
+ */
+ virtual Return<void> reportSlowIo(const SlowIo& slowIo) override;
+
+ /**
+ * Binder call to get BatteryCausedShutdown atom.
+ */
+ virtual Return<void> reportBatteryCausedShutdown(
+ const BatteryCausedShutdown& batteryCausedShutdown) override;
+
/** IBinder::DeathRecipient */
virtual void binderDied(const wp<IBinder>& who) override;
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index 10a00ee..30d8bfc 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -138,6 +138,9 @@
FingerprintAuthenticated fingerprint_authenticated = 88;
FingerprintErrorOccurred fingerprint_error_occurred = 89;
Notification notification = 90;
+ BatteryHealthSnapshot battery_health_snapshot = 91;
+ SlowIo slow_io = 92;
+ BatteryCausedShutdown battery_caused_shutdown = 93;
}
// Pulled events will start at field 10000.
@@ -1313,6 +1316,68 @@
}
/**
+ * Log battery health snapshot.
+ *
+ * Resistance, Voltage, Open Circuit Voltage, Temperature, and Charge Level
+ * are snapshotted periodically over 24hrs.
+ */
+message BatteryHealthSnapshot {
+ enum BatterySnapshotType {
+ UNKNOWN = 0;
+ MIN_TEMP = 1; // Snapshot at min batt temp over 24hrs.
+ MAX_TEMP = 2; // Snapshot at max batt temp over 24hrs.
+ MIN_RESISTANCE = 3; // Snapshot at min batt resistance over 24hrs.
+ MAX_RESISTANCE = 4; // Snapshot at max batt resistance over 24hrs.
+ MIN_VOLTAGE = 5; // Snapshot at min batt voltage over 24hrs.
+ MAX_VOLTAGE = 6; // Snapshot at max batt voltage over 24hrs.
+ MIN_CURRENT = 7; // Snapshot at min batt current over 24hrs.
+ MAX_CURRENT = 8; // Snapshot at max batt current over 24hrs.
+ MIN_BATT_LEVEL = 9; // Snapshot at min battery level (SoC) over 24hrs.
+ MAX_BATT_LEVEL = 10; // Snapshot at max battery level (SoC) over 24hrs.
+ AVG_RESISTANCE = 11; // Snapshot at average battery resistance over 24hrs.
+ }
+ optional BatterySnapshotType type = 1;
+ // Temperature, in 1/10ths of degree C.
+ optional int32 temperature_deci_celcius = 2;
+ // Voltage Battery Voltage, in microVolts.
+ optional int32 voltage_micro_volt = 3;
+ // Current Battery current, in microAmps.
+ optional int32 current_micro_amps = 4;
+ // OpenCircuitVoltage Battery Open Circuit Voltage, in microVolts.
+ optional int32 open_circuit_micro_volt = 5;
+ // Resistance Battery Resistance, in microOhms.
+ optional int32 resistance_micro_ohm = 6;
+ // Level Battery Level, as % of full.
+ optional int32 level_percent = 7;
+}
+
+/**
+ * Log slow I/O operations on the primary storage.
+ */
+message SlowIo {
+ // Classifications of IO Operations.
+ enum IoOperation {
+ UNKNOWN = 0;
+ READ = 1;
+ WRITE = 2;
+ UNMAP = 3;
+ SYNC = 4;
+ }
+ optional IoOperation operation = 1;
+
+ // The number of slow IO operations of this type over 24 hours.
+ optional int32 count = 2;
+}
+
+/**
+ * Log battery caused shutdown with the last recorded voltage.
+ */
+message BatteryCausedShutdown {
+ // The last recorded battery voltage prior to shutdown.
+ optional int32 last_recorded_micro_volt = 1;
+}
+
+/**
* Logs the duration of a davey (jank of >=700ms) when it occurs
*
* Logged from:
diff --git a/cmds/statsd/src/logd/LogEvent.cpp b/cmds/statsd/src/logd/LogEvent.cpp
index 3afa08f..4bbcfd5 100644
--- a/cmds/statsd/src/logd/LogEvent.cpp
+++ b/cmds/statsd/src/logd/LogEvent.cpp
@@ -146,6 +146,127 @@
}
}
+LogEvent::LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
+ const SpeakerImpedance& speakerImpedance) {
+ mLogdTimestampNs = wallClockTimestampNs;
+ mElapsedTimestampNs = elapsedTimestampNs;
+ mTagId = android::util::SPEAKER_IMPEDANCE_REPORTED;
+
+ mValues.push_back(
+ FieldValue(Field(mTagId, getSimpleField(1)), Value(speakerImpedance.speakerLocation)));
+ mValues.push_back(
+ FieldValue(Field(mTagId, getSimpleField(2)), Value(speakerImpedance.milliOhms)));
+ if (!mValues.empty()) {
+ mValues.back().mField.decorateLastPos(1);
+ }
+}
+
+LogEvent::LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
+ const HardwareFailed& hardwareFailed) {
+ mLogdTimestampNs = wallClockTimestampNs;
+ mElapsedTimestampNs = elapsedTimestampNs;
+ mTagId = android::util::HARDWARE_FAILED;
+
+ mValues.push_back(FieldValue(Field(mTagId, getSimpleField(1)),
+ Value(int32_t(hardwareFailed.hardwareType))));
+ mValues.push_back(
+ FieldValue(Field(mTagId, getSimpleField(2)), Value(hardwareFailed.hardwareLocation)));
+ mValues.push_back(
+ FieldValue(Field(mTagId, getSimpleField(3)), Value(int32_t(hardwareFailed.errorCode))));
+ if (!mValues.empty()) {
+ mValues.back().mField.decorateLastPos(1);
+ }
+}
+
+LogEvent::LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
+ const PhysicalDropDetected& physicalDropDetected) {
+ mLogdTimestampNs = wallClockTimestampNs;
+ mElapsedTimestampNs = elapsedTimestampNs;
+ mTagId = android::util::PHYSICAL_DROP_DETECTED;
+
+ mValues.push_back(FieldValue(Field(mTagId, getSimpleField(1)),
+ Value(int32_t(physicalDropDetected.confidencePctg))));
+ mValues.push_back(
+ FieldValue(Field(mTagId, getSimpleField(2)), Value(physicalDropDetected.accelPeak)));
+ mValues.push_back(FieldValue(Field(mTagId, getSimpleField(3)),
+ Value(physicalDropDetected.freefallDuration)));
+ if (!mValues.empty()) {
+ mValues.back().mField.decorateLastPos(1);
+ }
+}
+
+LogEvent::LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
+ const ChargeCycles& chargeCycles) {
+ mLogdTimestampNs = wallClockTimestampNs;
+ mElapsedTimestampNs = elapsedTimestampNs;
+ mTagId = android::util::CHARGE_CYCLES_REPORTED;
+
+ for (size_t i = 0; i < chargeCycles.cycleBucket.size(); i++) {
+ mValues.push_back(FieldValue(Field(mTagId, getSimpleField(i + 1)),
+ Value(chargeCycles.cycleBucket[i])));
+ }
+
+ if (!mValues.empty()) {
+ mValues.back().mField.decorateLastPos(1);
+ }
+}
+
+LogEvent::LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
+ const BatteryHealthSnapshotArgs& batteryHealthSnapshotArgs) {
+ mLogdTimestampNs = wallClockTimestampNs;
+ mElapsedTimestampNs = elapsedTimestampNs;
+ mTagId = android::util::BATTERY_HEALTH_SNAPSHOT;
+
+ mValues.push_back(FieldValue(Field(mTagId, getSimpleField(1)),
+ Value(int32_t(batteryHealthSnapshotArgs.type))));
+ mValues.push_back(FieldValue(Field(mTagId, getSimpleField(2)),
+ Value(batteryHealthSnapshotArgs.temperatureDeciC)));
+ mValues.push_back(FieldValue(Field(mTagId, getSimpleField(3)),
+ Value(batteryHealthSnapshotArgs.voltageMicroV)));
+ mValues.push_back(FieldValue(Field(mTagId, getSimpleField(4)),
+ Value(batteryHealthSnapshotArgs.currentMicroA)));
+ mValues.push_back(FieldValue(Field(mTagId, getSimpleField(5)),
+ Value(batteryHealthSnapshotArgs.openCircuitVoltageMicroV)));
+ mValues.push_back(FieldValue(Field(mTagId, getSimpleField(6)),
+ Value(batteryHealthSnapshotArgs.resistanceMicroOhm)));
+ mValues.push_back(FieldValue(Field(mTagId, getSimpleField(7)),
+ Value(batteryHealthSnapshotArgs.levelPercent)));
+
+ if (!mValues.empty()) {
+ mValues.back().mField.decorateLastPos(1);
+ }
+}
+
+LogEvent::LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs, const SlowIo& slowIo) {
+ mLogdTimestampNs = wallClockTimestampNs;
+ mElapsedTimestampNs = elapsedTimestampNs;
+ mTagId = android::util::SLOW_IO;
+
+ int pos[] = {1};
+ mValues.push_back(
+ FieldValue(Field(mTagId, getSimpleField(1)), Value(int32_t(slowIo.operation))));
+ pos[0]++;
+ mValues.push_back(FieldValue(Field(mTagId, getSimpleField(2)), Value(slowIo.count)));
+
+ if (!mValues.empty()) {
+ mValues.back().mField.decorateLastPos(1);
+ }
+}
+
+LogEvent::LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
+ const BatteryCausedShutdown& batteryCausedShutdown) {
+ mLogdTimestampNs = wallClockTimestampNs;
+ mElapsedTimestampNs = elapsedTimestampNs;
+ mTagId = android::util::BATTERY_CAUSED_SHUTDOWN;
+
+ mValues.push_back(FieldValue(Field(mTagId, getSimpleField(1)),
+ Value(batteryCausedShutdown.voltageMicroV)));
+
+ if (!mValues.empty()) {
+ mValues.back().mField.decorateLastPos(1);
+ }
+}
+
LogEvent::LogEvent(int32_t tagId, int64_t timestampNs) {
mLogdTimestampNs = timestampNs;
mTagId = tagId;
@@ -223,8 +344,6 @@
return false;
}
-
-
bool LogEvent::writeKeyValuePairs(const std::map<int32_t, int32_t>& int_map,
const std::map<int32_t, int64_t>& long_map,
const std::map<int32_t, std::string>& string_map,
diff --git a/cmds/statsd/src/logd/LogEvent.h b/cmds/statsd/src/logd/LogEvent.h
index 0a8ac2b..c7e2a8c 100644
--- a/cmds/statsd/src/logd/LogEvent.h
+++ b/cmds/statsd/src/logd/LogEvent.h
@@ -18,6 +18,7 @@
#include "FieldValue.h"
+#include <android/frameworks/stats/1.0/types.h>
#include <android/os/StatsLogEventWrapper.h>
#include <android/util/ProtoOutputStream.h>
#include <log/log_event_list.h>
@@ -28,6 +29,8 @@
#include <string>
#include <vector>
+using namespace android::frameworks::stats::V1_0;
+
namespace android {
namespace os {
namespace statsd {
@@ -82,6 +85,27 @@
const std::map<int32_t, std::string>& string_map,
const std::map<int32_t, float>& float_map);
+ explicit LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
+ const SpeakerImpedance& speakerImpedance);
+
+ explicit LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
+ const HardwareFailed& hardwareFailed);
+
+ explicit LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
+ const PhysicalDropDetected& physicalDropDetected);
+
+ explicit LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
+ const ChargeCycles& chargeCycles);
+
+ explicit LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
+ const BatteryHealthSnapshotArgs& batteryHealthSnapshotArgs);
+
+ explicit LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
+ const SlowIo& slowIo);
+
+ explicit LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
+ const BatteryCausedShutdown& batteryCausedShutdown);
+
~LogEvent();
/**
diff --git a/cmds/statsd/src/main.cpp b/cmds/statsd/src/main.cpp
index 9002f07..a5dac08 100644
--- a/cmds/statsd/src/main.cpp
+++ b/cmds/statsd/src/main.cpp
@@ -25,6 +25,7 @@
#include <binder/IServiceManager.h>
#include <binder/ProcessState.h>
#include <binder/Status.h>
+#include <hidl/HidlTransportSupport.h>
#include <utils/Looper.h>
#include <utils/StrongPointer.h>
@@ -56,12 +57,21 @@
ps->giveThreadPoolName();
IPCThreadState::self()->disableBackgroundScheduling(true);
+ ::android::hardware::configureRpcThreadpool(1 /*threads*/, false /*willJoin*/);
+
// Create the service
sp<StatsService> service = new StatsService(looper);
if (defaultServiceManager()->addService(String16("stats"), service) != 0) {
- ALOGE("Failed to add service");
+ ALOGE("Failed to add service as AIDL service");
return -1;
}
+
+ auto ret = service->registerAsService();
+ if (ret != ::android::OK) {
+ ALOGE("Failed to add service as HIDL service");
+ return 1; // or handle error
+ }
+
service->sayHiToStatsCompanion();
service->Startup();