/* * Copyright (C) 2019 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. */ #include #include #include #include #include using android::frameworks::stats::V1_0::BatteryCausedShutdown; using android::frameworks::stats::V1_0::BatteryHealthSnapshotArgs; using android::frameworks::stats::V1_0::ChargeCycles; using android::frameworks::stats::V1_0::HardwareFailed; using android::frameworks::stats::V1_0::IStats; using android::frameworks::stats::V1_0::PhysicalDropDetected; using android::frameworks::stats::V1_0::SlowIo; using android::frameworks::stats::V1_0::SpeakerImpedance; using android::frameworks::stats::V1_0::SpeechDspStat; using android::frameworks::stats::V1_0::UsbPortOverheatEvent; using android::frameworks::stats::V1_0::VendorAtom; using Value = android::frameworks::stats::V1_0::VendorAtom::Value; void expect_message(int32_t action) { std::cout << "expect the following log in logcat:\n"; std::cout << "statsd.*(" << action << ")0x10000->\n"; } void show_help() { std::cout << "Stats HAL client\n"; std::cout << " arguments:\n"; std::cout << " -h or --help - shows help information\n"; std::cout << " -S or --SpeakerImpedance\n"; std::cout << " -f or --HardwareFailed\n"; std::cout << " -p or --PhysicalDropDetected\n"; std::cout << " -y or --ChargeCycles\n"; std::cout << " -n or --BatteryHealthSnapshot\n"; std::cout << " -i or --SlowIo\n"; std::cout << " -s or --BatteryCausedShutdown\n"; std::cout << " -u or --UsbPortOverheatEvent\n"; std::cout << " -d or --SpeechDspStat\n"; std::cout << " -v or --VendorAtom\n"; std::cout << "Please enable statsd logging using 'cmd stats print-logs'"; std::cout << "\n\n you can use multiple arguments to trigger multiple events.\n"; } int main(int argc, char* argv[]) { android::sp client = IStats::tryGetService(); if (!client) { std::cerr << "No Stats HAL"; return 1; } static struct option opts[] = { {"SpeakerImpedance", no_argument, 0, 'S'}, {"HardwareFailed", no_argument, 0, 'f'}, {"PhysicalDropDetected", no_argument, 0, 'p'}, {"ChargeCycles", no_argument, 0, 'y'}, {"BatteryHealthSnapshot", no_argument, 0, 'n'}, {"SlowIo", no_argument, 0, 'i'}, {"BatteryCausedShutdown", no_argument, 0, 's'}, {"UsbPortOverheatEvent", no_argument, 0, 'u'}, {"SpeechDspStat", no_argument, 0, 'd'}, {"VendorAtom", no_argument, 0, 'v'}, {"help", no_argument, 0, 'h'}, }; int c; int hal_calls = 0; while ((c = getopt_long(argc, argv, "hSfpynisudv", opts, nullptr)) != -1) { switch (c) { case 'h': { show_help(); break; } case 'S': { SpeakerImpedance left_obj = {.speakerLocation = 0, .milliOhms = static_cast(1234 * 1000)}; client->reportSpeakerImpedance(left_obj); expect_message(android::util::SPEAKER_IMPEDANCE_REPORTED); ++hal_calls; break; } case 'f': { HardwareFailed failed = {.hardwareType = HardwareFailed::HardwareType::CODEC, .hardwareLocation = 0, .errorCode = HardwareFailed::HardwareErrorCode::COMPLETE}; client->reportHardwareFailed(failed); expect_message(android::util::HARDWARE_FAILED); ++hal_calls; break; } case 'p': { PhysicalDropDetected drop{ .confidencePctg = 75, .accelPeak = 250, .freefallDuration = 1234}; client->reportPhysicalDropDetected(drop); expect_message(android::util::PHYSICAL_DROP_DETECTED); ++hal_calls; break; } case 'y': { std::vector charge_cycles = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; ChargeCycles cycles; cycles.cycleBucket = charge_cycles; client->reportChargeCycles(cycles); expect_message(android::util::CHARGE_CYCLES_REPORTED); ++hal_calls; break; } case 'n': { BatteryHealthSnapshotArgs args{.temperatureDeciC = 3000, .voltageMicroV = 1, .currentMicroA = 2, .openCircuitVoltageMicroV = 3, .resistanceMicroOhm = 5, .levelPercent = 101}; client->reportBatteryHealthSnapshot(args); expect_message(android::util::BATTERY_HEALTH_SNAPSHOT); ++hal_calls; break; } case 'i': { SlowIo slowio = {.operation = SlowIo::IoOperation::READ, .count = 5}; client->reportSlowIo(slowio); expect_message(android::util::SLOW_IO); ++hal_calls; break; } case 's': { BatteryCausedShutdown shutdown = {.voltageMicroV = 3}; client->reportBatteryCausedShutdown(shutdown); expect_message(android::util::BATTERY_CAUSED_SHUTDOWN); ++hal_calls; break; } case 'u': { UsbPortOverheatEvent event = {.plugTemperatureDeciC = 210, .maxTemperatureDeciC = 220, .timeToOverheat = 1, .timeToHysteresis = 2, .timeToInactive = 3}; client->reportUsbPortOverheatEvent(event); expect_message(android::util::USB_PORT_OVERHEAT_EVENT_REPORTED); ++hal_calls; break; } case 'd': { SpeechDspStat speech{.totalUptimeMillis = 1234, .totalDowntimeMillis = 4321, .totalCrashCount = 42, .totalRecoverCount = 99}; client->reportSpeechDspStat(speech); expect_message(android::util::SPEECH_DSP_STAT_REPORTED); ++hal_calls; break; } case 'v': { std::vector values; Value tmp; tmp.longValue(70000); values.push_back(tmp); tmp.intValue(7); values.push_back(tmp); tmp.floatValue(8.5); values.push_back(tmp); tmp.stringValue("test"); values.push_back(tmp); tmp.intValue(3); values.push_back(tmp); VendorAtom atom = { .reverseDomainName = "", .atomId = 100001, .values = values}; client->reportVendorAtom(atom); ++hal_calls; break; } default: { show_help(); return 1; } } } if (hal_calls > 0) { std::cout << hal_calls << " HAL methods called.\n"; std::cout << "try: logcat | grep \"statsd.*0x1000\"\n"; } return 0; }