device_google_gs101/dumpstate/DumpstateDevice.cpp
davidycchen 2b65d2e31c dumpstate: modify the method for dump touch information
Use bugreport flag to keep waking up the touch driver instead of
force active flag to prevent the kernel driver from blocking CPU
enter the suspend mode.

Bug: 183466375
Test: touch driver won't block system suspend.

Signed-off-by: davidycchen <davidycchen@google.com>
Change-Id: I586173485bd41deac891b7edb366b51a99977434
2021-05-14 05:47:39 +00:00

1057 lines
46 KiB
C++

/*
* Copyright 2016 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.
*/
#define LOG_TAG "dumpstate_device"
#include <inttypes.h>
#include <android-base/file.h>
#include <android-base/stringprintf.h>
#include <android-base/properties.h>
#include <android-base/unique_fd.h>
#include <hidl/HidlBinderSupport.h>
#include <log/log.h>
#include <sys/stat.h>
#include "DumpstateDevice.h"
#include "DumpstateUtil.h"
#define MODEM_LOG_DIRECTORY "/data/vendor/radio/logs/always-on"
#define MODEM_EXTENDED_LOG_DIRECTORY "/data/vendor/radio/extended_logs"
#define RIL_LOG_DIRECTORY "/data/vendor/radio"
#define RIL_LOG_DIRECTORY_PROPERTY "persist.vendor.ril.log.base_dir"
#define RIL_LOG_NUMBER_PROPERTY "persist.vendor.ril.log.num_file"
#define MODEM_LOGGING_PERSIST_PROPERTY "persist.vendor.sys.modem.logging.enable"
#define MODEM_LOGGING_PROPERTY "vendor.sys.modem.logging.enable"
#define MODEM_LOGGING_STATUS_PROPERTY "vendor.sys.modem.logging.status"
#define MODEM_LOGGING_NUMBER_BUGREPORT_PROPERTY "persist.vendor.sys.modem.logging.br_num"
#define GPS_LOG_DIRECTORY "/data/vendor/gps/logs"
#define GPS_LOG_NUMBER_PROPERTY "persist.vendor.gps.aol.log_num"
#define GPS_LOGGING_STATUS_PROPERTY "vendor.gps.aol.enabled"
#define UFS_BOOTDEVICE "ro.boot.bootdevice"
#define TCPDUMP_LOG_DIRECTORY "/data/vendor/tcpdump_logger/logs"
#define TCPDUMP_NUMBER_BUGREPORT "persist.vendor.tcpdump.log.br_num"
#define TCPDUMP_PERSIST_PROPERTY "persist.vendor.tcpdump.log.alwayson"
#define HW_REVISION "ro.boot.hardware.revision"
using android::os::dumpstate::CommandOptions;
using android::os::dumpstate::DumpFileToFd;
using android::os::dumpstate::PropertiesHelper;
using android::os::dumpstate::RunCommandToFd;
namespace android {
namespace hardware {
namespace dumpstate {
namespace V1_1 {
namespace implementation {
#define GPS_LOG_PREFIX "gl-"
#define MODEM_LOG_PREFIX "sbuff_"
#define EXTENDED_LOG_PREFIX "extended_log_"
#define RIL_LOG_PREFIX "rild.log."
#define BUFSIZE 65536
#define TCPDUMP_LOG_PREFIX "tcpdump"
typedef std::chrono::time_point<std::chrono::steady_clock> timepoint_t;
const char kVerboseLoggingProperty[] = "persist.dumpstate.verbose_logging.enabled";
void DumpstateDevice::dumpLogs(int fd, std::string srcDir, std::string destDir, int maxFileNum,
const char *logPrefix) {
struct dirent **dirent_list = NULL;
int num_entries = scandir(srcDir.c_str(),
&dirent_list,
0,
(int (*)(const struct dirent **, const struct dirent **)) alphasort);
if (!dirent_list) {
return;
} else if (num_entries <= 0) {
return;
}
int copiedFiles = 0;
for (int i = num_entries - 1; i >= 0; i--) {
ALOGD("Found %s\n", dirent_list[i]->d_name);
if (0 != strncmp(dirent_list[i]->d_name, logPrefix, strlen(logPrefix))) {
continue;
}
if ((copiedFiles >= maxFileNum) && (maxFileNum != -1)) {
ALOGD("Skipped %s\n", dirent_list[i]->d_name);
continue;
}
copiedFiles++;
CommandOptions options = CommandOptions::WithTimeout(120).Build();
std::string srcLogFile = srcDir + "/" + dirent_list[i]->d_name;
std::string destLogFile = destDir + "/" + dirent_list[i]->d_name;
std::string copyCmd = "/vendor/bin/cp " + srcLogFile + " " + destLogFile;
ALOGD("Copying %s to %s\n", srcLogFile.c_str(), destLogFile.c_str());
RunCommandToFd(fd, "CP DIAG LOGS", { "/vendor/bin/sh", "-c", copyCmd.c_str() }, options);
}
while (num_entries--) {
free(dirent_list[num_entries]);
}
free(dirent_list);
}
void DumpstateDevice::dumpRilLogs(int fd, std::string destDir) {
std::string rilLogDir =
android::base::GetProperty(RIL_LOG_DIRECTORY_PROPERTY, RIL_LOG_DIRECTORY);
int maxFileNum = android::base::GetIntProperty(RIL_LOG_NUMBER_PROPERTY, 50);
const std::string currentLogDir = rilLogDir + "/cur";
const std::string previousLogDir = rilLogDir + "/prev";
const std::string currentDestDir = destDir + "/cur";
const std::string previousDestDir = destDir + "/prev";
RunCommandToFd(fd, "MKDIR RIL CUR LOG", {"/vendor/bin/mkdir", "-p", currentDestDir.c_str()},
CommandOptions::WithTimeout(2).Build());
RunCommandToFd(fd, "MKDIR RIL PREV LOG", {"/vendor/bin/mkdir", "-p", previousDestDir.c_str()},
CommandOptions::WithTimeout(2).Build());
dumpLogs(fd, currentLogDir, currentDestDir, maxFileNum, RIL_LOG_PREFIX);
dumpLogs(fd, previousLogDir, previousDestDir, maxFileNum, RIL_LOG_PREFIX);
}
void copyFile(std::string srcFile, std::string destFile) {
uint8_t buffer[BUFSIZE];
ssize_t size;
int fdSrc = open(srcFile.c_str(), O_RDONLY);
if (fdSrc < 0) {
ALOGD("Failed to open source file %s\n", srcFile.c_str());
return;
}
int fdDest = open(destFile.c_str(), O_WRONLY | O_CREAT, 0666);
if (fdDest < 0) {
ALOGD("Failed to open destination file %s\n", destFile.c_str());
close(fdSrc);
return;
}
ALOGD("Copying %s to %s\n", srcFile.c_str(), destFile.c_str());
while ((size = TEMP_FAILURE_RETRY(read(fdSrc, buffer, BUFSIZE))) > 0) {
TEMP_FAILURE_RETRY(write(fdDest, buffer, size));
}
close(fdDest);
close(fdSrc);
}
void dumpNetmgrLogs(std::string destDir) {
const std::vector <std::string> netmgrLogs
{
"/data/vendor/radio/metrics_data",
"/data/vendor/radio/omadm_logs.txt",
"/data/vendor/radio/power_anomaly_data.txt",
};
for (const auto& logFile : netmgrLogs) {
copyFile(logFile, destDir + "/" + basename(logFile.c_str()));
}
}
/** Dumps last synced NV data into bugreports */
void dumpModemEFS(std::string destDir) {
const std::string EFS_DIRECTORY = "/mnt/vendor/efs/";
const std::vector <std::string> nv_files
{
EFS_DIRECTORY+"nv_normal.bin",
EFS_DIRECTORY+"nv_protected.bin",
};
for (const auto& logFile : nv_files) {
copyFile(logFile, destDir + "/" + basename(logFile.c_str()));
}
}
void DumpstateDevice::dumpGpsLogs(int fd, std::string destDir) {
const std::string gpsLogDir = GPS_LOG_DIRECTORY;
const std::string gpsTmpLogDir = gpsLogDir + "/.tmp";
int maxFileNum = android::base::GetIntProperty(GPS_LOG_NUMBER_PROPERTY, 30);
dumpLogs(fd, gpsTmpLogDir, destDir, 1, GPS_LOG_PREFIX);
dumpLogs(fd, gpsLogDir, destDir, maxFileNum, GPS_LOG_PREFIX);
}
timepoint_t startSection(int fd, const std::string &sectionName) {
android::base::WriteStringToFd(
"\n"
"------ Section start: " + sectionName + " ------\n"
"\n", fd);
return std::chrono::steady_clock::now();
}
void endSection(int fd, const std::string &sectionName, timepoint_t startTime) {
auto endTime = std::chrono::steady_clock::now();
auto elapsedMsec = std::chrono::duration_cast<std::chrono::milliseconds>
(endTime - startTime).count();
android::base::WriteStringToFd(
"\n"
"------ Section end: " + sectionName + " ------\n"
"Elapsed msec: " + std::to_string(elapsedMsec) + "\n"
"\n", fd);
}
// If you are adding a single RunCommandToFd() or DumpFileToFd() call, please
// add it to dumpMiscSection(). But if you are adding multiple items that are
// related to each other - for instance, for a Foo peripheral - please add them
// to a new dump function and include it in this table so it can be accessed from the
// command line, e.g.:
// lshal debug android.hardware.dumpstate@1.0::IDumpstateDevice/default foo
//
// However, if your addition generates attachments and/or binary data for the
// bugreport (i.e. if it requires two file descriptors to execute), it must not be
// added to this table and should instead be added to dumpstateBoard() below.
DumpstateDevice::DumpstateDevice()
: mTextSections{
{ "wlan", [this](int fd) { dumpWlanSection(fd); } },
{ "soc", [this](int fd) { dumpSocSection(fd); } },
{ "storage", [this](int fd) { dumpStorageSection(fd); } },
{ "memory", [this](int fd) { dumpMemorySection(fd); } },
{ "Devfreq", [this](int fd) { dumpDevfreqSection(fd); } },
{ "cpu", [this](int fd) { dumpCpuSection(fd); } },
{ "power", [this](int fd) { dumpPowerSection(fd); } },
{ "thermal", [this](int fd) { dumpThermalSection(fd); } },
{ "touch", [this](int fd) { dumpTouchSection(fd); } },
{ "display", [this](int fd) { dumpDisplaySection(fd); } },
{ "sensors-usf", [this](int fd) { dumpSensorsUSFSection(fd); } },
{ "aoc", [this](int fd) { dumpAoCSection(fd); } },
{ "ramdump", [this](int fd) { dumpRamdumpSection(fd); } },
{ "misc", [this](int fd) { dumpMiscSection(fd); } },
{ "gsc", [this](int fd) { dumpGscSection(fd); } },
} {
}
// Dump data requested by an argument to the "debug" HAL interface, or help info
// if the specified section is not supported.
void DumpstateDevice::dumpTextSection(int fd, const std::string &sectionName) {
bool dumpAll = (sectionName == kAllSections);
for (const auto &section : mTextSections) {
if (dumpAll || sectionName == section.first) {
auto startTime = startSection(fd, section.first);
section.second(fd);
endSection(fd, section.first, startTime);
if (!dumpAll) {
return;
}
}
}
if (dumpAll) {
return;
}
// An unsupported section was requested on the command line
android::base::WriteStringToFd("Unrecognized text section: " + sectionName + "\n", fd);
android::base::WriteStringToFd("Try \"" + kAllSections + "\" or one of the following:", fd);
for (const auto &section : mTextSections) {
android::base::WriteStringToFd(" " + section.first, fd);
}
android::base::WriteStringToFd("\nNote: sections with attachments (e.g. modem) are"
"not avalable from the command line.\n", fd);
}
// Dump items related to wlan
void DumpstateDevice::dumpWlanSection(int fd) {
RunCommandToFd(fd, "WLAN Debug Dump", {"/vendor/bin/sh", "-c",
"cat /sys/wifi/dump_start"});
}
// Dump items related to power and battery
void DumpstateDevice::dumpPowerSection(int fd) {
struct stat buffer;
RunCommandToFd(fd, "Power Stats Times", {"/vendor/bin/sh", "-c",
"echo -n \"Boot: \" && /vendor/bin/uptime -s && "
"echo -n \"Now: \" && date"});
RunCommandToFd(fd, "ACPM stats", {"/vendor/bin/sh", "-c",
"for f in /sys/devices/platform/acpm_stats/*_stats ; do "
"echo \"\\n\\n$f\" ; cat $f ; "
"done"});
DumpFileToFd(fd, "CPU PM stats", "/sys/devices/system/cpu/cpupm/cpupm/time_in_state");
DumpFileToFd(fd, "GENPD summary", "/d/pm_genpd/pm_genpd_summary");
DumpFileToFd(fd, "Power supply property battery", "/sys/class/power_supply/battery/uevent");
DumpFileToFd(fd, "Power supply property dc", "/sys/class/power_supply/dc/uevent");
DumpFileToFd(fd, "Power supply property gcpm", "/sys/class/power_supply/gcpm/uevent");
DumpFileToFd(fd, "Power supply property gcpm_pps", "/sys/class/power_supply/gcpm_pps/uevent");
DumpFileToFd(fd, "Power supply property main-charger", "/sys/class/power_supply/main-charger/uevent");
DumpFileToFd(fd, "Power supply property pca9486-mains", "/sys/class/power_supply/pca9468-mains/uevent");
DumpFileToFd(fd, "Power supply property tcpm", "/sys/class/power_supply/tcpm-source-psy-5-0025/uevent");
DumpFileToFd(fd, "Power supply property usb", "/sys/class/power_supply/usb/uevent");
DumpFileToFd(fd, "Power supply property wireless", "/sys/class/power_supply/wireless/uevent");
if (!stat("/sys/class/power_supply/maxfg", &buffer)) {
DumpFileToFd(fd, "Power supply property maxfg", "/sys/class/power_supply/maxfg/uevent");
DumpFileToFd(fd, "m5_state", "/sys/class/power_supply/maxfg/m5_model_state");
DumpFileToFd(fd, "maxfg", "/dev/logbuffer_maxfg");
} else {
DumpFileToFd(fd, "Power supply property maxfg_base", "/sys/class/power_supply/maxfg_base/uevent");
DumpFileToFd(fd, "Power supply property maxfg_flip", "/sys/class/power_supply/maxfg_flip/uevent");
DumpFileToFd(fd, "m5_state", "/sys/class/power_supply/maxfg_base/m5_model_state");
DumpFileToFd(fd, "maxfg_base", "/dev/logbuffer_maxfg_base");
DumpFileToFd(fd, "maxfg_flip", "/dev/logbuffer_maxfg_flip");
}
if (!stat("/sys/kernel/debug/tcpm", &buffer)) {
RunCommandToFd(fd, "TCPM logs", {"/vendor/bin/sh", "-c", "cat /sys/kernel/debug/tcpm/*"});
} else {
RunCommandToFd(fd, "TCPM logs", {"/vendor/bin/sh", "-c", "cat /sys/kernel/debug/usb/tcpm*"});
}
DumpFileToFd(fd, "PD Engine", "/dev/logbuffer_usbpd");
DumpFileToFd(fd, "PPS-google_cpm", "/dev/logbuffer_google,cpm");
DumpFileToFd(fd, "PPS-dc", "/dev/logbuffer_pca9468_tcpm");
DumpFileToFd(fd, "BMS", "/dev/logbuffer_ssoc");
DumpFileToFd(fd, "TTF", "/dev/logbuffer_ttf");
DumpFileToFd(fd, "TTF details", "/sys/class/power_supply/battery/ttf_details");
DumpFileToFd(fd, "TTF stats", "/sys/class/power_supply/battery/ttf_stats");
DumpFileToFd(fd, "maxq", "/dev/logbuffer_maxq");
DumpFileToFd(fd, "RTX", "/dev/logbuffer_rtx");
DumpFileToFd(fd, "WIRELESS", "/dev/logbuffer_wireless");
RunCommandToFd(fd, "TRICKLE-DEFEND Config", {"/vendor/bin/sh", "-c",
" cd /sys/devices/platform/google,battery/power_supply/battery/;"
" for f in `ls bd_*` ; do echo \"$f: `cat $f`\" ; done"});
RunCommandToFd(fd, "DWELL-DEFEND Config", {"/vendor/bin/sh", "-c",
" cd /sys/devices/platform/google,charger/;"
" for f in `ls charge_s*` ; do echo \"$f: `cat $f`\" ; done"});
RunCommandToFd(fd, "TEMP-DEFEND Config", {"/vendor/bin/sh", "-c",
" cd /sys/devices/platform/google,charger/;"
" for f in `ls bd_*` ; do echo \"$f: `cat $f`\" ; done"});
RunCommandToFd(fd, "DC_registers dump", {"/vendor/bin/sh", "-c", "cat /d/regmap/*-0057-pca9468-mains/registers"});
RunCommandToFd(fd, "fg_model", {"/vendor/bin/sh", "-c",
"for f in /d/maxfg* ; do "
"regs=`cat $f/fg_model`; echo $f: ;"
"echo \"$regs\"; done"});
RunCommandToFd(fd, "fg_alo_ver", {"/vendor/bin/sh", "-c",
"for f in /d/maxfg* ; do "
"regs=`cat $f/algo_ver`; echo $f: ;"
"echo \"$regs\"; done"});
RunCommandToFd(fd, "fg_model_ok", {"/vendor/bin/sh", "-c",
"for f in /d/maxfg* ; do "
"regs=`cat $f/model_ok`; echo $f: ;"
"echo \"$regs\"; done"});
/* FG Registers */
RunCommandToFd(fd, "fg registers", {"/vendor/bin/sh", "-c",
"for f in /d/regmap/*-0036 ; do "
"regs=`cat $f/registers`; echo $f: ;"
"echo \"$regs\"; done"});
/* EEPROM State */
if (!stat("/sys/devices/platform/10970000.hsi2c/i2c-4/4-0050/eeprom", &buffer)) {
RunCommandToFd(fd, "Battery EEPROM", {"/vendor/bin/sh", "-c", "xxd /sys/devices/platform/10970000.hsi2c/i2c-4/4-0050/eeprom"});
} else {
RunCommandToFd(fd, "Battery EEPROM", {"/vendor/bin/sh", "-c", "xxd /sys/devices/platform/10970000.hsi2c/i2c-5/5-0050/eeprom"});
}
DumpFileToFd(fd, "Charger Stats", "/sys/class/power_supply/battery/charge_details");
RunCommandToFd(fd, "Google Charger", {"/vendor/bin/sh", "-c", "cd /sys/kernel/debug/google_charger/; "
"for f in `ls pps_*` ; do echo \"$f: `cat $f`\" ; done"});
RunCommandToFd(fd, "Google Battery", {"/vendor/bin/sh", "-c", "cd /sys/kernel/debug/google_battery/; "
"for f in `ls ssoc_*` ; do echo \"$f: `cat $f`\" ; done"});
DumpFileToFd(fd, "WLC logs", "/dev/logbuffer_wireless");
DumpFileToFd(fd, "WLC VER", "/sys/class/power_supply/wireless/device/version");
DumpFileToFd(fd, "WLC STATUS", "/sys/class/power_supply/wireless/device/status");
DumpFileToFd(fd, "RTX", "/dev/logbuffer_rtx");
RunCommandToFd(fd, "gvotables", {"/vendor/bin/sh", "-c", "cat /sys/kernel/debug/gvotables/*/status"});
DumpFileToFd(fd, "BCL", "/sys/devices/virtual/pmic/mitigation/triggered_stats");
DumpFileToFd(fd, "IF PMIC", "/sys/devices/virtual/pmic/max77759-mitigation/triggered_stats");
}
// Dump items related to thermal
void DumpstateDevice::dumpThermalSection(int fd) {
RunCommandToFd(fd, "Temperatures", {"/vendor/bin/sh", "-c",
"for f in /sys/class/thermal/thermal* ; do "
"type=`cat $f/type` ; temp=`cat $f/temp` ; echo \"$type: $temp\" ; "
"done"});
RunCommandToFd(fd, "Cooling Device Current State", {"/vendor/bin/sh", "-c",
"for f in /sys/class/thermal/cooling* ; do "
"type=`cat $f/type` ; temp=`cat $f/cur_state` ; echo \"$type: $temp\" ; "
"done"});
}
// Dump items related to touch
void DumpstateDevice::dumpTouchSection(int fd) {
const char stm_cmd_path[4][50] = {"/sys/class/spi_master/spi11/spi11.0",
"/proc/fts/driver_test",
"/sys/class/spi_master/spi6/spi6.0",
"/proc/fts_ext/driver_test"};
const char lsi_spi_path[] = "/sys/devices/virtual/sec/tsp";
char cmd[256];
for (int i = 0; i < 4; i+=2) {
snprintf(cmd, sizeof(cmd), "%s", stm_cmd_path[i + 1]);
if (!access(cmd, R_OK)) {
snprintf(cmd, sizeof(cmd), "echo A0 01 01 > %s", stm_cmd_path[i + 1]);
RunCommandToFd(fd, "Force Set AP as Bus Owner with Bugreport Flag",
{"/vendor/bin/sh", "-c", cmd});
}
snprintf(cmd, sizeof(cmd), "%s/appid", stm_cmd_path[i]);
if (!access(cmd, R_OK)) {
// Touch firmware version
DumpFileToFd(fd, "STM touch firmware version", cmd);
// Touch controller status
snprintf(cmd, sizeof(cmd), "%s/status", stm_cmd_path[i]);
DumpFileToFd(fd, "STM touch status", cmd);
// Mutual raw data
snprintf(cmd, sizeof(cmd),
"echo 13 00 01 > %s/stm_fts_cmd && cat %s/stm_fts_cmd",
stm_cmd_path[i], stm_cmd_path[i]);
RunCommandToFd(fd, "Mutual Raw", {"/vendor/bin/sh", "-c", cmd});
// Mutual strength data
snprintf(cmd, sizeof(cmd),
"echo 17 01 > %s/stm_fts_cmd && cat %s/stm_fts_cmd",
stm_cmd_path[i], stm_cmd_path[i]);
RunCommandToFd(fd, "Mutual Strength", {"/vendor/bin/sh", "-c", cmd});
// Self raw data
snprintf(cmd, sizeof(cmd),
"echo 15 00 01 > %s/stm_fts_cmd && cat %s/stm_fts_cmd",
stm_cmd_path[i], stm_cmd_path[i]);
RunCommandToFd(fd, "Self Raw", {"/vendor/bin/sh", "-c", cmd});
}
snprintf(cmd, sizeof(cmd), "%s", stm_cmd_path[i + 1]);
if (!access(cmd, R_OK)) {
snprintf(cmd, sizeof(cmd), "echo 23 00 > %s && cat %s",
stm_cmd_path[i + 1], stm_cmd_path[i + 1]);
RunCommandToFd(fd, "Mutual Raw Data",
{"/vendor/bin/sh", "-c", cmd});
snprintf(cmd, sizeof(cmd), "echo 23 03 > %s && cat %s",
stm_cmd_path[i + 1], stm_cmd_path[i + 1]);
RunCommandToFd(fd, "Mutual Baseline Data",
{"/vendor/bin/sh", "-c", cmd});
snprintf(cmd, sizeof(cmd), "echo 23 02 > %s && cat %s",
stm_cmd_path[i + 1], stm_cmd_path[i + 1]);
RunCommandToFd(fd, "Mutual Strength Data",
{"/vendor/bin/sh", "-c", cmd});
snprintf(cmd, sizeof(cmd), "echo 24 00 > %s && cat %s",
stm_cmd_path[i + 1], stm_cmd_path[i + 1]);
RunCommandToFd(fd, "Self Raw Data",
{"/vendor/bin/sh", "-c", cmd});
snprintf(cmd, sizeof(cmd), "echo 24 03 > %s && cat %s",
stm_cmd_path[i + 1], stm_cmd_path[i + 1]);
RunCommandToFd(fd, "Self Baseline Data",
{"/vendor/bin/sh", "-c", cmd});
snprintf(cmd, sizeof(cmd), "echo 24 02 > %s && cat %s",
stm_cmd_path[i + 1], stm_cmd_path[i + 1]);
RunCommandToFd(fd, "Self Strength Data",
{"/vendor/bin/sh", "-c", cmd});
snprintf(cmd, sizeof(cmd), "echo 32 10 > %s && cat %s",
stm_cmd_path[i + 1], stm_cmd_path[i + 1]);
RunCommandToFd(fd, "Mutual Compensation",
{"/vendor/bin/sh", "-c", cmd});
snprintf(cmd, sizeof(cmd), "echo 32 11 > %s && cat %s",
stm_cmd_path[i + 1], stm_cmd_path[i + 1]);
RunCommandToFd(fd, "Mutual Low Power Compensation",
{"/vendor/bin/sh", "-c", cmd});
snprintf(cmd, sizeof(cmd), "echo 33 12 > %s && cat %s",
stm_cmd_path[i + 1], stm_cmd_path[i + 1]);
RunCommandToFd(fd, "Self Compensation",
{"/vendor/bin/sh", "-c", cmd});
snprintf(cmd, sizeof(cmd), "echo 34 > %s && cat %s",
stm_cmd_path[i + 1], stm_cmd_path[i + 1]);
RunCommandToFd(fd, "Golden Mutual Raw Data",
{"/vendor/bin/sh", "-c", cmd});
snprintf(cmd, sizeof(cmd), "echo 01 FA 20 00 00 24 80 > %s",
stm_cmd_path[i + 1]);
RunCommandToFd(fd, "Packaging Plant - HW reset",
{"/vendor/bin/sh", "-c", cmd});
snprintf(cmd, sizeof(cmd), "echo 01 FA 20 00 00 68 08 > %s",
stm_cmd_path[i + 1]);
RunCommandToFd(fd, "Packaging Plant - Hibernate Memory",
{"/vendor/bin/sh", "-c", cmd});
snprintf(cmd, sizeof(cmd),
"echo 02 FB 00 04 3F D8 00 10 01 > %s && cat %s",
stm_cmd_path[i + 1], stm_cmd_path[i + 1]);
RunCommandToFd(fd, "Packaging Plant - Read 16 bytes from Address 0x00041FD8",
{"/vendor/bin/sh", "-c", cmd});
}
snprintf(cmd, sizeof(cmd), "%s/stm_fts_cmd", stm_cmd_path[i]);
if (!access(cmd, R_OK)) {
// ITO raw data
snprintf(cmd, sizeof(cmd),
"echo 01 > %s/stm_fts_cmd && cat %s/stm_fts_cmd",
stm_cmd_path[i], stm_cmd_path[i]);
RunCommandToFd(fd, "ITO Raw", {"/vendor/bin/sh", "-c", cmd});
}
snprintf(cmd, sizeof(cmd), "%s", stm_cmd_path[i + 1]);
if (!access(cmd, R_OK)) {
snprintf(cmd, sizeof(cmd), "echo A0 00 01 > %s", stm_cmd_path[i + 1]);
RunCommandToFd(fd, "Restore Bus Owner",
{"/vendor/bin/sh", "-c", cmd});
}
}
if (!access(lsi_spi_path, R_OK)) {
// Enable: force touch active
snprintf(cmd, sizeof(cmd),
"echo %s > %s/cmd && cat %s/cmd_result",
"force_touch_active,1",
lsi_spi_path, lsi_spi_path);
RunCommandToFd(fd, "Force Touch Active", {"/vendor/bin/sh", "-c", cmd});
// Firmware info
snprintf(cmd, sizeof(cmd), "%s/fw_version", lsi_spi_path);
DumpFileToFd(fd, "LSI firmware version", cmd);
// Touch status
snprintf(cmd, sizeof(cmd), "%s/status", lsi_spi_path);
DumpFileToFd(fd, "LSI touch status", cmd);
// Calibration info
snprintf(cmd, sizeof(cmd),
"echo %s > %s/cmd && cat %s/cmd_result",
"get_mis_cal_info",
lsi_spi_path, lsi_spi_path);
RunCommandToFd(fd, "Calibration info", {"/vendor/bin/sh", "-c", cmd});
// Mutual strength
snprintf(cmd, sizeof(cmd),
"echo %s > %s/cmd && cat %s/cmd_result",
"run_delta_read_all",
lsi_spi_path, lsi_spi_path);
RunCommandToFd(fd, "Mutual Strength", {"/vendor/bin/sh", "-c", cmd});
// Self strength
snprintf(cmd, sizeof(cmd),
"echo %s > %s/cmd && cat %s/cmd_result",
"run_self_delta_read_all",
lsi_spi_path, lsi_spi_path);
RunCommandToFd(fd, "Self Strength", {"/vendor/bin/sh", "-c", cmd});
// Raw cap
snprintf(cmd, sizeof(cmd),
"echo %s > %s/cmd && cat %s/cmd_result",
"run_rawcap_read_all",
lsi_spi_path, lsi_spi_path);
RunCommandToFd(fd, "Mutual Raw Cap", {"/vendor/bin/sh", "-c", cmd});
// Self raw cap
snprintf(cmd, sizeof(cmd),
"echo %s > %s/cmd && cat %s/cmd_result",
"run_self_rawcap_read_all",
lsi_spi_path, lsi_spi_path);
RunCommandToFd(fd, "Self Raw Cap", {"/vendor/bin/sh", "-c", cmd});
// TYPE_AMBIENT_DATA
snprintf(cmd, sizeof(cmd),
"echo %s > %s/cmd && cat %s/cmd_result",
"run_rawdata_read_type,3",
lsi_spi_path, lsi_spi_path);
RunCommandToFd(fd, "TYPE_AMBIENT_DATA", {"/vendor/bin/sh", "-c", cmd});
// TYPE_DECODED_DATA
snprintf(cmd, sizeof(cmd),
"echo %s > %s/cmd && cat %s/cmd_result",
"run_rawdata_read_type,5",
lsi_spi_path, lsi_spi_path);
RunCommandToFd(fd, "TYPE_DECODED_DATA", {"/vendor/bin/sh", "-c", cmd});
// TYPE_NOI_P2P_MIN
snprintf(cmd, sizeof(cmd),
"echo %s > %s/cmd && cat %s/cmd_result",
"run_rawdata_read_type,30",
lsi_spi_path, lsi_spi_path);
RunCommandToFd(fd, "TYPE_NOI_P2P_MIN", {"/vendor/bin/sh", "-c", cmd});
// TYPE_NOI_P2P_MAX
snprintf(cmd, sizeof(cmd),
"echo %s > %s/cmd && cat %s/cmd_result",
"run_rawdata_read_type,31",
lsi_spi_path, lsi_spi_path);
RunCommandToFd(fd, "TYPE_NOI_P2P_MAX", {"/vendor/bin/sh", "-c", cmd});
// Disable: force touch active
snprintf(cmd, sizeof(cmd),
"echo %s > %s/cmd && cat %s/cmd_result",
"force_touch_active,0",
lsi_spi_path, lsi_spi_path);
RunCommandToFd(fd, "Force Touch Active", {"/vendor/bin/sh", "-c", cmd});
}
}
// Dump items related to SoC
void DumpstateDevice::dumpSocSection(int fd) {
DumpFileToFd(fd, "AP HW TUNE", "/sys/devices/system/chip-id/ap_hw_tune_str");
DumpFileToFd(fd, "EVT VERSION", "/sys/devices/system/chip-id/evt_ver");
DumpFileToFd(fd, "LOT ID", "/sys/devices/system/chip-id/lot_id");
DumpFileToFd(fd, "PRODUCT ID", "/sys/devices/system/chip-id/product_id");
DumpFileToFd(fd, "REVISION", "/sys/devices/system/chip-id/revision");
DumpFileToFd(fd, "RAW STR", "/sys/devices/system/chip-id/raw_str");
}
// Dump items related to CPUs
void DumpstateDevice::dumpCpuSection(int fd) {
DumpFileToFd(fd, "CPU present", "/sys/devices/system/cpu/present");
DumpFileToFd(fd, "CPU online", "/sys/devices/system/cpu/online");
RunCommandToFd(fd, "CPU time-in-state", {"/vendor/bin/sh", "-c",
"for cpu in /sys/devices/system/cpu/cpu*; do "
"f=$cpu/cpufreq/stats/time_in_state; "
"if [ ! -f $f ]; then continue; fi; "
"echo $f:; cat $f; "
"done"});
RunCommandToFd(fd, "CPU cpuidle", {"/vendor/bin/sh", "-c",
"for cpu in /sys/devices/system/cpu/cpu*; do "
"for d in $cpu/cpuidle/state*; do "
"if [ ! -d $d ]; then continue; fi; "
"echo \"$d: `cat $d/name` `cat $d/desc` `cat $d/time` `cat $d/usage`\"; "
"done; "
"done"});
DumpFileToFd(fd, "INTERRUPTS", "/proc/interrupts");
}
// Dump items related to Devfreq & BTS
void DumpstateDevice::dumpDevfreqSection(int fd) {
DumpFileToFd(fd, "MIF DVFS",
"/sys/devices/platform/17000010.devfreq_mif/devfreq/17000010.devfreq_mif/time_in_state");
DumpFileToFd(fd, "INT DVFS",
"/sys/devices/platform/17000020.devfreq_int/devfreq/17000020.devfreq_int/time_in_state");
DumpFileToFd(fd, "INTCAM DVFS",
"/sys/devices/platform/17000030.devfreq_intcam/devfreq/17000030.devfreq_intcam/time_in_state");
DumpFileToFd(fd, "DISP DVFS",
"/sys/devices/platform/17000040.devfreq_disp/devfreq/17000040.devfreq_disp/time_in_state");
DumpFileToFd(fd, "CAM DVFS",
"/sys/devices/platform/17000050.devfreq_cam/devfreq/17000050.devfreq_cam/time_in_state");
DumpFileToFd(fd, "TNR DVFS",
"/sys/devices/platform/17000060.devfreq_tnr/devfreq/17000060.devfreq_tnr/time_in_state");
DumpFileToFd(fd, "MFC DVFS",
"/sys/devices/platform/17000070.devfreq_mfc/devfreq/17000070.devfreq_mfc/time_in_state");
DumpFileToFd(fd, "BO DVFS",
"/sys/devices/platform/17000080.devfreq_bo/devfreq/17000080.devfreq_bo/time_in_state");
DumpFileToFd(fd, "BTS stats", "/sys/devices/platform/exynos-bts/bts_stats");
}
// Dump items related to memory
void DumpstateDevice::dumpMemorySection(int fd) {
RunCommandToFd(fd, "ION HEAPS", {"/vendor/bin/sh", "-c",
"for d in $(ls -d /d/ion/*); do "
"if [ -f $d ]; then "
"echo --- $d; cat $d; "
"else "
"for f in $(ls $d); do "
"echo --- $d/$f; cat $d/$f; "
"done; "
"fi; "
"done"});
DumpFileToFd(fd, "dmabuf info", "/d/dma_buf/bufinfo");
}
static void DumpF2FS(int fd) {
DumpFileToFd(fd, "F2FS", "/sys/kernel/debug/f2fs/status");
RunCommandToFd(fd, "F2FS - fsck time (ms)", {"/vendor/bin/sh", "-c", "getprop ro.boottime.init.fsck.data"});
RunCommandToFd(fd, "F2FS - checkpoint=disable time (ms)", {"/vendor/bin/sh", "-c", "getprop ro.boottime.init.mount.data"});
}
static void DumpUFS(int fd) {
DumpFileToFd(fd, "UFS model", "/sys/block/sda/device/model");
DumpFileToFd(fd, "UFS rev", "/sys/block/sda/device/rev");
DumpFileToFd(fd, "UFS size", "/sys/block/sda/size");
DumpFileToFd(fd, "UFS Slow IO Read", "/dev/sys/block/bootdevice/slowio_read_cnt");
DumpFileToFd(fd, "UFS Slow IO Write", "/dev/sys/block/bootdevice/slowio_write_cnt");
DumpFileToFd(fd, "UFS Slow IO Unmap", "/dev/sys/block/bootdevice/slowio_unmap_cnt");
DumpFileToFd(fd, "UFS Slow IO Sync", "/dev/sys/block/bootdevice/slowio_sync_cnt");
RunCommandToFd(fd, "UFS err_stats", {"/vendor/bin/sh", "-c",
"path=\"/dev/sys/block/bootdevice/err_stats\"; "
"for node in `ls $path/* | grep -v reset_err_status`; do "
"printf \"%s:%d\\n\" $(basename $node) $(cat $node); done;"});
RunCommandToFd(fd, "UFS io_stats", {"/vendor/bin/sh", "-c",
"path=\"/dev/sys/block/bootdevice/io_stats\"; "
"printf \"\\t\\t%-10s %-10s %-10s %-10s %-10s %-10s\\n\" "
"ReadCnt ReadBytes WriteCnt WriteBytes RWCnt RWBytes; "
"str=$(cat $path/*_start); arr=($str); "
"printf \"Started: \\t%-10s %-10s %-10s %-10s %-10s %-10s\\n\" "
"${arr[1]} ${arr[0]} ${arr[5]} ${arr[4]} ${arr[3]} ${arr[2]}; "
"str=$(cat $path/*_complete); arr=($str); "
"printf \"Completed: \\t%-10s %-10s %-10s %-10s %-10s %-10s\\n\" "
"${arr[1]} ${arr[0]} ${arr[5]} ${arr[4]} ${arr[3]} ${arr[2]}; "
"str=$(cat $path/*_maxdiff); arr=($str); "
"printf \"MaxDiff: \\t%-10s %-10s %-10s %-10s %-10s %-10s\\n\\n\" "
"${arr[1]} ${arr[0]} ${arr[5]} ${arr[4]} ${arr[3]} ${arr[2]}; "});
RunCommandToFd(fd, "UFS req_stats", {"/vendor/bin/sh", "-c",
"path=\"/dev/sys/block/bootdevice/req_stats\"; "
"printf \"\\t%-10s %-10s %-10s %-10s %-10s %-10s\\n\" "
"All Write Read Security Flush Discard; "
"str=$(cat $path/*_min); arr=($str); "
"printf \"Min:\\t%-10s %-10s %-10s %-10s %-10s %-10s\\n\" "
"${arr[0]} ${arr[5]} ${arr[3]} ${arr[4]} ${arr[2]} ${arr[1]}; "
"str=$(cat $path/*_max); arr=($str); "
"printf \"Max:\\t%-10s %-10s %-10s %-10s %-10s %-10s\\n\" "
"${arr[0]} ${arr[5]} ${arr[3]} ${arr[4]} ${arr[2]} ${arr[1]}; "
"str=$(cat $path/*_avg); arr=($str); "
"printf \"Avg.:\\t%-10s %-10s %-10s %-10s %-10s %-10s\\n\" "
"${arr[0]} ${arr[5]} ${arr[3]} ${arr[4]} ${arr[2]} ${arr[1]}; "
"str=$(cat $path/*_sum); arr=($str); "
"printf \"Count:\\t%-10s %-10s %-10s %-10s %-10s %-10s\\n\\n\" "
"${arr[0]} ${arr[5]} ${arr[3]} ${arr[4]} ${arr[2]} ${arr[1]};"});
std::string ufs_health = "for f in $(find /dev/sys/block/bootdevice/health_descriptor -type f); do if [[ -r $f && -f $f ]]; then echo --- $f; cat $f; echo ''; fi; done";
RunCommandToFd(fd, "UFS health", {"/vendor/bin/sh", "-c", ufs_health.c_str()});
}
// Dump items related to storage
void DumpstateDevice::dumpStorageSection(int fd) {
DumpF2FS(fd);
DumpUFS(fd);
}
// Dump items related to display
void DumpstateDevice::dumpDisplaySection(int fd) {
DumpFileToFd(fd, "CRTC-0 underrun count", "/sys/kernel/debug/dri/0/crtc-0/underrun_cnt");
DumpFileToFd(fd, "CRTC-0 crc count", "/sys/kernel/debug/dri/0/crtc-0/crc_cnt");
DumpFileToFd(fd, "CRTC-0 ecc count", "/sys/kernel/debug/dri/0/crtc-0/ecc_cnt");
DumpFileToFd(fd, "CRTC-0 event log", "/sys/kernel/debug/dri/0/crtc-0/event");
DumpFileToFd(fd, "CRTC-1 underrun count", "/sys/kernel/debug/dri/0/crtc-1/underrun_cnt");
DumpFileToFd(fd, "CRTC-1 crc count", "/sys/kernel/debug/dri/0/crtc-1/crc_cnt");
DumpFileToFd(fd, "CRTC-1 ecc count", "/sys/kernel/debug/dri/0/crtc-1/ecc_cnt");
DumpFileToFd(fd, "CRTC-1 event log", "/sys/kernel/debug/dri/0/crtc-1/event");
RunCommandToFd(fd, "libdisplaycolor", {"/vendor/bin/dumpsys", "displaycolor", "-v"},
CommandOptions::WithTimeout(2).Build());
}
// Dump items related to AoC
void DumpstateDevice::dumpAoCSection(int fd) {
DumpFileToFd(fd, "AoC Service Status", "/sys/devices/platform/19000000.aoc/services");
DumpFileToFd(fd, "AoC Restarts", "/sys/devices/platform/19000000.aoc/restart_count");
DumpFileToFd(fd, "AoC Coredumps", "/sys/devices/platform/19000000.aoc/coredump_count");
}
// Dump items related to sensors usf.
void DumpstateDevice::dumpSensorsUSFSection(int fd) {
CommandOptions options = CommandOptions::WithTimeout(2).Build();
RunCommandToFd(fd, "USF statistics",
{"/vendor/bin/sh", "-c", "usf_stats get --all"},
options);
if (!PropertiesHelper::IsUserBuild()) {
// Not a user build, if this is also not a production device dump the USF registry.
std::string hwRev = android::base::GetProperty(HW_REVISION, "");
if (hwRev.find("PROTO") != std::string::npos ||
hwRev.find("EVT") != std::string::npos ||
hwRev.find("DVT") != std::string::npos) {
RunCommandToFd(fd, "USF Registry",
{"/vendor/bin/sh", "-c", "usf_reg_edit save -"},
options);
}
}
}
// Gzip binary data and dump to fd in base64 format. Cmd to decode is also attached.
void dumpGzippedFileInBase64ToFd(int fd, const char* title, const char* file_path) {
auto cmd = android::base::StringPrintf("echo 'base64 -d <<EOF | gunzip' ; "
"/vendor/bin/gzip < \"%s\" | /vendor/bin/base64 ; "
"echo 'EOF'", file_path);
RunCommandToFd(fd, title,
{"/vendor/bin/sh", "-c", cmd.c_str()},
CommandOptions::WithTimeout(10).Build());
}
struct abl_log_header {
uint64_t i;
uint64_t size;
char buf[];
} __attribute__((packed));
// Dump items related to ramdump.
void DumpstateDevice::dumpRamdumpSection(int fd) {
std::string abl_log;
if (android::base::ReadFileToString("/mnt/vendor/ramdump/abl.log", &abl_log)) {
const struct abl_log_header *header = (const struct abl_log_header*) abl_log.c_str();
android::base::WriteStringToFd(android::base::StringPrintf(
"------ Ramdump misc file: abl.log (i:0x%" PRIx64 " size:0x%" PRIx64 ") ------\n%s\n",
header->i, header->size, std::string(header->buf, header->i).c_str()), fd);
} else {
android::base::WriteStringToFd("*** Ramdump misc file: abl.log: File not found\n", fd);
}
dumpGzippedFileInBase64ToFd(
fd, "Ramdump misc file: acpm.lst (gzipped in base64)", "/mnt/vendor/ramdump/acpm.lst");
dumpGzippedFileInBase64ToFd(
fd, "Ramdump misc file: s2d.lst (gzipped in base64)", "/mnt/vendor/ramdump/s2d.lst");
}
// Dump items that don't fit well into any other section
void DumpstateDevice::dumpMiscSection(int fd) {
RunCommandToFd(fd, "VENDOR PROPERTIES", {"/vendor/bin/getprop"});
}
// Dump items related to GSC
void DumpstateDevice::dumpGscSection(int fd) {
RunCommandToFd(fd, "Citadel VERSION", {"vendor/bin/hw/citadel_updater", "-lv"});
RunCommandToFd(fd, "Citadel STATS", {"vendor/bin/hw/citadel_updater", "--stats"});
}
void DumpstateDevice::dumpModem(int fd, int fdModem)
{
std::string modemLogDir = MODEM_LOG_DIRECTORY;
std::string extendedLogDir = MODEM_EXTENDED_LOG_DIRECTORY;
std::string tcpdumpLogDir = TCPDUMP_LOG_DIRECTORY;
static const std::string sectionName = "modem";
auto startTime = startSection(fd, sectionName);
const std::string modemLogCombined = modemLogDir + "/modem_log_all.tar";
const std::string modemLogAllDir = modemLogDir + "/modem_log";
DumpFileToFd(fd, "Modem Stat", "/data/vendor/modem_stat/debug.txt");
RunCommandToFd(fd, "Modem SSR history", {"/vendor/bin/sh", "-c",
"for f in $(ls /data/vendor/ssrdump/crashinfo_modem*); do "
"echo $f ; cat $f ; done"},
CommandOptions::WithTimeout(2).Build());
RunCommandToFd(fd, "RFSD error log", {"/vendor/bin/sh", "-c",
"for f in $(ls /data/vendor/log/rfsd/rfslog_*); do "
"echo $f ; cat $f ; done"},
CommandOptions::WithTimeout(2).Build());
RunCommandToFd(fd, "MKDIR MODEM LOG", {"/vendor/bin/mkdir", "-p", modemLogAllDir.c_str()}, CommandOptions::WithTimeout(2).Build());
if (!PropertiesHelper::IsUserBuild()) {
bool modemLogEnabled = android::base::GetBoolProperty(MODEM_LOGGING_PERSIST_PROPERTY, false);
bool gpsLogEnabled = android::base::GetBoolProperty(GPS_LOGGING_STATUS_PROPERTY, false);
bool tcpdumpEnabled = android::base::GetBoolProperty(TCPDUMP_PERSIST_PROPERTY, false);
int maxFileNum = android::base::GetIntProperty(MODEM_LOGGING_NUMBER_BUGREPORT_PROPERTY, 100);
if (tcpdumpEnabled) {
dumpLogs(fd, tcpdumpLogDir, modemLogAllDir, android::base::GetIntProperty(TCPDUMP_NUMBER_BUGREPORT, 5), TCPDUMP_LOG_PREFIX);
}
if (modemLogEnabled) {
bool modemLogStarted = android::base::GetBoolProperty(MODEM_LOGGING_STATUS_PROPERTY, false);
if (modemLogStarted) {
android::base::SetProperty(MODEM_LOGGING_PROPERTY, "false");
ALOGD("Stopping modem logging...\n");
} else {
ALOGD("modem logging is not running\n");
}
for (int i = 0; i < 30; i++) {
if (!android::base::GetBoolProperty(MODEM_LOGGING_STATUS_PROPERTY, false)) {
ALOGD("modem logging stopped\n");
sleep(1);
break;
}
sleep(1);
}
dumpLogs(fd, modemLogDir, modemLogAllDir, maxFileNum, MODEM_LOG_PREFIX);
if (modemLogStarted) {
ALOGD("Restarting modem logging...\n");
android::base::SetProperty(MODEM_LOGGING_PROPERTY, "true");
}
}
if (gpsLogEnabled) {
dumpGpsLogs(fd, modemLogAllDir);
} else {
ALOGD("gps logging is not running\n");
}
dumpLogs(fd, extendedLogDir, modemLogAllDir, maxFileNum, EXTENDED_LOG_PREFIX);
dumpRilLogs(fd, modemLogAllDir);
dumpNetmgrLogs(modemLogAllDir);
dumpModemEFS(modemLogAllDir);
}
RunCommandToFd(fd, "TAR LOG", {"/vendor/bin/tar", "cvf", modemLogCombined.c_str(), "-C", modemLogAllDir.c_str(), "."}, CommandOptions::WithTimeout(120).Build());
RunCommandToFd(fd, "CHG PERM", {"/vendor/bin/chmod", "a+w", modemLogCombined.c_str()}, CommandOptions::WithTimeout(2).Build());
std::vector<uint8_t> buffer(65536);
android::base::unique_fd fdLog(TEMP_FAILURE_RETRY(open(modemLogCombined.c_str(), O_RDONLY | O_CLOEXEC | O_NONBLOCK)));
if (fdLog >= 0) {
while (1) {
ssize_t bytes_read = TEMP_FAILURE_RETRY(read(fdLog, buffer.data(), buffer.size()));
if (bytes_read == 0) {
break;
} else if (bytes_read < 0) {
ALOGD("read(%s): %s\n", modemLogCombined.c_str(), strerror(errno));
break;
}
ssize_t result = TEMP_FAILURE_RETRY(write(fdModem, buffer.data(), bytes_read));
if (result != bytes_read) {
ALOGD("Failed to write %ld bytes, actually written: %ld", bytes_read, result);
break;
}
}
}
RunCommandToFd(fd, "RM MODEM DIR", { "/vendor/bin/rm", "-r", modemLogAllDir.c_str()}, CommandOptions::WithTimeout(2).Build());
RunCommandToFd(fd, "RM LOG", { "/vendor/bin/rm", modemLogCombined.c_str()}, CommandOptions::WithTimeout(2).Build());
endSection(fd, sectionName, startTime);
}
// Methods from ::android::hardware::dumpstate::V1_0::IDumpstateDevice follow.
Return<void> DumpstateDevice::dumpstateBoard(const hidl_handle &handle) {
// Ignore return value, just return an empty status.
dumpstateBoard_1_1(handle, DumpstateMode::DEFAULT, 30 * 1000 /* timeoutMillis */);
return Void();
}
// Methods from ::android::hardware::dumpstate::V1_1::IDumpstateDevice follow.
Return<DumpstateStatus> DumpstateDevice::dumpstateBoard_1_1(const hidl_handle& handle,
const DumpstateMode mode,
const uint64_t timeoutMillis) {
// Unused arguments.
(void) timeoutMillis;
if (handle == nullptr || handle->numFds < 1) {
ALOGE("no FDs\n");
return DumpstateStatus::ILLEGAL_ARGUMENT;
}
int fd = handle->data[0];
if (fd < 0) {
ALOGE("invalid FD: %d\n", handle->data[0]);
return DumpstateStatus::ILLEGAL_ARGUMENT;
}
if (mode == DumpstateMode::WEAR) {
// We aren't a Wear device.
ALOGE("Unsupported mode: %d\n", mode);
return DumpstateStatus::UNSUPPORTED_MODE;
} else if (mode < DumpstateMode::FULL || mode > DumpstateMode::PROTO) {
ALOGE("Invalid mode: %d\n", mode);
return DumpstateStatus::ILLEGAL_ARGUMENT;
}
dumpTextSection(fd, kAllSections);
if (handle->numFds < 2) {
ALOGE("no FD for modem\n");
} else {
int fdModem = handle->data[1];
dumpModem(fd, fdModem);
}
// Keep this at the end as very long on not for humans
static const char* kBcmdhd43752Path =
"/sys/module/bcmdhd43752/parameters/info_string";
static const char* kBcmdhd4389Path =
"/sys/module/bcmdhd4389/parameters/info_string";
std::string chip_info;
if (android::base::ReadFileToString(kBcmdhd43752Path, &chip_info) &&
(chip_info.find("Chip: aae8") != std::string::npos)) {
RunCommandToFd(fd, "WLAN FW Log Symbol Table",
{"/vendor/bin/base64",
"/vendor/etc/wifi/logstrs_43752.bin"});
} else if (android::base::ReadFileToString(kBcmdhd4389Path, &chip_info) &&
(chip_info.find("Chip: 4389") != std::string::npos)) {
RunCommandToFd(fd, "WLAN FW Log Symbol Table",
{"/vendor/bin/base64",
"/vendor/firmware/logstrs.bin"});
}
return DumpstateStatus::OK;
}
Return<void> DumpstateDevice::setVerboseLoggingEnabled(const bool enable) {
::android::base::SetProperty(kVerboseLoggingProperty, enable ? "true" : "false");
return Void();
}
Return<bool> DumpstateDevice::getVerboseLoggingEnabled() {
return ::android::base::GetBoolProperty(kVerboseLoggingProperty, false);
}
// Since HALs that support the debug() interface are automatically invoked during
// bugreport generation and we don't want to generate a second copy of the same
// data that will go into dumpstate_board.txt, this function will only do
// something if it is called with an option, e.g.
// lshal debug android.hardware.dumpstate@1.0::IDumpstateDevice/default all
//
// Also, note that sections which generate attachments and/or binary data when
// included in a bugreport are not available through the debug() interface.
Return<void> DumpstateDevice::debug(const hidl_handle &handle, const hidl_vec<hidl_string> &args) {
// Exit when dump is completed since this is a lazy HAL.
addPostCommandTask([]() {
exit(0);
});
if (handle == nullptr || handle->numFds < 1 || args.size() != 1) {
return Void();
}
int fd = handle->data[0];
dumpTextSection(fd, static_cast<std::string>(args[0]));
fsync(fd);
return Void();
}
} // namespace implementation
} // namespace V1_1
} // namespace dumpstate
} // namespace hardware
} // namespace android