Add an intent extra to force master clear

Currently, if a priv-app sends ACTION_MASTER_CLEAR, whilst
DISALLOW_FACTORY_RESET is set, the factory reset is blocked. This CL
introduces a new extra for master clear that let's the priv-app bypass
the user restriction.

Bug: 28689894
Change-Id: I4bf979a3826454e977f1abff4562f85c8d0eec4a
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 9118f01..df2c6fc 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -3174,6 +3174,14 @@
     public static final String ACTION_MASTER_CLEAR = "android.intent.action.MASTER_CLEAR";
 
     /**
+     * Boolean intent extra to be used with {@link ACTION_MASTER_CLEAR} in order to force a factory
+     * reset even if {@link android.os.UserManager.DISALLOW_FACTORY_RESET} is set.
+     * @hide
+     */
+    public static final String EXTRA_FORCE_MASTER_CLEAR =
+            "android.intent.extra.FORCE_MASTER_CLEAR";
+
+    /**
      * Broadcast action: report that a settings element is being restored from backup.  The intent
      * contains three extras: EXTRA_SETTING_NAME is a string naming the restored setting,
      * EXTRA_SETTING_NEW_VALUE is the value being restored, and EXTRA_SETTING_PREVIOUS_VALUE
diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java
index 4abbf0e..acb24e1 100644
--- a/core/java/android/os/RecoverySystem.java
+++ b/core/java/android/os/RecoverySystem.java
@@ -570,18 +570,19 @@
      * @throws SecurityException if the current user is not allowed to wipe data.
      */
     public static void rebootWipeUserData(Context context) throws IOException {
-        rebootWipeUserData(context, false, context.getPackageName());
+        rebootWipeUserData(context, false /* shutdown */, context.getPackageName(),
+                false /* force */);
     }
 
     /** {@hide} */
     public static void rebootWipeUserData(Context context, String reason) throws IOException {
-        rebootWipeUserData(context, false, reason);
+        rebootWipeUserData(context, false /* shutdown */, reason, false /* force */);
     }
 
     /** {@hide} */
     public static void rebootWipeUserData(Context context, boolean shutdown)
             throws IOException {
-        rebootWipeUserData(context, shutdown, context.getPackageName());
+        rebootWipeUserData(context, shutdown, context.getPackageName(), false /* force */);
     }
 
     /**
@@ -595,6 +596,9 @@
      * @param shutdown  if true, the device will be powered down after
      *                  the wipe completes, rather than being rebooted
      *                  back to the regular system.
+     * @param reason    the reason for the wipe that is visible in the logs
+     * @param force     whether the {@link UserManager.DISALLOW_FACTORY_RESET} user restriction
+     *                  should be ignored
      *
      * @throws IOException  if writing the recovery command file
      * fails, or if the reboot itself fails.
@@ -602,10 +606,10 @@
      *
      * @hide
      */
-    public static void rebootWipeUserData(Context context, boolean shutdown, String reason)
-            throws IOException {
+    public static void rebootWipeUserData(Context context, boolean shutdown, String reason,
+            boolean force) throws IOException {
         UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
-        if (um.hasUserRestriction(UserManager.DISALLOW_FACTORY_RESET)) {
+        if (!force && um.hasUserRestriction(UserManager.DISALLOW_FACTORY_RESET)) {
             throw new SecurityException("Wiping data is not allowed for this user.");
         }
         final ConditionVariable condition = new ConditionVariable();