Merge "On strongAuthChanges, update fp & face states" into tm-qpr-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
60ccbef8b5
@@ -48,11 +48,13 @@ import com.android.keyguard.InternalFaceAuthReasons.KEYGUARD_INIT
|
|||||||
import com.android.keyguard.InternalFaceAuthReasons.KEYGUARD_OCCLUSION_CHANGED
|
import com.android.keyguard.InternalFaceAuthReasons.KEYGUARD_OCCLUSION_CHANGED
|
||||||
import com.android.keyguard.InternalFaceAuthReasons.KEYGUARD_RESET
|
import com.android.keyguard.InternalFaceAuthReasons.KEYGUARD_RESET
|
||||||
import com.android.keyguard.InternalFaceAuthReasons.KEYGUARD_VISIBILITY_CHANGED
|
import com.android.keyguard.InternalFaceAuthReasons.KEYGUARD_VISIBILITY_CHANGED
|
||||||
|
import com.android.keyguard.InternalFaceAuthReasons.NON_STRONG_BIOMETRIC_ALLOWED_CHANGED
|
||||||
import com.android.keyguard.InternalFaceAuthReasons.OCCLUDING_APP_REQUESTED
|
import com.android.keyguard.InternalFaceAuthReasons.OCCLUDING_APP_REQUESTED
|
||||||
import com.android.keyguard.InternalFaceAuthReasons.PRIMARY_BOUNCER_SHOWN
|
import com.android.keyguard.InternalFaceAuthReasons.PRIMARY_BOUNCER_SHOWN
|
||||||
import com.android.keyguard.InternalFaceAuthReasons.PRIMARY_BOUNCER_SHOWN_OR_WILL_BE_SHOWN
|
import com.android.keyguard.InternalFaceAuthReasons.PRIMARY_BOUNCER_SHOWN_OR_WILL_BE_SHOWN
|
||||||
import com.android.keyguard.InternalFaceAuthReasons.RETRY_AFTER_HW_UNAVAILABLE
|
import com.android.keyguard.InternalFaceAuthReasons.RETRY_AFTER_HW_UNAVAILABLE
|
||||||
import com.android.keyguard.InternalFaceAuthReasons.STARTED_WAKING_UP
|
import com.android.keyguard.InternalFaceAuthReasons.STARTED_WAKING_UP
|
||||||
|
import com.android.keyguard.InternalFaceAuthReasons.STRONG_AUTH_ALLOWED_CHANGED
|
||||||
import com.android.keyguard.InternalFaceAuthReasons.TRUST_DISABLED
|
import com.android.keyguard.InternalFaceAuthReasons.TRUST_DISABLED
|
||||||
import com.android.keyguard.InternalFaceAuthReasons.TRUST_ENABLED
|
import com.android.keyguard.InternalFaceAuthReasons.TRUST_ENABLED
|
||||||
import com.android.keyguard.InternalFaceAuthReasons.USER_SWITCHING
|
import com.android.keyguard.InternalFaceAuthReasons.USER_SWITCHING
|
||||||
@@ -121,6 +123,9 @@ private object InternalFaceAuthReasons {
|
|||||||
const val FACE_AUTHENTICATED = "Face auth started/stopped because face is authenticated"
|
const val FACE_AUTHENTICATED = "Face auth started/stopped because face is authenticated"
|
||||||
const val BIOMETRIC_ENABLED =
|
const val BIOMETRIC_ENABLED =
|
||||||
"Face auth started/stopped because biometric is enabled on keyguard"
|
"Face auth started/stopped because biometric is enabled on keyguard"
|
||||||
|
const val STRONG_AUTH_ALLOWED_CHANGED = "Face auth stopped because strong auth allowed changed"
|
||||||
|
const val NON_STRONG_BIOMETRIC_ALLOWED_CHANGED =
|
||||||
|
"Face auth stopped because non strong biometric allowed changed"
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -204,7 +209,11 @@ constructor(private val id: Int, val reason: String, var extraInfo: Int = 0) :
|
|||||||
@UiEvent(doc = FACE_AUTHENTICATED)
|
@UiEvent(doc = FACE_AUTHENTICATED)
|
||||||
FACE_AUTH_UPDATED_ON_FACE_AUTHENTICATED(1187, FACE_AUTHENTICATED),
|
FACE_AUTH_UPDATED_ON_FACE_AUTHENTICATED(1187, FACE_AUTHENTICATED),
|
||||||
@UiEvent(doc = BIOMETRIC_ENABLED)
|
@UiEvent(doc = BIOMETRIC_ENABLED)
|
||||||
FACE_AUTH_UPDATED_BIOMETRIC_ENABLED_ON_KEYGUARD(1188, BIOMETRIC_ENABLED);
|
FACE_AUTH_UPDATED_BIOMETRIC_ENABLED_ON_KEYGUARD(1188, BIOMETRIC_ENABLED),
|
||||||
|
@UiEvent(doc = STRONG_AUTH_ALLOWED_CHANGED)
|
||||||
|
FACE_AUTH_UPDATED_STRONG_AUTH_CHANGED(1255, STRONG_AUTH_ALLOWED_CHANGED),
|
||||||
|
@UiEvent(doc = NON_STRONG_BIOMETRIC_ALLOWED_CHANGED)
|
||||||
|
FACE_AUTH_NON_STRONG_BIOMETRIC_ALLOWED_CHANGED(1256, NON_STRONG_BIOMETRIC_ALLOWED_CHANGED);
|
||||||
|
|
||||||
override fun getId(): Int = this.id
|
override fun getId(): Int = this.id
|
||||||
|
|
||||||
|
|||||||
@@ -53,17 +53,17 @@ data class KeyguardFaceListenModel(
|
|||||||
val biometricSettingEnabledForUser: Boolean,
|
val biometricSettingEnabledForUser: Boolean,
|
||||||
val bouncerFullyShown: Boolean,
|
val bouncerFullyShown: Boolean,
|
||||||
val faceAndFpNotAuthenticated: Boolean,
|
val faceAndFpNotAuthenticated: Boolean,
|
||||||
|
val faceAuthAllowed: Boolean,
|
||||||
val faceDisabled: Boolean,
|
val faceDisabled: Boolean,
|
||||||
val faceLockedOut: Boolean,
|
val faceLockedOut: Boolean,
|
||||||
val fpLockedOut: Boolean,
|
|
||||||
val goingToSleep: Boolean,
|
val goingToSleep: Boolean,
|
||||||
val keyguardAwake: Boolean,
|
val keyguardAwake: Boolean,
|
||||||
val keyguardGoingAway: Boolean,
|
val keyguardGoingAway: Boolean,
|
||||||
val listeningForFaceAssistant: Boolean,
|
val listeningForFaceAssistant: Boolean,
|
||||||
val occludingAppRequestingFaceAuth: Boolean,
|
val occludingAppRequestingFaceAuth: Boolean,
|
||||||
val primaryUser: Boolean,
|
val primaryUser: Boolean,
|
||||||
val scanningAllowedByStrongAuth: Boolean,
|
|
||||||
val secureCameraLaunched: Boolean,
|
val secureCameraLaunched: Boolean,
|
||||||
|
val supportsDetect: Boolean,
|
||||||
val switchingUser: Boolean,
|
val switchingUser: Boolean,
|
||||||
val udfpsBouncerShowing: Boolean,
|
val udfpsBouncerShowing: Boolean,
|
||||||
val udfpsFingerDown: Boolean,
|
val udfpsFingerDown: Boolean,
|
||||||
@@ -79,9 +79,8 @@ data class KeyguardActiveUnlockModel(
|
|||||||
// keep sorted
|
// keep sorted
|
||||||
val awakeKeyguard: Boolean,
|
val awakeKeyguard: Boolean,
|
||||||
val authInterruptActive: Boolean,
|
val authInterruptActive: Boolean,
|
||||||
val encryptedOrTimedOut: Boolean,
|
val fpLockedOut: Boolean,
|
||||||
val fpLockout: Boolean,
|
val primaryAuthRequired: Boolean,
|
||||||
val lockDown: Boolean,
|
|
||||||
val switchingUser: Boolean,
|
val switchingUser: Boolean,
|
||||||
val triggerActiveUnlockForAssistant: Boolean,
|
val triggerActiveUnlockForAssistant: Boolean,
|
||||||
val userCanDismissLockScreen: Boolean
|
val userCanDismissLockScreen: Boolean
|
||||||
|
|||||||
@@ -34,9 +34,9 @@ import static android.os.BatteryManager.BATTERY_STATUS_UNKNOWN;
|
|||||||
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT;
|
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT;
|
||||||
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW;
|
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW;
|
||||||
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT;
|
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT;
|
||||||
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_TIMEOUT;
|
|
||||||
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN;
|
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN;
|
||||||
import static com.android.keyguard.FaceAuthReasonKt.apiRequestReasonToUiEvent;
|
import static com.android.keyguard.FaceAuthReasonKt.apiRequestReasonToUiEvent;
|
||||||
|
import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_NON_STRONG_BIOMETRIC_ALLOWED_CHANGED;
|
||||||
import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_STOPPED_DREAM_STARTED;
|
import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_STOPPED_DREAM_STARTED;
|
||||||
import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_STOPPED_FACE_CANCEL_NOT_RECEIVED;
|
import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_STOPPED_FACE_CANCEL_NOT_RECEIVED;
|
||||||
import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_STOPPED_FINISHED_GOING_TO_SLEEP;
|
import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_STOPPED_FINISHED_GOING_TO_SLEEP;
|
||||||
@@ -65,6 +65,7 @@ import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_UPDATED_ON_FACE_AUT
|
|||||||
import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_UPDATED_ON_KEYGUARD_INIT;
|
import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_UPDATED_ON_KEYGUARD_INIT;
|
||||||
import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_UPDATED_PRIMARY_BOUNCER_SHOWN;
|
import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_UPDATED_PRIMARY_BOUNCER_SHOWN;
|
||||||
import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_UPDATED_STARTED_WAKING_UP;
|
import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_UPDATED_STARTED_WAKING_UP;
|
||||||
|
import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_UPDATED_STRONG_AUTH_CHANGED;
|
||||||
import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_UPDATED_USER_SWITCHING;
|
import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_UPDATED_USER_SWITCHING;
|
||||||
import static com.android.systemui.DejankUtils.whitelistIpcs;
|
import static com.android.systemui.DejankUtils.whitelistIpcs;
|
||||||
|
|
||||||
@@ -171,7 +172,6 @@ import java.util.Map.Entry;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.function.Consumer;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
@@ -1421,6 +1421,9 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the user locked down the device. This doesn't include device policy manager lockdown.
|
||||||
|
*/
|
||||||
public boolean isUserInLockdown(int userId) {
|
public boolean isUserInLockdown(int userId) {
|
||||||
return containsFlag(mStrongAuthTracker.getStrongAuthForUser(userId),
|
return containsFlag(mStrongAuthTracker.getStrongAuthForUser(userId),
|
||||||
STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN);
|
STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN);
|
||||||
@@ -1452,7 +1455,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
return mStrongAuthTracker;
|
return mStrongAuthTracker;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void notifyStrongAuthStateChanged(int userId) {
|
@VisibleForTesting
|
||||||
|
void notifyStrongAuthAllowedChanged(int userId) {
|
||||||
Assert.isMainThread();
|
Assert.isMainThread();
|
||||||
for (int i = 0; i < mCallbacks.size(); i++) {
|
for (int i = 0; i < mCallbacks.size(); i++) {
|
||||||
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
|
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
|
||||||
@@ -1460,6 +1464,15 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
cb.onStrongAuthStateChanged(userId);
|
cb.onStrongAuthStateChanged(userId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (userId == getCurrentUser()) {
|
||||||
|
FACE_AUTH_UPDATED_STRONG_AUTH_CHANGED.setExtraInfo(
|
||||||
|
mStrongAuthTracker.getStrongAuthForUser(getCurrentUser()));
|
||||||
|
|
||||||
|
// Strong auth is only reset when primary auth is used to enter the device,
|
||||||
|
// so we only check whether to stop biometric listening states here
|
||||||
|
updateBiometricListeningState(
|
||||||
|
BIOMETRIC_ACTION_STOP, FACE_AUTH_UPDATED_STRONG_AUTH_CHANGED);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void notifyLockedOutStateChanged(BiometricSourceType type) {
|
private void notifyLockedOutStateChanged(BiometricSourceType type) {
|
||||||
@@ -1471,8 +1484,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@VisibleForTesting
|
||||||
private void notifyNonStrongBiometricStateChanged(int userId) {
|
void notifyNonStrongBiometricAllowedChanged(int userId) {
|
||||||
Assert.isMainThread();
|
Assert.isMainThread();
|
||||||
for (int i = 0; i < mCallbacks.size(); i++) {
|
for (int i = 0; i < mCallbacks.size(); i++) {
|
||||||
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
|
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
|
||||||
@@ -1480,6 +1493,16 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
cb.onNonStrongBiometricAllowedChanged(userId);
|
cb.onNonStrongBiometricAllowedChanged(userId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (userId == getCurrentUser()) {
|
||||||
|
FACE_AUTH_NON_STRONG_BIOMETRIC_ALLOWED_CHANGED.setExtraInfo(
|
||||||
|
mStrongAuthTracker.isNonStrongBiometricAllowedAfterIdleTimeout(
|
||||||
|
getCurrentUser()) ? -1 : 1);
|
||||||
|
|
||||||
|
// This is only reset when primary auth is used to enter the device, so we only check
|
||||||
|
// whether to stop biometric listening states here
|
||||||
|
updateBiometricListeningState(BIOMETRIC_ACTION_STOP,
|
||||||
|
FACE_AUTH_NON_STRONG_BIOMETRIC_ALLOWED_CHANGED);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void dispatchErrorMessage(CharSequence message) {
|
private void dispatchErrorMessage(CharSequence message) {
|
||||||
@@ -1825,16 +1848,12 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class StrongAuthTracker extends LockPatternUtils.StrongAuthTracker {
|
/**
|
||||||
private final Consumer<Integer> mStrongAuthRequiredChangedCallback;
|
* Updates callbacks when strong auth requirements change.
|
||||||
private final Consumer<Integer> mNonStrongBiometricAllowedChanged;
|
*/
|
||||||
|
public class StrongAuthTracker extends LockPatternUtils.StrongAuthTracker {
|
||||||
public StrongAuthTracker(Context context,
|
public StrongAuthTracker(Context context) {
|
||||||
Consumer<Integer> strongAuthRequiredChangedCallback,
|
|
||||||
Consumer<Integer> nonStrongBiometricAllowedChanged) {
|
|
||||||
super(context);
|
super(context);
|
||||||
mStrongAuthRequiredChangedCallback = strongAuthRequiredChangedCallback;
|
|
||||||
mNonStrongBiometricAllowedChanged = nonStrongBiometricAllowedChanged;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isUnlockingWithBiometricAllowed(boolean isStrongBiometric) {
|
public boolean isUnlockingWithBiometricAllowed(boolean isStrongBiometric) {
|
||||||
@@ -1850,7 +1869,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStrongAuthRequiredChanged(int userId) {
|
public void onStrongAuthRequiredChanged(int userId) {
|
||||||
mStrongAuthRequiredChangedCallback.accept(userId);
|
notifyStrongAuthAllowedChanged(userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(b/247091681): Renaming the inappropriate onIsNonStrongBiometricAllowedChanged
|
// TODO(b/247091681): Renaming the inappropriate onIsNonStrongBiometricAllowedChanged
|
||||||
@@ -1858,7 +1877,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
// Strong-Auth
|
// Strong-Auth
|
||||||
@Override
|
@Override
|
||||||
public void onIsNonStrongBiometricAllowedChanged(int userId) {
|
public void onIsNonStrongBiometricAllowedChanged(int userId) {
|
||||||
mNonStrongBiometricAllowedChanged.accept(userId);
|
notifyNonStrongBiometricAllowedChanged(userId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2019,8 +2038,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
mUserTracker = userTracker;
|
mUserTracker = userTracker;
|
||||||
mTelephonyListenerManager = telephonyListenerManager;
|
mTelephonyListenerManager = telephonyListenerManager;
|
||||||
mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
|
mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
|
||||||
mStrongAuthTracker = new StrongAuthTracker(context, this::notifyStrongAuthStateChanged,
|
mStrongAuthTracker = new StrongAuthTracker(context);
|
||||||
this::notifyNonStrongBiometricStateChanged);
|
|
||||||
mBackgroundExecutor = backgroundExecutor;
|
mBackgroundExecutor = backgroundExecutor;
|
||||||
mBroadcastDispatcher = broadcastDispatcher;
|
mBroadcastDispatcher = broadcastDispatcher;
|
||||||
mInteractionJankMonitor = interactionJankMonitor;
|
mInteractionJankMonitor = interactionJankMonitor;
|
||||||
@@ -2594,24 +2612,17 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
|| !mLockPatternUtils.isSecure(user);
|
|| !mLockPatternUtils.isSecure(user);
|
||||||
|
|
||||||
// Don't trigger active unlock if fp is locked out
|
// Don't trigger active unlock if fp is locked out
|
||||||
final boolean fpLockedout = mFingerprintLockedOut || mFingerprintLockedOutPermanent;
|
final boolean fpLockedOut = mFingerprintLockedOut || mFingerprintLockedOutPermanent;
|
||||||
|
|
||||||
// Don't trigger active unlock if primary auth is required
|
// Don't trigger active unlock if primary auth is required
|
||||||
final int strongAuth = mStrongAuthTracker.getStrongAuthForUser(user);
|
final boolean primaryAuthRequired = !isUnlockingWithBiometricAllowed(true);
|
||||||
final boolean isLockDown =
|
|
||||||
containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW)
|
|
||||||
|| containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN);
|
|
||||||
final boolean isEncryptedOrTimedOut =
|
|
||||||
containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_BOOT)
|
|
||||||
|| containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_TIMEOUT);
|
|
||||||
|
|
||||||
final boolean shouldTriggerActiveUnlock =
|
final boolean shouldTriggerActiveUnlock =
|
||||||
(mAuthInterruptActive || triggerActiveUnlockForAssistant || awakeKeyguard)
|
(mAuthInterruptActive || triggerActiveUnlockForAssistant || awakeKeyguard)
|
||||||
&& !mSwitchingUser
|
&& !mSwitchingUser
|
||||||
&& !userCanDismissLockScreen
|
&& !userCanDismissLockScreen
|
||||||
&& !fpLockedout
|
&& !fpLockedOut
|
||||||
&& !isLockDown
|
&& !primaryAuthRequired
|
||||||
&& !isEncryptedOrTimedOut
|
|
||||||
&& !mKeyguardGoingAway
|
&& !mKeyguardGoingAway
|
||||||
&& !mSecureCameraLaunched;
|
&& !mSecureCameraLaunched;
|
||||||
|
|
||||||
@@ -2623,9 +2634,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
shouldTriggerActiveUnlock,
|
shouldTriggerActiveUnlock,
|
||||||
awakeKeyguard,
|
awakeKeyguard,
|
||||||
mAuthInterruptActive,
|
mAuthInterruptActive,
|
||||||
isEncryptedOrTimedOut,
|
fpLockedOut,
|
||||||
fpLockedout,
|
primaryAuthRequired,
|
||||||
isLockDown,
|
|
||||||
mSwitchingUser,
|
mSwitchingUser,
|
||||||
triggerActiveUnlockForAssistant,
|
triggerActiveUnlockForAssistant,
|
||||||
userCanDismissLockScreen));
|
userCanDismissLockScreen));
|
||||||
@@ -2677,7 +2687,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
&& !fingerprintDisabledForUser
|
&& !fingerprintDisabledForUser
|
||||||
&& (!mKeyguardGoingAway || !mDeviceInteractive)
|
&& (!mKeyguardGoingAway || !mDeviceInteractive)
|
||||||
&& mIsPrimaryUser
|
&& mIsPrimaryUser
|
||||||
&& biometricEnabledForUser;
|
&& biometricEnabledForUser
|
||||||
|
&& !isUserInLockdown(user);
|
||||||
final boolean strongerAuthRequired = !isUnlockingWithFingerprintAllowed();
|
final boolean strongerAuthRequired = !isUnlockingWithFingerprintAllowed();
|
||||||
final boolean isSideFps = isSfpsSupported() && isSfpsEnrolled();
|
final boolean isSideFps = isSfpsSupported() && isSfpsEnrolled();
|
||||||
final boolean shouldListenBouncerState =
|
final boolean shouldListenBouncerState =
|
||||||
@@ -2739,14 +2750,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
final boolean awakeKeyguard = isKeyguardVisible() && mDeviceInteractive
|
final boolean awakeKeyguard = isKeyguardVisible() && mDeviceInteractive
|
||||||
&& !statusBarShadeLocked;
|
&& !statusBarShadeLocked;
|
||||||
final int user = getCurrentUser();
|
final int user = getCurrentUser();
|
||||||
final int strongAuth = mStrongAuthTracker.getStrongAuthForUser(user);
|
final boolean faceAuthAllowed = isUnlockingWithBiometricAllowed(FACE);
|
||||||
final boolean isLockDown =
|
|
||||||
containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW)
|
|
||||||
|| containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN);
|
|
||||||
final boolean isEncryptedOrTimedOut =
|
|
||||||
containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_BOOT)
|
|
||||||
|| containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_TIMEOUT);
|
|
||||||
final boolean fpLockedOut = isFingerprintLockedOut();
|
|
||||||
final boolean canBypass = mKeyguardBypassController != null
|
final boolean canBypass = mKeyguardBypassController != null
|
||||||
&& mKeyguardBypassController.canBypass();
|
&& mKeyguardBypassController.canBypass();
|
||||||
// There's no reason to ask the HAL for authentication when the user can dismiss the
|
// There's no reason to ask the HAL for authentication when the user can dismiss the
|
||||||
@@ -2754,20 +2758,15 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
// the lock screen even when TrustAgents are keeping the device unlocked.
|
// the lock screen even when TrustAgents are keeping the device unlocked.
|
||||||
final boolean userNotTrustedOrDetectionIsNeeded = !getUserHasTrust(user) || canBypass;
|
final boolean userNotTrustedOrDetectionIsNeeded = !getUserHasTrust(user) || canBypass;
|
||||||
|
|
||||||
// Scan even when encrypted or timeout to show a preemptive bouncer when bypassing.
|
// If the device supports face detection (without authentication), if bypass is enabled,
|
||||||
// Lock-down mode shouldn't scan, since it is more explicit.
|
// allow face detection to happen even if stronger auth is required. When face is detected,
|
||||||
boolean strongAuthAllowsScanning = (!isEncryptedOrTimedOut || canBypass
|
// we show the bouncer. However, if the user manually locked down the device themselves,
|
||||||
&& !mPrimaryBouncerFullyShown);
|
// never attempt to detect face.
|
||||||
|
final boolean supportsDetect = !mFaceSensorProperties.isEmpty()
|
||||||
// If the device supports face detection (without authentication) and bypass is enabled,
|
&& mFaceSensorProperties.get(0).supportsFaceDetection
|
||||||
// allow face scanning to happen if the device is in lockdown mode.
|
&& canBypass && !mPrimaryBouncerIsOrWillBeShowing
|
||||||
// Otherwise, prevent scanning.
|
&& !isUserInLockdown(user);
|
||||||
final boolean supportsDetectOnly = !mFaceSensorProperties.isEmpty()
|
final boolean faceAuthAllowedOrDetectionIsNeeded = faceAuthAllowed || supportsDetect;
|
||||||
&& canBypass
|
|
||||||
&& mFaceSensorProperties.get(0).supportsFaceDetection;
|
|
||||||
if (isLockDown && !supportsDetectOnly) {
|
|
||||||
strongAuthAllowsScanning = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the face or fp has recently been authenticated do not attempt to authenticate again.
|
// If the face or fp has recently been authenticated do not attempt to authenticate again.
|
||||||
final boolean faceAndFpNotAuthenticated = !getUserUnlockedWithBiometric(user);
|
final boolean faceAndFpNotAuthenticated = !getUserUnlockedWithBiometric(user);
|
||||||
@@ -2788,14 +2787,10 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
|| mUdfpsBouncerShowing)
|
|| mUdfpsBouncerShowing)
|
||||||
&& !mSwitchingUser && !faceDisabledForUser && userNotTrustedOrDetectionIsNeeded
|
&& !mSwitchingUser && !faceDisabledForUser && userNotTrustedOrDetectionIsNeeded
|
||||||
&& !mKeyguardGoingAway && biometricEnabledForUser
|
&& !mKeyguardGoingAway && biometricEnabledForUser
|
||||||
&& strongAuthAllowsScanning && mIsPrimaryUser
|
&& faceAuthAllowedOrDetectionIsNeeded && mIsPrimaryUser
|
||||||
&& (!mSecureCameraLaunched || mOccludingAppRequestingFace)
|
&& (!mSecureCameraLaunched || mOccludingAppRequestingFace)
|
||||||
&& faceAndFpNotAuthenticated
|
&& faceAndFpNotAuthenticated
|
||||||
&& !mGoingToSleep
|
&& !mGoingToSleep;
|
||||||
// We only care about fp locked out state and not face because we still trigger
|
|
||||||
// face auth even when face is locked out to show the user a message that face
|
|
||||||
// unlock was supposed to run but didn't
|
|
||||||
&& !fpLockedOut;
|
|
||||||
|
|
||||||
// Aggregate relevant fields for debug logging.
|
// Aggregate relevant fields for debug logging.
|
||||||
maybeLogListenerModelData(
|
maybeLogListenerModelData(
|
||||||
@@ -2805,19 +2800,19 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
shouldListen,
|
shouldListen,
|
||||||
mAuthInterruptActive,
|
mAuthInterruptActive,
|
||||||
biometricEnabledForUser,
|
biometricEnabledForUser,
|
||||||
mPrimaryBouncerFullyShown,
|
mPrimaryBouncerFullyShown,
|
||||||
faceAndFpNotAuthenticated,
|
faceAndFpNotAuthenticated,
|
||||||
|
faceAuthAllowed,
|
||||||
faceDisabledForUser,
|
faceDisabledForUser,
|
||||||
isFaceLockedOut(),
|
isFaceLockedOut(),
|
||||||
fpLockedOut,
|
|
||||||
mGoingToSleep,
|
mGoingToSleep,
|
||||||
awakeKeyguard,
|
awakeKeyguard,
|
||||||
mKeyguardGoingAway,
|
mKeyguardGoingAway,
|
||||||
shouldListenForFaceAssistant,
|
shouldListenForFaceAssistant,
|
||||||
mOccludingAppRequestingFace,
|
mOccludingAppRequestingFace,
|
||||||
mIsPrimaryUser,
|
mIsPrimaryUser,
|
||||||
strongAuthAllowsScanning,
|
|
||||||
mSecureCameraLaunched,
|
mSecureCameraLaunched,
|
||||||
|
supportsDetect,
|
||||||
mSwitchingUser,
|
mSwitchingUser,
|
||||||
mUdfpsBouncerShowing,
|
mUdfpsBouncerShowing,
|
||||||
isUdfpsFingerDown,
|
isUdfpsFingerDown,
|
||||||
@@ -2921,9 +2916,11 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
// This would need to be updated for multi-sensor devices
|
// This would need to be updated for multi-sensor devices
|
||||||
final boolean supportsFaceDetection = !mFaceSensorProperties.isEmpty()
|
final boolean supportsFaceDetection = !mFaceSensorProperties.isEmpty()
|
||||||
&& mFaceSensorProperties.get(0).supportsFaceDetection;
|
&& mFaceSensorProperties.get(0).supportsFaceDetection;
|
||||||
if (isEncryptedOrLockdown(userId) && supportsFaceDetection) {
|
if (!isUnlockingWithBiometricAllowed(FACE) && supportsFaceDetection) {
|
||||||
|
mLogger.v("startListeningForFace - detect");
|
||||||
mFaceManager.detectFace(mFaceCancelSignal, mFaceDetectionCallback, userId);
|
mFaceManager.detectFace(mFaceCancelSignal, mFaceDetectionCallback, userId);
|
||||||
} else {
|
} else {
|
||||||
|
mLogger.v("startListeningForFace - authenticate");
|
||||||
final boolean isBypassEnabled = mKeyguardBypassController != null
|
final boolean isBypassEnabled = mKeyguardBypassController != null
|
||||||
&& mKeyguardBypassController.isBypassEnabled();
|
&& mKeyguardBypassController.isBypassEnabled();
|
||||||
mFaceManager.authenticate(null /* crypto */, mFaceCancelSignal,
|
mFaceManager.authenticate(null /* crypto */, mFaceCancelSignal,
|
||||||
|
|||||||
@@ -87,17 +87,17 @@ private fun faceModel(user: Int) = KeyguardFaceListenModel(
|
|||||||
biometricSettingEnabledForUser = false,
|
biometricSettingEnabledForUser = false,
|
||||||
bouncerFullyShown = false,
|
bouncerFullyShown = false,
|
||||||
faceAndFpNotAuthenticated = false,
|
faceAndFpNotAuthenticated = false,
|
||||||
|
faceAuthAllowed = true,
|
||||||
faceDisabled = false,
|
faceDisabled = false,
|
||||||
faceLockedOut = false,
|
faceLockedOut = false,
|
||||||
fpLockedOut = false,
|
|
||||||
goingToSleep = false,
|
goingToSleep = false,
|
||||||
keyguardAwake = false,
|
keyguardAwake = false,
|
||||||
keyguardGoingAway = false,
|
keyguardGoingAway = false,
|
||||||
listeningForFaceAssistant = false,
|
listeningForFaceAssistant = false,
|
||||||
occludingAppRequestingFaceAuth = false,
|
occludingAppRequestingFaceAuth = false,
|
||||||
primaryUser = false,
|
primaryUser = false,
|
||||||
scanningAllowedByStrongAuth = false,
|
|
||||||
secureCameraLaunched = false,
|
secureCameraLaunched = false,
|
||||||
|
supportsDetect = true,
|
||||||
switchingUser = false,
|
switchingUser = false,
|
||||||
udfpsBouncerShowing = false,
|
udfpsBouncerShowing = false,
|
||||||
udfpsFingerDown = false,
|
udfpsFingerDown = false,
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import static android.telephony.SubscriptionManager.NAME_SOURCE_CARRIER_ID;
|
|||||||
|
|
||||||
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_USER_REQUEST;
|
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_USER_REQUEST;
|
||||||
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT;
|
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT;
|
||||||
|
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN;
|
||||||
import static com.android.keyguard.FaceAuthApiRequestReason.NOTIFICATION_PANEL_CLICKED;
|
import static com.android.keyguard.FaceAuthApiRequestReason.NOTIFICATION_PANEL_CLICKED;
|
||||||
import static com.android.keyguard.KeyguardUpdateMonitor.BIOMETRIC_STATE_CANCELLING_RESTARTING;
|
import static com.android.keyguard.KeyguardUpdateMonitor.BIOMETRIC_STATE_CANCELLING_RESTARTING;
|
||||||
import static com.android.keyguard.KeyguardUpdateMonitor.DEFAULT_CANCEL_SIGNAL_TIMEOUT;
|
import static com.android.keyguard.KeyguardUpdateMonitor.DEFAULT_CANCEL_SIGNAL_TIMEOUT;
|
||||||
@@ -100,6 +101,8 @@ import android.test.suitebuilder.annotation.SmallTest;
|
|||||||
import android.testing.AndroidTestingRunner;
|
import android.testing.AndroidTestingRunner;
|
||||||
import android.testing.TestableLooper;
|
import android.testing.TestableLooper;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
import com.android.dx.mockito.inline.extended.ExtendedMockito;
|
import com.android.dx.mockito.inline.extended.ExtendedMockito;
|
||||||
import com.android.internal.jank.InteractionJankMonitor;
|
import com.android.internal.jank.InteractionJankMonitor;
|
||||||
import com.android.internal.logging.InstanceId;
|
import com.android.internal.logging.InstanceId;
|
||||||
@@ -267,21 +270,9 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
|||||||
|
|
||||||
// IBiometricsFace@1.0 does not support detection, only authentication.
|
// IBiometricsFace@1.0 does not support detection, only authentication.
|
||||||
when(mFaceSensorProperties.isEmpty()).thenReturn(false);
|
when(mFaceSensorProperties.isEmpty()).thenReturn(false);
|
||||||
|
when(mFaceSensorProperties.get(anyInt())).thenReturn(
|
||||||
|
createFaceSensorProperties(/* supportsFaceDetection = */ false));
|
||||||
|
|
||||||
final List<ComponentInfoInternal> componentInfo = new ArrayList<>();
|
|
||||||
componentInfo.add(new ComponentInfoInternal("faceSensor" /* componentId */,
|
|
||||||
"vendor/model/revision" /* hardwareVersion */, "1.01" /* firmwareVersion */,
|
|
||||||
"00000001" /* serialNumber */, "" /* softwareVersion */));
|
|
||||||
componentInfo.add(new ComponentInfoInternal("matchingAlgorithm" /* componentId */,
|
|
||||||
"" /* hardwareVersion */, "" /* firmwareVersion */, "" /* serialNumber */,
|
|
||||||
"vendor/version/revision" /* softwareVersion */));
|
|
||||||
|
|
||||||
when(mFaceSensorProperties.get(anyInt())).thenReturn(new FaceSensorPropertiesInternal(
|
|
||||||
0 /* id */,
|
|
||||||
FaceSensorProperties.STRENGTH_STRONG, 1 /* maxTemplatesAllowed */,
|
|
||||||
componentInfo, FaceSensorProperties.TYPE_UNKNOWN,
|
|
||||||
false /* supportsFaceDetection */, true /* supportsSelfIllumination */,
|
|
||||||
false /* resetLockoutRequiresChallenge */));
|
|
||||||
when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
|
when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
|
||||||
when(mFingerprintManager.hasEnrolledTemplates(anyInt())).thenReturn(true);
|
when(mFingerprintManager.hasEnrolledTemplates(anyInt())).thenReturn(true);
|
||||||
when(mFingerprintManager.getSensorPropertiesInternal()).thenReturn(List.of(
|
when(mFingerprintManager.getSensorPropertiesInternal()).thenReturn(List.of(
|
||||||
@@ -354,6 +345,28 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
|||||||
when(mAuthController.areAllFingerprintAuthenticatorsRegistered()).thenReturn(true);
|
when(mAuthController.areAllFingerprintAuthenticatorsRegistered()).thenReturn(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
private FaceSensorPropertiesInternal createFaceSensorProperties(boolean supportsFaceDetection) {
|
||||||
|
final List<ComponentInfoInternal> componentInfo = new ArrayList<>();
|
||||||
|
componentInfo.add(new ComponentInfoInternal("faceSensor" /* componentId */,
|
||||||
|
"vendor/model/revision" /* hardwareVersion */, "1.01" /* firmwareVersion */,
|
||||||
|
"00000001" /* serialNumber */, "" /* softwareVersion */));
|
||||||
|
componentInfo.add(new ComponentInfoInternal("matchingAlgorithm" /* componentId */,
|
||||||
|
"" /* hardwareVersion */, "" /* firmwareVersion */, "" /* serialNumber */,
|
||||||
|
"vendor/version/revision" /* softwareVersion */));
|
||||||
|
|
||||||
|
|
||||||
|
return new FaceSensorPropertiesInternal(
|
||||||
|
0 /* id */,
|
||||||
|
FaceSensorProperties.STRENGTH_STRONG,
|
||||||
|
1 /* maxTemplatesAllowed */,
|
||||||
|
componentInfo,
|
||||||
|
FaceSensorProperties.TYPE_UNKNOWN,
|
||||||
|
supportsFaceDetection /* supportsFaceDetection */,
|
||||||
|
true /* supportsSelfIllumination */,
|
||||||
|
false /* resetLockoutRequiresChallenge */);
|
||||||
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
public void tearDown() {
|
public void tearDown() {
|
||||||
if (mMockitoSession != null) {
|
if (mMockitoSession != null) {
|
||||||
@@ -611,7 +624,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void testUnlockingWithFaceAllowed_strongAuthTrackerUnlockingWithBiometricAllowed() {
|
public void testUnlockingWithFaceAllowed_strongAuthTrackerUnlockingWithBiometricAllowed() {
|
||||||
// GIVEN unlocking with biometric is allowed
|
// GIVEN unlocking with biometric is allowed
|
||||||
when(mStrongAuthTracker.isUnlockingWithBiometricAllowed(anyBoolean())).thenReturn(true);
|
strongAuthNotRequired();
|
||||||
|
|
||||||
// THEN unlocking with face and fp is allowed
|
// THEN unlocking with face and fp is allowed
|
||||||
Assert.assertTrue(mKeyguardUpdateMonitor.isUnlockingWithBiometricAllowed(
|
Assert.assertTrue(mKeyguardUpdateMonitor.isUnlockingWithBiometricAllowed(
|
||||||
@@ -633,7 +646,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void testUnlockingWithFaceAllowed_fingerprintLockout() {
|
public void testUnlockingWithFaceAllowed_fingerprintLockout() {
|
||||||
// GIVEN unlocking with biometric is allowed
|
// GIVEN unlocking with biometric is allowed
|
||||||
when(mStrongAuthTracker.isUnlockingWithBiometricAllowed(anyBoolean())).thenReturn(true);
|
strongAuthNotRequired();
|
||||||
|
|
||||||
// WHEN fingerprint is locked out
|
// WHEN fingerprint is locked out
|
||||||
fingerprintErrorLockedOut();
|
fingerprintErrorLockedOut();
|
||||||
@@ -656,7 +669,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void testUnlockingWithFpAllowed_fingerprintLockout() {
|
public void testUnlockingWithFpAllowed_fingerprintLockout() {
|
||||||
// GIVEN unlocking with biometric is allowed
|
// GIVEN unlocking with biometric is allowed
|
||||||
when(mStrongAuthTracker.isUnlockingWithBiometricAllowed(anyBoolean())).thenReturn(true);
|
strongAuthNotRequired();
|
||||||
|
|
||||||
// WHEN fingerprint is locked out
|
// WHEN fingerprint is locked out
|
||||||
fingerprintErrorLockedOut();
|
fingerprintErrorLockedOut();
|
||||||
@@ -710,10 +723,9 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void skipsAuthentication_whenEncryptedKeyguard() {
|
public void skipsAuthentication_whenStrongAuthRequired_nonBypass() {
|
||||||
when(mStrongAuthTracker.getStrongAuthForUser(anyInt())).thenReturn(
|
lockscreenBypassIsNotAllowed();
|
||||||
STRONG_AUTH_REQUIRED_AFTER_BOOT);
|
when(mStrongAuthTracker.isUnlockingWithBiometricAllowed(anyBoolean())).thenReturn(false);
|
||||||
mKeyguardUpdateMonitor.setKeyguardBypassController(mKeyguardBypassController);
|
|
||||||
|
|
||||||
mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON);
|
mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON);
|
||||||
mTestableLooper.processAllMessages();
|
mTestableLooper.processAllMessages();
|
||||||
@@ -723,15 +735,48 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void requiresAuthentication_whenEncryptedKeyguard_andBypass() {
|
public void faceDetect_whenStrongAuthRequiredAndBypass() {
|
||||||
testStrongAuthExceptOnBouncer(
|
// GIVEN bypass is enabled, face detection is supported and strong auth is required
|
||||||
STRONG_AUTH_REQUIRED_AFTER_BOOT);
|
lockscreenBypassIsAllowed();
|
||||||
|
supportsFaceDetection();
|
||||||
|
strongAuthRequiredEncrypted();
|
||||||
|
keyguardIsVisible();
|
||||||
|
|
||||||
|
// WHEN the device wakes up
|
||||||
|
mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON);
|
||||||
|
mTestableLooper.processAllMessages();
|
||||||
|
|
||||||
|
// FACE detect is triggered, not authenticate
|
||||||
|
verify(mFaceManager).detectFace(any(), any(), anyInt());
|
||||||
|
verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt(),
|
||||||
|
anyBoolean());
|
||||||
|
|
||||||
|
// WHEN bouncer becomes visible
|
||||||
|
setKeyguardBouncerVisibility(true);
|
||||||
|
clearInvocations(mFaceManager);
|
||||||
|
|
||||||
|
// THEN face scanning is not run
|
||||||
|
mKeyguardUpdateMonitor.requestFaceAuth(FaceAuthApiRequestReason.UDFPS_POINTER_DOWN);
|
||||||
|
verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt(),
|
||||||
|
anyBoolean());
|
||||||
|
verify(mFaceManager, never()).detectFace(any(), any(), anyInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void requiresAuthentication_whenTimeoutKeyguard_andBypass() {
|
public void noFaceDetect_whenStrongAuthRequiredAndBypass_faceDetectionUnsupported() {
|
||||||
testStrongAuthExceptOnBouncer(
|
// GIVEN bypass is enabled, face detection is NOT supported and strong auth is required
|
||||||
KeyguardUpdateMonitor.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_TIMEOUT);
|
lockscreenBypassIsAllowed();
|
||||||
|
strongAuthRequiredEncrypted();
|
||||||
|
keyguardIsVisible();
|
||||||
|
|
||||||
|
// WHEN the device wakes up
|
||||||
|
mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON);
|
||||||
|
mTestableLooper.processAllMessages();
|
||||||
|
|
||||||
|
// FACE detect and authenticate are NOT triggered
|
||||||
|
verify(mFaceManager, never()).detectFace(any(), any(), anyInt());
|
||||||
|
verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt(),
|
||||||
|
anyBoolean());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -764,24 +809,6 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
|||||||
assertThat(didFaceAuthRun).isFalse();
|
assertThat(didFaceAuthRun).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void testStrongAuthExceptOnBouncer(int strongAuth) {
|
|
||||||
when(mKeyguardBypassController.canBypass()).thenReturn(true);
|
|
||||||
mKeyguardUpdateMonitor.setKeyguardBypassController(mKeyguardBypassController);
|
|
||||||
when(mStrongAuthTracker.getStrongAuthForUser(anyInt())).thenReturn(strongAuth);
|
|
||||||
|
|
||||||
mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON);
|
|
||||||
mTestableLooper.processAllMessages();
|
|
||||||
keyguardIsVisible();
|
|
||||||
verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt(), anyBoolean());
|
|
||||||
|
|
||||||
// Stop scanning when bouncer becomes visible
|
|
||||||
setKeyguardBouncerVisibility(true);
|
|
||||||
clearInvocations(mFaceManager);
|
|
||||||
mKeyguardUpdateMonitor.requestFaceAuth(FaceAuthApiRequestReason.UDFPS_POINTER_DOWN);
|
|
||||||
verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt(),
|
|
||||||
anyBoolean());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTriesToAuthenticate_whenAssistant() {
|
public void testTriesToAuthenticate_whenAssistant() {
|
||||||
mKeyguardUpdateMonitor.setKeyguardShowing(true, true);
|
mKeyguardUpdateMonitor.setKeyguardShowing(true, true);
|
||||||
@@ -792,10 +819,9 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTriesToAuthenticate_whenTrustOnAgentKeyguard_ifBypass() {
|
public void testTriesToAuthenticate_whenTrustOnAgentKeyguard_ifBypass() {
|
||||||
mKeyguardUpdateMonitor.setKeyguardBypassController(mKeyguardBypassController);
|
|
||||||
mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON);
|
mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON);
|
||||||
mTestableLooper.processAllMessages();
|
mTestableLooper.processAllMessages();
|
||||||
when(mKeyguardBypassController.canBypass()).thenReturn(true);
|
lockscreenBypassIsAllowed();
|
||||||
mKeyguardUpdateMonitor.onTrustChanged(true /* enabled */,
|
mKeyguardUpdateMonitor.onTrustChanged(true /* enabled */,
|
||||||
KeyguardUpdateMonitor.getCurrentUser(), 0 /* flags */,
|
KeyguardUpdateMonitor.getCurrentUser(), 0 /* flags */,
|
||||||
new ArrayList<>());
|
new ArrayList<>());
|
||||||
@@ -815,26 +841,17 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIgnoresAuth_whenLockdown() {
|
public void testNoFaceAuth_whenLockDown() {
|
||||||
mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON);
|
when(mStrongAuthTracker.isUnlockingWithBiometricAllowed(anyBoolean())).thenReturn(false);
|
||||||
mTestableLooper.processAllMessages();
|
userDeviceLockDown();
|
||||||
when(mStrongAuthTracker.getStrongAuthForUser(anyInt())).thenReturn(
|
|
||||||
KeyguardUpdateMonitor.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN);
|
|
||||||
|
|
||||||
|
mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON);
|
||||||
keyguardIsVisible();
|
keyguardIsVisible();
|
||||||
|
mTestableLooper.processAllMessages();
|
||||||
|
|
||||||
verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt(),
|
verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt(),
|
||||||
anyBoolean());
|
anyBoolean());
|
||||||
}
|
verify(mFaceManager, never()).detectFace(any(), any(), anyInt());
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testTriesToAuthenticate_whenLockout() {
|
|
||||||
mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON);
|
|
||||||
mTestableLooper.processAllMessages();
|
|
||||||
when(mStrongAuthTracker.getStrongAuthForUser(anyInt())).thenReturn(
|
|
||||||
KeyguardUpdateMonitor.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT);
|
|
||||||
|
|
||||||
keyguardIsVisible();
|
|
||||||
verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt(), anyBoolean());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -1329,7 +1346,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
|||||||
mStatusBarStateListener.onStateChanged(StatusBarState.SHADE_LOCKED);
|
mStatusBarStateListener.onStateChanged(StatusBarState.SHADE_LOCKED);
|
||||||
setKeyguardBouncerVisibility(false /* isVisible */);
|
setKeyguardBouncerVisibility(false /* isVisible */);
|
||||||
mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON);
|
mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON);
|
||||||
when(mKeyguardBypassController.canBypass()).thenReturn(true);
|
lockscreenBypassIsAllowed();
|
||||||
keyguardIsVisible();
|
keyguardIsVisible();
|
||||||
|
|
||||||
// WHEN status bar state reports a change to the keyguard that would normally indicate to
|
// WHEN status bar state reports a change to the keyguard that would normally indicate to
|
||||||
@@ -1513,11 +1530,9 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
|||||||
userNotCurrentlySwitching();
|
userNotCurrentlySwitching();
|
||||||
|
|
||||||
// This disables face auth
|
// This disables face auth
|
||||||
when(mStrongAuthTracker.getStrongAuthForUser(KeyguardUpdateMonitor.getCurrentUser()))
|
when(mStrongAuthTracker.isUnlockingWithBiometricAllowed(anyBoolean())).thenReturn(false);
|
||||||
.thenReturn(STRONG_AUTH_REQUIRED_AFTER_BOOT);
|
|
||||||
mTestableLooper.processAllMessages();
|
mTestableLooper.processAllMessages();
|
||||||
|
|
||||||
|
|
||||||
assertThat(mKeyguardUpdateMonitor.shouldListenForFace()).isFalse();
|
assertThat(mKeyguardUpdateMonitor.shouldListenForFace()).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1981,6 +1996,109 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStrongAuthChange_lockDown_stopsFpAndFaceListeningState() {
|
||||||
|
// GIVEN device is listening for face and fingerprint
|
||||||
|
mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON);
|
||||||
|
mTestableLooper.processAllMessages();
|
||||||
|
keyguardIsVisible();
|
||||||
|
|
||||||
|
verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt(), anyBoolean());
|
||||||
|
verify(mFingerprintManager).authenticate(any(), any(), any(), any(), anyInt(), anyInt(),
|
||||||
|
anyInt());
|
||||||
|
|
||||||
|
final CancellationSignal faceCancel = spy(mKeyguardUpdateMonitor.mFaceCancelSignal);
|
||||||
|
final CancellationSignal fpCancel = spy(mKeyguardUpdateMonitor.mFingerprintCancelSignal);
|
||||||
|
mKeyguardUpdateMonitor.mFaceCancelSignal = faceCancel;
|
||||||
|
mKeyguardUpdateMonitor.mFingerprintCancelSignal = fpCancel;
|
||||||
|
KeyguardUpdateMonitorCallback callback = mock(KeyguardUpdateMonitorCallback.class);
|
||||||
|
mKeyguardUpdateMonitor.registerCallback(callback);
|
||||||
|
|
||||||
|
// WHEN strong auth changes and device is in user lockdown
|
||||||
|
when(mStrongAuthTracker.isUnlockingWithBiometricAllowed(anyBoolean())).thenReturn(false);
|
||||||
|
userDeviceLockDown();
|
||||||
|
mKeyguardUpdateMonitor.notifyStrongAuthAllowedChanged(getCurrentUser());
|
||||||
|
mTestableLooper.processAllMessages();
|
||||||
|
|
||||||
|
// THEN face and fingerprint listening are cancelled
|
||||||
|
verify(faceCancel).cancel();
|
||||||
|
verify(callback).onBiometricRunningStateChanged(
|
||||||
|
eq(false), eq(BiometricSourceType.FACE));
|
||||||
|
verify(fpCancel).cancel();
|
||||||
|
verify(callback).onBiometricRunningStateChanged(
|
||||||
|
eq(false), eq(BiometricSourceType.FINGERPRINT));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNonStrongBiometricAllowedChanged_stopsFaceListeningState() {
|
||||||
|
// GIVEN device is listening for face and fingerprint
|
||||||
|
mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON);
|
||||||
|
mTestableLooper.processAllMessages();
|
||||||
|
keyguardIsVisible();
|
||||||
|
|
||||||
|
verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt(), anyBoolean());
|
||||||
|
|
||||||
|
final CancellationSignal faceCancel = spy(mKeyguardUpdateMonitor.mFaceCancelSignal);
|
||||||
|
mKeyguardUpdateMonitor.mFaceCancelSignal = faceCancel;
|
||||||
|
KeyguardUpdateMonitorCallback callback = mock(KeyguardUpdateMonitorCallback.class);
|
||||||
|
mKeyguardUpdateMonitor.registerCallback(callback);
|
||||||
|
|
||||||
|
// WHEN non-strong biometric allowed changes
|
||||||
|
when(mStrongAuthTracker.isUnlockingWithBiometricAllowed(anyBoolean())).thenReturn(false);
|
||||||
|
mKeyguardUpdateMonitor.notifyNonStrongBiometricAllowedChanged(getCurrentUser());
|
||||||
|
mTestableLooper.processAllMessages();
|
||||||
|
|
||||||
|
// THEN face and fingerprint listening are cancelled
|
||||||
|
verify(faceCancel).cancel();
|
||||||
|
verify(callback).onBiometricRunningStateChanged(
|
||||||
|
eq(false), eq(BiometricSourceType.FACE));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testShouldListenForFace_withLockedDown_returnsFalse()
|
||||||
|
throws RemoteException {
|
||||||
|
keyguardNotGoingAway();
|
||||||
|
bouncerFullyVisibleAndNotGoingToSleep();
|
||||||
|
currentUserIsPrimary();
|
||||||
|
currentUserDoesNotHaveTrust();
|
||||||
|
biometricsNotDisabledThroughDevicePolicyManager();
|
||||||
|
biometricsEnabledForCurrentUser();
|
||||||
|
userNotCurrentlySwitching();
|
||||||
|
supportsFaceDetection();
|
||||||
|
mTestableLooper.processAllMessages();
|
||||||
|
|
||||||
|
assertThat(mKeyguardUpdateMonitor.shouldListenForFace()).isTrue();
|
||||||
|
|
||||||
|
userDeviceLockDown();
|
||||||
|
|
||||||
|
assertThat(mKeyguardUpdateMonitor.shouldListenForFace()).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void userDeviceLockDown() {
|
||||||
|
when(mStrongAuthTracker.isUnlockingWithBiometricAllowed(anyBoolean())).thenReturn(false);
|
||||||
|
when(mStrongAuthTracker.getStrongAuthForUser(mCurrentUserId))
|
||||||
|
.thenReturn(STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void supportsFaceDetection() {
|
||||||
|
when(mFaceSensorProperties.get(anyInt()))
|
||||||
|
.thenReturn(createFaceSensorProperties(
|
||||||
|
/* supportsFaceDetection = */ true));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void lockscreenBypassIsAllowed() {
|
||||||
|
mockCanBypassLockscreen(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void mockCanBypassLockscreen(boolean canBypass) {
|
||||||
|
mKeyguardUpdateMonitor.setKeyguardBypassController(mKeyguardBypassController);
|
||||||
|
when(mKeyguardBypassController.canBypass()).thenReturn(canBypass);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void lockscreenBypassIsNotAllowed() {
|
||||||
|
mockCanBypassLockscreen(false);
|
||||||
|
}
|
||||||
|
|
||||||
private void cleanupKeyguardUpdateMonitor() {
|
private void cleanupKeyguardUpdateMonitor() {
|
||||||
if (mKeyguardUpdateMonitor != null) {
|
if (mKeyguardUpdateMonitor != null) {
|
||||||
mKeyguardUpdateMonitor.removeCallback(mTestCallback);
|
mKeyguardUpdateMonitor.removeCallback(mTestCallback);
|
||||||
@@ -2074,9 +2192,16 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void strongAuthRequiredEncrypted() {
|
||||||
|
when(mStrongAuthTracker.getStrongAuthForUser(KeyguardUpdateMonitor.getCurrentUser()))
|
||||||
|
.thenReturn(STRONG_AUTH_REQUIRED_AFTER_BOOT);
|
||||||
|
when(mStrongAuthTracker.isUnlockingWithBiometricAllowed(anyBoolean())).thenReturn(false);
|
||||||
|
}
|
||||||
|
|
||||||
private void strongAuthNotRequired() {
|
private void strongAuthNotRequired() {
|
||||||
when(mStrongAuthTracker.getStrongAuthForUser(KeyguardUpdateMonitor.getCurrentUser()))
|
when(mStrongAuthTracker.getStrongAuthForUser(KeyguardUpdateMonitor.getCurrentUser()))
|
||||||
.thenReturn(0);
|
.thenReturn(0);
|
||||||
|
when(mStrongAuthTracker.isUnlockingWithBiometricAllowed(anyBoolean())).thenReturn(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void currentUserDoesNotHaveTrust() {
|
private void currentUserDoesNotHaveTrust() {
|
||||||
@@ -2117,6 +2242,10 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
|||||||
setKeyguardBouncerVisibility(true);
|
setKeyguardBouncerVisibility(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void bouncerNotVisible() {
|
||||||
|
setKeyguardBouncerVisibility(false);
|
||||||
|
}
|
||||||
|
|
||||||
private void setKeyguardBouncerVisibility(boolean isVisible) {
|
private void setKeyguardBouncerVisibility(boolean isVisible) {
|
||||||
mKeyguardUpdateMonitor.sendPrimaryBouncerChanged(isVisible, isVisible);
|
mKeyguardUpdateMonitor.sendPrimaryBouncerChanged(isVisible, isVisible);
|
||||||
mTestableLooper.processAllMessages();
|
mTestableLooper.processAllMessages();
|
||||||
|
|||||||
Reference in New Issue
Block a user