1 #include "PixelStats.h"
2
3 #define LOG_TAG "pixelstats-system"
4 #include <log/log.h>
5 #include <metricslogger/metrics_logger.h>
6
7 namespace hardware {
8 namespace google {
9 namespace pixelstats {
10 namespace V1_0 {
11 namespace implementation {
12
13 using namespace android::metricslogger;
14
PixelStats()15 PixelStats::PixelStats()
16 :limiter_(kDailyRatelimit) {}
17
loggerAddFields(ComplexEventLogger * logger)18 void loggerAddFields(ComplexEventLogger* logger) {
19 logger->Record();
20 }
21
22 template<typename... Args>
loggerAddFields(ComplexEventLogger * logger,int32_t field,int32_t value,Args...args)23 void loggerAddFields(ComplexEventLogger* logger, int32_t field, int32_t value, Args... args) {
24 logger->AddTaggedData(LOGBUILDER_TYPE, TYPE_ACTION);
25 logger->AddTaggedData(field, value);
26 loggerAddFields(logger, args...);
27 }
28
29 template<typename... Args>
logIntAction(int32_t category,Args...args)30 void logIntAction(int32_t category, Args... args) {
31 ComplexEventLogger logger(category);
32 logger.AddTaggedData(LOGBUILDER_TYPE, TYPE_ACTION);
33 loggerAddFields(&logger, args...);
34 }
35
36 // Methods from ::hardware::google::pixelstats::V1_0::IPixelStats follow.
reportUsbConnectorConnected()37 Return<void> PixelStats::reportUsbConnectorConnected() {
38 // Ratelimit to max 20 / 24hrs (expected 0/24hrs)
39 if (rateLimit(android::metricslogger::ACTION_USB_CONNECTOR_CONNECTED, 20))
40 return Void();
41 logIntAction(android::metricslogger::ACTION_USB_CONNECTOR_CONNECTED);
42 return Void();
43 }
44
reportUsbConnectorDisconnected(int32_t durationMillis)45 Return<void> PixelStats::reportUsbConnectorDisconnected(int32_t durationMillis) {
46 // Ratelimit to max 20 / 24hrs (expected 0/24hrs)
47 if (rateLimit(android::metricslogger::ACTION_USB_CONNECTOR_DISCONNECTED, 20))
48 return Void();
49 logIntAction(android::metricslogger::ACTION_USB_CONNECTOR_DISCONNECTED,
50 android::metricslogger::FIELD_DURATION_MILLIS, durationMillis);
51 return Void();
52 }
53
reportUsbAudioConnected(int32_t vid,int32_t pid)54 Return<void> PixelStats::reportUsbAudioConnected(int32_t vid, int32_t pid) {
55 // Ratelimit to max 20 / 24hrs (expected 0/24hrs)
56 if (rateLimit(android::metricslogger::ACTION_USB_AUDIO_CONNECTED, 20))
57 return Void();
58 logIntAction(android::metricslogger::ACTION_USB_AUDIO_CONNECTED,
59 android::metricslogger::FIELD_USB_AUDIO_VIDPID, (vid << 16) | pid);
60 return Void();
61 }
62
reportUsbAudioDisconnected(int32_t vid,int32_t pid,int32_t durationMillis)63 Return<void> PixelStats::reportUsbAudioDisconnected(int32_t vid, int32_t pid,
64 int32_t durationMillis) {
65 // Ratelimit to max 20 / 24hrs (expected 0/24hrs)
66 if (rateLimit(android::metricslogger::ACTION_USB_AUDIO_DISCONNECTED, 20))
67 return Void();
68 logIntAction(android::metricslogger::ACTION_USB_AUDIO_DISCONNECTED, FIELD_USB_AUDIO_VIDPID,
69 (vid << 16) | pid, android::metricslogger::FIELD_DURATION_MILLIS,
70 durationMillis);
71 return Void();
72 }
73
reportSpeakerImpedance(int32_t speakerLocation,int32_t milliOhms)74 Return<void> PixelStats::reportSpeakerImpedance(int32_t speakerLocation, int32_t milliOhms) {
75 // Ratelimit to max 2 / 24hrs (expected 1/24hrs)
76 if (rateLimit(android::metricslogger::ACTION_SPEAKER_IMPEDANCE, 2))
77 return Void();
78
79 logIntAction(android::metricslogger::ACTION_SPEAKER_IMPEDANCE, FIELD_SPEAKER_LOCATION,
80 speakerLocation, FIELD_SPEAKER_IMPEDANCE_MILLIOHMS, milliOhms);
81 return Void();
82 }
83
toMetricsLoggerHardwareType(IPixelStats::HardwareType pixelstatsType)84 static android::metricslogger::HardwareType toMetricsLoggerHardwareType(
85 IPixelStats::HardwareType pixelstatsType) {
86 switch (pixelstatsType) {
87 case IPixelStats::HardwareType::MICROPHONE:
88 return android::metricslogger::HardwareType::HARDWARE_MICROPHONE;
89 case IPixelStats::HardwareType::CODEC:
90 return android::metricslogger::HardwareType::HARDWARE_CODEC;
91 case IPixelStats::HardwareType::SPEAKER:
92 return android::metricslogger::HardwareType::HARDWARE_SPEAKER;
93 case IPixelStats::HardwareType::FINGERPRINT:
94 return android::metricslogger::HardwareType::HARDWARE_FINGERPRINT;
95 case IPixelStats::HardwareType::UNKNOWN:
96 default:
97 return android::metricslogger::HardwareType::HARDWARE_UNKNOWN;
98
99 }
100 }
101
toMetricsLoggerHardwareFailure(IPixelStats::HardwareErrorCode pixelstatsError)102 static android::metricslogger::HardwareFailureCode toMetricsLoggerHardwareFailure(
103 IPixelStats::HardwareErrorCode pixelstatsError) {
104 switch (pixelstatsError) {
105 case IPixelStats::HardwareErrorCode::COMPLETE:
106 return HARDWARE_FAILURE_COMPLETE;
107 case IPixelStats::HardwareErrorCode::SPEAKER_HIGH_Z:
108 return HARDWARE_FAILURE_SPEAKER_HIGH_Z;
109 case IPixelStats::HardwareErrorCode::SPEAKER_SHORT:
110 return HARDWARE_FAILURE_SPEAKER_SHORT;
111 case IPixelStats::HardwareErrorCode::FINGERPRINT_SENSOR_BROKEN:
112 return HARDWARE_FAILURE_FINGERPRINT_SENSOR_BROKEN;
113 case IPixelStats::HardwareErrorCode::FINGERPRINT_TOO_MANY_DEAD_PIXELS:
114 return HARDWARE_FAILURE_FINGERPRINT_TOO_MANY_DEAD_PIXELS;
115 case IPixelStats::HardwareErrorCode::UNKNOWN:
116 default:
117 return HARDWARE_FAILURE_UNKNOWN;
118 }
119 }
120
reportHardwareFailed(HardwareType hardwareType,int32_t hardwareLocation,HardwareErrorCode errorCode)121 Return<void> PixelStats::reportHardwareFailed(HardwareType hardwareType, int32_t hardwareLocation,
122 HardwareErrorCode errorCode) {
123 // Ratelimit to max 15 / 24hrs (expected 0/24hrs)
124 if (rateLimit(android::metricslogger::ACTION_HARDWARE_FAILED, 15))
125 return Void();
126
127 logIntAction(ACTION_HARDWARE_FAILED,
128 FIELD_HARDWARE_TYPE, toMetricsLoggerHardwareType(hardwareType),
129 FIELD_HARDWARE_LOCATION, hardwareLocation,
130 FIELD_HARDWARE_FAILURE_CODE, toMetricsLoggerHardwareFailure(errorCode));
131 return Void();
132 }
133
reportPhysicalDropDetected(int32_t confidencePctg,int32_t accelPeak,int32_t freefallDurationMs)134 Return<void> PixelStats::reportPhysicalDropDetected(int32_t confidencePctg, int32_t accelPeak,
135 int32_t freefallDurationMs) {
136 // Ratelimit to max 10 / 24hrs (expected 0/24hrs)
137 if (rateLimit(android::metricslogger::ACTION_PHYSICAL_DROP, 10))
138 return Void();
139
140 logIntAction(ACTION_PHYSICAL_DROP, FIELD_CONFIDENCE_PERCENT, confidencePctg,
141 FIELD_ACCEL_MILLI_G, accelPeak,
142 FIELD_DURATION_MILLIS, freefallDurationMs);
143 return Void();
144 }
145
reportChargeCycles(const hidl_string & buckets)146 Return<void> PixelStats::reportChargeCycles(const hidl_string& buckets) {
147 // Ratelimit to max 2 / 24hrs (expected 1/24hrs)
148 if (rateLimit(android::metricslogger::ACTION_BATTERY_CHARGE_CYCLES, 2))
149 return Void();
150 LogMultiAction(ACTION_BATTERY_CHARGE_CYCLES, FIELD_BATTERY_CHARGE_CYCLES, buckets);
151 return Void();
152 }
153
toMetricsLoggerIoOperation(IPixelStats::IoOperation op)154 static android::metricslogger::IoOperation toMetricsLoggerIoOperation(IPixelStats::IoOperation op) {
155 switch (op) {
156 default:
157 case IPixelStats::IoOperation::UNKNOWN:
158 return android::metricslogger::IoOperation::IOOP_UNKNOWN;
159 case IPixelStats::IoOperation::READ:
160 return android::metricslogger::IoOperation::IOOP_READ;
161 case IPixelStats::IoOperation::WRITE:
162 return android::metricslogger::IoOperation::IOOP_WRITE;
163 case IPixelStats::IoOperation::UNMAP:
164 return android::metricslogger::IoOperation::IOOP_UNMAP;
165 case IPixelStats::IoOperation::SYNC:
166 return android::metricslogger::IoOperation::IOOP_SYNC;
167 }
168 }
169
reportSlowIo(IoOperation operation,int32_t count)170 Return<void> PixelStats::reportSlowIo(IoOperation operation, int32_t count) {
171 // Ratelimit to max 2 per 24hrs
172 if (rateLimit(android::metricslogger::ACTION_SLOW_IO, 2))
173 return Void();
174 logIntAction(ACTION_SLOW_IO, FIELD_IO_OPERATION_TYPE, toMetricsLoggerIoOperation(operation),
175 FIELD_IO_OPERATION_COUNT, count);
176 return Void();
177 }
178
reportBatteryHealthSnapshot(const BatteryHealthSnapshotArgs & args)179 Return<void> PixelStats::reportBatteryHealthSnapshot(const BatteryHealthSnapshotArgs& args) {
180 // Ratelimit to max 2 per 24hrs
181 if (rateLimit(android::metricslogger::ACTION_BATTERY_HEALTH, 2))
182 return Void();
183 logIntAction(ACTION_BATTERY_HEALTH,
184 FIELD_BATTERY_HEALTH_SNAPSHOT_TYPE, (int32_t)args.type,
185 FIELD_BATTERY_TEMPERATURE_DECI_C, args.temperatureDeciC,
186 FIELD_BATTERY_VOLTAGE_UV, args.voltageMicroV,
187 FIELD_BATTERY_CURRENT_UA, args.currentMicroA,
188 FIELD_BATTERY_OPEN_CIRCUIT_VOLTAGE_UV, args.openCircuitVoltageMicroV,
189 FIELD_BATTERY_RESISTANCE_UOHMS, args.resistanceMicroOhm,
190 FIELD_END_BATTERY_PERCENT, args.levelPercent);
191 return Void();
192 }
193
reportBatteryCausedShutdown(int32_t voltageMicroV)194 Return<void> PixelStats::reportBatteryCausedShutdown(int32_t voltageMicroV) {
195 // Ratelimit to max 5 per 24hrs
196 if (rateLimit(android::metricslogger::ACTION_BATTERY_CAUSED_SHUTDOWN, 5))
197 return Void();
198 logIntAction(ACTION_BATTERY_CAUSED_SHUTDOWN, FIELD_BATTERY_VOLTAGE_UV, voltageMicroV);
199 return Void();
200 }
201
rateLimit(int action,int limit)202 bool PixelStats::rateLimit(int action, int limit) {
203 if (limiter_.RateLimit(action, limit)) {
204 ALOGE("Rate limited action %d\n", action);
205 return true;
206 }
207 return false;
208 }
209
210 } // namespace implementation
211 } // namespace V1_0
212 } // namespace pixelstats
213 } // namespace google
214 } // namespace hardware
215