Merge "Add ability to retrieve bugreport multiple times" into main
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();