| #include "PixelStats.h" |
| |
| #define LOG_TAG "pixelstats-system" |
| #include <log/log.h> |
| #include <metricslogger/metrics_logger.h> |
| |
| namespace hardware { |
| namespace google { |
| namespace pixelstats { |
| namespace V1_0 { |
| namespace implementation { |
| |
| using namespace android::metricslogger; |
| |
| PixelStats::PixelStats() |
| :limiter_(kDailyRatelimit) {} |
| |
| void loggerAddFields(ComplexEventLogger* logger) { |
| logger->Record(); |
| } |
| |
| template<typename... Args> |
| void loggerAddFields(ComplexEventLogger* logger, int32_t field, int32_t value, Args... args) { |
| logger->AddTaggedData(LOGBUILDER_TYPE, TYPE_ACTION); |
| logger->AddTaggedData(field, value); |
| loggerAddFields(logger, args...); |
| } |
| |
| template<typename... Args> |
| void logIntAction(int32_t category, Args... args) { |
| ComplexEventLogger logger(category); |
| logger.AddTaggedData(LOGBUILDER_TYPE, TYPE_ACTION); |
| loggerAddFields(&logger, args...); |
| } |
| |
| // Methods from ::hardware::google::pixelstats::V1_0::IPixelStats follow. |
| Return<void> PixelStats::reportUsbConnectorConnected() { |
| // Ratelimit to max 20 / 24hrs (expected 0/24hrs) |
| if (rateLimit(android::metricslogger::ACTION_USB_CONNECTOR_CONNECTED, 20)) |
| return Void(); |
| logIntAction(android::metricslogger::ACTION_USB_CONNECTOR_CONNECTED); |
| return Void(); |
| } |
| |
| Return<void> PixelStats::reportUsbConnectorDisconnected(int32_t durationMillis) { |
| // Ratelimit to max 20 / 24hrs (expected 0/24hrs) |
| if (rateLimit(android::metricslogger::ACTION_USB_CONNECTOR_DISCONNECTED, 20)) |
| return Void(); |
| logIntAction(android::metricslogger::ACTION_USB_CONNECTOR_DISCONNECTED, |
| android::metricslogger::FIELD_DURATION_MILLIS, durationMillis); |
| return Void(); |
| } |
| |
| Return<void> PixelStats::reportUsbAudioConnected(int32_t vid, int32_t pid) { |
| // Ratelimit to max 20 / 24hrs (expected 0/24hrs) |
| if (rateLimit(android::metricslogger::ACTION_USB_AUDIO_CONNECTED, 20)) |
| return Void(); |
| logIntAction(android::metricslogger::ACTION_USB_AUDIO_CONNECTED, |
| android::metricslogger::FIELD_USB_AUDIO_VIDPID, (vid << 16) | pid); |
| return Void(); |
| } |
| |
| Return<void> PixelStats::reportUsbAudioDisconnected(int32_t vid, int32_t pid, |
| int32_t durationMillis) { |
| // Ratelimit to max 20 / 24hrs (expected 0/24hrs) |
| if (rateLimit(android::metricslogger::ACTION_USB_AUDIO_DISCONNECTED, 20)) |
| return Void(); |
| logIntAction(android::metricslogger::ACTION_USB_AUDIO_DISCONNECTED, FIELD_USB_AUDIO_VIDPID, |
| (vid << 16) | pid, android::metricslogger::FIELD_DURATION_MILLIS, |
| durationMillis); |
| return Void(); |
| } |
| |
| Return<void> PixelStats::reportSpeakerImpedance(int32_t speakerLocation, int32_t milliOhms) { |
| // Ratelimit to max 2 / 24hrs (expected 1/24hrs) |
| if (rateLimit(android::metricslogger::ACTION_SPEAKER_IMPEDANCE, 2)) |
| return Void(); |
| |
| logIntAction(android::metricslogger::ACTION_SPEAKER_IMPEDANCE, FIELD_SPEAKER_LOCATION, |
| speakerLocation, FIELD_SPEAKER_IMPEDANCE_MILLIOHMS, milliOhms); |
| return Void(); |
| } |
| |
| static android::metricslogger::HardwareType toMetricsLoggerHardwareType( |
| IPixelStats::HardwareType pixelstatsType) { |
| switch (pixelstatsType) { |
| case IPixelStats::HardwareType::MICROPHONE: |
| return android::metricslogger::HardwareType::HARDWARE_MICROPHONE; |
| case IPixelStats::HardwareType::CODEC: |
| return android::metricslogger::HardwareType::HARDWARE_CODEC; |
| case IPixelStats::HardwareType::SPEAKER: |
| return android::metricslogger::HardwareType::HARDWARE_SPEAKER; |
| case IPixelStats::HardwareType::FINGERPRINT: |
| return android::metricslogger::HardwareType::HARDWARE_FINGERPRINT; |
| case IPixelStats::HardwareType::UNKNOWN: |
| default: |
| return android::metricslogger::HardwareType::HARDWARE_UNKNOWN; |
| |
| } |
| } |
| |
| static android::metricslogger::HardwareFailureCode toMetricsLoggerHardwareFailure( |
| IPixelStats::HardwareErrorCode pixelstatsError) { |
| switch (pixelstatsError) { |
| case IPixelStats::HardwareErrorCode::COMPLETE: |
| return HARDWARE_FAILURE_COMPLETE; |
| case IPixelStats::HardwareErrorCode::SPEAKER_HIGH_Z: |
| return HARDWARE_FAILURE_SPEAKER_HIGH_Z; |
| case IPixelStats::HardwareErrorCode::SPEAKER_SHORT: |
| return HARDWARE_FAILURE_SPEAKER_SHORT; |
| case IPixelStats::HardwareErrorCode::FINGERPRINT_SENSOR_BROKEN: |
| return HARDWARE_FAILURE_FINGERPRINT_SENSOR_BROKEN; |
| case IPixelStats::HardwareErrorCode::FINGERPRINT_TOO_MANY_DEAD_PIXELS: |
| return HARDWARE_FAILURE_FINGERPRINT_TOO_MANY_DEAD_PIXELS; |
| case IPixelStats::HardwareErrorCode::UNKNOWN: |
| default: |
| return HARDWARE_FAILURE_UNKNOWN; |
| } |
| } |
| |
| Return<void> PixelStats::reportHardwareFailed(HardwareType hardwareType, int32_t hardwareLocation, |
| HardwareErrorCode errorCode) { |
| // Ratelimit to max 15 / 24hrs (expected 0/24hrs) |
| if (rateLimit(android::metricslogger::ACTION_HARDWARE_FAILED, 15)) |
| return Void(); |
| |
| logIntAction(ACTION_HARDWARE_FAILED, |
| FIELD_HARDWARE_TYPE, toMetricsLoggerHardwareType(hardwareType), |
| FIELD_HARDWARE_LOCATION, hardwareLocation, |
| FIELD_HARDWARE_FAILURE_CODE, toMetricsLoggerHardwareFailure(errorCode)); |
| return Void(); |
| } |
| |
| Return<void> PixelStats::reportPhysicalDropDetected(int32_t confidencePctg, int32_t accelPeak, |
| int32_t freefallDurationMs) { |
| // Ratelimit to max 10 / 24hrs (expected 0/24hrs) |
| if (rateLimit(android::metricslogger::ACTION_PHYSICAL_DROP, 10)) |
| return Void(); |
| |
| logIntAction(ACTION_PHYSICAL_DROP, FIELD_CONFIDENCE_PERCENT, confidencePctg, |
| FIELD_ACCEL_MILLI_G, accelPeak, |
| FIELD_DURATION_MILLIS, freefallDurationMs); |
| return Void(); |
| } |
| |
| Return<void> PixelStats::reportChargeCycles(const hidl_string& buckets) { |
| // Ratelimit to max 2 / 24hrs (expected 1/24hrs) |
| if (rateLimit(android::metricslogger::ACTION_BATTERY_CHARGE_CYCLES, 2)) |
| return Void(); |
| LogMultiAction(ACTION_BATTERY_CHARGE_CYCLES, FIELD_BATTERY_CHARGE_CYCLES, buckets); |
| return Void(); |
| } |
| |
| static android::metricslogger::IoOperation toMetricsLoggerIoOperation(IPixelStats::IoOperation op) { |
| switch (op) { |
| default: |
| case IPixelStats::IoOperation::UNKNOWN: |
| return android::metricslogger::IoOperation::IOOP_UNKNOWN; |
| case IPixelStats::IoOperation::READ: |
| return android::metricslogger::IoOperation::IOOP_READ; |
| case IPixelStats::IoOperation::WRITE: |
| return android::metricslogger::IoOperation::IOOP_WRITE; |
| case IPixelStats::IoOperation::UNMAP: |
| return android::metricslogger::IoOperation::IOOP_UNMAP; |
| case IPixelStats::IoOperation::SYNC: |
| return android::metricslogger::IoOperation::IOOP_SYNC; |
| } |
| } |
| |
| Return<void> PixelStats::reportSlowIo(IoOperation operation, int32_t count) { |
| // Ratelimit to max 2 per 24hrs |
| if (rateLimit(android::metricslogger::ACTION_SLOW_IO, 2)) |
| return Void(); |
| logIntAction(ACTION_SLOW_IO, FIELD_IO_OPERATION_TYPE, toMetricsLoggerIoOperation(operation), |
| FIELD_IO_OPERATION_COUNT, count); |
| return Void(); |
| } |
| |
| Return<void> PixelStats::reportBatteryHealthSnapshot(const BatteryHealthSnapshotArgs& args) { |
| // Ratelimit to max 2 per 24hrs |
| if (rateLimit(android::metricslogger::ACTION_BATTERY_HEALTH, 2)) |
| return Void(); |
| logIntAction(ACTION_BATTERY_HEALTH, |
| FIELD_BATTERY_HEALTH_SNAPSHOT_TYPE, (int32_t)args.type, |
| FIELD_BATTERY_TEMPERATURE_DECI_C, args.temperatureDeciC, |
| FIELD_BATTERY_VOLTAGE_UV, args.voltageMicroV, |
| FIELD_BATTERY_CURRENT_UA, args.currentMicroA, |
| FIELD_BATTERY_OPEN_CIRCUIT_VOLTAGE_UV, args.openCircuitVoltageMicroV, |
| FIELD_BATTERY_RESISTANCE_UOHMS, args.resistanceMicroOhm, |
| FIELD_END_BATTERY_PERCENT, args.levelPercent); |
| return Void(); |
| } |
| |
| Return<void> PixelStats::reportBatteryCausedShutdown(int32_t voltageMicroV) { |
| // Ratelimit to max 5 per 24hrs |
| if (rateLimit(android::metricslogger::ACTION_BATTERY_CAUSED_SHUTDOWN, 5)) |
| return Void(); |
| logIntAction(ACTION_BATTERY_CAUSED_SHUTDOWN, FIELD_BATTERY_VOLTAGE_UV, voltageMicroV); |
| return Void(); |
| } |
| |
| bool PixelStats::rateLimit(int action, int limit) { |
| if (limiter_.RateLimit(action, limit)) { |
| ALOGE("Rate limited action %d\n", action); |
| return true; |
| } |
| return false; |
| } |
| |
| } // namespace implementation |
| } // namespace V1_0 |
| } // namespace pixelstats |
| } // namespace google |
| } // namespace hardware |