diff options
4 files changed, 73 insertions, 0 deletions
diff --git a/services/core/java/com/android/server/FactoryResetter.java b/services/core/java/com/android/server/FactoryResetter.java new file mode 100644 index 000000000000..30314a3683a6 --- /dev/null +++ b/services/core/java/com/android/server/FactoryResetter.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server; + +import android.content.Context; +import android.content.pm.PackageManager; + +import com.android.internal.util.Preconditions; + +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * TODO(b/225012970): add javadoc from {@code com.android.server.devicepolicy.FactoryResetter} + */ +public final class FactoryResetter { + + private static final AtomicBoolean sFactoryResetting = new AtomicBoolean(false); + + /** + * Checks whether a factory reset is in progress. + */ + public static boolean isFactoryResetting() { + return sFactoryResetting.get(); + } + + /** + * @deprecated called by {@code com.android.server.devicepolicy.FactoryResetter}, won't be + * needed once that class logic is moved into this. + */ + @Deprecated + public static void setFactoryResetting(Context context) { + Preconditions.checkCallAuthorization(context.checkCallingOrSelfPermission( + android.Manifest.permission.MASTER_CLEAR) == PackageManager.PERMISSION_GRANTED); + sFactoryResetting.set(true); + } + + private FactoryResetter() { + throw new UnsupportedOperationException("Provides only static methods"); + } +} diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java index 5a43f4d6c3dc..c465be149ac2 100644 --- a/services/core/java/com/android/server/am/UserController.java +++ b/services/core/java/com/android/server/am/UserController.java @@ -106,6 +106,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.ArrayUtils; import com.android.internal.util.FrameworkStatsLog; import com.android.internal.widget.LockPatternUtils; +import com.android.server.FactoryResetter; import com.android.server.FgThread; import com.android.server.LocalServices; import com.android.server.SystemServiceManager; @@ -1756,6 +1757,10 @@ class UserController implements Handler.Callback { Slogf.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user"); return false; } + if (FactoryResetter.isFactoryResetting()) { + Slogf.w(TAG, "Cannot switch to User #" + targetUserId + ": factory reset in progress"); + return false; + } boolean userSwitchUiEnabled; synchronized (mLock) { if (!mInitialized) { diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/FactoryResetter.java b/services/devicepolicy/java/com/android/server/devicepolicy/FactoryResetter.java index 964be38943bf..c72e1eabb086 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/FactoryResetter.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/FactoryResetter.java @@ -16,6 +16,8 @@ package com.android.server.devicepolicy; +import static com.android.server.FactoryResetter.setFactoryResetting; + import android.annotation.Nullable; import android.app.admin.DevicePolicySafetyChecker; import android.content.Context; @@ -36,7 +38,10 @@ import java.util.Objects; /** * Entry point for "factory reset" requests. + * + * @deprecated TODO(b/225012970): should be moved to {@code com.android.server.FactoryResetter} */ +@Deprecated public final class FactoryResetter { private static final String TAG = FactoryResetter.class.getSimpleName(); @@ -60,6 +65,8 @@ public final class FactoryResetter { Preconditions.checkCallAuthorization(mContext.checkCallingOrSelfPermission( android.Manifest.permission.MASTER_CLEAR) == PackageManager.PERMISSION_GRANTED); + setFactoryResetting(mContext); + if (mSafetyChecker == null) { factoryResetInternalUnchecked(); return true; diff --git a/services/tests/mockingservicestests/src/com/android/server/devicepolicy/FactoryResetterTest.java b/services/tests/mockingservicestests/src/com/android/server/devicepolicy/FactoryResetterTest.java index 457c8db9fdf3..4ffa0fbec758 100644 --- a/services/tests/mockingservicestests/src/com/android/server/devicepolicy/FactoryResetterTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/devicepolicy/FactoryResetterTest.java @@ -14,11 +14,13 @@ * limitations under the License. */ +// TODO(b/225012970): should be moved to com.android.server package com.android.server.devicepolicy; 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.android.server.FactoryResetter.isFactoryResetting; import static com.google.common.truth.Truth.assertThat; @@ -165,6 +167,7 @@ public final class FactoryResetterTest { .factoryReset(); assertThat(success).isTrue(); + assertThat(isFactoryResetting()).isTrue(); verifyWipeAdoptableStorageCalled(); verifyWipeFactoryResetProtectionNotCalled(); verifyRebootWipeUserDataMinimumArgsCalled(); @@ -179,6 +182,7 @@ public final class FactoryResetterTest { .build().factoryReset(); assertThat(success).isTrue(); + assertThat(isFactoryResetting()).isTrue(); verifyWipeAdoptableStorageNotCalled(); verifyWipeFactoryResetProtectionCalled(); verifyRebootWipeUserDataMinimumArgsCalled(); @@ -198,6 +202,7 @@ public final class FactoryResetterTest { .build().factoryReset(); assertThat(success).isTrue(); + assertThat(isFactoryResetting()).isTrue(); verifyWipeAdoptableStorageCalled(); verifyWipeFactoryResetProtectionCalled(); verifyRebootWipeUserDataAllArgsCalled(); @@ -211,6 +216,7 @@ public final class FactoryResetterTest { .setSafetyChecker(mSafetyChecker).build().factoryReset(); assertThat(success).isFalse(); + assertThat(isFactoryResetting()).isTrue(); verifyWipeAdoptableStorageNotCalled(); verifyWipeFactoryResetProtectionNotCalled(); verifyRebootWipeUserDataNotCalled(); @@ -238,6 +244,7 @@ public final class FactoryResetterTest { .build().factoryReset(); assertThat(success).isFalse(); + assertThat(isFactoryResetting()).isTrue(); verifyWipeAdoptableStorageCalled(); verifyWipeFactoryResetProtectionCalled(); verifyRebootWipeUserDataAllArgsCalled(); |