Created a dumpstate service.

For now this is still a limited service:

- It's only created when running an interactive bugreport.
- It only provides a listener to get updates.
- It will be just used by Shell to get updates.

Test: dumpstate_test passes
BUG: 31636879

Change-Id: Iae820261d220523c979bf905030456fcf0b2b618
diff --git a/cmds/dumpstate/utils.cpp b/cmds/dumpstate/utils.cpp
index c41cca4..34e09d7 100644
--- a/cmds/dumpstate/utils.cpp
+++ b/cmds/dumpstate/utils.cpp
@@ -165,7 +165,11 @@
 }
 
 Dumpstate::Dumpstate(const std::string& version, bool dry_run, const std::string& build_type)
-    : version_(version), now_(time(nullptr)), dry_run_(dry_run), build_type_(build_type) {
+    : pid_(getpid()),
+      version_(version),
+      now_(time(nullptr)),
+      dry_run_(dry_run),
+      build_type_(build_type) {
 }
 
 Dumpstate& Dumpstate::GetInstance() {
@@ -211,6 +215,10 @@
     return "user" == build_type_;
 }
 
+bool Dumpstate::IsZipping() const {
+    return zip_writer_ != nullptr;
+}
+
 std::string Dumpstate::GetPath(const std::string& suffix) const {
     return android::base::StringPrintf("%s/%s-%s%s", bugreport_dir_.c_str(), base_name_.c_str(),
                                        name_.c_str(), suffix.c_str());
@@ -1317,6 +1325,7 @@
 
     progress_ += delta;
 
+    // TODO: remove property support once Shell uses IDumpstateListener
     char key[PROPERTY_KEY_MAX];
     char value[PROPERTY_VALUE_MAX];
 
@@ -1325,36 +1334,55 @@
         int new_total = weight_total_ * 1.2;
         MYLOGD("Adjusting total weight from %d to %d\n", weight_total_, new_total);
         weight_total_ = new_total;
-        snprintf(key, sizeof(key), "dumpstate.%d.max", getpid());
-        snprintf(value, sizeof(value), "%d", weight_total_);
-        int status = property_set(key, value);
-        if (status != 0) {
-            MYLOGE("Could not update max weight by setting system property %s to %s: %d\n",
-                    key, value, status);
+
+        if (listener_ != nullptr) {
+            listener_->onMaxProgressUpdated(weight_total_);
+        } else {
+            snprintf(key, sizeof(key), "dumpstate.%d.max", pid_);
+            snprintf(value, sizeof(value), "%d", weight_total_);
+            int status = property_set(key, value);
+            if (status != 0) {
+                MYLOGE("Could not update max weight by setting system property %s to %s: %d\n", key,
+                       value, status);
+            }
         }
     }
 
-    snprintf(key, sizeof(key), "dumpstate.%d.progress", getpid());
-    snprintf(value, sizeof(value), "%d", progress_);
-
-    if (progress_ % 100 == 0) {
-        // We don't want to spam logcat, so only log multiples of 100.
-        MYLOGD("Setting progress (%s): %s/%d\n", key, value, weight_total_);
-    } else {
-        // stderr is ignored on normal invocations, but useful when calling /system/bin/dumpstate
-        // directly for debuggging.
-        fprintf(stderr, "Setting progress (%s): %s/%d\n", key, value, weight_total_);
-    }
-
     if (control_socket_fd_ >= 0) {
         dprintf(control_socket_fd_, "PROGRESS:%d/%d\n", progress_, weight_total_);
         fsync(control_socket_fd_);
     }
 
-    int status = property_set(key, value);
-    if (status) {
-        MYLOGE("Could not update progress by setting system property %s to %s: %d\n",
-                key, value, status);
+    if (listener_ != nullptr) {
+        if (progress_ % 100 == 0) {
+            // We don't want to spam logcat, so only log multiples of 100.
+            MYLOGD("Setting progress (%s): %d/%d\n", listener_name_.c_str(), progress_,
+                   weight_total_);
+        } else {
+            // stderr is ignored on normal invocations, but useful when calling
+            // /system/bin/dumpstate directly for debuggging.
+            fprintf(stderr, "Setting progress (%s): %d/%d\n", listener_name_.c_str(), progress_,
+                    weight_total_);
+        }
+        listener_->onProgressUpdated(progress_);
+    } else {
+        snprintf(key, sizeof(key), "dumpstate.%d.progress", pid_);
+        snprintf(value, sizeof(value), "%d", progress_);
+
+        if (progress_ % 100 == 0) {
+            // We don't want to spam logcat, so only log multiples of 100.
+            MYLOGD("Setting progress (%s): %s/%d\n", key, value, weight_total_);
+        } else {
+            // stderr is ignored on normal invocations, but useful when calling
+            // /system/bin/dumpstate directly for debuggging.
+            fprintf(stderr, "Setting progress (%s): %s/%d\n", key, value, weight_total_);
+        }
+
+        int status = property_set(key, value);
+        if (status) {
+            MYLOGE("Could not update progress by setting system property %s to %s: %d\n", key,
+                   value, status);
+        }
     }
 }