Merge changes from topic "face-challenge-bug" into qt-r1-dev

am: 01462c0b95

Change-Id: I86587feb4d6a1e845cf605c8e5b6536d10f1b479
This commit is contained in:
Kevin Chyn
2019-06-12 11:04:31 -07:00
committed by android-build-merger
7 changed files with 55 additions and 18 deletions

View File

@@ -104,9 +104,17 @@ public class BiometricManager {
*/
@RequiresPermission(USE_BIOMETRIC)
public @BiometricError int canAuthenticate() {
return canAuthenticate(mContext.getUserId());
}
/**
* @hide
*/
@RequiresPermission(USE_BIOMETRIC_INTERNAL)
public @BiometricError int canAuthenticate(int userId) {
if (mService != null) {
try {
return mService.canAuthenticate(mContext.getOpPackageName());
return mService.canAuthenticate(mContext.getOpPackageName(), userId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}

View File

@@ -40,7 +40,7 @@ interface IBiometricService {
void cancelAuthentication(IBinder token, String opPackageName);
// Checks if biometrics can be used.
int canAuthenticate(String opPackageName);
int canAuthenticate(String opPackageName, int userId);
// Register callback for when keyguard biometric eligibility changes.
void registerEnabledOnKeyguardCallback(IBiometricEnabledOnKeyguardCallback callback);

View File

@@ -766,10 +766,16 @@ public class BiometricService extends SystemService {
}
@Override // Binder call
public int canAuthenticate(String opPackageName) {
checkPermission();
public int canAuthenticate(String opPackageName, int userId) {
Slog.d(TAG, "canAuthenticate: User=" + userId
+ ", Caller=" + UserHandle.getCallingUserId());
if (userId != UserHandle.getCallingUserId()) {
checkInternalPermission();
} else {
checkPermission();
}
final int userId = UserHandle.getCallingUserId();
final long ident = Binder.clearCallingIdentity();
int error;
try {
@@ -965,6 +971,11 @@ public class BiometricService extends SystemService {
}
}
Slog.d(TAG, "checkAndGetBiometricModality: user=" + userId
+ " isHardwareDetected=" + isHardwareDetected
+ " hasTemplatesEnrolled=" + hasTemplatesEnrolled
+ " enabledForApps=" + enabledForApps);
// Check error conditions
if (!isHardwareDetected) {
return new Pair<>(TYPE_NONE, BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE);

View File

@@ -1090,6 +1090,8 @@ public abstract class BiometricServiceBase extends SystemService
if (DEBUG) Slog.v(getTag(), "starting client "
+ mCurrentClient.getClass().getSuperclass().getSimpleName()
+ "(" + mCurrentClient.getOwnerString() + ")"
+ " targetUserId: " + mCurrentClient.getTargetUserId()
+ " currentUserId: " + mCurrentUserId
+ " cookie: " + cookie + "/" + mCurrentClient.getCookie());
if (cookie != mCurrentClient.getCookie()) {
Slog.e(getTag(), "Mismatched cookie");

View File

@@ -193,6 +193,7 @@ public class FaceService extends BiometricServiceBase {
.setAutoCancel(true)
.setCategory(Notification.CATEGORY_SYSTEM)
.setContentIntent(pendingIntent)
.setVisibility(Notification.VISIBILITY_SECRET)
.build();
nm.createNotificationChannel(channel);
@@ -480,6 +481,8 @@ public class FaceService extends BiometricServiceBase {
return;
}
Slog.d(TAG, "Resetting lockout for user: " + mCurrentUserId);
try {
mDaemonWrapper.resetLockout(token);
} catch (RemoteException e) {

View File

@@ -420,9 +420,9 @@ public class LockSettingsService extends ILockSettings.Stub {
new PasswordSlotManager());
}
public boolean hasEnrolledBiometrics() {
public boolean hasEnrolledBiometrics(int userId) {
BiometricManager bm = mContext.getSystemService(BiometricManager.class);
return bm.canAuthenticate() == BiometricManager.BIOMETRIC_SUCCESS;
return bm.canAuthenticate(userId) == BiometricManager.BIOMETRIC_SUCCESS;
}
public int binderGetCallingUid() {
@@ -584,7 +584,8 @@ public class LockSettingsService extends ILockSettings.Stub {
// If boot took too long and the password in vold got expired, parent keystore will
// be still locked, we ignore this case since the user will be prompted to unlock
// the device after boot.
unlockChildProfile(userId, true /* ignoreUserNotAuthenticated */);
unlockChildProfile(userId, true /* ignoreUserNotAuthenticated */,
false /* hasChallenge */, 0 /* challenge */);
} catch (RemoteException e) {
Slog.e(TAG, "Failed to unlock child profile");
}
@@ -1160,12 +1161,13 @@ public class LockSettingsService extends ILockSettings.Stub {
return decryptionResult;
}
private void unlockChildProfile(int profileHandle, boolean ignoreUserNotAuthenticated)
private void unlockChildProfile(int profileHandle, boolean ignoreUserNotAuthenticated,
boolean hasChallenge, long challenge)
throws RemoteException {
try {
doVerifyCredential(getDecryptedPasswordForTiedProfile(profileHandle),
CREDENTIAL_TYPE_PASSWORD,
false, 0 /* no challenge */, profileHandle, null /* progressCallback */);
hasChallenge, challenge, profileHandle, null /* progressCallback */);
} catch (UnrecoverableKeyException | InvalidKeyException | KeyStoreException
| NoSuchAlgorithmException | NoSuchPaddingException
| InvalidAlgorithmParameterException | IllegalBlockSizeException
@@ -1180,6 +1182,10 @@ public class LockSettingsService extends ILockSettings.Stub {
}
}
private void unlockUser(int userId, byte[] token, byte[] secret) {
unlockUser(userId, token, secret, false /* hasChallenge */, 0 /* challenge */);
}
/**
* Unlock the user (both storage and user state) and its associated managed profiles
* synchronously.
@@ -1188,7 +1194,8 @@ public class LockSettingsService extends ILockSettings.Stub {
* can end up calling into other system services to process user unlock request (via
* {@link com.android.server.SystemServiceManager#unlockUser} </em>
*/
private void unlockUser(int userId, byte[] token, byte[] secret) {
private void unlockUser(int userId, byte[] token, byte[] secret,
boolean hasChallenge, long challenge) {
// TODO: make this method fully async so we can update UI with progress strings
final boolean alreadyUnlocked = mUserManager.isUserUnlockingOrUnlocked(userId);
final CountDownLatch latch = new CountDownLatch(1);
@@ -1230,7 +1237,10 @@ public class LockSettingsService extends ILockSettings.Stub {
// Unlock managed profile with unified lock
if (tiedManagedProfileReadyToUnlock(profile)) {
try {
unlockChildProfile(profile.id, false /* ignoreUserNotAuthenticated */);
// Must pass the challenge on for resetLockout, so it's not over-written, which
// causes LockSettingsService to revokeChallenge inappropriately.
unlockChildProfile(profile.id, false /* ignoreUserNotAuthenticated */,
hasChallenge, challenge);
} catch (RemoteException e) {
Log.d(TAG, "Failed to unlock child profile", e);
}
@@ -2493,7 +2503,11 @@ public class LockSettingsService extends ILockSettings.Stub {
private VerifyCredentialResponse spBasedDoVerifyCredential(byte[] userCredential,
@CredentialType int credentialType, boolean hasChallenge, long challenge, int userId,
ICheckCredentialProgressCallback progressCallback) throws RemoteException {
if (DEBUG) Slog.d(TAG, "spBasedDoVerifyCredential: user=" + userId);
final boolean hasEnrolledBiometrics = mInjector.hasEnrolledBiometrics(userId);
Slog.d(TAG, "spBasedDoVerifyCredential: user=" + userId + " hasChallenge=" + hasChallenge
+ " hasEnrolledBiometrics=" + hasEnrolledBiometrics);
if (credentialType == CREDENTIAL_TYPE_NONE) {
userCredential = null;
}
@@ -2503,7 +2517,7 @@ public class LockSettingsService extends ILockSettings.Stub {
// we need to generate challenge for each one, have it signed by GK and reset lockout
// for each modality.
if (!hasChallenge && pm.hasSystemFeature(PackageManager.FEATURE_FACE)
&& mInjector.hasEnrolledBiometrics()) {
&& hasEnrolledBiometrics) {
challenge = mContext.getSystemService(FaceManager.class).generateChallenge();
}
@@ -2546,9 +2560,8 @@ public class LockSettingsService extends ILockSettings.Stub {
notifyActivePasswordMetricsAvailable(credentialType, userCredential, userId);
unlockKeystore(authResult.authToken.deriveKeyStorePassword(), userId);
// Reset lockout only if user has enrolled templates
if (mInjector.hasEnrolledBiometrics()) {
if (hasEnrolledBiometrics) {
BiometricManager bm = mContext.getSystemService(BiometricManager.class);
Slog.i(TAG, "Resetting lockout, length: " + response.getPayload().length);
bm.resetLockout(response.getPayload());
if (!hasChallenge && pm.hasSystemFeature(PackageManager.FEATURE_FACE)) {
@@ -2558,7 +2571,7 @@ public class LockSettingsService extends ILockSettings.Stub {
final byte[] secret = authResult.authToken.deriveDiskEncryptionKey();
Slog.i(TAG, "Unlocking user " + userId + " with secret only, length " + secret.length);
unlockUser(userId, null, secret);
unlockUser(userId, null, secret, hasChallenge, challenge);
activateEscrowTokens(authResult.authToken, userId);

View File

@@ -110,7 +110,7 @@ public class LockSettingsServiceTestable extends LockSettingsService {
}
@Override
public boolean hasEnrolledBiometrics() {
public boolean hasEnrolledBiometrics(int userId) {
return false;
}