Add ability to retrieve bugreport multiple times

If specified by the caller, it keeps the bugreport stored in the framework
after it's retrieved, allowing it to be retrieved multiple times.

Bug: 304272173
Bug: 302517677
Test: manual testing
Change-Id: I2aaf0a7bea629bdad92aab567c96b2a9e7d64633
diff --git a/cmds/dumpstate/Android.bp b/cmds/dumpstate/Android.bp
index 860a2d8..23f185e 100644
--- a/cmds/dumpstate/Android.bp
+++ b/cmds/dumpstate/Android.bp
@@ -104,6 +104,8 @@
         "libvintf",
         "libbinderdebug",
         "packagemanager_aidl-cpp",
+        "server_configurable_flags",
+        "device_policy_aconfig_flags_c_lib",
     ],
     srcs: [
         "DumpstateService.cpp",
diff --git a/cmds/dumpstate/DumpstateService.cpp b/cmds/dumpstate/DumpstateService.cpp
index c787113..ba0a38a 100644
--- a/cmds/dumpstate/DumpstateService.cpp
+++ b/cmds/dumpstate/DumpstateService.cpp
@@ -37,6 +37,8 @@
     Dumpstate* ds = nullptr;
     int32_t calling_uid = -1;
     std::string calling_package;
+    int32_t user_id = -1;
+    bool keep_bugreport_on_retrieval = false;
 };
 
 static binder::Status exception(uint32_t code, const std::string& msg,
@@ -60,7 +62,7 @@
 
 [[noreturn]] static void* dumpstate_thread_retrieve(void* data) {
     std::unique_ptr<DumpstateInfo> ds_info(static_cast<DumpstateInfo*>(data));
-    ds_info->ds->Retrieve(ds_info->calling_uid, ds_info->calling_package);
+    ds_info->ds->Retrieve(ds_info->calling_uid, ds_info->calling_package, ds_info->keep_bugreport_on_retrieval);
     MYLOGD("Finished retrieving a bugreport. Exiting.\n");
     exit(0);
 }
@@ -201,9 +203,10 @@
 }
 
 binder::Status DumpstateService::retrieveBugreport(
-    int32_t calling_uid, const std::string& calling_package,
+    int32_t calling_uid, const std::string& calling_package, int32_t user_id,
     android::base::unique_fd bugreport_fd,
     const std::string& bugreport_file,
+    const bool keep_bugreport_on_retrieval,
     const sp<IDumpstateListener>& listener) {
 
     ds_ = &(Dumpstate::GetInstance());
@@ -211,6 +214,8 @@
     ds_info->ds = ds_;
     ds_info->calling_uid = calling_uid;
     ds_info->calling_package = calling_package;
+    ds_info->user_id = user_id;
+    ds_info->keep_bugreport_on_retrieval = keep_bugreport_on_retrieval;
     ds_->listener_ = listener;
     std::unique_ptr<Dumpstate::DumpOptions> options = std::make_unique<Dumpstate::DumpOptions>();
     // Use a /dev/null FD when initializing options since none is provided.
diff --git a/cmds/dumpstate/DumpstateService.h b/cmds/dumpstate/DumpstateService.h
index dd73319..7b76c36 100644
--- a/cmds/dumpstate/DumpstateService.h
+++ b/cmds/dumpstate/DumpstateService.h
@@ -48,8 +48,10 @@
 
     binder::Status retrieveBugreport(int32_t calling_uid,
                                      const std::string& calling_package,
+                                     int32_t user_id,
                                      android::base::unique_fd bugreport_fd,
                                      const std::string& bugreport_file,
+                                     const bool keep_bugreport_on_retrieval,
                                      const sp<IDumpstateListener>& listener)
                                      override;
 
diff --git a/cmds/dumpstate/binder/android/os/IDumpstate.aidl b/cmds/dumpstate/binder/android/os/IDumpstate.aidl
index fa9bcf3..97c470e 100644
--- a/cmds/dumpstate/binder/android/os/IDumpstate.aidl
+++ b/cmds/dumpstate/binder/android/os/IDumpstate.aidl
@@ -58,6 +58,9 @@
     // Defer user consent.
     const int BUGREPORT_FLAG_DEFER_CONSENT = 0x2;
 
+    // Keep bugreport stored after retrieval.
+    const int BUGREPORT_FLAG_KEEP_BUGREPORT_ON_RETRIEVAL = 0x4;
+
     /**
      * Speculatively pre-dumps UI data for a bugreport request that might come later.
      *
@@ -116,12 +119,16 @@
      *
      * @param callingUid UID of the original application that requested the report.
      * @param callingPackage package of the original application that requested the report.
+     * @param userId user Id of the original package that requested the report.
      * @param bugreportFd the file to which the zipped bugreport should be written
      * @param bugreportFile the path of the bugreport file
+     * @param keepBugreportOnRetrieval boolean to indicate if the bugreport should be kept in the
+     * platform after it has been retrieved by the caller.
      * @param listener callback for updates; optional
      */
-    void retrieveBugreport(int callingUid, @utf8InCpp String callingPackage,
+    void retrieveBugreport(int callingUid, @utf8InCpp String callingPackage, int userId,
                            FileDescriptor bugreportFd,
                            @utf8InCpp String bugreportFile,
+                           boolean keepBugreportOnRetrieval,
                            IDumpstateListener listener);
 }
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 33f6d38..4f80190 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -59,6 +59,7 @@
 #include <vector>
 
 #include <aidl/android/hardware/dumpstate/IDumpstateDevice.h>
+#include <android_app_admin_flags.h>
 #include <android-base/file.h>
 #include <android-base/properties.h>
 #include <android-base/scopeguard.h>
@@ -2977,14 +2978,17 @@
     return status;
 }
 
-Dumpstate::RunStatus Dumpstate::Retrieve(int32_t calling_uid, const std::string& calling_package) {
-    Dumpstate::RunStatus status = RetrieveInternal(calling_uid, calling_package);
+Dumpstate::RunStatus Dumpstate::Retrieve(int32_t calling_uid, const std::string& calling_package,
+                                         const bool keep_bugreport_on_retrieval) {
+    Dumpstate::RunStatus status = RetrieveInternal(calling_uid, calling_package,
+                                                    keep_bugreport_on_retrieval);
     HandleRunStatus(status);
     return status;
 }
 
 Dumpstate::RunStatus  Dumpstate::RetrieveInternal(int32_t calling_uid,
-                                                  const std::string& calling_package) {
+                                                  const std::string& calling_package,
+                                                  const bool keep_bugreport_on_retrieval) {
   consent_callback_ = new ConsentCallback();
   const String16 incidentcompanion("incidentcompanion");
   sp<android::IBinder> ics(
@@ -3019,9 +3023,12 @@
 
   bool copy_succeeded =
       android::os::CopyFileToFd(path_, options_->bugreport_fd.get());
-  if (copy_succeeded) {
-    android::os::UnlinkAndLogOnError(path_);
+
+  if (copy_succeeded && (!android::app::admin::flags::onboarding_bugreport_v2_enabled()
+                         || !keep_bugreport_on_retrieval)) {
+        android::os::UnlinkAndLogOnError(path_);
   }
+
   return copy_succeeded ? Dumpstate::RunStatus::OK
                         : Dumpstate::RunStatus::ERROR;
 }
diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h
index 0a032ec..d01cfce 100644
--- a/cmds/dumpstate/dumpstate.h
+++ b/cmds/dumpstate/dumpstate.h
@@ -210,7 +210,9 @@
         BUGREPORT_USE_PREDUMPED_UI_DATA =
           android::os::IDumpstate::BUGREPORT_FLAG_USE_PREDUMPED_UI_DATA,
         BUGREPORT_FLAG_DEFER_CONSENT =
-          android::os::IDumpstate::BUGREPORT_FLAG_DEFER_CONSENT
+          android::os::IDumpstate::BUGREPORT_FLAG_DEFER_CONSENT,
+          BUGREPORT_FLAG_KEEP_BUGREPORT_ON_RETRIEVAL =
+                    android::os::IDumpstate::BUGREPORT_FLAG_KEEP_BUGREPORT_ON_RETRIEVAL
     };
 
     static android::os::dumpstate::CommandOptions DEFAULT_DUMPSYS;
@@ -361,7 +363,8 @@
      *
      * Initialize() dumpstate before calling this method.
      */
-    RunStatus Retrieve(int32_t calling_uid, const std::string& calling_package);
+    RunStatus Retrieve(int32_t calling_uid, const std::string& calling_package,
+                        const bool keep_bugreport_on_retrieval);
 
 
 
@@ -562,7 +565,8 @@
 
   private:
     RunStatus RunInternal(int32_t calling_uid, const std::string& calling_package);
-    RunStatus RetrieveInternal(int32_t calling_uid, const std::string& calling_package);
+    RunStatus RetrieveInternal(int32_t calling_uid, const std::string& calling_package,
+                                const bool keep_bugreport_on_retrieval);
 
     RunStatus DumpstateDefaultAfterCritical();
     RunStatus dumpstate();