Enable biometric support to unlock profiles
This change ensures the ConfirmCredentialActivity allows biometric authentication to unlock (or disable quiet mode for) a profile if the profile storage is unlocked when in quiet mode. Test: atest SettingsRoboTest Bug: 312184187 Change-Id: Iefcebf2f93403591a1a4c50ff5da8d6055a37b03
This commit is contained in:
@@ -43,6 +43,7 @@ import android.os.Handler;
|
|||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.os.UserManager;
|
import android.os.UserManager;
|
||||||
|
import android.os.storage.StorageManager;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
|
|
||||||
@@ -292,7 +293,7 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity {
|
|||||||
// use, which optionally accepts a challenge.
|
// use, which optionally accepts a challenge.
|
||||||
mForceVerifyPath = true;
|
mForceVerifyPath = true;
|
||||||
if (isBiometricAllowed(effectiveUserId, mUserId)) {
|
if (isBiometricAllowed(effectiveUserId, mUserId)) {
|
||||||
showBiometricPrompt(promptInfo);
|
showBiometricPrompt(promptInfo, mUserId);
|
||||||
launchedBiometric = true;
|
launchedBiometric = true;
|
||||||
} else {
|
} else {
|
||||||
showConfirmCredentials();
|
showConfirmCredentials();
|
||||||
@@ -302,19 +303,25 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity {
|
|||||||
&& userProperties != null
|
&& userProperties != null
|
||||||
&& userProperties.isAuthAlwaysRequiredToDisableQuietMode()
|
&& userProperties.isAuthAlwaysRequiredToDisableQuietMode()
|
||||||
&& isInternalActivity()) {
|
&& isInternalActivity()) {
|
||||||
// Force verification path is required to be invoked as we might need to verify the tied
|
// Force verification path is required to be invoked as we might need to verify the
|
||||||
// profile challenge if the profile is using the unified challenge mode. This would
|
// tied profile challenge if the profile is using the unified challenge mode. This
|
||||||
// result in ConfirmLockPassword.startVerifyPassword/
|
// would result in ConfirmLockPassword.startVerifyPassword/
|
||||||
// ConfirmLockPattern.startVerifyPattern being called instead of the
|
// ConfirmLockPattern.startVerifyPattern being called instead of the
|
||||||
// startCheckPassword/startCheckPattern
|
// startCheckPassword/startCheckPattern
|
||||||
mForceVerifyPath = userProperties.isCredentialShareableWithParent();
|
mForceVerifyPath = userProperties.isCredentialShareableWithParent();
|
||||||
showConfirmCredentials();
|
if (android.multiuser.Flags.enableBiometricsToUnlockPrivateSpace()
|
||||||
launchedCDC = true;
|
&& isBiometricAllowed(effectiveUserId, mUserId)) {
|
||||||
|
showBiometricPrompt(promptInfo, effectiveUserId);
|
||||||
|
launchedBiometric = true;
|
||||||
|
} else {
|
||||||
|
showConfirmCredentials();
|
||||||
|
launchedCDC = true;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (isBiometricAllowed(effectiveUserId, mUserId)) {
|
if (isBiometricAllowed(effectiveUserId, mUserId)) {
|
||||||
// Don't need to check if biometrics / pin/pattern/pass are enrolled. It will go to
|
// Don't need to check if biometrics / pin/pattern/pass are enrolled. It will go to
|
||||||
// onAuthenticationError and do the right thing automatically.
|
// onAuthenticationError and do the right thing automatically.
|
||||||
showBiometricPrompt(promptInfo);
|
showBiometricPrompt(promptInfo, mUserId);
|
||||||
launchedBiometric = true;
|
launchedBiometric = true;
|
||||||
} else {
|
} else {
|
||||||
showConfirmCredentials();
|
showConfirmCredentials();
|
||||||
@@ -400,7 +407,19 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity {
|
|||||||
// biometric is disabled due to device restart.
|
// biometric is disabled due to device restart.
|
||||||
private boolean isStrongAuthRequired(int effectiveUserId) {
|
private boolean isStrongAuthRequired(int effectiveUserId) {
|
||||||
return !mLockPatternUtils.isBiometricAllowedForUser(effectiveUserId)
|
return !mLockPatternUtils.isBiometricAllowedForUser(effectiveUserId)
|
||||||
|| !mUserManager.isUserUnlocked(mUserId);
|
|| doesUserStateEnforceStrongAuth(mUserId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean doesUserStateEnforceStrongAuth(int userId) {
|
||||||
|
if (android.os.Flags.allowPrivateProfile()
|
||||||
|
&& android.multiuser.Flags.enableBiometricsToUnlockPrivateSpace()) {
|
||||||
|
// Check if CE storage for user is locked since biometrics can't unlock fbe/keystore of
|
||||||
|
// the profile user using verifyTiedProfileChallenge. Biometrics can still be used if
|
||||||
|
// the user is stopped with delayed locking (i.e., with storage unlocked), so the user
|
||||||
|
// state (whether the user is in the RUNNING_UNLOCKED state) should not be relied upon.
|
||||||
|
return !StorageManager.isUserKeyUnlocked(userId);
|
||||||
|
}
|
||||||
|
return !mUserManager.isUserUnlocked(userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isBiometricAllowed(int effectiveUserId, int realUserId) {
|
private boolean isBiometricAllowed(int effectiveUserId, int realUserId) {
|
||||||
@@ -408,7 +427,7 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity {
|
|||||||
.hasPendingEscrowToken(realUserId);
|
.hasPendingEscrowToken(realUserId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showBiometricPrompt(PromptInfo promptInfo) {
|
private void showBiometricPrompt(PromptInfo promptInfo, int userId) {
|
||||||
mBiometricFragment = (BiometricFragment) getSupportFragmentManager()
|
mBiometricFragment = (BiometricFragment) getSupportFragmentManager()
|
||||||
.findFragmentByTag(TAG_BIOMETRIC_FRAGMENT);
|
.findFragmentByTag(TAG_BIOMETRIC_FRAGMENT);
|
||||||
boolean newFragment = false;
|
boolean newFragment = false;
|
||||||
@@ -418,7 +437,9 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity {
|
|||||||
newFragment = true;
|
newFragment = true;
|
||||||
}
|
}
|
||||||
mBiometricFragment.setCallbacks(mExecutor, mAuthenticationCallback);
|
mBiometricFragment.setCallbacks(mExecutor, mAuthenticationCallback);
|
||||||
mBiometricFragment.setUser(mUserId);
|
// TODO(b/315864564): Move the logic of choosing the user id against which the
|
||||||
|
// authentication needs to happen to the BiometricPrompt API
|
||||||
|
mBiometricFragment.setUser(userId);
|
||||||
|
|
||||||
if (newFragment) {
|
if (newFragment) {
|
||||||
getSupportFragmentManager().beginTransaction()
|
getSupportFragmentManager().beginTransaction()
|
||||||
|
Reference in New Issue
Block a user