Merge "Add a verification flow for the user to exit repair mode" into udc-qpr-dev
This commit is contained in:
@@ -127,6 +127,15 @@ public class KeyguardManager {
|
||||
public static final String ACTION_PREPARE_REPAIR_MODE_DEVICE_CREDENTIAL =
|
||||
"android.app.action.PREPARE_REPAIR_MODE_DEVICE_CREDENTIAL";
|
||||
|
||||
/**
|
||||
* Intent used to prompt user for device credential that is written by
|
||||
* {@link #ACTION_PREPARE_REPAIR_MODE_DEVICE_CREDENTIAL} for exiting
|
||||
* repair mode.
|
||||
* @hide
|
||||
*/
|
||||
public static final String ACTION_CONFIRM_REPAIR_MODE_DEVICE_CREDENTIAL =
|
||||
"android.app.action.CONFIRM_REPAIR_MODE_DEVICE_CREDENTIAL";
|
||||
|
||||
/**
|
||||
* A CharSequence dialog title to show to the user when used with a
|
||||
* {@link #ACTION_CONFIRM_DEVICE_CREDENTIAL}.
|
||||
|
||||
@@ -180,6 +180,11 @@ public class LockPatternUtils {
|
||||
*/
|
||||
public static final int USER_FRP = UserHandle.USER_NULL + 1;
|
||||
|
||||
/**
|
||||
* Special user id for triggering the exiting repair mode verification flow.
|
||||
*/
|
||||
public static final int USER_REPAIR_MODE = UserHandle.USER_NULL + 2;
|
||||
|
||||
public final static String PATTERN_EVER_CHOSEN_KEY = "lockscreen.patterneverchosen";
|
||||
public final static String PASSWORD_TYPE_KEY = "lockscreen.password_type";
|
||||
@Deprecated
|
||||
@@ -400,7 +405,7 @@ public class LockPatternUtils {
|
||||
|
||||
@UnsupportedAppUsage
|
||||
public void reportFailedPasswordAttempt(int userId) {
|
||||
if (userId == USER_FRP && frpCredentialEnabled(mContext)) {
|
||||
if (isSpecialUserId(mContext, userId, /* checkDeviceSupported= */ true)) {
|
||||
return;
|
||||
}
|
||||
getDevicePolicyManager().reportFailedPasswordAttempt(userId);
|
||||
@@ -409,7 +414,7 @@ public class LockPatternUtils {
|
||||
|
||||
@UnsupportedAppUsage
|
||||
public void reportSuccessfulPasswordAttempt(int userId) {
|
||||
if (userId == USER_FRP && frpCredentialEnabled(mContext)) {
|
||||
if (isSpecialUserId(mContext, userId, /* checkDeviceSupported= */ true)) {
|
||||
return;
|
||||
}
|
||||
getDevicePolicyManager().reportSuccessfulPasswordAttempt(userId);
|
||||
@@ -417,21 +422,21 @@ public class LockPatternUtils {
|
||||
}
|
||||
|
||||
public void reportPasswordLockout(int timeoutMs, int userId) {
|
||||
if (userId == USER_FRP && frpCredentialEnabled(mContext)) {
|
||||
if (isSpecialUserId(mContext, userId, /* checkDeviceSupported= */ true)) {
|
||||
return;
|
||||
}
|
||||
getTrustManager().reportUnlockLockout(timeoutMs, userId);
|
||||
}
|
||||
|
||||
public int getCurrentFailedPasswordAttempts(int userId) {
|
||||
if (userId == USER_FRP && frpCredentialEnabled(mContext)) {
|
||||
if (isSpecialUserId(mContext, userId, /* checkDeviceSupported= */ true)) {
|
||||
return 0;
|
||||
}
|
||||
return getDevicePolicyManager().getCurrentFailedPasswordAttempts(userId);
|
||||
}
|
||||
|
||||
public int getMaximumFailedPasswordsForWipe(int userId) {
|
||||
if (userId == USER_FRP && frpCredentialEnabled(mContext)) {
|
||||
if (isSpecialUserId(mContext, userId, /* checkDeviceSupported= */ true)) {
|
||||
return 0;
|
||||
}
|
||||
return getDevicePolicyManager().getMaximumFailedPasswordsForWipe(
|
||||
@@ -768,6 +773,17 @@ public class LockPatternUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns the credential type corresponding to the given PIN or password quality. */
|
||||
public static int pinOrPasswordQualityToCredentialType(int quality) {
|
||||
if (isQualityAlphabeticPassword(quality)) {
|
||||
return CREDENTIAL_TYPE_PASSWORD;
|
||||
}
|
||||
if (isQualityNumericPin(quality)) {
|
||||
return CREDENTIAL_TYPE_PIN;
|
||||
}
|
||||
throw new IllegalArgumentException("Quality is neither Pin nor password: " + quality);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save a new lockscreen credential.
|
||||
*
|
||||
@@ -1002,7 +1018,7 @@ public class LockPatternUtils {
|
||||
}
|
||||
@Override
|
||||
public boolean shouldBypassCache(Integer userHandle) {
|
||||
return userHandle == USER_FRP;
|
||||
return isSpecialUserId(userHandle);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1116,9 +1132,10 @@ public class LockPatternUtils {
|
||||
@UnsupportedAppUsage
|
||||
public long setLockoutAttemptDeadline(int userId, int timeoutMs) {
|
||||
final long deadline = SystemClock.elapsedRealtime() + timeoutMs;
|
||||
if (userId == USER_FRP) {
|
||||
// For secure password storage (that is required for FRP), the underlying storage also
|
||||
// enforces the deadline. Since we cannot store settings for the FRP user, don't.
|
||||
if (isSpecialUserId(userId)) {
|
||||
// For secure password storage (that is required for special users such as FRP), the
|
||||
// underlying storage also enforces the deadline. Since we cannot store settings
|
||||
// for special users, don't.
|
||||
return deadline;
|
||||
}
|
||||
mLockoutDeadlines.put(userId, deadline);
|
||||
@@ -1888,6 +1905,33 @@ public class LockPatternUtils {
|
||||
return SystemProperties.getInt(GSI_RUNNING_PROP, 0) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return {@code true} if the given user id is a special user such as {@link #USER_FRP}.
|
||||
*/
|
||||
public static boolean isSpecialUserId(int userId) {
|
||||
return isSpecialUserId(/* context= */ null, userId, /* checkDeviceSupported= */ false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return {@code true} if the given user id is a special user for the verification flow.
|
||||
*
|
||||
* @param checkDeviceSupported {@code true} to check the specified user is supported
|
||||
* by the device.
|
||||
*/
|
||||
private static boolean isSpecialUserId(@Nullable Context context, int userId,
|
||||
boolean checkDeviceSupported) {
|
||||
switch (userId) {
|
||||
case USER_FRP:
|
||||
if (checkDeviceSupported) return frpCredentialEnabled(context);
|
||||
return true;
|
||||
|
||||
case USER_REPAIR_MODE:
|
||||
if (checkDeviceSupported) return isRepairModeSupported(context);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to rederive the unified work challenge for the specified profile user and unlock the
|
||||
* user. If successful, this would allow the user to leave quiet mode automatically without
|
||||
|
||||
@@ -36,6 +36,11 @@ public class LockPatternUtilsTest {
|
||||
assertTrue(LockPatternUtils.USER_FRP < 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUserRepairMode_isNotRegularUser() {
|
||||
assertTrue(LockPatternUtils.USER_REPAIR_MODE < 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUserFrp_isNotAReservedSpecialUser() throws Exception {
|
||||
assertNotEquals(UserHandle.USER_NULL, LockPatternUtils.USER_FRP);
|
||||
@@ -43,4 +48,12 @@ public class LockPatternUtilsTest {
|
||||
assertNotEquals(UserHandle.USER_CURRENT, LockPatternUtils.USER_FRP);
|
||||
assertNotEquals(UserHandle.USER_CURRENT_OR_SELF, LockPatternUtils.USER_FRP);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUserRepairMode_isNotAReservedSpecialUser() throws Exception {
|
||||
assertNotEquals(UserHandle.USER_NULL, LockPatternUtils.USER_REPAIR_MODE);
|
||||
assertNotEquals(UserHandle.USER_ALL, LockPatternUtils.USER_REPAIR_MODE);
|
||||
assertNotEquals(UserHandle.USER_CURRENT, LockPatternUtils.USER_REPAIR_MODE);
|
||||
assertNotEquals(UserHandle.USER_CURRENT_OR_SELF, LockPatternUtils.USER_REPAIR_MODE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,6 @@ import static android.os.UserHandle.USER_ALL;
|
||||
import static android.os.UserHandle.USER_SYSTEM;
|
||||
|
||||
import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_NONE;
|
||||
import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD;
|
||||
import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD_OR_PIN;
|
||||
import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PIN;
|
||||
import static com.android.internal.widget.LockPatternUtils.CURRENT_LSKF_BASED_PROTECTOR_ID_KEY;
|
||||
@@ -40,9 +39,12 @@ import static com.android.internal.widget.LockPatternUtils.PIN_LENGTH_UNAVAILABL
|
||||
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT;
|
||||
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_FOR_UNATTENDED_UPDATE;
|
||||
import static com.android.internal.widget.LockPatternUtils.USER_FRP;
|
||||
import static com.android.internal.widget.LockPatternUtils.USER_REPAIR_MODE;
|
||||
import static com.android.internal.widget.LockPatternUtils.VERIFY_FLAG_REQUEST_GK_PW_HANDLE;
|
||||
import static com.android.internal.widget.LockPatternUtils.VERIFY_FLAG_WRITE_REPAIR_MODE_PW;
|
||||
import static com.android.internal.widget.LockPatternUtils.frpCredentialEnabled;
|
||||
import static com.android.internal.widget.LockPatternUtils.isSpecialUserId;
|
||||
import static com.android.internal.widget.LockPatternUtils.pinOrPasswordQualityToCredentialType;
|
||||
import static com.android.internal.widget.LockPatternUtils.userOwnsFrpCredential;
|
||||
import static com.android.server.locksettings.SyntheticPasswordManager.TOKEN_TYPE_STRONG;
|
||||
import static com.android.server.locksettings.SyntheticPasswordManager.TOKEN_TYPE_WEAK;
|
||||
@@ -1289,8 +1291,8 @@ public class LockSettingsService extends ILockSettings.Stub {
|
||||
* {@link #CREDENTIAL_TYPE_PASSWORD}
|
||||
*/
|
||||
private int getCredentialTypeInternal(int userId) {
|
||||
if (userId == USER_FRP) {
|
||||
return getFrpCredentialType();
|
||||
if (isSpecialUserId(userId)) {
|
||||
return mSpManager.getSpecialUserCredentialType(userId);
|
||||
}
|
||||
synchronized (mSpManager) {
|
||||
final long protectorId = getCurrentLskfBasedProtectorId(userId);
|
||||
@@ -1306,29 +1308,6 @@ public class LockSettingsService extends ILockSettings.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
private int getFrpCredentialType() {
|
||||
PersistentData data = mStorage.readPersistentDataBlock();
|
||||
if (data.type != PersistentData.TYPE_SP_GATEKEEPER &&
|
||||
data.type != PersistentData.TYPE_SP_WEAVER) {
|
||||
return CREDENTIAL_TYPE_NONE;
|
||||
}
|
||||
int credentialType = SyntheticPasswordManager.getFrpCredentialType(data.payload);
|
||||
if (credentialType != CREDENTIAL_TYPE_PASSWORD_OR_PIN) {
|
||||
return credentialType;
|
||||
}
|
||||
return pinOrPasswordQualityToCredentialType(data.qualityForUi);
|
||||
}
|
||||
|
||||
private static int pinOrPasswordQualityToCredentialType(int quality) {
|
||||
if (LockPatternUtils.isQualityAlphabeticPassword(quality)) {
|
||||
return CREDENTIAL_TYPE_PASSWORD;
|
||||
}
|
||||
if (LockPatternUtils.isQualityNumericPin(quality)) {
|
||||
return CREDENTIAL_TYPE_PIN;
|
||||
}
|
||||
throw new IllegalArgumentException("Quality is neither Pin nor password: " + quality);
|
||||
}
|
||||
|
||||
private boolean isUserSecure(int userId) {
|
||||
return getCredentialTypeInternal(userId) != CREDENTIAL_TYPE_NONE;
|
||||
}
|
||||
@@ -1570,8 +1549,8 @@ public class LockSettingsService extends ILockSettings.Stub {
|
||||
* unlock operation.
|
||||
*/
|
||||
private void sendCredentialsOnUnlockIfRequired(LockscreenCredential credential, int userId) {
|
||||
// Don't send credentials during the factory reset protection flow.
|
||||
if (userId == USER_FRP) {
|
||||
// Don't send credentials during the special user flow.
|
||||
if (isSpecialUserId(userId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2195,15 +2174,19 @@ public class LockSettingsService extends ILockSettings.Stub {
|
||||
Slog.e(TAG, "FRP credential can only be verified prior to provisioning.");
|
||||
return VerifyCredentialResponse.ERROR;
|
||||
}
|
||||
if (userId == USER_REPAIR_MODE && !LockPatternUtils.isRepairModeActive(mContext)) {
|
||||
Slog.e(TAG, "Repair mode is not active on the device.");
|
||||
return VerifyCredentialResponse.ERROR;
|
||||
}
|
||||
Slogf.i(TAG, "Verifying lockscreen credential for user %d", userId);
|
||||
|
||||
final AuthenticationResult authResult;
|
||||
VerifyCredentialResponse response;
|
||||
|
||||
synchronized (mSpManager) {
|
||||
if (userId == USER_FRP) {
|
||||
return mSpManager.verifyFrpCredential(getGateKeeperService(), credential,
|
||||
progressCallback);
|
||||
if (isSpecialUserId(userId)) {
|
||||
return mSpManager.verifySpecialUserCredential(userId, getGateKeeperService(),
|
||||
credential, progressCallback);
|
||||
}
|
||||
|
||||
long protectorId = getCurrentLskfBasedProtectorId(userId);
|
||||
|
||||
@@ -19,7 +19,7 @@ package com.android.server.locksettings;
|
||||
import static android.content.Context.USER_SERVICE;
|
||||
|
||||
import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;
|
||||
import static com.android.internal.widget.LockPatternUtils.USER_FRP;
|
||||
import static com.android.internal.widget.LockPatternUtils.isSpecialUserId;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.app.admin.DevicePolicyManager;
|
||||
@@ -536,7 +536,8 @@ class LockSettingsStorage {
|
||||
}
|
||||
|
||||
public void setString(String key, String value, int userId) {
|
||||
Preconditions.checkArgument(userId != USER_FRP, "cannot store lock settings for FRP user");
|
||||
Preconditions.checkArgument(!isSpecialUserId(userId),
|
||||
"cannot store lock settings for special user: %d", userId);
|
||||
|
||||
writeKeyValue(key, value, userId);
|
||||
if (ArrayUtils.contains(SETTINGS_TO_BACKUP, key)) {
|
||||
@@ -561,7 +562,7 @@ class LockSettingsStorage {
|
||||
}
|
||||
|
||||
public String getString(String key, String defaultValue, int userId) {
|
||||
if (userId == USER_FRP) {
|
||||
if (isSpecialUserId(userId)) {
|
||||
return null;
|
||||
}
|
||||
return readKeyValue(key, defaultValue, userId);
|
||||
|
||||
@@ -16,9 +16,14 @@
|
||||
|
||||
package com.android.server.locksettings;
|
||||
|
||||
import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_NONE;
|
||||
import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD_OR_PIN;
|
||||
import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PIN;
|
||||
import static com.android.internal.widget.LockPatternUtils.EscrowTokenStateChangeCallback;
|
||||
import static com.android.internal.widget.LockPatternUtils.PIN_LENGTH_UNAVAILABLE;
|
||||
import static com.android.internal.widget.LockPatternUtils.USER_FRP;
|
||||
import static com.android.internal.widget.LockPatternUtils.USER_REPAIR_MODE;
|
||||
import static com.android.internal.widget.LockPatternUtils.pinOrPasswordQualityToCredentialType;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
@@ -718,11 +723,30 @@ class SyntheticPasswordManager {
|
||||
return PasswordData.fromBytes(passwordData).credentialType;
|
||||
}
|
||||
|
||||
static int getFrpCredentialType(byte[] payload) {
|
||||
if (payload == null) {
|
||||
int getSpecialUserCredentialType(int userId) {
|
||||
final PersistentData data = getSpecialUserPersistentData(userId);
|
||||
if (data.type != PersistentData.TYPE_SP_GATEKEEPER
|
||||
&& data.type != PersistentData.TYPE_SP_WEAVER) {
|
||||
return CREDENTIAL_TYPE_NONE;
|
||||
}
|
||||
if (data.payload == null) {
|
||||
return LockPatternUtils.CREDENTIAL_TYPE_NONE;
|
||||
}
|
||||
return PasswordData.fromBytes(payload).credentialType;
|
||||
final int credentialType = PasswordData.fromBytes(data.payload).credentialType;
|
||||
if (credentialType != CREDENTIAL_TYPE_PASSWORD_OR_PIN) {
|
||||
return credentialType;
|
||||
}
|
||||
return pinOrPasswordQualityToCredentialType(data.qualityForUi);
|
||||
}
|
||||
|
||||
private PersistentData getSpecialUserPersistentData(int userId) {
|
||||
if (userId == USER_FRP) {
|
||||
return mStorage.readPersistentDataBlock();
|
||||
}
|
||||
if (userId == USER_REPAIR_MODE) {
|
||||
return mStorage.readRepairModePersistentData();
|
||||
}
|
||||
throw new IllegalArgumentException("Unknown special user id " + userId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1005,10 +1029,10 @@ class SyntheticPasswordManager {
|
||||
return sizeOfCredential;
|
||||
}
|
||||
|
||||
public VerifyCredentialResponse verifyFrpCredential(IGateKeeperService gatekeeper,
|
||||
LockscreenCredential userCredential,
|
||||
public VerifyCredentialResponse verifySpecialUserCredential(int sourceUserId,
|
||||
IGateKeeperService gatekeeper, LockscreenCredential userCredential,
|
||||
ICheckCredentialProgressCallback progressCallback) {
|
||||
PersistentData persistentData = mStorage.readPersistentDataBlock();
|
||||
final PersistentData persistentData = getSpecialUserPersistentData(sourceUserId);
|
||||
if (persistentData.type == PersistentData.TYPE_SP_GATEKEEPER) {
|
||||
PasswordData pwd = PasswordData.fromBytes(persistentData.payload);
|
||||
byte[] stretchedLskf = stretchLskf(userCredential, pwd);
|
||||
@@ -1019,13 +1043,13 @@ class SyntheticPasswordManager {
|
||||
0 /* challenge */, pwd.passwordHandle,
|
||||
stretchedLskfToGkPassword(stretchedLskf));
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "FRP verifyChallenge failed", e);
|
||||
Slog.e(TAG, "Persistent data credential verifyChallenge failed", e);
|
||||
return VerifyCredentialResponse.ERROR;
|
||||
}
|
||||
return VerifyCredentialResponse.fromGateKeeperResponse(response);
|
||||
} else if (persistentData.type == PersistentData.TYPE_SP_WEAVER) {
|
||||
if (!isWeaverAvailable()) {
|
||||
Slog.e(TAG, "No weaver service to verify SP-based FRP credential");
|
||||
Slog.e(TAG, "No weaver service to verify SP-based persistent data credential");
|
||||
return VerifyCredentialResponse.ERROR;
|
||||
}
|
||||
PasswordData pwd = PasswordData.fromBytes(persistentData.payload);
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.server.locksettings;
|
||||
|
||||
import static com.android.internal.widget.LockPatternUtils.USER_REPAIR_MODE;
|
||||
import static com.android.internal.widget.LockPatternUtils.VERIFY_FLAG_WRITE_REPAIR_MODE_PW;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
@@ -31,7 +32,6 @@ import androidx.test.runner.AndroidJUnit4;
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.internal.widget.VerifyCredentialResponse;
|
||||
import com.android.server.locksettings.LockSettingsStorage.PersistentData;
|
||||
import com.android.server.locksettings.SyntheticPasswordManager.PasswordData;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -58,7 +58,7 @@ public class LockscreenRepairModeTest extends BaseLockSettingsServiceTests {
|
||||
newPin("1234"), PRIMARY_USER_ID, VERIFY_FLAG_WRITE_REPAIR_MODE_PW)
|
||||
.getResponseCode());
|
||||
assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PIN,
|
||||
getCredentialType(mStorage.readRepairModePersistentData()));
|
||||
mService.getCredentialType(USER_REPAIR_MODE));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -71,7 +71,7 @@ public class LockscreenRepairModeTest extends BaseLockSettingsServiceTests {
|
||||
newPattern("4321"), PRIMARY_USER_ID, VERIFY_FLAG_WRITE_REPAIR_MODE_PW)
|
||||
.getResponseCode());
|
||||
assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PATTERN,
|
||||
getCredentialType(mStorage.readRepairModePersistentData()));
|
||||
mService.getCredentialType(USER_REPAIR_MODE));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -84,7 +84,7 @@ public class LockscreenRepairModeTest extends BaseLockSettingsServiceTests {
|
||||
newPassword("4321"), PRIMARY_USER_ID, VERIFY_FLAG_WRITE_REPAIR_MODE_PW)
|
||||
.getResponseCode());
|
||||
assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
|
||||
getCredentialType(mStorage.readRepairModePersistentData()));
|
||||
mService.getCredentialType(USER_REPAIR_MODE));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -109,21 +109,98 @@ public class LockscreenRepairModeTest extends BaseLockSettingsServiceTests {
|
||||
newPin("1234"), PRIMARY_USER_ID, VERIFY_FLAG_WRITE_REPAIR_MODE_PW)
|
||||
.getResponseCode());
|
||||
assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PIN,
|
||||
getCredentialType(mStorage.readRepairModePersistentData()));
|
||||
mService.getCredentialType(USER_REPAIR_MODE));
|
||||
|
||||
mService.deleteRepairModePersistentDataIfNeeded();
|
||||
assertSame(PersistentData.NONE, mStorage.readRepairModePersistentData());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void verifyPin_userRepairMode() {
|
||||
mService.setLockCredential(newPin("1234"), nonePassword(), PRIMARY_USER_ID);
|
||||
assertSame(PersistentData.NONE, mStorage.readRepairModePersistentData());
|
||||
assertEquals(VerifyCredentialResponse.RESPONSE_OK,
|
||||
mService.verifyCredential(
|
||||
newPin("1234"), PRIMARY_USER_ID, VERIFY_FLAG_WRITE_REPAIR_MODE_PW)
|
||||
.getResponseCode());
|
||||
setRepairModeActive(true);
|
||||
|
||||
assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PIN,
|
||||
mService.getCredentialType(USER_REPAIR_MODE));
|
||||
assertEquals(VerifyCredentialResponse.RESPONSE_OK,
|
||||
mService.verifyCredential(newPin("1234"), USER_REPAIR_MODE, 0 /* flags */)
|
||||
.getResponseCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void verifyPattern_userRepairMode() {
|
||||
mService.setLockCredential(newPattern("4321"), nonePassword(), PRIMARY_USER_ID);
|
||||
assertSame(PersistentData.NONE, mStorage.readRepairModePersistentData());
|
||||
assertEquals(VerifyCredentialResponse.RESPONSE_OK,
|
||||
mService.verifyCredential(
|
||||
newPattern("4321"), PRIMARY_USER_ID, VERIFY_FLAG_WRITE_REPAIR_MODE_PW)
|
||||
.getResponseCode());
|
||||
setRepairModeActive(true);
|
||||
|
||||
assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PATTERN,
|
||||
mService.getCredentialType(USER_REPAIR_MODE));
|
||||
assertEquals(VerifyCredentialResponse.RESPONSE_OK,
|
||||
mService.verifyCredential(newPattern("4321"), USER_REPAIR_MODE, 0 /* flags */)
|
||||
.getResponseCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void verifyPassword_userRepairMode() {
|
||||
mService.setLockCredential(newPassword("4321"), nonePassword(), PRIMARY_USER_ID);
|
||||
assertSame(PersistentData.NONE, mStorage.readRepairModePersistentData());
|
||||
assertEquals(VerifyCredentialResponse.RESPONSE_OK,
|
||||
mService.verifyCredential(
|
||||
newPassword("4321"), PRIMARY_USER_ID, VERIFY_FLAG_WRITE_REPAIR_MODE_PW)
|
||||
.getResponseCode());
|
||||
setRepairModeActive(true);
|
||||
|
||||
assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
|
||||
mService.getCredentialType(USER_REPAIR_MODE));
|
||||
assertEquals(VerifyCredentialResponse.RESPONSE_OK,
|
||||
mService.verifyCredential(newPassword("4321"), USER_REPAIR_MODE, 0 /* flags */)
|
||||
.getResponseCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void verifyCredential_userRepairMode_repairModeIsNotActive() {
|
||||
mService.setLockCredential(newPin("1234"), nonePassword(), PRIMARY_USER_ID);
|
||||
assertSame(PersistentData.NONE, mStorage.readRepairModePersistentData());
|
||||
assertEquals(VerifyCredentialResponse.RESPONSE_OK,
|
||||
mService.verifyCredential(
|
||||
newPin("1234"), PRIMARY_USER_ID, VERIFY_FLAG_WRITE_REPAIR_MODE_PW)
|
||||
.getResponseCode());
|
||||
|
||||
assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PIN,
|
||||
mService.getCredentialType(USER_REPAIR_MODE));
|
||||
assertEquals(VerifyCredentialResponse.RESPONSE_ERROR,
|
||||
mService.verifyCredential(newPin("1234"), USER_REPAIR_MODE, 0 /* flags */)
|
||||
.getResponseCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void verifyCredential_userRepairMode_wrongPin() {
|
||||
mService.setLockCredential(newPin("1234"), nonePassword(), PRIMARY_USER_ID);
|
||||
assertSame(PersistentData.NONE, mStorage.readRepairModePersistentData());
|
||||
assertEquals(VerifyCredentialResponse.RESPONSE_OK,
|
||||
mService.verifyCredential(
|
||||
newPin("1234"), PRIMARY_USER_ID, VERIFY_FLAG_WRITE_REPAIR_MODE_PW)
|
||||
.getResponseCode());
|
||||
setRepairModeActive(true);
|
||||
|
||||
assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PIN,
|
||||
mService.getCredentialType(USER_REPAIR_MODE));
|
||||
assertEquals(VerifyCredentialResponse.RESPONSE_ERROR,
|
||||
mService.verifyCredential(newPin("5678"), USER_REPAIR_MODE, 0 /* flags */)
|
||||
.getResponseCode());
|
||||
}
|
||||
|
||||
private void setRepairModeActive(boolean active) {
|
||||
Settings.Global.putInt(mContext.getContentResolver(),
|
||||
Settings.Global.REPAIR_MODE_ACTIVE, active ? 1 : 0);
|
||||
}
|
||||
|
||||
private static int getCredentialType(PersistentData persistentData) {
|
||||
if (persistentData == null || persistentData.payload == null) {
|
||||
return LockPatternUtils.CREDENTIAL_TYPE_NONE;
|
||||
}
|
||||
return PasswordData.fromBytes(persistentData.payload).credentialType;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user