Add priority based dumpsys support to dumpstate

Adds a new version of dumpstate which calls dumpsys with different
priorities. Current version will remain INITIAL_VERSION (1.0) until tools
support the new version and services register with supported priorities.
Modified dumpsys to pass prioirty args to services.

BugReport format changes:
- removed service specific dumps and dump order changed
- Start of dumpsys section changed to
  DUMPSYS CRITICAL/HIGH/NORMAL
- Start of service dump changed to
  DUMP OF SERVICE CRITICAL/HIGH/NORMAL <servicename>

Bug: 27429130

Test: adb shell setprop dumpstate.version "1.0" && \
            adb bugreport ~/tmp_old.zip
Test: adb shell setprop dumpstate.version "2.0-dev-split-anr" && \
            adb bugreport ~/tmp_anr.zip
Test: adb shell setprop dumpstate.version "2.0-dev-priority-dumps" && \
            adb bugreport ~/tmp_new.zip

Change-Id: I9fd0f2d0e6d73b36cc8ee0f8239092ce83da9560
diff --git a/cmds/dumpstate/bugreport-format.md b/cmds/dumpstate/bugreport-format.md
index b995b80..dee89cf 100644
--- a/cmds/dumpstate/bugreport-format.md
+++ b/cmds/dumpstate/bugreport-format.md
@@ -56,8 +56,20 @@
 - `description.txt`: whose value is a multi-line, detailed description of the problem.
 
 ## Android O versions
-On _Android O (OhMightyAndroidWhatsYourNextReleaseName?)_, the following changes were made:
-- The ANR traces are added to the `FS` folder, typically under `FS/data/anr` (version `2.0-dev-1`).
+On _Android O (Oreo)_, the following changes were made:
+- The ANR traces are added to the `FS` folder, typically under `FS/data/anr` (version `2.0-dev-split-anr`).
+
+## Android P versions
+On _Android P (PleaseMightyAndroidWhatsYourNextReleaseName?)_, the following changes were made:
+- Dumpsys sections are dumped by priority (version `2.0-dev-priority-dumps`).
+  Supported priorities can be specified when registering framework services. Section headers are
+  changed to contain priority info.
+  `DUMPSYS` -> `DUMPSYS CRITICAL/HIGH/NORMAL`
+  `DUMP OF SERVICE <servicename>` -> `DUMP OF SERVICE CRITICAL/HIGH/NORMAL <servicename>`
+  Supported Priorities:
+    - CRITICAL - services that must dump first, and fast (under 100ms). Ex: cpuinfo.
+    - HIGH - services that also must dump first, but can take longer (under 250ms) to dump. Ex: meminfo.
+    - NORMAL - services that have no rush to dump and can take a long time (under 10s).
 
 ## Intermediate versions
 During development, the versions will be suffixed with _-devX_ or
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 5b0c155..335d25c 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -1038,6 +1038,40 @@
     RunCommand("IP RULES v6", {"ip", "-6", "rule", "show"});
 }
 
+// Runs dumpsys on services that must dump first and and will take less than 100ms to dump.
+static void RunDumpsysCritical() {
+    if (ds.CurrentVersionSupportsPriorityDumps()) {
+        RunDumpsys("DUMPSYS CRITICAL", {"--priority", "CRITICAL"},
+                   CommandOptions::WithTimeout(5).DropRoot().Build());
+    } else {
+        RunDumpsys("DUMPSYS MEMINFO", {"meminfo", "-a"},
+                   CommandOptions::WithTimeout(90).DropRoot().Build());
+        RunDumpsys("DUMPSYS CPUINFO", {"cpuinfo", "-a"},
+                   CommandOptions::WithTimeout(10).DropRoot().Build());
+    }
+}
+
+// Runs dumpsys on services that must dump first but can take up to 250ms to dump.
+static void RunDumpsysHigh() {
+    if (ds.CurrentVersionSupportsPriorityDumps()) {
+        RunDumpsys("DUMPSYS HIGH", {"--priority", "HIGH"},
+                   CommandOptions::WithTimeout(20).DropRoot().Build());
+    } else {
+        RunDumpsys("NETWORK DIAGNOSTICS", {"connectivity", "--diag"});
+    }
+}
+
+// Runs dumpsys on services that must dump but can take up to 10s to dump.
+static void RunDumpsysNormal() {
+    if (ds.CurrentVersionSupportsPriorityDumps()) {
+        RunDumpsys("DUMPSYS NORMAL", {"--priority", "NORMAL"},
+                   CommandOptions::WithTimeout(90).DropRoot().Build());
+    } else {
+        RunDumpsys("DUMPSYS", {"--skip", "meminfo", "cpuinfo"},
+                   CommandOptions::WithTimeout(90).Build(), 10);
+    }
+}
+
 static void dumpstate() {
     DurationReporter duration_reporter("DUMPSTATE");
 
@@ -1128,8 +1162,7 @@
     RunCommand("IPv6 ND CACHE", {"ip", "-6", "neigh", "show"});
     RunCommand("MULTICAST ADDRESSES", {"ip", "maddr"});
 
-    RunDumpsys("NETWORK DIAGNOSTICS", {"connectivity", "--diag"},
-               CommandOptions::WithTimeout(10).Build());
+    RunDumpsysHigh();
 
     RunCommand("SYSTEM PROPERTIES", {"getprop"});
 
@@ -1182,8 +1215,7 @@
     printf("== Android Framework Services\n");
     printf("========================================================\n");
 
-    RunDumpsys("DUMPSYS", {"--skip", "meminfo", "cpuinfo"}, CommandOptions::WithTimeout(90).Build(),
-               10);
+    RunDumpsysNormal();
 
     printf("========================================================\n");
     printf("== Checkins\n");
@@ -1624,10 +1656,12 @@
         ds.version_ = VERSION_CURRENT;
     }
 
-    if (ds.version_ != VERSION_CURRENT && ds.version_ != VERSION_SPLIT_ANR) {
-        MYLOGE("invalid version requested ('%s'); suppported values are: ('%s', '%s', '%s')\n",
-               ds.version_.c_str(), VERSION_DEFAULT.c_str(), VERSION_CURRENT.c_str(),
-               VERSION_SPLIT_ANR.c_str());
+    if (ds.version_ != VERSION_CURRENT && ds.version_ != VERSION_SPLIT_ANR &&
+        ds.version_ != VERSION_PRIORITY_DUMPS) {
+        MYLOGE(
+            "invalid version requested ('%s'); suppported values are: ('%s', '%s', '%s', '%s')\n",
+            ds.version_.c_str(), VERSION_DEFAULT.c_str(), VERSION_CURRENT.c_str(),
+            VERSION_SPLIT_ANR.c_str(), VERSION_PRIORITY_DUMPS.c_str());
         exit(1);
     }
 
@@ -1818,10 +1852,7 @@
 
         // Invoking the following dumpsys calls before dump_traces() to try and
         // keep the system stats as close to its initial state as possible.
-        RunDumpsys("DUMPSYS MEMINFO", {"meminfo", "-a"},
-                   CommandOptions::WithTimeout(90).DropRoot().Build());
-        RunDumpsys("DUMPSYS CPUINFO", {"cpuinfo", "-a"},
-                   CommandOptions::WithTimeout(10).DropRoot().Build());
+        RunDumpsysCritical();
 
         // TODO: Drop root user and move into dumpstate() once b/28633932 is fixed.
         dump_raft();
diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h
index 7757c1e..1bfafba 100644
--- a/cmds/dumpstate/dumpstate.h
+++ b/cmds/dumpstate/dumpstate.h
@@ -149,9 +149,15 @@
 
 /*
  * Temporary version that adds a anr-traces.txt entry. Once tools support it, the current version
- * will be bumped to 2.0-dev-1.
+ * will be bumped to 2.0.
  */
-static std::string VERSION_SPLIT_ANR = "2.0-dev-1";
+static std::string VERSION_SPLIT_ANR = "2.0-dev-split-anr";
+
+/*
+ * Temporary version that adds priority based dumps. Once tools support it, the current version
+ * will be bumped to 2.0.
+ */
+static std::string VERSION_PRIORITY_DUMPS = "2.0-dev-priority-dumps";
 
 /*
  * "Alias" for the current version.
@@ -266,6 +272,9 @@
     /* Gets the path of a bugreport file with the given suffix. */
     std::string GetPath(const std::string& suffix) const;
 
+    /* Returns true if the current version supports priority dump feature. */
+    bool CurrentVersionSupportsPriorityDumps() const;
+
     // TODO: initialize fields on constructor
 
     // dumpstate id - unique after each device reboot.
diff --git a/cmds/dumpstate/utils.cpp b/cmds/dumpstate/utils.cpp
index 93f4c22..c2c9071 100644
--- a/cmds/dumpstate/utils.cpp
+++ b/cmds/dumpstate/utils.cpp
@@ -257,6 +257,10 @@
                                        name_.c_str(), suffix.c_str());
 }
 
+bool Dumpstate::CurrentVersionSupportsPriorityDumps() const {
+    return (version_ == VERSION_PRIORITY_DUMPS);
+}
+
 void Dumpstate::SetProgress(std::unique_ptr<Progress> progress) {
     progress_ = std::move(progress);
 }