Loading core/java/android/os/RecoverySystem.java +14 −2 Original line number Diff line number Diff line Loading @@ -933,6 +933,12 @@ public class RecoverySystem { rebootWipeUserData(context, shutdown, reason, force, false /* wipeEuicc */); } /** {@hide} */ public static void rebootWipeUserData(Context context, boolean shutdown, String reason, boolean force, boolean wipeEuicc) throws IOException { rebootWipeUserData(context, shutdown, reason, force, wipeEuicc, false /* keepMemtagMode */); } /** * Reboots the device and wipes the user data and cache * partitions. This is sometimes called a "factory reset", which Loading @@ -948,6 +954,7 @@ public class RecoverySystem { * @param force whether the {@link UserManager.DISALLOW_FACTORY_RESET} user restriction * should be ignored * @param wipeEuicc whether wipe the euicc data * @param keepMemtagMode whether to tell recovery to keep currently configured memtag mode * * @throws IOException if writing the recovery command file * fails, or if the reboot itself fails. Loading @@ -956,7 +963,7 @@ public class RecoverySystem { * @hide */ public static void rebootWipeUserData(Context context, boolean shutdown, String reason, boolean force, boolean wipeEuicc) throws IOException { boolean force, boolean wipeEuicc, boolean keepMemtagMode) throws IOException { UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE); if (!force && um.hasUserRestriction(UserManager.DISALLOW_FACTORY_RESET)) { throw new SecurityException("Wiping data is not allowed for this user."); Loading Loading @@ -996,8 +1003,13 @@ public class RecoverySystem { reasonArg = "--reason=" + sanitizeArg(reason + "," + timeStamp); } String memtagArg = null; if (keepMemtagMode) { memtagArg = "--keep_memtag_mode"; } final String localeArg = "--locale=" + Locale.getDefault().toLanguageTag() ; bootCommand(context, shutdownArg, "--wipe_data", reasonArg, localeArg); bootCommand(context, shutdownArg, "--wipe_data", reasonArg, localeArg, memtagArg); } /** Loading services/core/java/com/android/server/MasterClearReceiver.java +7 −2 Original line number Diff line number Diff line Loading @@ -88,6 +88,9 @@ public class MasterClearReceiver extends BroadcastReceiver { mWipeEsims = intent.getBooleanExtra(Intent.EXTRA_WIPE_ESIMS, false); final boolean forceWipe = intent.getBooleanExtra(Intent.EXTRA_FORCE_MASTER_CLEAR, false) || intent.getBooleanExtra(Intent.EXTRA_FORCE_FACTORY_RESET, false); // This is ONLY used by TestHarnessService within System Server, so we don't add a proper // API constant in Intent for this. final boolean keepMemtagMode = intent.getBooleanExtra("keep_memtag_mode", false); // TODO(b/189938391): properly handle factory reset on headless system user mode. final int sendingUserId = getSendingUserId(); Loading @@ -110,9 +113,11 @@ public class MasterClearReceiver extends BroadcastReceiver { try { Slog.i(TAG, "Calling RecoverySystem.rebootWipeUserData(context, " + "shutdown=" + shutdown + ", reason=" + reason + ", forceWipe=" + forceWipe + ", wipeEsims=" + mWipeEsims + ")"); + ", forceWipe=" + forceWipe + ", wipeEsims=" + mWipeEsims + ", keepMemtagMode=" + keepMemtagMode + ")"); RecoverySystem .rebootWipeUserData(context, shutdown, reason, forceWipe, mWipeEsims); .rebootWipeUserData( context, shutdown, reason, forceWipe, mWipeEsims, keepMemtagMode); Slog.wtf(TAG, "Still running after master clear?!"); } catch (IOException e) { Slog.e(TAG, "Can't perform master clear/factory reset", e); Loading services/core/java/com/android/server/testharness/TestHarnessModeService.java +14 −0 Original line number Diff line number Diff line Loading @@ -71,6 +71,7 @@ import java.util.Set; public class TestHarnessModeService extends SystemService { public static final String TEST_HARNESS_MODE_PROPERTY = "persist.sys.test_harness"; private static final String TAG = TestHarnessModeService.class.getSimpleName(); private boolean mEnableKeepMemtagMode = false; private PersistentDataBlockManagerInternal mPersistentDataBlockManagerInternal; Loading Loading @@ -298,6 +299,18 @@ public class TestHarnessModeService extends SystemService { switch (cmd) { case "enable": case "restore": String opt; while ((opt = getNextOption()) != null) { switch (opt) { case "--keep-memtag": mEnableKeepMemtagMode = true; break; default: getErrPrintWriter().println("Invalid option: " + opt); return 1; } } checkPermissions(); final long originalId = Binder.clearCallingIdentity(); try { Loading Loading @@ -357,6 +370,7 @@ public class TestHarnessModeService extends SystemService { i.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); i.putExtra(Intent.EXTRA_REASON, TAG); i.putExtra(Intent.EXTRA_WIPE_EXTERNAL_STORAGE, true); i.putExtra("keep_memtag_mode", mEnableKeepMemtagMode); getContext().sendBroadcastAsUser(i, UserHandle.SYSTEM); return 0; } Loading services/tests/mockingservicestests/src/com/android/server/MasterClearReceiverTest.java +9 −3 Original line number Diff line number Diff line Loading @@ -154,10 +154,11 @@ public final class MasterClearReceiverTest { intent.putExtra(Intent.EXTRA_REASON, "Self destruct"); intent.putExtra(Intent.EXTRA_FORCE_FACTORY_RESET, true); intent.putExtra(Intent.EXTRA_WIPE_ESIMS, true); intent.putExtra("keep_memtag_mode", true); mReceiver.onReceive(mContext, intent); verifyRebootWipeUserData(/* shutdown= */ true, /* reason= */ "Self destruct", /* force= */ true, /* wipeEuicc= */ true); /* force= */ true, /* wipeEuicc= */ true, /* keepMemtagMode= */ true); verifyWipeExternalData(); } Loading Loading @@ -211,7 +212,7 @@ public final class MasterClearReceiverTest { mRebootWipeUserDataLatch.countDown(); return null; }).when(() -> RecoverySystem .rebootWipeUserData(any(), anyBoolean(), any(), anyBoolean(), anyBoolean())); .rebootWipeUserData(any(), anyBoolean(), any(), anyBoolean(), anyBoolean(), anyBoolean())); } private void expectWipeExternalData() { Loading Loading @@ -244,11 +245,16 @@ public final class MasterClearReceiverTest { private void verifyRebootWipeUserData(boolean shutdown, String reason, boolean force, boolean wipeEuicc) throws Exception { verifyRebootWipeUserData(shutdown, reason, force, wipeEuicc, /* keepMemtagMode= */ false); } private void verifyRebootWipeUserData(boolean shutdown, String reason, boolean force, boolean wipeEuicc, boolean keepMemtagMode) throws Exception { boolean called = mRebootWipeUserDataLatch.await(5, TimeUnit.SECONDS); assertWithMessage("rebootWipeUserData not called in 5s").that(called).isTrue(); verify(()-> RecoverySystem.rebootWipeUserData(same(mContext), eq(shutdown), eq(reason), eq(force), eq(wipeEuicc))); eq(force), eq(wipeEuicc), eq(keepMemtagMode))); } private void verifyNoRebootWipeUserData() { Loading services/tests/mockingservicestests/src/com/android/server/devicepolicy/FactoryResetterTest.java +7 −4 Original line number Diff line number Diff line Loading @@ -88,7 +88,7 @@ public final class FactoryResetterTest { Log.d(TAG, "Mocking " + inv); return null; }).when(() -> RecoverySystem.rebootWipeUserData(any(), anyBoolean(), any(), anyBoolean(), anyBoolean())); anyBoolean(), anyBoolean(), anyBoolean())); } @After Loading Loading @@ -270,17 +270,20 @@ public final class FactoryResetterTest { private void verifyRebootWipeUserDataMinimumArgsCalled() { verify(() -> RecoverySystem.rebootWipeUserData(mContext, /* shutdown= */ false, /* reason= */ null, /* force= */ false, /* wipeEuicc= */ false)); /* reason= */ null, /* force= */ false, /* wipeEuicc= */ false, /* keepMemtagMode= */ false)); } private void verifyRebootWipeUserDataMinimumArgsButForceCalled() { verify(() -> RecoverySystem.rebootWipeUserData(mContext, /* shutdown= */ false, /* reason= */ null, /* force= */ true, /* wipeEuicc= */ false)); /* reason= */ null, /* force= */ true, /* wipeEuicc= */ false, /* keepMemtagMode= */ false)); } private void verifyRebootWipeUserDataAllArgsCalled() { verify(() -> RecoverySystem.rebootWipeUserData(mContext, /* shutdown= */ true, /* reason= */ REASON, /* force= */ true, /* wipeEuicc= */ true)); /* reason= */ REASON, /* force= */ true, /* wipeEuicc= */ true, /* keepMemtagMode= */ false)); } private void verifyWipeAdoptableStorageNotCalled() { Loading Loading
core/java/android/os/RecoverySystem.java +14 −2 Original line number Diff line number Diff line Loading @@ -933,6 +933,12 @@ public class RecoverySystem { rebootWipeUserData(context, shutdown, reason, force, false /* wipeEuicc */); } /** {@hide} */ public static void rebootWipeUserData(Context context, boolean shutdown, String reason, boolean force, boolean wipeEuicc) throws IOException { rebootWipeUserData(context, shutdown, reason, force, wipeEuicc, false /* keepMemtagMode */); } /** * Reboots the device and wipes the user data and cache * partitions. This is sometimes called a "factory reset", which Loading @@ -948,6 +954,7 @@ public class RecoverySystem { * @param force whether the {@link UserManager.DISALLOW_FACTORY_RESET} user restriction * should be ignored * @param wipeEuicc whether wipe the euicc data * @param keepMemtagMode whether to tell recovery to keep currently configured memtag mode * * @throws IOException if writing the recovery command file * fails, or if the reboot itself fails. Loading @@ -956,7 +963,7 @@ public class RecoverySystem { * @hide */ public static void rebootWipeUserData(Context context, boolean shutdown, String reason, boolean force, boolean wipeEuicc) throws IOException { boolean force, boolean wipeEuicc, boolean keepMemtagMode) throws IOException { UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE); if (!force && um.hasUserRestriction(UserManager.DISALLOW_FACTORY_RESET)) { throw new SecurityException("Wiping data is not allowed for this user."); Loading Loading @@ -996,8 +1003,13 @@ public class RecoverySystem { reasonArg = "--reason=" + sanitizeArg(reason + "," + timeStamp); } String memtagArg = null; if (keepMemtagMode) { memtagArg = "--keep_memtag_mode"; } final String localeArg = "--locale=" + Locale.getDefault().toLanguageTag() ; bootCommand(context, shutdownArg, "--wipe_data", reasonArg, localeArg); bootCommand(context, shutdownArg, "--wipe_data", reasonArg, localeArg, memtagArg); } /** Loading
services/core/java/com/android/server/MasterClearReceiver.java +7 −2 Original line number Diff line number Diff line Loading @@ -88,6 +88,9 @@ public class MasterClearReceiver extends BroadcastReceiver { mWipeEsims = intent.getBooleanExtra(Intent.EXTRA_WIPE_ESIMS, false); final boolean forceWipe = intent.getBooleanExtra(Intent.EXTRA_FORCE_MASTER_CLEAR, false) || intent.getBooleanExtra(Intent.EXTRA_FORCE_FACTORY_RESET, false); // This is ONLY used by TestHarnessService within System Server, so we don't add a proper // API constant in Intent for this. final boolean keepMemtagMode = intent.getBooleanExtra("keep_memtag_mode", false); // TODO(b/189938391): properly handle factory reset on headless system user mode. final int sendingUserId = getSendingUserId(); Loading @@ -110,9 +113,11 @@ public class MasterClearReceiver extends BroadcastReceiver { try { Slog.i(TAG, "Calling RecoverySystem.rebootWipeUserData(context, " + "shutdown=" + shutdown + ", reason=" + reason + ", forceWipe=" + forceWipe + ", wipeEsims=" + mWipeEsims + ")"); + ", forceWipe=" + forceWipe + ", wipeEsims=" + mWipeEsims + ", keepMemtagMode=" + keepMemtagMode + ")"); RecoverySystem .rebootWipeUserData(context, shutdown, reason, forceWipe, mWipeEsims); .rebootWipeUserData( context, shutdown, reason, forceWipe, mWipeEsims, keepMemtagMode); Slog.wtf(TAG, "Still running after master clear?!"); } catch (IOException e) { Slog.e(TAG, "Can't perform master clear/factory reset", e); Loading
services/core/java/com/android/server/testharness/TestHarnessModeService.java +14 −0 Original line number Diff line number Diff line Loading @@ -71,6 +71,7 @@ import java.util.Set; public class TestHarnessModeService extends SystemService { public static final String TEST_HARNESS_MODE_PROPERTY = "persist.sys.test_harness"; private static final String TAG = TestHarnessModeService.class.getSimpleName(); private boolean mEnableKeepMemtagMode = false; private PersistentDataBlockManagerInternal mPersistentDataBlockManagerInternal; Loading Loading @@ -298,6 +299,18 @@ public class TestHarnessModeService extends SystemService { switch (cmd) { case "enable": case "restore": String opt; while ((opt = getNextOption()) != null) { switch (opt) { case "--keep-memtag": mEnableKeepMemtagMode = true; break; default: getErrPrintWriter().println("Invalid option: " + opt); return 1; } } checkPermissions(); final long originalId = Binder.clearCallingIdentity(); try { Loading Loading @@ -357,6 +370,7 @@ public class TestHarnessModeService extends SystemService { i.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); i.putExtra(Intent.EXTRA_REASON, TAG); i.putExtra(Intent.EXTRA_WIPE_EXTERNAL_STORAGE, true); i.putExtra("keep_memtag_mode", mEnableKeepMemtagMode); getContext().sendBroadcastAsUser(i, UserHandle.SYSTEM); return 0; } Loading
services/tests/mockingservicestests/src/com/android/server/MasterClearReceiverTest.java +9 −3 Original line number Diff line number Diff line Loading @@ -154,10 +154,11 @@ public final class MasterClearReceiverTest { intent.putExtra(Intent.EXTRA_REASON, "Self destruct"); intent.putExtra(Intent.EXTRA_FORCE_FACTORY_RESET, true); intent.putExtra(Intent.EXTRA_WIPE_ESIMS, true); intent.putExtra("keep_memtag_mode", true); mReceiver.onReceive(mContext, intent); verifyRebootWipeUserData(/* shutdown= */ true, /* reason= */ "Self destruct", /* force= */ true, /* wipeEuicc= */ true); /* force= */ true, /* wipeEuicc= */ true, /* keepMemtagMode= */ true); verifyWipeExternalData(); } Loading Loading @@ -211,7 +212,7 @@ public final class MasterClearReceiverTest { mRebootWipeUserDataLatch.countDown(); return null; }).when(() -> RecoverySystem .rebootWipeUserData(any(), anyBoolean(), any(), anyBoolean(), anyBoolean())); .rebootWipeUserData(any(), anyBoolean(), any(), anyBoolean(), anyBoolean(), anyBoolean())); } private void expectWipeExternalData() { Loading Loading @@ -244,11 +245,16 @@ public final class MasterClearReceiverTest { private void verifyRebootWipeUserData(boolean shutdown, String reason, boolean force, boolean wipeEuicc) throws Exception { verifyRebootWipeUserData(shutdown, reason, force, wipeEuicc, /* keepMemtagMode= */ false); } private void verifyRebootWipeUserData(boolean shutdown, String reason, boolean force, boolean wipeEuicc, boolean keepMemtagMode) throws Exception { boolean called = mRebootWipeUserDataLatch.await(5, TimeUnit.SECONDS); assertWithMessage("rebootWipeUserData not called in 5s").that(called).isTrue(); verify(()-> RecoverySystem.rebootWipeUserData(same(mContext), eq(shutdown), eq(reason), eq(force), eq(wipeEuicc))); eq(force), eq(wipeEuicc), eq(keepMemtagMode))); } private void verifyNoRebootWipeUserData() { Loading
services/tests/mockingservicestests/src/com/android/server/devicepolicy/FactoryResetterTest.java +7 −4 Original line number Diff line number Diff line Loading @@ -88,7 +88,7 @@ public final class FactoryResetterTest { Log.d(TAG, "Mocking " + inv); return null; }).when(() -> RecoverySystem.rebootWipeUserData(any(), anyBoolean(), any(), anyBoolean(), anyBoolean())); anyBoolean(), anyBoolean(), anyBoolean())); } @After Loading Loading @@ -270,17 +270,20 @@ public final class FactoryResetterTest { private void verifyRebootWipeUserDataMinimumArgsCalled() { verify(() -> RecoverySystem.rebootWipeUserData(mContext, /* shutdown= */ false, /* reason= */ null, /* force= */ false, /* wipeEuicc= */ false)); /* reason= */ null, /* force= */ false, /* wipeEuicc= */ false, /* keepMemtagMode= */ false)); } private void verifyRebootWipeUserDataMinimumArgsButForceCalled() { verify(() -> RecoverySystem.rebootWipeUserData(mContext, /* shutdown= */ false, /* reason= */ null, /* force= */ true, /* wipeEuicc= */ false)); /* reason= */ null, /* force= */ true, /* wipeEuicc= */ false, /* keepMemtagMode= */ false)); } private void verifyRebootWipeUserDataAllArgsCalled() { verify(() -> RecoverySystem.rebootWipeUserData(mContext, /* shutdown= */ true, /* reason= */ REASON, /* force= */ true, /* wipeEuicc= */ true)); /* reason= */ REASON, /* force= */ true, /* wipeEuicc= */ true, /* keepMemtagMode= */ false)); } private void verifyWipeAdoptableStorageNotCalled() { Loading