From 0ef9b6dc302efd7b21a6cbd12c1ea1bbed0a5249 Mon Sep 17 00:00:00 2001 From: Diya Bera Date: Mon, 27 Mar 2023 18:23:07 +0000 Subject: Use callback to update sensor properties The callback is called in BiometricServiceRegistry where the props are updated. Any update in the value will update the cached values in Keyguard, keeping it up to date and avoiding stale values. Bug: b/272528261 Test: Manual (tried enrollment and authentication for face and fingerprint), atest KeyguardUpdateMonitorTest Change-Id: I1f4e73db257057c2f82624da1163a146a4b65a65 --- .../android/keyguard/KeyguardUpdateMonitor.java | 30 +++++++-- .../keyguard/KeyguardUpdateMonitorTest.java | 78 +++++++++++++++++----- 2 files changed, 89 insertions(+), 19 deletions(-) diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java index b3a641cbe93a..64366ee2004d 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -98,11 +98,13 @@ import android.hardware.biometrics.SensorProperties; import android.hardware.face.FaceAuthenticateOptions; import android.hardware.face.FaceManager; import android.hardware.face.FaceSensorPropertiesInternal; +import android.hardware.face.IFaceAuthenticatorsRegisteredCallback; import android.hardware.fingerprint.FingerprintAuthenticateOptions; import android.hardware.fingerprint.FingerprintManager; import android.hardware.fingerprint.FingerprintManager.AuthenticationCallback; import android.hardware.fingerprint.FingerprintManager.AuthenticationResult; import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; +import android.hardware.fingerprint.IFingerprintAuthenticatorsRegisteredCallback; import android.hardware.usb.UsbManager; import android.nfc.NfcAdapter; import android.os.CancellationSignal; @@ -171,6 +173,7 @@ import java.io.PrintWriter; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; @@ -1888,8 +1891,9 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab CancellationSignal mFingerprintCancelSignal; @VisibleForTesting CancellationSignal mFaceCancelSignal; - private List mFingerprintSensorProperties; - private List mFaceSensorProperties; + private List mFingerprintSensorProperties = + Collections.emptyList(); + private List mFaceSensorProperties = Collections.emptyList(); private boolean mFingerprintLockedOut; private boolean mFingerprintLockedOutPermanent; private boolean mFaceLockedOutPermanent; @@ -2371,11 +2375,29 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab setStrongAuthTracker(mStrongAuthTracker); if (mFpm != null) { - mFingerprintSensorProperties = mFpm.getSensorPropertiesInternal(); + mFpm.addAuthenticatorsRegisteredCallback( + new IFingerprintAuthenticatorsRegisteredCallback.Stub() { + @Override + public void onAllAuthenticatorsRegistered( + List sensors) + throws RemoteException { + mFingerprintSensorProperties = sensors; + updateFingerprintListeningState(BIOMETRIC_ACTION_UPDATE); + mLogger.d("FingerprintManager onAllAuthenticatorsRegistered"); + } + }); mFpm.addLockoutResetCallback(mFingerprintLockoutResetCallback); } if (mFaceManager != null) { - mFaceSensorProperties = mFaceManager.getSensorPropertiesInternal(); + mFaceManager.addAuthenticatorsRegisteredCallback( + new IFaceAuthenticatorsRegisteredCallback.Stub() { + @Override + public void onAllAuthenticatorsRegistered( + List sensors) throws RemoteException { + mFaceSensorProperties = sensors; + mLogger.d("FaceManager onAllAuthenticatorsRegistered"); + } + }); mFaceManager.addLockoutResetCallback(mFaceLockoutResetCallback); } diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java index 86ba30cee7a3..9db6e8b6d77e 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java @@ -84,9 +84,11 @@ import android.hardware.face.FaceAuthenticateOptions; import android.hardware.face.FaceManager; import android.hardware.face.FaceSensorProperties; import android.hardware.face.FaceSensorPropertiesInternal; +import android.hardware.face.IFaceAuthenticatorsRegisteredCallback; import android.hardware.fingerprint.FingerprintManager; import android.hardware.fingerprint.FingerprintSensorProperties; import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; +import android.hardware.fingerprint.IFingerprintAuthenticatorsRegisteredCallback; import android.hardware.usb.UsbManager; import android.hardware.usb.UsbPort; import android.hardware.usb.UsbPortStatus; @@ -194,8 +196,6 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { @Mock private FaceManager mFaceManager; @Mock - private List mFaceSensorProperties; - @Mock private BiometricManager mBiometricManager; @Mock private PackageManager mPackageManager; @@ -254,6 +254,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { @Mock private Uri mURI; + private List mFaceSensorProperties; private List mFingerprintSensorProperties; private final int mCurrentUserId = 100; private final UserInfo mCurrentUserInfo = new UserInfo(mCurrentUserId, "Test user", 0); @@ -274,21 +275,22 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { private StatusBarStateController.StateListener mStatusBarStateListener; private IBiometricEnabledOnKeyguardCallback mBiometricEnabledOnKeyguardCallback; private FaceWakeUpTriggersConfig mFaceWakeUpTriggersConfig; + private IFingerprintAuthenticatorsRegisteredCallback + mFingerprintAuthenticatorsRegisteredCallback; + private IFaceAuthenticatorsRegisteredCallback mFaceAuthenticatorsRegisteredCallback; private final InstanceId mKeyguardInstanceId = InstanceId.fakeInstanceId(999); @Before public void setup() throws RemoteException { MockitoAnnotations.initMocks(this); + + mFaceSensorProperties = + List.of(createFaceSensorProperties(/* supportsFaceDetection = */ false)); when(mFaceManager.isHardwareDetected()).thenReturn(true); when(mAuthController.isFaceAuthEnrolled(anyInt())).thenReturn(true); when(mFaceManager.getSensorPropertiesInternal()).thenReturn(mFaceSensorProperties); when(mSessionTracker.getSessionId(SESSION_KEYGUARD)).thenReturn(mKeyguardInstanceId); - // IBiometricsFace@1.0 does not support detection, only authentication. - when(mFaceSensorProperties.isEmpty()).thenReturn(false); - when(mFaceSensorProperties.get(anyInt())).thenReturn( - createFaceSensorProperties(/* supportsFaceDetection = */ false)); - mFingerprintSensorProperties = List.of( new FingerprintSensorPropertiesInternal(1 /* sensorId */, FingerprintSensorProperties.STRENGTH_STRONG, @@ -345,6 +347,20 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { mKeyguardUpdateMonitor = new TestableKeyguardUpdateMonitor(mContext); + ArgumentCaptor faceCaptor = + ArgumentCaptor.forClass(IFaceAuthenticatorsRegisteredCallback.class); + verify(mFaceManager).addAuthenticatorsRegisteredCallback(faceCaptor.capture()); + mFaceAuthenticatorsRegisteredCallback = faceCaptor.getValue(); + mFaceAuthenticatorsRegisteredCallback.onAllAuthenticatorsRegistered(mFaceSensorProperties); + + ArgumentCaptor fingerprintCaptor = + ArgumentCaptor.forClass(IFingerprintAuthenticatorsRegisteredCallback.class); + verify(mFingerprintManager).addAuthenticatorsRegisteredCallback( + fingerprintCaptor.capture()); + mFingerprintAuthenticatorsRegisteredCallback = fingerprintCaptor.getValue(); + mFingerprintAuthenticatorsRegisteredCallback + .onAllAuthenticatorsRegistered(mFingerprintSensorProperties); + verify(mBiometricManager) .registerEnabledOnKeyguardCallback(mBiometricEnabledCallbackArgCaptor.capture()); mBiometricEnabledOnKeyguardCallback = mBiometricEnabledCallbackArgCaptor.getValue(); @@ -651,7 +667,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { } @Test - public void whenDetectFace_biometricDetectCallback() { + public void whenDetectFace_biometricDetectCallback() throws RemoteException { ArgumentCaptor faceDetectCallbackCaptor = ArgumentCaptor.forClass(FaceManager.FaceDetectionCallback.class); @@ -801,7 +817,8 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { } @Test - public void nofaceDetect_whenStrongAuthRequiredAndBypassUdfpsSupportedAndFpRunning() { + public void nofaceDetect_whenStrongAuthRequiredAndBypassUdfpsSupportedAndFpRunning() + throws RemoteException { // GIVEN bypass is enabled, face detection is supported lockscreenBypassIsAllowed(); supportsFaceDetection(); @@ -825,7 +842,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { } @Test - public void faceDetect_whenStrongAuthRequiredAndBypass() { + public void faceDetect_whenStrongAuthRequiredAndBypass() throws RemoteException { givenDetectFace(); // FACE detect is triggered, not authenticate @@ -2548,6 +2565,37 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { assertThat(captor.getValue().getWakeReason()) .isEqualTo(PowerManager.WAKE_REASON_POWER_BUTTON); } + @Test + public void testFingerprintSensorProperties() throws RemoteException { + mFingerprintAuthenticatorsRegisteredCallback.onAllAuthenticatorsRegistered( + new ArrayList<>()); + + assertThat(mKeyguardUpdateMonitor.isUnlockWithFingerprintPossible( + KeyguardUpdateMonitor.getCurrentUser())).isFalse(); + + mFingerprintAuthenticatorsRegisteredCallback + .onAllAuthenticatorsRegistered(mFingerprintSensorProperties); + + verifyFingerprintAuthenticateCall(); + assertThat(mKeyguardUpdateMonitor.isUnlockWithFingerprintPossible( + KeyguardUpdateMonitor.getCurrentUser())).isTrue(); + } + @Test + public void testFaceSensorProperties() throws RemoteException { + mFaceAuthenticatorsRegisteredCallback.onAllAuthenticatorsRegistered(new ArrayList<>()); + + assertThat(mKeyguardUpdateMonitor.isFaceAuthEnabledForUser( + KeyguardUpdateMonitor.getCurrentUser())).isFalse(); + + mFaceAuthenticatorsRegisteredCallback.onAllAuthenticatorsRegistered(mFaceSensorProperties); + biometricsEnabledForCurrentUser(); + + verifyFaceAuthenticateNeverCalled(); + verifyFaceDetectNeverCalled(); + assertThat(mKeyguardUpdateMonitor.isFaceAuthEnabledForUser( + KeyguardUpdateMonitor.getCurrentUser())).isTrue(); + } + private void verifyFingerprintAuthenticateNeverCalled() { verify(mFingerprintManager, never()).authenticate(any(), any(), any(), any(), any()); @@ -2591,10 +2639,10 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { .thenReturn(STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN); } - private void supportsFaceDetection() { - when(mFaceSensorProperties.get(anyInt())) - .thenReturn(createFaceSensorProperties( - /* supportsFaceDetection = */ true)); + private void supportsFaceDetection() throws RemoteException { + mFaceSensorProperties = + List.of(createFaceSensorProperties(/* supportsFaceDetection = */ true)); + mFaceAuthenticatorsRegisteredCallback.onAllAuthenticatorsRegistered(mFaceSensorProperties); } private void lockscreenBypassIsAllowed() { @@ -2804,7 +2852,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { mTestableLooper.processAllMessages(); } - private void givenDetectFace() { + private void givenDetectFace() throws RemoteException { // GIVEN bypass is enabled, face detection is supported and strong auth is required lockscreenBypassIsAllowed(); supportsFaceDetection(); -- cgit v1.2.3-59-g8ed1b