Merge "Revert "Persist delayed calls to factory reset...""

This commit is contained in:
Rick Yiu
2021-01-13 09:41:06 +00:00
committed by Android (Google) Code Review
6 changed files with 16 additions and 170 deletions

View File

@@ -16,7 +16,6 @@
package com.android.server.devicepolicy;
import android.annotation.NonNull;
import android.annotation.UserIdInt;
import android.app.admin.DeviceAdminInfo;
import android.app.admin.DevicePolicyManager;
@@ -25,7 +24,6 @@ import android.os.FileUtils;
import android.os.PersistableBundle;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.DebugUtils;
import android.util.IndentingPrintWriter;
import android.util.Slog;
import android.util.TypedXmlPullParser;
@@ -87,15 +85,6 @@ class DevicePolicyData {
static final String NEW_USER_DISCLAIMER_NOT_NEEDED = "not_needed";
static final String NEW_USER_DISCLAIMER_NEEDED = "needed";
private static final String ATTR_FACTORY_RESET_FLAGS = "factory-reset-flags";
private static final String ATTR_FACTORY_RESET_REASON = "factory-reset-reason";
// NOTE: must be public because of DebugUtils.flagsToString()
public static final int FACTORY_RESET_FLAG_ON_BOOT = 1;
public static final int FACTORY_RESET_FLAG_WIPE_EXTERNAL_STORAGE = 2;
public static final int FACTORY_RESET_FLAG_WIPE_EUICC = 4;
public static final int FACTORY_RESET_FLAG_WIPE_FACTORY_RESET_PROTECTION = 8;
private static final String TAG = DevicePolicyManagerService.LOG_TAG;
private static final boolean VERBOSE_LOG = false; // DO NOT SUBMIT WITH TRUE
@@ -110,9 +99,6 @@ class DevicePolicyData {
int mUserProvisioningState;
int mPermissionPolicy;
int mFactoryResetFlags;
String mFactoryResetReason;
boolean mDeviceProvisioningConfigApplied = false;
final ArrayMap<ComponentName, ActiveAdmin> mAdminMap = new ArrayMap<>();
@@ -214,17 +200,6 @@ class DevicePolicyData {
out.attribute(null, ATTR_NEW_USER_DISCLAIMER, policyData.mNewUserDisclaimer);
}
if (policyData.mFactoryResetFlags != 0) {
if (VERBOSE_LOG) {
Slog.v(TAG, "Storing factory reset flags for user " + policyData.mUserId + ": "
+ factoryResetFlagsToString(policyData.mFactoryResetFlags));
}
out.attributeInt(null, ATTR_FACTORY_RESET_FLAGS, policyData.mFactoryResetFlags);
}
if (policyData.mFactoryResetReason != null) {
out.attribute(null, ATTR_FACTORY_RESET_REASON, policyData.mFactoryResetReason);
}
// Serialize delegations.
for (int i = 0; i < policyData.mDelegationMap.size(); ++i) {
final String delegatePackage = policyData.mDelegationMap.keyAt(i);
@@ -452,14 +427,6 @@ class DevicePolicyData {
}
policy.mNewUserDisclaimer = parser.getAttributeValue(null, ATTR_NEW_USER_DISCLAIMER);
policy.mFactoryResetFlags = parser.getAttributeInt(null, ATTR_FACTORY_RESET_FLAGS, 0);
if (VERBOSE_LOG) {
Slog.v(TAG, "Restored factory reset flags for user " + policy.mUserId + ": "
+ factoryResetFlagsToString(policy.mFactoryResetFlags));
}
policy.mFactoryResetReason = parser.getAttributeValue(null, ATTR_FACTORY_RESET_REASON);
parser.next();
int outerDepth = parser.getDepth();
policy.mLockTaskPackages.clear();
policy.mAdminList.clear();
@@ -605,22 +572,6 @@ class DevicePolicyData {
}
}
void setDelayedFactoryReset(@NonNull String reason, boolean wipeExtRequested, boolean wipeEuicc,
boolean wipeResetProtectionData) {
mFactoryResetReason = reason;
mFactoryResetFlags = FACTORY_RESET_FLAG_ON_BOOT;
if (wipeExtRequested) {
mFactoryResetFlags |= FACTORY_RESET_FLAG_WIPE_EXTERNAL_STORAGE;
}
if (wipeEuicc) {
mFactoryResetFlags |= FACTORY_RESET_FLAG_WIPE_EUICC;
}
if (wipeResetProtectionData) {
mFactoryResetFlags |= FACTORY_RESET_FLAG_WIPE_FACTORY_RESET_PROTECTION;
}
}
void dump(IndentingPrintWriter pw) {
pw.println();
pw.println("Enabled Device Admins (User " + mUserId + ", provisioningState: "
@@ -652,19 +603,6 @@ class DevicePolicyData {
pw.print("mUserSetupComplete="); pw.println(mUserSetupComplete);
pw.print("mAffiliationIds="); pw.println(mAffiliationIds);
pw.print("mNewUserDisclaimer="); pw.println(mNewUserDisclaimer);
if (mFactoryResetFlags != 0) {
pw.print("mFactoryResetFlags="); pw.print(mFactoryResetFlags);
pw.print(" (");
pw.print(factoryResetFlagsToString(mFactoryResetFlags));
pw.println(')');
}
if (mFactoryResetReason != null) {
pw.print("mFactoryResetReason="); pw.println(mFactoryResetReason);
}
pw.decreaseIndent();
}
static String factoryResetFlagsToString(int flags) {
return DebugUtils.flagsToString(DevicePolicyData.class, "FACTORY_RESET_FLAG_", flags);
}
}

View File

@@ -1317,11 +1317,12 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
mContext.getSystemService(PowerManager.class).reboot(reason);
}
boolean recoverySystemRebootWipeUserData(boolean shutdown, String reason, boolean force,
void recoverySystemRebootWipeUserData(boolean shutdown, String reason, boolean force,
boolean wipeEuicc, boolean wipeExtRequested, boolean wipeResetProtectionData)
throws IOException {
return FactoryResetter.newBuilder(mContext).setSafetyChecker(mSafetyChecker)
.setReason(reason).setShutdown(shutdown).setForce(force).setWipeEuicc(wipeEuicc)
FactoryResetter.newBuilder(mContext).setSafetyChecker(mSafetyChecker)
.setReason(reason).setShutdown(shutdown)
.setForce(force).setWipeEuicc(wipeEuicc)
.setWipeAdoptableStorage(wipeExtRequested)
.setWipeFactoryResetProtection(wipeResetProtectionData)
.build().factoryReset();
@@ -2783,10 +2784,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
maybeStartSecurityLogMonitorOnActivityManagerReady();
break;
case SystemService.PHASE_BOOT_COMPLETED:
// Ideally it should be done earlier, but currently it relies on RecoverySystem,
// which would hang on earlier phases
factoryResetIfDelayedEarlier();
ensureDeviceOwnerUserStarted(); // TODO Consider better place to do this.
break;
}
@@ -6220,24 +6217,10 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
boolean wipeResetProtectionData) {
wtfIfInLock();
boolean success = false;
try {
boolean delayed = !mInjector.recoverySystemRebootWipeUserData(
mInjector.recoverySystemRebootWipeUserData(
/* shutdown= */ false, reason, /* force= */ true, /* wipeEuicc= */ wipeEuicc,
wipeExtRequested, wipeResetProtectionData);
if (delayed) {
// Persist the request so the device is automatically factory-reset on next start if
// the system crashes or reboots before the {@code DevicePolicySafetyChecker} calls
// its callback.
Slog.i(LOG_TAG, String.format("Persisting factory reset request as it could be "
+ "delayed by %s", mSafetyChecker));
synchronized (getLockObject()) {
DevicePolicyData policy = getUserData(UserHandle.USER_SYSTEM);
policy.setDelayedFactoryReset(reason, wipeExtRequested, wipeEuicc,
wipeResetProtectionData);
saveSettingsLocked(UserHandle.USER_SYSTEM);
}
}
success = true;
} catch (IOException | SecurityException e) {
Slog.w(LOG_TAG, "Failed requesting data wipe", e);
@@ -6246,40 +6229,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
}
}
private void factoryResetIfDelayedEarlier() {
synchronized (getLockObject()) {
DevicePolicyData policy = getUserData(UserHandle.USER_SYSTEM);
if (policy.mFactoryResetFlags == 0) return;
if (policy.mFactoryResetReason == null) {
// Shouldn't happen.
Slog.e(LOG_TAG, "no persisted reason for factory resetting");
policy.mFactoryResetReason = "requested before boot";
}
FactoryResetter factoryResetter = FactoryResetter.newBuilder(mContext)
.setReason(policy.mFactoryResetReason).setForce(true)
.setWipeEuicc((policy.mFactoryResetFlags & DevicePolicyData
.FACTORY_RESET_FLAG_WIPE_EUICC) != 0)
.setWipeAdoptableStorage((policy.mFactoryResetFlags & DevicePolicyData
.FACTORY_RESET_FLAG_WIPE_EXTERNAL_STORAGE) != 0)
.setWipeFactoryResetProtection((policy.mFactoryResetFlags & DevicePolicyData
.FACTORY_RESET_FLAG_WIPE_FACTORY_RESET_PROTECTION) != 0)
.build();
Slog.i(LOG_TAG, "Factory resetting on boot using " + factoryResetter);
try {
if (!factoryResetter.factoryReset()) {
// Shouldn't happen because FactoryResetter was created without a
// DevicePolicySafetyChecker.
Slog.wtf(LOG_TAG, "Factory reset using " + factoryResetter + " failed.");
}
} catch (IOException e) {
// Shouldn't happen.
Slog.wtf(LOG_TAG, "Could not factory reset using " + factoryResetter, e);
}
}
}
private void forceWipeUser(int userId, String wipeReasonForUser, boolean wipeSilently) {
boolean success = false;
try {

View File

@@ -52,17 +52,14 @@ public final class FactoryResetter {
/**
* Factory reset the device according to the builder's arguments.
*
* @return {@code true} if device was factory reset, or {@code false} if it was delayed by the
* {@link DevicePolicySafetyChecker}.
*/
public boolean factoryReset() throws IOException {
public void factoryReset() throws IOException {
Preconditions.checkCallAuthorization(mContext.checkCallingOrSelfPermission(
android.Manifest.permission.MASTER_CLEAR) == PackageManager.PERMISSION_GRANTED);
if (mSafetyChecker == null) {
factoryResetInternalUnchecked();
return true;
return;
}
IResultReceiver receiver = new IResultReceiver.Stub() {
@@ -80,36 +77,6 @@ public final class FactoryResetter {
};
Slog.i(TAG, String.format("Delaying factory reset until %s confirms", mSafetyChecker));
mSafetyChecker.onFactoryReset(receiver);
return false;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder("FactoryResetter[");
if (mReason == null) {
builder.append("no_reason");
} else {
builder.append("reason='").append(mReason).append("'");
}
if (mSafetyChecker != null) {
builder.append(",hasSafetyChecker");
}
if (mShutdown) {
builder.append(",shutdown");
}
if (mForce) {
builder.append(",force");
}
if (mWipeEuicc) {
builder.append(",wipeEuicc");
}
if (mWipeAdoptableStorage) {
builder.append(",wipeAdoptableStorage");
}
if (mWipeFactoryResetProtection) {
builder.append(",ipeFactoryResetProtection");
}
return builder.append(']').toString();
}
private void factoryResetInternalUnchecked() throws IOException {

View File

@@ -20,8 +20,6 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.Mockito.never;
@@ -160,11 +158,10 @@ public final class FactoryResetterTest {
public void testFactoryReset_storageOnly() throws Exception {
allowFactoryReset();
boolean success = FactoryResetter.newBuilder(mContext)
FactoryResetter.newBuilder(mContext)
.setWipeAdoptableStorage(true).build()
.factoryReset();
assertThat(success).isTrue();
verifyWipeAdoptableStorageCalled();
verifyWipeFactoryResetProtectionNotCalled();
verifyRebootWipeUserDataMinimumArgsCalled();
@@ -174,11 +171,10 @@ public final class FactoryResetterTest {
public void testFactoryReset_frpOnly() throws Exception {
allowFactoryReset();
boolean success = FactoryResetter.newBuilder(mContext)
FactoryResetter.newBuilder(mContext)
.setWipeFactoryResetProtection(true)
.build().factoryReset();
assertThat(success).isTrue();
verifyWipeAdoptableStorageNotCalled();
verifyWipeFactoryResetProtectionCalled();
verifyRebootWipeUserDataMinimumArgsCalled();
@@ -188,7 +184,7 @@ public final class FactoryResetterTest {
public void testFactoryReset_allArgs() throws Exception {
allowFactoryReset();
boolean success = FactoryResetter.newBuilder(mContext)
FactoryResetter.newBuilder(mContext)
.setReason(REASON)
.setForce(true)
.setShutdown(true)
@@ -197,7 +193,6 @@ public final class FactoryResetterTest {
.setWipeFactoryResetProtection(true)
.build().factoryReset();
assertThat(success).isTrue();
verifyWipeAdoptableStorageCalled();
verifyWipeFactoryResetProtectionCalled();
verifyRebootWipeUserDataAllArgsCalled();
@@ -207,10 +202,9 @@ public final class FactoryResetterTest {
public void testFactoryReset_minimumArgs_safetyChecker_neverReplied() throws Exception {
allowFactoryReset();
boolean success = FactoryResetter.newBuilder(mContext)
.setSafetyChecker(mSafetyChecker).build().factoryReset();
FactoryResetter.newBuilder(mContext).setSafetyChecker(mSafetyChecker).build()
.factoryReset();
assertThat(success).isFalse();
verifyWipeAdoptableStorageNotCalled();
verifyWipeFactoryResetProtectionNotCalled();
verifyRebootWipeUserDataNotCalled();
@@ -227,7 +221,7 @@ public final class FactoryResetterTest {
return null;
}).when(mSafetyChecker).onFactoryReset(any());
boolean success = FactoryResetter.newBuilder(mContext)
FactoryResetter.newBuilder(mContext)
.setSafetyChecker(mSafetyChecker)
.setReason(REASON)
.setForce(true)
@@ -237,7 +231,6 @@ public final class FactoryResetterTest {
.setWipeFactoryResetProtection(true)
.build().factoryReset();
assertThat(success).isFalse();
verifyWipeAdoptableStorageCalled();
verifyWipeFactoryResetProtectionCalled();
verifyRebootWipeUserDataAllArgsCalled();

View File

@@ -319,10 +319,10 @@ public class DevicePolicyManagerServiceTestable extends DevicePolicyManagerServi
}
@Override
boolean recoverySystemRebootWipeUserData(boolean shutdown, String reason, boolean force,
void recoverySystemRebootWipeUserData(boolean shutdown, String reason, boolean force,
boolean wipeEuicc, boolean wipeExtRequested, boolean wipeResetProtectionData)
throws IOException {
return services.recoverySystem.rebootWipeUserData(shutdown, reason, force, wipeEuicc,
services.recoverySystem.rebootWipeUserData(shutdown, reason, force, wipeEuicc,
wipeExtRequested, wipeResetProtectionData);
}

View File

@@ -392,10 +392,9 @@ public class MockSystemServices {
}
public static class RecoverySystemForMock {
public boolean rebootWipeUserData(boolean shutdown, String reason, boolean force,
public void rebootWipeUserData(boolean shutdown, String reason, boolean force,
boolean wipeEuicc, boolean wipeExtRequested, boolean wipeResetProtectionData)
throws IOException {
return false;
}
}