summaryrefslogtreecommitdiffstats
path: root/adb/commandline.cpp
diff options
context:
space:
mode:
authorFelipe Leme <felipeal@google.com>2016-04-01 17:43:27 -0700
committerFelipe Leme <felipeal@google.com>2016-04-13 09:21:23 -0700
commit44a42677cfde5f1ae6d0be67dcd07659d9c0f265 (patch)
tree74fe6bb42fa83ddd45161277c514022cfdab9a6f /adb/commandline.cpp
parentc2648132d2dc5874bb49de4efdf1d9a2e12eb6e8 (diff)
downloadcore-44a42677cfde5f1ae6d0be67dcd07659d9c0f265.tar.gz
core-44a42677cfde5f1ae6d0be67dcd07659d9c0f265.tar.bz2
core-44a42677cfde5f1ae6d0be67dcd07659d9c0f265.zip
Implements 'adb bugreport <ZIP_FILE>'.
Dumpstate now supports zipped bugreport, whose output is more complete than the flat-file bugreports provided prior to N. As such, adb now has a 'adb bugreport <ZIP_FILE>' name whose implementation: - Calls the new bugreportz binary. - Parses its output, which in case of success is the path of the .zip file. - Pulls the device file and renames it according to the command-line argument. BUG: 27653204 Change-Id: I7169fe157c77bbef1684d0cb4e43095d95ddf2b8
Diffstat (limited to 'adb/commandline.cpp')
-rw-r--r--adb/commandline.cpp63
1 files changed, 51 insertions, 12 deletions
diff --git a/adb/commandline.cpp b/adb/commandline.cpp
index 5aa878b59..3aa919982 100644
--- a/adb/commandline.cpp
+++ b/adb/commandline.cpp
@@ -65,6 +65,9 @@ static int uninstall_app_legacy(TransportType t, const char* serial, int argc, c
static auto& gProductOutPath = *new std::string();
extern int gListenAll;
+static constexpr char BUGZ_OK_PREFIX[] = "OK:";
+static constexpr char BUGZ_FAIL_PREFIX[] = "FAIL:";
+
static std::string product_file(const char *extra) {
if (gProductOutPath.empty()) {
fprintf(stderr, "adb: Product directory not specified; "
@@ -170,7 +173,7 @@ static void help() {
" (-g: grant all runtime permissions)\n"
" adb uninstall [-k] <package> - remove this app package from the device\n"
" ('-k' means keep the data and cache directories)\n"
- " adb bugreport - return all information from the device\n"
+ " adb bugreport [<zip_file>] - return all information from the device\n"
" that should be included in a bug report.\n"
"\n"
" adb backup [-f <file>] [-apk|-noapk] [-obb|-noobb] [-shared|-noshared] [-all] [-system|-nosystem] [<packages...>]\n"
@@ -285,7 +288,8 @@ static void stdin_raw_restore() {
// this expects that incoming data will use the shell protocol, in which case
// stdout/stderr are routed independently and the remote exit code will be
// returned.
-static int read_and_dump(int fd, bool use_shell_protocol=false) {
+// if |output| is non-null, stdout will be appended to it instead.
+static int read_and_dump(int fd, bool use_shell_protocol=false, std::string* output=nullptr) {
int exit_code = 0;
std::unique_ptr<ShellProtocol> protocol;
int length = 0;
@@ -330,8 +334,12 @@ static int read_and_dump(int fd, bool use_shell_protocol=false) {
}
}
- fwrite(buffer_ptr, 1, length, outfile);
- fflush(outfile);
+ if (output == nullptr) {
+ fwrite(buffer_ptr, 1, length, outfile);
+ fflush(outfile);
+ } else {
+ output->append(buffer_ptr, length);
+ }
}
return exit_code;
@@ -1121,7 +1129,8 @@ static bool adb_root(const char* command) {
// resulting output.
static int send_shell_command(TransportType transport_type, const char* serial,
const std::string& command,
- bool disable_shell_protocol) {
+ bool disable_shell_protocol,
+ std::string* output=nullptr) {
int fd;
bool use_shell_protocol = false;
@@ -1156,7 +1165,7 @@ static int send_shell_command(TransportType transport_type, const char* serial,
}
}
- int exit_code = read_and_dump(fd, use_shell_protocol);
+ int exit_code = read_and_dump(fd, use_shell_protocol, output);
if (adb_close(fd) < 0) {
PLOG(ERROR) << "failure closing FD " << fd;
@@ -1165,6 +1174,40 @@ static int send_shell_command(TransportType transport_type, const char* serial,
return exit_code;
}
+static int bugreport(TransportType transport_type, const char* serial, int argc,
+ const char** argv) {
+ // No need for shell protocol with bugreport, always disable for simplicity.
+ if (argc == 1) return send_shell_command(transport_type, serial, "bugreport", true);
+ if (argc != 2) return usage();
+
+ // Zipped bugreport option - will call 'bugreportz', which prints the location of the generated
+ // file, then pull it to the destination file provided by the user.
+ const char* dest_file = argv[1];
+ std::string output;
+
+ int status = send_shell_command(transport_type, serial, "bugreportz", true, &output);
+ if (status != 0 || output.empty()) return status;
+ output = android::base::Trim(output);
+
+ if (android::base::StartsWith(output, BUGZ_OK_PREFIX)) {
+ const char* zip_file = &output[strlen(BUGZ_OK_PREFIX)];
+ std::vector<const char*> srcs{zip_file};
+ status = do_sync_pull(srcs, dest_file, true, dest_file) ? 0 : 1;
+ if (status != 0) {
+ fprintf(stderr, "Could not copy file '%s' to '%s'\n", zip_file, dest_file);
+ }
+ return status;
+ }
+ if (android::base::StartsWith(output, BUGZ_FAIL_PREFIX)) {
+ const char* error_message = &output[strlen(BUGZ_FAIL_PREFIX)];
+ fprintf(stderr, "device failed to take a zipped bugreport: %s\n", error_message);
+ return -1;
+ }
+ fprintf(stderr, "unexpected string (%s) returned by bugreportz, "
+ "device probably does not support -z option\n", output.c_str());
+ return -1;
+}
+
static int logcat(TransportType transport, const char* serial, int argc, const char** argv) {
char* log_tags = getenv("ANDROID_LOG_TAGS");
std::string quoted = escape_arg(log_tags == nullptr ? "" : log_tags);
@@ -1694,12 +1737,8 @@ int adb_commandline(int argc, const char **argv) {
} else if (!strcmp(argv[0], "root") || !strcmp(argv[0], "unroot")) {
return adb_root(argv[0]) ? 0 : 1;
} else if (!strcmp(argv[0], "bugreport")) {
- if (argc != 1) return usage();
- // No need for shell protocol with bugreport, always disable for
- // simplicity.
- return send_shell_command(transport_type, serial, "bugreport", true);
- }
- else if (!strcmp(argv[0], "forward") || !strcmp(argv[0], "reverse")) {
+ return bugreport(transport_type, serial, argc, argv);
+ } else if (!strcmp(argv[0], "forward") || !strcmp(argv[0], "reverse")) {
bool reverse = !strcmp(argv[0], "reverse");
++argv;
--argc;