Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f9d5e6a3 authored by Benjamin Franz's avatar Benjamin Franz
Browse files

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
parent 8ea65f22
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -3173,6 +3173,14 @@ public class Intent implements Parcelable, Cloneable {
    /** {@hide} */
    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,
+10 −6
Original line number Diff line number Diff line
@@ -570,18 +570,19 @@ public class RecoverySystem {
     * @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 @@ public class RecoverySystem {
     * @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 @@ public class RecoverySystem {
     *
     * @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();
+2 −1
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@ public class MasterClearReceiver extends BroadcastReceiver {
        final String reason = intent.getStringExtra(Intent.EXTRA_REASON);
        final boolean wipeExternalStorage = intent.getBooleanExtra(
                Intent.EXTRA_WIPE_EXTERNAL_STORAGE, false);
        final boolean forceWipe = intent.getBooleanExtra(Intent.EXTRA_FORCE_MASTER_CLEAR, false);

        Slog.w(TAG, "!!! FACTORY RESET !!!");
        // The reboot call is blocking, so we need to do it on another thread.
@@ -54,7 +55,7 @@ public class MasterClearReceiver extends BroadcastReceiver {
            @Override
            public void run() {
                try {
                    RecoverySystem.rebootWipeUserData(context, shutdown, reason);
                    RecoverySystem.rebootWipeUserData(context, shutdown, reason, forceWipe);
                    Log.wtf(TAG, "Still running after master clear?!");
                } catch (IOException e) {
                    Slog.e(TAG, "Can't perform master clear/factory reset", e);