Making RescueParty reboot and factory reset synchronous.

PackageWatchdog.dump() waits on a lock which is held when RescueParty attempts remediation, making the dump not use the lock in those cases.

Bug: 328203835
Change-Id: I69aa3ef11a435d10479b8a63060699ff01647ebc
Test: presubmit
Flag: android.crashrecovery.flags.synchronous_reboot_in_rescue_party
diff --git a/packages/CrashRecovery/aconfig/flags.aconfig b/packages/CrashRecovery/aconfig/flags.aconfig
index 52e0cbb..c6c49e0 100644
--- a/packages/CrashRecovery/aconfig/flags.aconfig
+++ b/packages/CrashRecovery/aconfig/flags.aconfig
@@ -39,3 +39,10 @@
     bug: "289203818"
     is_fixed_read_only: true
 }
+
+flag {
+    name: "synchronous_reboot_in_rescue_party"
+    namespace: "modularization"
+    description: "Makes reboot and factory reset synchronous in RescueParty"
+    bug: "328203835"
+}
\ No newline at end of file
diff --git a/services/core/java/com/android/server/PackageWatchdog.java b/services/core/java/com/android/server/PackageWatchdog.java
index 682eb76..9060250 100644
--- a/services/core/java/com/android/server/PackageWatchdog.java
+++ b/services/core/java/com/android/server/PackageWatchdog.java
@@ -1292,6 +1292,16 @@
 
     /** Dump status of every observer in mAllObservers. */
     public void dump(@NonNull PrintWriter pw) {
+        if (Flags.synchronousRebootInRescueParty() && RescueParty.isRecoveryTriggeredReboot()) {
+            dumpInternal(pw);
+        } else {
+            synchronized (mLock) {
+                dumpInternal(pw);
+            }
+        }
+    }
+
+    private void dumpInternal(@NonNull PrintWriter pw) {
         IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ");
         ipw.println("Package Watchdog status");
         ipw.increaseIndent();
diff --git a/services/core/java/com/android/server/RescueParty.java b/services/core/java/com/android/server/RescueParty.java
index a6e21fc..ada1953 100644
--- a/services/core/java/com/android/server/RescueParty.java
+++ b/services/core/java/com/android/server/RescueParty.java
@@ -631,7 +631,8 @@
         // Request the reboot from a separate thread to avoid deadlock on PackageWatchdog
         // when device shutting down.
         setRebootProperty(true);
-        Runnable runnable = () -> {
+
+        if (Flags.synchronousRebootInRescueParty()) {
             try {
                 PowerManager pm = context.getSystemService(PowerManager.class);
                 if (pm != null) {
@@ -640,9 +641,20 @@
             } catch (Throwable t) {
                 logRescueException(level, failedPackage, t);
             }
-        };
-        Thread thread = new Thread(runnable);
-        thread.start();
+        } else {
+            Runnable runnable = () -> {
+                try {
+                    PowerManager pm = context.getSystemService(PowerManager.class);
+                    if (pm != null) {
+                        pm.reboot(TAG);
+                    }
+                } catch (Throwable t) {
+                    logRescueException(level, failedPackage, t);
+                }
+            };
+            Thread thread = new Thread(runnable);
+            thread.start();
+        }
     }
 
     private static void executeFactoryReset(Context context, int level,
@@ -655,18 +667,28 @@
         setFactoryResetProperty(true);
         long now = System.currentTimeMillis();
         setLastFactoryResetTimeMs(now);
-        Runnable runnable = new Runnable() {
-            @Override
-            public void run() {
-                try {
-                    RecoverySystem.rebootPromptAndWipeUserData(context, TAG + "," + failedPackage);
-                } catch (Throwable t) {
-                    logRescueException(level, failedPackage, t);
-                }
+
+        if (Flags.synchronousRebootInRescueParty()) {
+            try {
+                RecoverySystem.rebootPromptAndWipeUserData(context, TAG + "," + failedPackage);
+            } catch (Throwable t) {
+                logRescueException(level, failedPackage, t);
             }
-        };
-        Thread thread = new Thread(runnable);
-        thread.start();
+        } else {
+            Runnable runnable = new Runnable() {
+                @Override
+                public void run() {
+                    try {
+                        RecoverySystem.rebootPromptAndWipeUserData(context,
+                            TAG + "," + failedPackage);
+                    } catch (Throwable t) {
+                        logRescueException(level, failedPackage, t);
+                    }
+                }
+            };
+            Thread thread = new Thread(runnable);
+            thread.start();
+        }
     }