Loading services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +6 −5 Original line number Diff line number Diff line Loading @@ -1032,9 +1032,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { Slog.w(LOG_TAG, "factoryReset(): " + reason); final long identity = Binder.clearCallingIdentity(); try { FactoryResetter.factoryReset(mContext, /* shutdown= */ false, reason, /* force= */ false, /* wipeEuicc= */ false, /* wipeAdoptableStorage= */ false, /* wipeFactoryResetProtection= */ false); FactoryResetter.newBuilder(mContext).setReason(reason).build().factoryReset(); } catch (IOException e) { // Shouldn't happen. Slog.wtf(LOG_TAG, "Could not factory reset", e); Loading Loading @@ -1295,8 +1293,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { void recoverySystemRebootWipeUserData(boolean shutdown, String reason, boolean force, boolean wipeEuicc, boolean wipeExtRequested, boolean wipeResetProtectionData) throws IOException { FactoryResetter.factoryReset(mContext, shutdown, reason, force, wipeEuicc, wipeExtRequested, wipeResetProtectionData); FactoryResetter.newBuilder(mContext).setReason(reason).setShutdown(shutdown) .setForce(force).setWipeEuicc(wipeEuicc) .setWipeAdoptableStorage(wipeExtRequested) .setWipeFactoryResetProtection(wipeResetProtectionData) .build().factoryReset(); } boolean systemPropertiesGetBoolean(String key, boolean def) { Loading services/devicepolicy/java/com/android/server/devicepolicy/FactoryResetter.java +117 −23 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.devicepolicy; import android.annotation.Nullable; import android.content.Context; import android.content.pm.PackageManager; import android.os.RecoverySystem; Loading @@ -27,37 +28,43 @@ import android.util.Log; import com.android.internal.util.Preconditions; import java.io.IOException; import java.util.Objects; /** * Entry point for "factory reset" requests. */ final class FactoryResetter { public final class FactoryResetter { private static final String TAG = FactoryResetter.class.getSimpleName(); // TODO(b/171603586): use an object that's constructed with a Builder instead (then update // javadoc) private final Context mContext; private final @Nullable String mReason; private final boolean mShutdown; private final boolean mForce; private final boolean mWipeEuicc; private final boolean mWipeAdoptableStorage; private final boolean mWipeFactoryResetProtection; /** * Factory reset the device. * Factory reset the device according to the builder's arguments. */ public static void factoryReset(Context context, boolean shutdown, String reason, boolean force, boolean wipeEuicc, boolean wipeAdoptableStorage, boolean wipeFactoryResetProtection) throws IOException { Log.i(TAG, "factoryReset(): shutdown=" + shutdown + ", force=" + force + ", wipeEuicc=" + wipeEuicc + ", wipeAdoptableStorage=" + wipeAdoptableStorage + ", wipeFRP=" + wipeFactoryResetProtection); Preconditions.checkCallAuthorization(context.checkCallingOrSelfPermission( public void factoryReset() throws IOException { Log.i(TAG, String.format("factoryReset(): reason=%s, shutdown=%b, force=%b, wipeEuicc=%b" + ", wipeAdoptableStorage=%b, wipeFRP=%b", mReason, mShutdown, mForce, mWipeEuicc, mWipeAdoptableStorage, mWipeFactoryResetProtection)); Preconditions.checkCallAuthorization(mContext.checkCallingOrSelfPermission( android.Manifest.permission.MASTER_CLEAR) == PackageManager.PERMISSION_GRANTED); UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE); if (!force && um.hasUserRestriction(UserManager.DISALLOW_FACTORY_RESET)) { UserManager um = mContext.getSystemService(UserManager.class); if (!mForce && um.hasUserRestriction(UserManager.DISALLOW_FACTORY_RESET)) { throw new SecurityException("Factory reset is not allowed for this user."); } if (wipeFactoryResetProtection) { PersistentDataBlockManager manager = (PersistentDataBlockManager) context.getSystemService(Context.PERSISTENT_DATA_BLOCK_SERVICE); if (mWipeFactoryResetProtection) { PersistentDataBlockManager manager = mContext .getSystemService(PersistentDataBlockManager.class); if (manager != null) { Log.w(TAG, "Wiping factory reset protection"); manager.wipe(); Loading @@ -66,17 +73,104 @@ final class FactoryResetter { } } if (wipeAdoptableStorage) { if (mWipeAdoptableStorage) { Log.w(TAG, "Wiping adoptable storage"); StorageManager sm = (StorageManager) context.getSystemService( Context.STORAGE_SERVICE); StorageManager sm = mContext.getSystemService(StorageManager.class); sm.wipeAdoptableDisks(); } RecoverySystem.rebootWipeUserData(context, shutdown, reason, force, wipeEuicc); RecoverySystem.rebootWipeUserData(mContext, mShutdown, mReason, mForce, mWipeEuicc); } private FactoryResetter(Builder builder) { mContext = builder.mContext; mShutdown = builder.mShutdown; mReason = builder.mReason; mForce = builder.mForce; mWipeEuicc = builder.mWipeEuicc; mWipeAdoptableStorage = builder.mWipeAdoptableStorage; mWipeFactoryResetProtection = builder.mWipeFactoryResetProtection; } /** * Creates a new builder. */ public static Builder newBuilder(Context context) { return new Builder(context); } /** * Builder for {@link FactoryResetter} instances. */ public static final class Builder { private final Context mContext; private @Nullable String mReason; private boolean mShutdown; private boolean mForce; private boolean mWipeEuicc; private boolean mWipeAdoptableStorage; private boolean mWipeFactoryResetProtection; private Builder(Context context) { mContext = Objects.requireNonNull(context); } /** * Sets the (non-null) reason for the factory reset that is visible in the logs */ public Builder setReason(String reason) { mReason = Objects.requireNonNull(reason); return this; } /** * Sets whether the device will be powered down after the wipe completes, rather than being * rebooted back to the regular system. */ public Builder setShutdown(boolean value) { mShutdown = value; return this; } /** * Sets whether the {@link UserManager.DISALLOW_FACTORY_RESET} user restriction should be * ignored. */ public Builder setForce(boolean value) { mForce = value; return this; } private FactoryResetter() { throw new UnsupportedOperationException("Contains only static methods"); /** * Sets whether to wipe the {@code euicc} data. */ public Builder setWipeEuicc(boolean value) { mWipeEuicc = value; return this; } /** * Sets whether to wipe the adoptable external storage (if any). */ public Builder setWipeAdoptableStorage(boolean value) { mWipeAdoptableStorage = value; return this; } /** * Sets whether to reset the factory reset protection. */ public Builder setWipeFactoryResetProtection(boolean value) { mWipeFactoryResetProtection = value; return this; } /** * Builds the {@link FactoryResetter} instance. */ public FactoryResetter build() { return new FactoryResetter(this); } } } services/tests/mockingservicestests/src/com/android/server/devicepolicy/FactoryResetterTest.java +82 −65 Original line number Diff line number Diff line Loading @@ -50,18 +50,7 @@ public final class FactoryResetterTest { private static final String TAG = FactoryResetterTest.class.getSimpleName(); // Fixed parameters private static final String REASON = "self-destruct"; private static final boolean SHUTDOWN = true; private static final boolean WIPE_EUICC = true; // Parameters under test private static final boolean FORCE = true; private static final boolean NO_FORCE = false; private static final boolean WIPE_ADOPTABLE_STORAGE = true; private static final boolean NO_WIPE_ADOPTABLE_STORAGE = false; private static final boolean WIPE_FACTORY_RESET_PROTECTION = true; private static final boolean NO_WIPE_FACTORY_RESET_PROTECTION = false; private MockitoSession mSession; Loading @@ -78,19 +67,13 @@ public final class FactoryResetterTest { .strictness(Strictness.LENIENT) .startMocking(); when(mContext.getSystemService(any(String.class))).thenAnswer((inv) -> { when(mContext.getSystemService(any(Class.class))).thenAnswer((inv) -> { Log.d(TAG, "Mocking " + inv); String service = (String) inv.getArguments()[0]; switch (service) { case Context.PERSISTENT_DATA_BLOCK_SERVICE: return mPdbm; case Context.STORAGE_SERVICE: return mSm; case Context.USER_SERVICE: return mUm; default: throw new IllegalArgumentException("Not expecting call for " + service); } Class serviceClass = (Class) inv.getArguments()[0]; if (serviceClass.equals(PersistentDataBlockManager.class)) return mPdbm; if (serviceClass.equals(StorageManager.class)) return mSm; if (serviceClass.equals(UserManager.class)) return mUm; throw new IllegalArgumentException("Not expecting call for " + serviceClass); }); doAnswer((inv) -> { Loading @@ -110,13 +93,23 @@ public final class FactoryResetterTest { } @Test public void testFactoryReset_noMasterClearPermission() throws Exception { public void testFactoryResetBuilder_nullContext() throws Exception { assertThrows(NullPointerException.class, () -> FactoryResetter.newBuilder(null)); } @Test public void testFactoryResetBuilder_nullReason() throws Exception { assertThrows(NullPointerException.class, () -> FactoryResetter.newBuilder(mContext).setReason(null)); } @Test public void testFactoryReset_minimumArgs_noMasterClearPermission() throws Exception { revokeMasterClearPermission(); setFactoryResetRestriction(/* allowed= */ true); allowFactoryReset(); assertThrows(SecurityException.class, () -> FactoryResetter.factoryReset(mContext, SHUTDOWN, REASON, NO_FORCE, WIPE_EUICC, WIPE_ADOPTABLE_STORAGE, WIPE_FACTORY_RESET_PROTECTION)); () -> FactoryResetter.newBuilder(mContext).build().factoryReset()); verifyWipeAdoptableStorageNotCalled(); verifyWipeFactoryResetProtectionNotCalled(); Loading @@ -124,13 +117,11 @@ public final class FactoryResetterTest { } @Test public void testFactoryReset_noForceDisallowed() throws Exception { setFactoryResetRestriction(/* allowed= */ false); public void testFactoryReset_minimumArgs_withRestriction_notForced() throws Exception { disallowFactoryReset(); assertThrows(SecurityException.class, () -> FactoryResetter.factoryReset(mContext, SHUTDOWN, REASON, NO_FORCE, WIPE_EUICC, WIPE_ADOPTABLE_STORAGE, WIPE_FACTORY_RESET_PROTECTION)); () -> FactoryResetter.newBuilder(mContext).build().factoryReset()); verifyWipeAdoptableStorageNotCalled(); verifyWipeFactoryResetProtectionNotCalled(); Loading @@ -138,57 +129,69 @@ public final class FactoryResetterTest { } @Test public void testFactoryReset_noForceAllowed() throws Exception { setFactoryResetRestriction(/* allowed= */ true); public void testFactoryReset_minimumArgs_noRestriction_notForced() throws Exception { allowFactoryReset(); FactoryResetter.factoryReset(mContext, SHUTDOWN, REASON, NO_FORCE, WIPE_EUICC, WIPE_ADOPTABLE_STORAGE, WIPE_FACTORY_RESET_PROTECTION); FactoryResetter.newBuilder(mContext).build().factoryReset(); verifyWipeAdoptableStorageCalled(); verifyWipeFactoryResetProtectionCalled(); verifyRebootWipeUserDataCalled(NO_FORCE); verifyWipeAdoptableStorageNotCalled(); verifyWipeFactoryResetProtectionNotCalled(); verifyRebootWipeUserDataMinimumArgsCalled(); } @Test public void testFactoryReset_forceDisallowed() throws Exception { setFactoryResetRestriction(/* allowed= */ false); FactoryResetter.factoryReset(mContext, SHUTDOWN, REASON, FORCE, WIPE_EUICC, WIPE_ADOPTABLE_STORAGE, WIPE_FACTORY_RESET_PROTECTION); verifyWipeAdoptableStorageCalled(); verifyWipeFactoryResetProtectionCalled(); verifyRebootWipeUserDataCalled(FORCE); } public void testFactoryReset_minimumArgs_withRestriction_forced() throws Exception { disallowFactoryReset(); @Test public void testFactoryReset_bothFalse() throws Exception { FactoryResetter.factoryReset(mContext, SHUTDOWN, REASON, FORCE, WIPE_EUICC, NO_WIPE_ADOPTABLE_STORAGE, NO_WIPE_FACTORY_RESET_PROTECTION); FactoryResetter.newBuilder(mContext).setForce(true).build().factoryReset(); verifyWipeAdoptableStorageNotCalled(); verifyWipeFactoryResetProtectionNotCalled(); verifyRebootWipeUserDataCalled(FORCE); verifyRebootWipeUserDataMinimumArgsButForceCalled(); } @Test public void testFactoryReset_storageOnly() throws Exception { FactoryResetter.factoryReset(mContext, SHUTDOWN, REASON, FORCE, WIPE_EUICC, WIPE_ADOPTABLE_STORAGE, NO_WIPE_FACTORY_RESET_PROTECTION); allowFactoryReset(); FactoryResetter.newBuilder(mContext) .setWipeAdoptableStorage(true).build() .factoryReset(); verifyWipeAdoptableStorageCalled(); verifyWipeFactoryResetProtectionNotCalled(); verifyRebootWipeUserDataCalled(FORCE); verifyRebootWipeUserDataMinimumArgsCalled(); } @Test public void testFactoryReset_frpOnly() throws Exception { FactoryResetter.factoryReset(mContext, SHUTDOWN, REASON, FORCE, WIPE_EUICC, NO_WIPE_ADOPTABLE_STORAGE, WIPE_FACTORY_RESET_PROTECTION); allowFactoryReset(); FactoryResetter.newBuilder(mContext) .setWipeFactoryResetProtection(true) .build().factoryReset(); verifyWipeAdoptableStorageNotCalled(); verifyWipeFactoryResetProtectionCalled(); verifyRebootWipeUserDataCalled(FORCE); verifyRebootWipeUserDataMinimumArgsCalled(); } @Test public void testFactoryReset_allArgs() throws Exception { allowFactoryReset(); FactoryResetter.newBuilder(mContext) .setReason(REASON) .setForce(true) .setShutdown(true) .setWipeEuicc(true) .setWipeAdoptableStorage(true) .setWipeFactoryResetProtection(true) .build().factoryReset(); verifyWipeAdoptableStorageCalled(); verifyWipeFactoryResetProtectionCalled(); verifyRebootWipeUserDataAllArgsCalled(); } private void revokeMasterClearPermission() { Loading @@ -196,8 +199,12 @@ public final class FactoryResetterTest { .thenReturn(PackageManager.PERMISSION_DENIED); } private void setFactoryResetRestriction(boolean allowed) { when(mUm.hasUserRestriction(UserManager.DISALLOW_FACTORY_RESET)).thenReturn(!allowed); private void allowFactoryReset() { when(mUm.hasUserRestriction(UserManager.DISALLOW_FACTORY_RESET)).thenReturn(false); } private void disallowFactoryReset() { when(mUm.hasUserRestriction(UserManager.DISALLOW_FACTORY_RESET)).thenReturn(true); } private void verifyRebootWipeUserDataNotCalled() { Loading @@ -205,9 +212,19 @@ public final class FactoryResetterTest { anyBoolean()), never()); } private void verifyRebootWipeUserDataCalled(boolean force) { verify(() -> RecoverySystem.rebootWipeUserData(mContext, SHUTDOWN, REASON, force, WIPE_EUICC)); private void verifyRebootWipeUserDataMinimumArgsCalled() { verify(() -> RecoverySystem.rebootWipeUserData(mContext, /* shutdown= */ false, /* reason= */ null, /* force= */ false, /* wipeEuicc= */ false)); } private void verifyRebootWipeUserDataMinimumArgsButForceCalled() { verify(() -> RecoverySystem.rebootWipeUserData(mContext, /* shutdown= */ false, /* reason= */ null, /* force= */ true, /* wipeEuicc= */ false)); } private void verifyRebootWipeUserDataAllArgsCalled() { verify(() -> RecoverySystem.rebootWipeUserData(mContext, /* shutdown= */ true, /* reason= */ REASON, /* force= */ true, /* wipeEuicc= */ true)); } private void verifyWipeAdoptableStorageNotCalled() { Loading Loading
services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +6 −5 Original line number Diff line number Diff line Loading @@ -1032,9 +1032,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { Slog.w(LOG_TAG, "factoryReset(): " + reason); final long identity = Binder.clearCallingIdentity(); try { FactoryResetter.factoryReset(mContext, /* shutdown= */ false, reason, /* force= */ false, /* wipeEuicc= */ false, /* wipeAdoptableStorage= */ false, /* wipeFactoryResetProtection= */ false); FactoryResetter.newBuilder(mContext).setReason(reason).build().factoryReset(); } catch (IOException e) { // Shouldn't happen. Slog.wtf(LOG_TAG, "Could not factory reset", e); Loading Loading @@ -1295,8 +1293,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { void recoverySystemRebootWipeUserData(boolean shutdown, String reason, boolean force, boolean wipeEuicc, boolean wipeExtRequested, boolean wipeResetProtectionData) throws IOException { FactoryResetter.factoryReset(mContext, shutdown, reason, force, wipeEuicc, wipeExtRequested, wipeResetProtectionData); FactoryResetter.newBuilder(mContext).setReason(reason).setShutdown(shutdown) .setForce(force).setWipeEuicc(wipeEuicc) .setWipeAdoptableStorage(wipeExtRequested) .setWipeFactoryResetProtection(wipeResetProtectionData) .build().factoryReset(); } boolean systemPropertiesGetBoolean(String key, boolean def) { Loading
services/devicepolicy/java/com/android/server/devicepolicy/FactoryResetter.java +117 −23 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.devicepolicy; import android.annotation.Nullable; import android.content.Context; import android.content.pm.PackageManager; import android.os.RecoverySystem; Loading @@ -27,37 +28,43 @@ import android.util.Log; import com.android.internal.util.Preconditions; import java.io.IOException; import java.util.Objects; /** * Entry point for "factory reset" requests. */ final class FactoryResetter { public final class FactoryResetter { private static final String TAG = FactoryResetter.class.getSimpleName(); // TODO(b/171603586): use an object that's constructed with a Builder instead (then update // javadoc) private final Context mContext; private final @Nullable String mReason; private final boolean mShutdown; private final boolean mForce; private final boolean mWipeEuicc; private final boolean mWipeAdoptableStorage; private final boolean mWipeFactoryResetProtection; /** * Factory reset the device. * Factory reset the device according to the builder's arguments. */ public static void factoryReset(Context context, boolean shutdown, String reason, boolean force, boolean wipeEuicc, boolean wipeAdoptableStorage, boolean wipeFactoryResetProtection) throws IOException { Log.i(TAG, "factoryReset(): shutdown=" + shutdown + ", force=" + force + ", wipeEuicc=" + wipeEuicc + ", wipeAdoptableStorage=" + wipeAdoptableStorage + ", wipeFRP=" + wipeFactoryResetProtection); Preconditions.checkCallAuthorization(context.checkCallingOrSelfPermission( public void factoryReset() throws IOException { Log.i(TAG, String.format("factoryReset(): reason=%s, shutdown=%b, force=%b, wipeEuicc=%b" + ", wipeAdoptableStorage=%b, wipeFRP=%b", mReason, mShutdown, mForce, mWipeEuicc, mWipeAdoptableStorage, mWipeFactoryResetProtection)); Preconditions.checkCallAuthorization(mContext.checkCallingOrSelfPermission( android.Manifest.permission.MASTER_CLEAR) == PackageManager.PERMISSION_GRANTED); UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE); if (!force && um.hasUserRestriction(UserManager.DISALLOW_FACTORY_RESET)) { UserManager um = mContext.getSystemService(UserManager.class); if (!mForce && um.hasUserRestriction(UserManager.DISALLOW_FACTORY_RESET)) { throw new SecurityException("Factory reset is not allowed for this user."); } if (wipeFactoryResetProtection) { PersistentDataBlockManager manager = (PersistentDataBlockManager) context.getSystemService(Context.PERSISTENT_DATA_BLOCK_SERVICE); if (mWipeFactoryResetProtection) { PersistentDataBlockManager manager = mContext .getSystemService(PersistentDataBlockManager.class); if (manager != null) { Log.w(TAG, "Wiping factory reset protection"); manager.wipe(); Loading @@ -66,17 +73,104 @@ final class FactoryResetter { } } if (wipeAdoptableStorage) { if (mWipeAdoptableStorage) { Log.w(TAG, "Wiping adoptable storage"); StorageManager sm = (StorageManager) context.getSystemService( Context.STORAGE_SERVICE); StorageManager sm = mContext.getSystemService(StorageManager.class); sm.wipeAdoptableDisks(); } RecoverySystem.rebootWipeUserData(context, shutdown, reason, force, wipeEuicc); RecoverySystem.rebootWipeUserData(mContext, mShutdown, mReason, mForce, mWipeEuicc); } private FactoryResetter(Builder builder) { mContext = builder.mContext; mShutdown = builder.mShutdown; mReason = builder.mReason; mForce = builder.mForce; mWipeEuicc = builder.mWipeEuicc; mWipeAdoptableStorage = builder.mWipeAdoptableStorage; mWipeFactoryResetProtection = builder.mWipeFactoryResetProtection; } /** * Creates a new builder. */ public static Builder newBuilder(Context context) { return new Builder(context); } /** * Builder for {@link FactoryResetter} instances. */ public static final class Builder { private final Context mContext; private @Nullable String mReason; private boolean mShutdown; private boolean mForce; private boolean mWipeEuicc; private boolean mWipeAdoptableStorage; private boolean mWipeFactoryResetProtection; private Builder(Context context) { mContext = Objects.requireNonNull(context); } /** * Sets the (non-null) reason for the factory reset that is visible in the logs */ public Builder setReason(String reason) { mReason = Objects.requireNonNull(reason); return this; } /** * Sets whether the device will be powered down after the wipe completes, rather than being * rebooted back to the regular system. */ public Builder setShutdown(boolean value) { mShutdown = value; return this; } /** * Sets whether the {@link UserManager.DISALLOW_FACTORY_RESET} user restriction should be * ignored. */ public Builder setForce(boolean value) { mForce = value; return this; } private FactoryResetter() { throw new UnsupportedOperationException("Contains only static methods"); /** * Sets whether to wipe the {@code euicc} data. */ public Builder setWipeEuicc(boolean value) { mWipeEuicc = value; return this; } /** * Sets whether to wipe the adoptable external storage (if any). */ public Builder setWipeAdoptableStorage(boolean value) { mWipeAdoptableStorage = value; return this; } /** * Sets whether to reset the factory reset protection. */ public Builder setWipeFactoryResetProtection(boolean value) { mWipeFactoryResetProtection = value; return this; } /** * Builds the {@link FactoryResetter} instance. */ public FactoryResetter build() { return new FactoryResetter(this); } } }
services/tests/mockingservicestests/src/com/android/server/devicepolicy/FactoryResetterTest.java +82 −65 Original line number Diff line number Diff line Loading @@ -50,18 +50,7 @@ public final class FactoryResetterTest { private static final String TAG = FactoryResetterTest.class.getSimpleName(); // Fixed parameters private static final String REASON = "self-destruct"; private static final boolean SHUTDOWN = true; private static final boolean WIPE_EUICC = true; // Parameters under test private static final boolean FORCE = true; private static final boolean NO_FORCE = false; private static final boolean WIPE_ADOPTABLE_STORAGE = true; private static final boolean NO_WIPE_ADOPTABLE_STORAGE = false; private static final boolean WIPE_FACTORY_RESET_PROTECTION = true; private static final boolean NO_WIPE_FACTORY_RESET_PROTECTION = false; private MockitoSession mSession; Loading @@ -78,19 +67,13 @@ public final class FactoryResetterTest { .strictness(Strictness.LENIENT) .startMocking(); when(mContext.getSystemService(any(String.class))).thenAnswer((inv) -> { when(mContext.getSystemService(any(Class.class))).thenAnswer((inv) -> { Log.d(TAG, "Mocking " + inv); String service = (String) inv.getArguments()[0]; switch (service) { case Context.PERSISTENT_DATA_BLOCK_SERVICE: return mPdbm; case Context.STORAGE_SERVICE: return mSm; case Context.USER_SERVICE: return mUm; default: throw new IllegalArgumentException("Not expecting call for " + service); } Class serviceClass = (Class) inv.getArguments()[0]; if (serviceClass.equals(PersistentDataBlockManager.class)) return mPdbm; if (serviceClass.equals(StorageManager.class)) return mSm; if (serviceClass.equals(UserManager.class)) return mUm; throw new IllegalArgumentException("Not expecting call for " + serviceClass); }); doAnswer((inv) -> { Loading @@ -110,13 +93,23 @@ public final class FactoryResetterTest { } @Test public void testFactoryReset_noMasterClearPermission() throws Exception { public void testFactoryResetBuilder_nullContext() throws Exception { assertThrows(NullPointerException.class, () -> FactoryResetter.newBuilder(null)); } @Test public void testFactoryResetBuilder_nullReason() throws Exception { assertThrows(NullPointerException.class, () -> FactoryResetter.newBuilder(mContext).setReason(null)); } @Test public void testFactoryReset_minimumArgs_noMasterClearPermission() throws Exception { revokeMasterClearPermission(); setFactoryResetRestriction(/* allowed= */ true); allowFactoryReset(); assertThrows(SecurityException.class, () -> FactoryResetter.factoryReset(mContext, SHUTDOWN, REASON, NO_FORCE, WIPE_EUICC, WIPE_ADOPTABLE_STORAGE, WIPE_FACTORY_RESET_PROTECTION)); () -> FactoryResetter.newBuilder(mContext).build().factoryReset()); verifyWipeAdoptableStorageNotCalled(); verifyWipeFactoryResetProtectionNotCalled(); Loading @@ -124,13 +117,11 @@ public final class FactoryResetterTest { } @Test public void testFactoryReset_noForceDisallowed() throws Exception { setFactoryResetRestriction(/* allowed= */ false); public void testFactoryReset_minimumArgs_withRestriction_notForced() throws Exception { disallowFactoryReset(); assertThrows(SecurityException.class, () -> FactoryResetter.factoryReset(mContext, SHUTDOWN, REASON, NO_FORCE, WIPE_EUICC, WIPE_ADOPTABLE_STORAGE, WIPE_FACTORY_RESET_PROTECTION)); () -> FactoryResetter.newBuilder(mContext).build().factoryReset()); verifyWipeAdoptableStorageNotCalled(); verifyWipeFactoryResetProtectionNotCalled(); Loading @@ -138,57 +129,69 @@ public final class FactoryResetterTest { } @Test public void testFactoryReset_noForceAllowed() throws Exception { setFactoryResetRestriction(/* allowed= */ true); public void testFactoryReset_minimumArgs_noRestriction_notForced() throws Exception { allowFactoryReset(); FactoryResetter.factoryReset(mContext, SHUTDOWN, REASON, NO_FORCE, WIPE_EUICC, WIPE_ADOPTABLE_STORAGE, WIPE_FACTORY_RESET_PROTECTION); FactoryResetter.newBuilder(mContext).build().factoryReset(); verifyWipeAdoptableStorageCalled(); verifyWipeFactoryResetProtectionCalled(); verifyRebootWipeUserDataCalled(NO_FORCE); verifyWipeAdoptableStorageNotCalled(); verifyWipeFactoryResetProtectionNotCalled(); verifyRebootWipeUserDataMinimumArgsCalled(); } @Test public void testFactoryReset_forceDisallowed() throws Exception { setFactoryResetRestriction(/* allowed= */ false); FactoryResetter.factoryReset(mContext, SHUTDOWN, REASON, FORCE, WIPE_EUICC, WIPE_ADOPTABLE_STORAGE, WIPE_FACTORY_RESET_PROTECTION); verifyWipeAdoptableStorageCalled(); verifyWipeFactoryResetProtectionCalled(); verifyRebootWipeUserDataCalled(FORCE); } public void testFactoryReset_minimumArgs_withRestriction_forced() throws Exception { disallowFactoryReset(); @Test public void testFactoryReset_bothFalse() throws Exception { FactoryResetter.factoryReset(mContext, SHUTDOWN, REASON, FORCE, WIPE_EUICC, NO_WIPE_ADOPTABLE_STORAGE, NO_WIPE_FACTORY_RESET_PROTECTION); FactoryResetter.newBuilder(mContext).setForce(true).build().factoryReset(); verifyWipeAdoptableStorageNotCalled(); verifyWipeFactoryResetProtectionNotCalled(); verifyRebootWipeUserDataCalled(FORCE); verifyRebootWipeUserDataMinimumArgsButForceCalled(); } @Test public void testFactoryReset_storageOnly() throws Exception { FactoryResetter.factoryReset(mContext, SHUTDOWN, REASON, FORCE, WIPE_EUICC, WIPE_ADOPTABLE_STORAGE, NO_WIPE_FACTORY_RESET_PROTECTION); allowFactoryReset(); FactoryResetter.newBuilder(mContext) .setWipeAdoptableStorage(true).build() .factoryReset(); verifyWipeAdoptableStorageCalled(); verifyWipeFactoryResetProtectionNotCalled(); verifyRebootWipeUserDataCalled(FORCE); verifyRebootWipeUserDataMinimumArgsCalled(); } @Test public void testFactoryReset_frpOnly() throws Exception { FactoryResetter.factoryReset(mContext, SHUTDOWN, REASON, FORCE, WIPE_EUICC, NO_WIPE_ADOPTABLE_STORAGE, WIPE_FACTORY_RESET_PROTECTION); allowFactoryReset(); FactoryResetter.newBuilder(mContext) .setWipeFactoryResetProtection(true) .build().factoryReset(); verifyWipeAdoptableStorageNotCalled(); verifyWipeFactoryResetProtectionCalled(); verifyRebootWipeUserDataCalled(FORCE); verifyRebootWipeUserDataMinimumArgsCalled(); } @Test public void testFactoryReset_allArgs() throws Exception { allowFactoryReset(); FactoryResetter.newBuilder(mContext) .setReason(REASON) .setForce(true) .setShutdown(true) .setWipeEuicc(true) .setWipeAdoptableStorage(true) .setWipeFactoryResetProtection(true) .build().factoryReset(); verifyWipeAdoptableStorageCalled(); verifyWipeFactoryResetProtectionCalled(); verifyRebootWipeUserDataAllArgsCalled(); } private void revokeMasterClearPermission() { Loading @@ -196,8 +199,12 @@ public final class FactoryResetterTest { .thenReturn(PackageManager.PERMISSION_DENIED); } private void setFactoryResetRestriction(boolean allowed) { when(mUm.hasUserRestriction(UserManager.DISALLOW_FACTORY_RESET)).thenReturn(!allowed); private void allowFactoryReset() { when(mUm.hasUserRestriction(UserManager.DISALLOW_FACTORY_RESET)).thenReturn(false); } private void disallowFactoryReset() { when(mUm.hasUserRestriction(UserManager.DISALLOW_FACTORY_RESET)).thenReturn(true); } private void verifyRebootWipeUserDataNotCalled() { Loading @@ -205,9 +212,19 @@ public final class FactoryResetterTest { anyBoolean()), never()); } private void verifyRebootWipeUserDataCalled(boolean force) { verify(() -> RecoverySystem.rebootWipeUserData(mContext, SHUTDOWN, REASON, force, WIPE_EUICC)); private void verifyRebootWipeUserDataMinimumArgsCalled() { verify(() -> RecoverySystem.rebootWipeUserData(mContext, /* shutdown= */ false, /* reason= */ null, /* force= */ false, /* wipeEuicc= */ false)); } private void verifyRebootWipeUserDataMinimumArgsButForceCalled() { verify(() -> RecoverySystem.rebootWipeUserData(mContext, /* shutdown= */ false, /* reason= */ null, /* force= */ true, /* wipeEuicc= */ false)); } private void verifyRebootWipeUserDataAllArgsCalled() { verify(() -> RecoverySystem.rebootWipeUserData(mContext, /* shutdown= */ true, /* reason= */ REASON, /* force= */ true, /* wipeEuicc= */ true)); } private void verifyWipeAdoptableStorageNotCalled() { Loading