Implement dumpsys for incident service

Implement dump() function in IncidentService so that it can be dumped by
default. Dumpstate calls it twice, one with and one without '--proto'.
dump() ignores the former.
Dumpsys allows 10s max for each service. Hence, section 1200, 1201, 1202
are skipped because they take too long. Section 3008 and 3015 are
skipped temporarily due to errors. All sections should be enabled once
we find a workaround.
A follow-up change in SELinux is needed to allow dumpstate to access
incidentd.

Bug: 119417232
Test: Run `adb shell dumpsys incident --proto`, inspect result and logs
Test: Run `adb bugreport`, make sure incident.proto is in the zip file
      Check the proto for validity via aprotoc:
      cat incident.proto | ./out/soong/host/linux-x86/bin/aprotoc --decode_raw
Exempt-From-Owner-Approval: The original owners no longer work on this
                            project.
Change-Id: I7d08f6b644cb6751b201fb7ba37ac5e1c42fd3c5
diff --git a/cmds/incidentd/src/IncidentService.cpp b/cmds/incidentd/src/IncidentService.cpp
index 1c3ebd8..b23c1ed 100644
--- a/cmds/incidentd/src/IncidentService.cpp
+++ b/cmds/incidentd/src/IncidentService.cpp
@@ -24,6 +24,7 @@
 #include "incidentd_util.h"
 #include "section_list.h"
 
+#include <android/os/IncidentReportArgs.h>
 #include <binder/IPCThreadState.h>
 #include <binder/IResultReceiver.h>
 #include <binder/IServiceManager.h>
@@ -41,6 +42,15 @@
 #define DEFAULT_BYTES_SIZE_LIMIT (20 * 1024 * 1024)        // 20MB
 #define DEFAULT_REFACTORY_PERIOD_MS (24 * 60 * 60 * 1000)  // 1 Day
 
+// Skip logs (1100 - 1108) because they are already in the bug report
+// Skip 1200, 1201, 1202, 3018 because they take too long
+// TODO(120079956): Skip 3008, 3015 because of error
+#define SKIPPED_SECTIONS { 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, /* Logs */ \
+                           1200, 1201, 1202, /* Native, hal, java traces */ \
+                           3008, /* "package --proto" */ \
+                           3015, /* "activity --proto processes" */ \
+                           3018  /* "meminfo -a --proto" */ }
+
 namespace android {
 namespace os {
 namespace incidentd {
@@ -391,6 +401,38 @@
     return NO_ERROR;
 }
 
+status_t IncidentService::dump(int fd, const Vector<String16>& args) {
+    if (std::find(args.begin(), args.end(), String16("--proto")) == args.end()) {
+        ALOGD("Skip dumping incident. Only proto format is supported.");
+        dprintf(fd, "Incident dump only supports proto version.\n");
+        return NO_ERROR;
+    }
+
+    ALOGD("Dump incident proto");
+    IncidentReportArgs incidentArgs;
+    incidentArgs.setDest(DEST_EXPLICIT);
+    int skipped[] = SKIPPED_SECTIONS;
+    for (const Section** section = SECTION_LIST; *section; section++) {
+        const int id = (*section)->id;
+        if (std::find(std::begin(skipped), std::end(skipped), id) == std::end(skipped)) {
+            incidentArgs.addSection(id);
+        }
+    }
+
+    if (!checkIncidentPermissions(incidentArgs).isOk()) {
+        return PERMISSION_DENIED;
+    }
+
+    int fd1 = dup(fd);
+    if (fd1 < 0) {
+        return -errno;
+    }
+
+    mHandler->scheduleRunReport(new ReportRequest(incidentArgs, NULL, fd1));
+
+    return NO_ERROR;
+}
+
 }  // namespace incidentd
 }  // namespace os
 }  // namespace android
diff --git a/cmds/incidentd/src/IncidentService.h b/cmds/incidentd/src/IncidentService.h
index e176bfd..6252ad2 100644
--- a/cmds/incidentd/src/IncidentService.h
+++ b/cmds/incidentd/src/IncidentService.h
@@ -112,6 +112,7 @@
     virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
                                 uint32_t flags) override;
     virtual status_t command(FILE* in, FILE* out, FILE* err, Vector<String8>& args);
+    virtual status_t dump(int fd, const Vector<String16>& args);
 
 private:
     sp<ReportRequestQueue> mQueue;
diff --git a/cmds/incidentd/src/main.cpp b/cmds/incidentd/src/main.cpp
index 4948823..098d74e 100644
--- a/cmds/incidentd/src/main.cpp
+++ b/cmds/incidentd/src/main.cpp
@@ -45,7 +45,8 @@
 
     // Create the service
     sp<IncidentService> service = new IncidentService(looper);
-    if (defaultServiceManager()->addService(String16("incident"), service) != 0) {
+    if (defaultServiceManager()->addService(String16("incident"), service, false,
+            IServiceManager::DUMP_FLAG_PRIORITY_NORMAL | IServiceManager::DUMP_FLAG_PROTO) != 0) {
         ALOGE("Failed to add service");
         return -1;
     }