Add metadata and headers to incident reports.

+ Remove the spawned thread inside the ReportFile for filter_and_write_report
  because it leads to accessing freed memory

  Instead, let the caller of ReportFile::startFileteringData create the thread.
  ReportFile class shouldn't care about whether it's writing to a pipe for IPC
  or regular file.

+ Add uri building in incidentd

+ Add metadata and headers to incident reports

Test: existing passed tests in incidentd_test still pass.
      Manually tested with statsd

Change-Id: I5fef900d31f5d181275814f1e1c8c98443f201a7
diff --git a/cmds/incidentd/src/IncidentService.cpp b/cmds/incidentd/src/IncidentService.cpp
index 4ba31b4..b4021d1b 100644
--- a/cmds/incidentd/src/IncidentService.cpp
+++ b/cmds/incidentd/src/IncidentService.cpp
@@ -32,6 +32,7 @@
 #include <log/log.h>
 #include <private/android_filesystem_config.h>
 #include <utils/Looper.h>
+#include <thread>
 
 #include <unistd.h>
 
@@ -117,7 +118,8 @@
 }
 
 static string build_uri(const string& pkg, const string& cls, const string& id) {
-    return "build_uri not implemented " + pkg + "/" + cls + "/" + id;
+    return "content://android.os.IncidentManager/pending?pkg="
+        + pkg + "&receiver=" + cls + "&r=" + id;
 }
 
 // ================================================================================
@@ -358,17 +360,21 @@
     IncidentReportArgs args;
     sp<ReportFile> file = mWorkDirectory->getReport(pkg, cls, id, &args);
     if (file != nullptr) {
-        int fd;
-        err = file->startFilteringData(&fd, args);
-        if (err != 0) {
-            ALOGW("Error reading data file that we think should exist: %s",
-                    file->getDataFileName().c_str());
+        // Create pipe
+        int fds[2];
+        if (pipe(fds) != 0) {
+            ALOGW("Error opening pipe to filter incident report: %s",
+                  file->getDataFileName().c_str());
             return Status::ok();
         }
-
         result->setTimestampNs(file->getTimestampNs());
         result->setPrivacyPolicy(file->getEnvelope().privacy_policy());
-        result->takeFileDescriptor(fd);
+        result->takeFileDescriptor(fds[0]);
+        int writeFd = fds[1];
+        // spawn a thread to write the data. Release the writeFd ownership to the thread.
+        thread th([file, writeFd, args]() { file->startFilteringData(writeFd, args); });
+
+        th.detach();
     }
 
     return Status::ok();