summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Nandana Dutt <nandana@google.com> 2019-01-22 12:10:16 +0000
committer Nandana Dutt <nandana@google.com> 2019-01-22 21:03:25 +0000
commit235864b47896d308f56a012b1d509588a5069daf (patch)
tree40796f37cd810135864670741b1ffaabd7b49c97
parent9a76d20e4fa6d4a3c29bb1aba662f0d839077782 (diff)
Add a flag that makes dumpstate wait for options
There are 2 ways of running bugreports. Running dumpstate binary directly with command line options (existing flow), or running the binary to start the binder service, which waits for a caller to supply arguments like file descriptors to write output to (new flow to support the bugreport triggering API). Support the second flow with a new commandline flag. Also add a new service that uses the flag, to be used in the API. BUG:111441001 Test: adb shell setprop "ctl.start" "bugreportd" -> starts service & waits. Test: interactive bugreport still works Change-Id: I64cd03d15f45a896692d7462998d4faa6e413ef1
-rw-r--r--cmds/dumpstate/dumpstate.cpp6
-rw-r--r--cmds/dumpstate/dumpstate.rc6
-rw-r--r--cmds/dumpstate/main.cpp49
3 files changed, 59 insertions, 2 deletions
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index b226a7d89e..ec8393be55 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -1654,6 +1654,7 @@ static void ShowUsage() {
"progress (requires -o and -B)\n"
" -R: take bugreport in remote mode (requires -o, -z, -d and -B, "
"shouldn't be used with -P)\n"
+ " -w: start binder service and make it wait for a call to startBugreport\n"
" -v: prints the dumpstate header and exit\n");
}
@@ -2112,7 +2113,7 @@ void Dumpstate::DumpOptions::Initialize(BugreportMode bugreport_mode,
Dumpstate::RunStatus Dumpstate::DumpOptions::Initialize(int argc, char* argv[]) {
RunStatus status = RunStatus::OK;
int c;
- while ((c = getopt(argc, argv, "dho:svqzpPBRSV:")) != -1) {
+ while ((c = getopt(argc, argv, "dho:svqzpPBRSV:w")) != -1) {
switch (c) {
// clang-format off
case 'd': do_add_date = true; break;
@@ -2129,6 +2130,9 @@ Dumpstate::RunStatus Dumpstate::DumpOptions::Initialize(int argc, char* argv[])
case 'R': is_remote_mode = true; break;
case 'B': do_broadcast = true; break;
case 'V': break; // compatibility no-op
+ case 'w':
+ // This was already processed
+ break;
case 'h':
status = RunStatus::HELP;
break;
diff --git a/cmds/dumpstate/dumpstate.rc b/cmds/dumpstate/dumpstate.rc
index 2e72574738..14937b80b9 100644
--- a/cmds/dumpstate/dumpstate.rc
+++ b/cmds/dumpstate/dumpstate.rc
@@ -17,3 +17,9 @@ service dumpstatez /system/bin/dumpstate -S -d -z \
class main
disabled
oneshot
+
+# bugreportd starts dumpstate binder service and makes it wait for a listener to connect.
+service bugreportd /system/bin/dumpstate -w
+ class main
+ disabled
+ oneshot
diff --git a/cmds/dumpstate/main.cpp b/cmds/dumpstate/main.cpp
index 78aad1137b..68d373377c 100644
--- a/cmds/dumpstate/main.cpp
+++ b/cmds/dumpstate/main.cpp
@@ -14,8 +14,55 @@
* limitations under the License.
*/
+#define LOG_TAG "dumpstate"
+
+#include <binder/IPCThreadState.h>
+
+#include "DumpstateInternal.h"
+#include "DumpstateService.h"
#include "dumpstate.h"
+namespace {
+
+// Returns true if we should start the service and wait for a listener
+// to bind with bugreport options.
+bool ShouldStartServiceAndWait(int argc, char* argv[]) {
+ bool do_wait = false;
+ int c;
+ // Keep flags in sync with Dumpstate::DumpOptions::Initialize.
+ while ((c = getopt(argc, argv, "wdho:svqzpPBRSV:")) != -1 && !do_wait) {
+ switch (c) {
+ case 'w':
+ do_wait = true;
+ break;
+ default:
+ // Ignore all other options
+ break;
+ }
+ }
+
+ // Reset next index used by getopt so getopt can be called called again in Dumpstate::Run to
+ // parse bugreport options.
+ optind = 1;
+ return do_wait;
+}
+
+} // namespace
+
int main(int argc, char* argv[]) {
- return run_main(argc, argv);
+ if (ShouldStartServiceAndWait(argc, argv)) {
+ int ret;
+ if ((ret = android::os::DumpstateService::Start()) != android::OK) {
+ MYLOGE("Unable to start 'dumpstate' service: %d", ret);
+ exit(1);
+ }
+ MYLOGI("'dumpstate' service started and will wait for a call to startBugreport()");
+
+ // Waits forever for an incoming connection.
+ // TODO(b/111441001): should this time out?
+ android::IPCThreadState::self()->joinThreadPool();
+ return 0;
+ } else {
+ return run_main(argc, argv);
+ }
}