Loading packages/SystemUI/src/com/android/systemui/biometrics/BiometricNotificationService.java +38 −7 Original line number Diff line number Diff line Loading @@ -21,6 +21,8 @@ import static android.app.PendingIntent.FLAG_IMMUTABLE; import static com.android.systemui.biometrics.BiometricNotificationBroadcastReceiver.ACTION_SHOW_FACE_REENROLL_DIALOG; import static com.android.systemui.biometrics.BiometricNotificationBroadcastReceiver.ACTION_SHOW_FINGERPRINT_REENROLL_DIALOG; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationManager; Loading @@ -30,6 +32,9 @@ import android.content.Intent; import android.content.IntentFilter; import android.hardware.biometrics.BiometricFaceConstants; import android.hardware.biometrics.BiometricSourceType; import android.hardware.biometrics.BiometricStateListener; import android.hardware.face.FaceManager; import android.hardware.fingerprint.FingerprintManager; import android.os.Handler; import android.os.UserHandle; import android.provider.Settings; Loading @@ -42,7 +47,6 @@ import com.android.systemui.R; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.statusbar.policy.KeyguardStateController; import java.util.Optional; import javax.inject.Inject; Loading @@ -69,6 +73,8 @@ public class BiometricNotificationService implements CoreStartable { private final NotificationManager mNotificationManager; private final BiometricNotificationBroadcastReceiver mBroadcastReceiver; private final FingerprintReEnrollNotification mFingerprintReEnrollNotification; private final FingerprintManager mFingerprintManager; private final FaceManager mFaceManager; private NotificationChannel mNotificationChannel; private boolean mFaceNotificationQueued; private boolean mFingerprintNotificationQueued; Loading Loading @@ -119,14 +125,29 @@ public class BiometricNotificationService implements CoreStartable { } }; private final BiometricStateListener mFaceStateListener = new BiometricStateListener() { @Override public void onEnrollmentsChanged(int userId, int sensorId, boolean hasEnrollments) { mNotificationManager.cancelAsUser(TAG, FACE_NOTIFICATION_ID, UserHandle.CURRENT); } }; private final BiometricStateListener mFingerprintStateListener = new BiometricStateListener() { @Override public void onEnrollmentsChanged(int userId, int sensorId, boolean hasEnrollments) { mNotificationManager.cancelAsUser(TAG, FINGERPRINT_NOTIFICATION_ID, UserHandle.CURRENT); } }; @Inject public BiometricNotificationService(Context context, KeyguardUpdateMonitor keyguardUpdateMonitor, KeyguardStateController keyguardStateController, Handler handler, NotificationManager notificationManager, BiometricNotificationBroadcastReceiver biometricNotificationBroadcastReceiver, Optional<FingerprintReEnrollNotification> fingerprintReEnrollNotification) { public BiometricNotificationService(@NonNull Context context, @NonNull KeyguardUpdateMonitor keyguardUpdateMonitor, @NonNull KeyguardStateController keyguardStateController, @NonNull Handler handler, @NonNull NotificationManager notificationManager, @NonNull BiometricNotificationBroadcastReceiver biometricNotificationBroadcastReceiver, @NonNull Optional<FingerprintReEnrollNotification> fingerprintReEnrollNotification, @Nullable FingerprintManager fingerprintManager, @Nullable FaceManager faceManager) { mContext = context; mKeyguardUpdateMonitor = keyguardUpdateMonitor; mKeyguardStateController = keyguardStateController; Loading @@ -135,6 +156,8 @@ public class BiometricNotificationService implements CoreStartable { mBroadcastReceiver = biometricNotificationBroadcastReceiver; mFingerprintReEnrollNotification = fingerprintReEnrollNotification.orElse( new FingerprintReEnrollNotificationImpl()); mFingerprintManager = fingerprintManager; mFaceManager = faceManager; } @Override Loading @@ -148,9 +171,16 @@ public class BiometricNotificationService implements CoreStartable { intentFilter.addAction(ACTION_SHOW_FACE_REENROLL_DIALOG); mContext.registerReceiver(mBroadcastReceiver, intentFilter, Context.RECEIVER_EXPORTED_UNAUDITED); if (mFingerprintManager != null) { mFingerprintManager.registerBiometricStateListener(mFingerprintStateListener); } if (mFaceManager != null) { mFaceManager.registerBiometricStateListener(mFaceStateListener); } } private void queueFaceReenrollNotification() { Log.d(TAG, "Face re-enroll notification queued."); mFaceNotificationQueued = true; final String title = mContext.getString(R.string.face_re_enroll_notification_title); final String content = mContext.getString( Loading @@ -163,6 +193,7 @@ public class BiometricNotificationService implements CoreStartable { } private void queueFingerprintReenrollNotification() { Log.d(TAG, "Fingerprint re-enroll notification queued."); mFingerprintNotificationQueued = true; final String title = mContext.getString(R.string.fingerprint_re_enroll_notification_title); final String content = mContext.getString( Loading packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricNotificationServiceTest.java +73 −3 Original line number Diff line number Diff line Loading @@ -30,7 +30,11 @@ import android.app.Notification; import android.app.NotificationManager; import android.hardware.biometrics.BiometricFaceConstants; import android.hardware.biometrics.BiometricSourceType; import android.hardware.biometrics.BiometricStateListener; import android.hardware.face.FaceManager; import android.hardware.fingerprint.FingerprintManager; import android.os.Handler; import android.os.UserHandle; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; Loading Loading @@ -69,6 +73,10 @@ public class BiometricNotificationServiceTest extends SysuiTestCase { Optional<FingerprintReEnrollNotification> mFingerprintReEnrollNotificationOptional; @Mock FingerprintReEnrollNotification mFingerprintReEnrollNotification; @Mock FingerprintManager mFingerprintManager; @Mock FaceManager mFaceManager; private static final String TAG = "BiometricNotificationService"; private static final int FACE_NOTIFICATION_ID = 1; Loading @@ -81,6 +89,8 @@ public class BiometricNotificationServiceTest extends SysuiTestCase { private TestableLooper mLooper; private KeyguardUpdateMonitorCallback mKeyguardUpdateMonitorCallback; private KeyguardStateController.Callback mKeyguardStateControllerCallback; private BiometricStateListener mFaceStateListener; private BiometricStateListener mFingerprintStateListener; @Before public void setUp() { Loading @@ -99,25 +109,37 @@ public class BiometricNotificationServiceTest extends SysuiTestCase { mKeyguardUpdateMonitor, mKeyguardStateController, handler, mNotificationManager, broadcastReceiver, mFingerprintReEnrollNotificationOptional); mFingerprintReEnrollNotificationOptional, mFingerprintManager, mFaceManager); biometricNotificationService.start(); ArgumentCaptor<KeyguardUpdateMonitorCallback> updateMonitorCallbackArgumentCaptor = ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback.class); ArgumentCaptor<KeyguardStateController.Callback> stateControllerCallbackArgumentCaptor = ArgumentCaptor.forClass(KeyguardStateController.Callback.class); ArgumentCaptor<BiometricStateListener> faceStateListenerArgumentCaptor = ArgumentCaptor.forClass(BiometricStateListener.class); ArgumentCaptor<BiometricStateListener> fingerprintStateListenerArgumentCaptor = ArgumentCaptor.forClass(BiometricStateListener.class); verify(mKeyguardUpdateMonitor).registerCallback( updateMonitorCallbackArgumentCaptor.capture()); verify(mKeyguardStateController).addCallback( stateControllerCallbackArgumentCaptor.capture()); verify(mFaceManager).registerBiometricStateListener( faceStateListenerArgumentCaptor.capture()); verify(mFingerprintManager).registerBiometricStateListener( fingerprintStateListenerArgumentCaptor.capture()); mFaceStateListener = faceStateListenerArgumentCaptor.getValue(); mFingerprintStateListener = fingerprintStateListenerArgumentCaptor.getValue(); mKeyguardUpdateMonitorCallback = updateMonitorCallbackArgumentCaptor.getValue(); mKeyguardStateControllerCallback = stateControllerCallbackArgumentCaptor.getValue(); } @Test public void testShowFingerprintReEnrollNotification() { public void testShowFingerprintReEnrollNotification_onAcquiredReEnroll() { when(mKeyguardStateController.isShowing()).thenReturn(false); mKeyguardUpdateMonitorCallback.onBiometricHelp( Loading @@ -139,7 +161,7 @@ public class BiometricNotificationServiceTest extends SysuiTestCase { .isEqualTo(ACTION_SHOW_FINGERPRINT_REENROLL_DIALOG); } @Test public void testShowFaceReEnrollNotification() { public void testShowFaceReEnrollNotification_onErrorReEnroll() { when(mKeyguardStateController.isShowing()).thenReturn(false); mKeyguardUpdateMonitorCallback.onBiometricError( Loading @@ -161,4 +183,52 @@ public class BiometricNotificationServiceTest extends SysuiTestCase { .isEqualTo(ACTION_SHOW_FACE_REENROLL_DIALOG); } @Test public void testCancelReEnrollmentNotification_onFaceEnrollmentStateChange() { when(mKeyguardStateController.isShowing()).thenReturn(false); mKeyguardUpdateMonitorCallback.onBiometricError( BiometricFaceConstants.BIOMETRIC_ERROR_RE_ENROLL, "Testing Face Re-enrollment" /* errString */, BiometricSourceType.FACE ); mKeyguardStateControllerCallback.onKeyguardShowingChanged(); mLooper.moveTimeForward(SHOW_NOTIFICATION_DELAY_MS); mLooper.processAllMessages(); verify(mNotificationManager).notifyAsUser(eq(TAG), eq(FACE_NOTIFICATION_ID), mNotificationArgumentCaptor.capture(), any()); mFaceStateListener.onEnrollmentsChanged(0 /* userId */, 0 /* sensorId */, false /* hasEnrollments */); verify(mNotificationManager).cancelAsUser(eq(TAG), eq(FACE_NOTIFICATION_ID), eq(UserHandle.CURRENT)); } @Test public void testCancelReEnrollmentNotification_onFingerprintEnrollmentStateChange() { when(mKeyguardStateController.isShowing()).thenReturn(false); mKeyguardUpdateMonitorCallback.onBiometricHelp( FINGERPRINT_ACQUIRED_RE_ENROLL, "Testing Fingerprint Re-enrollment" /* errString */, BiometricSourceType.FINGERPRINT ); mKeyguardStateControllerCallback.onKeyguardShowingChanged(); mLooper.moveTimeForward(SHOW_NOTIFICATION_DELAY_MS); mLooper.processAllMessages(); verify(mNotificationManager).notifyAsUser(eq(TAG), eq(FINGERPRINT_NOTIFICATION_ID), mNotificationArgumentCaptor.capture(), any()); mFingerprintStateListener.onEnrollmentsChanged(0 /* userId */, 0 /* sensorId */, false /* hasEnrollments */); verify(mNotificationManager).cancelAsUser(eq(TAG), eq(FINGERPRINT_NOTIFICATION_ID), eq(UserHandle.CURRENT)); } } services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java +0 −4 Original line number Diff line number Diff line Loading @@ -43,7 +43,6 @@ import com.android.server.biometrics.log.BiometricLogger; import com.android.server.biometrics.log.OperationContextExt; import com.android.server.biometrics.sensors.AuthSessionCoordinator; import com.android.server.biometrics.sensors.AuthenticationClient; import com.android.server.biometrics.sensors.BiometricNotificationUtils; import com.android.server.biometrics.sensors.ClientMonitorCallback; import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter; import com.android.server.biometrics.sensors.ClientMonitorCompositeCallback; Loading Loading @@ -242,9 +241,6 @@ class FaceAuthenticationClient extends AuthenticationClient<AidlSession, FaceAut vendorCode, getTargetUserId())); if (error == BiometricConstants.BIOMETRIC_ERROR_RE_ENROLL) { BiometricNotificationUtils.showReEnrollmentNotification(getContext()); } super.onError(error, vendorCode); } Loading Loading
packages/SystemUI/src/com/android/systemui/biometrics/BiometricNotificationService.java +38 −7 Original line number Diff line number Diff line Loading @@ -21,6 +21,8 @@ import static android.app.PendingIntent.FLAG_IMMUTABLE; import static com.android.systemui.biometrics.BiometricNotificationBroadcastReceiver.ACTION_SHOW_FACE_REENROLL_DIALOG; import static com.android.systemui.biometrics.BiometricNotificationBroadcastReceiver.ACTION_SHOW_FINGERPRINT_REENROLL_DIALOG; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationManager; Loading @@ -30,6 +32,9 @@ import android.content.Intent; import android.content.IntentFilter; import android.hardware.biometrics.BiometricFaceConstants; import android.hardware.biometrics.BiometricSourceType; import android.hardware.biometrics.BiometricStateListener; import android.hardware.face.FaceManager; import android.hardware.fingerprint.FingerprintManager; import android.os.Handler; import android.os.UserHandle; import android.provider.Settings; Loading @@ -42,7 +47,6 @@ import com.android.systemui.R; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.statusbar.policy.KeyguardStateController; import java.util.Optional; import javax.inject.Inject; Loading @@ -69,6 +73,8 @@ public class BiometricNotificationService implements CoreStartable { private final NotificationManager mNotificationManager; private final BiometricNotificationBroadcastReceiver mBroadcastReceiver; private final FingerprintReEnrollNotification mFingerprintReEnrollNotification; private final FingerprintManager mFingerprintManager; private final FaceManager mFaceManager; private NotificationChannel mNotificationChannel; private boolean mFaceNotificationQueued; private boolean mFingerprintNotificationQueued; Loading Loading @@ -119,14 +125,29 @@ public class BiometricNotificationService implements CoreStartable { } }; private final BiometricStateListener mFaceStateListener = new BiometricStateListener() { @Override public void onEnrollmentsChanged(int userId, int sensorId, boolean hasEnrollments) { mNotificationManager.cancelAsUser(TAG, FACE_NOTIFICATION_ID, UserHandle.CURRENT); } }; private final BiometricStateListener mFingerprintStateListener = new BiometricStateListener() { @Override public void onEnrollmentsChanged(int userId, int sensorId, boolean hasEnrollments) { mNotificationManager.cancelAsUser(TAG, FINGERPRINT_NOTIFICATION_ID, UserHandle.CURRENT); } }; @Inject public BiometricNotificationService(Context context, KeyguardUpdateMonitor keyguardUpdateMonitor, KeyguardStateController keyguardStateController, Handler handler, NotificationManager notificationManager, BiometricNotificationBroadcastReceiver biometricNotificationBroadcastReceiver, Optional<FingerprintReEnrollNotification> fingerprintReEnrollNotification) { public BiometricNotificationService(@NonNull Context context, @NonNull KeyguardUpdateMonitor keyguardUpdateMonitor, @NonNull KeyguardStateController keyguardStateController, @NonNull Handler handler, @NonNull NotificationManager notificationManager, @NonNull BiometricNotificationBroadcastReceiver biometricNotificationBroadcastReceiver, @NonNull Optional<FingerprintReEnrollNotification> fingerprintReEnrollNotification, @Nullable FingerprintManager fingerprintManager, @Nullable FaceManager faceManager) { mContext = context; mKeyguardUpdateMonitor = keyguardUpdateMonitor; mKeyguardStateController = keyguardStateController; Loading @@ -135,6 +156,8 @@ public class BiometricNotificationService implements CoreStartable { mBroadcastReceiver = biometricNotificationBroadcastReceiver; mFingerprintReEnrollNotification = fingerprintReEnrollNotification.orElse( new FingerprintReEnrollNotificationImpl()); mFingerprintManager = fingerprintManager; mFaceManager = faceManager; } @Override Loading @@ -148,9 +171,16 @@ public class BiometricNotificationService implements CoreStartable { intentFilter.addAction(ACTION_SHOW_FACE_REENROLL_DIALOG); mContext.registerReceiver(mBroadcastReceiver, intentFilter, Context.RECEIVER_EXPORTED_UNAUDITED); if (mFingerprintManager != null) { mFingerprintManager.registerBiometricStateListener(mFingerprintStateListener); } if (mFaceManager != null) { mFaceManager.registerBiometricStateListener(mFaceStateListener); } } private void queueFaceReenrollNotification() { Log.d(TAG, "Face re-enroll notification queued."); mFaceNotificationQueued = true; final String title = mContext.getString(R.string.face_re_enroll_notification_title); final String content = mContext.getString( Loading @@ -163,6 +193,7 @@ public class BiometricNotificationService implements CoreStartable { } private void queueFingerprintReenrollNotification() { Log.d(TAG, "Fingerprint re-enroll notification queued."); mFingerprintNotificationQueued = true; final String title = mContext.getString(R.string.fingerprint_re_enroll_notification_title); final String content = mContext.getString( Loading
packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricNotificationServiceTest.java +73 −3 Original line number Diff line number Diff line Loading @@ -30,7 +30,11 @@ import android.app.Notification; import android.app.NotificationManager; import android.hardware.biometrics.BiometricFaceConstants; import android.hardware.biometrics.BiometricSourceType; import android.hardware.biometrics.BiometricStateListener; import android.hardware.face.FaceManager; import android.hardware.fingerprint.FingerprintManager; import android.os.Handler; import android.os.UserHandle; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; Loading Loading @@ -69,6 +73,10 @@ public class BiometricNotificationServiceTest extends SysuiTestCase { Optional<FingerprintReEnrollNotification> mFingerprintReEnrollNotificationOptional; @Mock FingerprintReEnrollNotification mFingerprintReEnrollNotification; @Mock FingerprintManager mFingerprintManager; @Mock FaceManager mFaceManager; private static final String TAG = "BiometricNotificationService"; private static final int FACE_NOTIFICATION_ID = 1; Loading @@ -81,6 +89,8 @@ public class BiometricNotificationServiceTest extends SysuiTestCase { private TestableLooper mLooper; private KeyguardUpdateMonitorCallback mKeyguardUpdateMonitorCallback; private KeyguardStateController.Callback mKeyguardStateControllerCallback; private BiometricStateListener mFaceStateListener; private BiometricStateListener mFingerprintStateListener; @Before public void setUp() { Loading @@ -99,25 +109,37 @@ public class BiometricNotificationServiceTest extends SysuiTestCase { mKeyguardUpdateMonitor, mKeyguardStateController, handler, mNotificationManager, broadcastReceiver, mFingerprintReEnrollNotificationOptional); mFingerprintReEnrollNotificationOptional, mFingerprintManager, mFaceManager); biometricNotificationService.start(); ArgumentCaptor<KeyguardUpdateMonitorCallback> updateMonitorCallbackArgumentCaptor = ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback.class); ArgumentCaptor<KeyguardStateController.Callback> stateControllerCallbackArgumentCaptor = ArgumentCaptor.forClass(KeyguardStateController.Callback.class); ArgumentCaptor<BiometricStateListener> faceStateListenerArgumentCaptor = ArgumentCaptor.forClass(BiometricStateListener.class); ArgumentCaptor<BiometricStateListener> fingerprintStateListenerArgumentCaptor = ArgumentCaptor.forClass(BiometricStateListener.class); verify(mKeyguardUpdateMonitor).registerCallback( updateMonitorCallbackArgumentCaptor.capture()); verify(mKeyguardStateController).addCallback( stateControllerCallbackArgumentCaptor.capture()); verify(mFaceManager).registerBiometricStateListener( faceStateListenerArgumentCaptor.capture()); verify(mFingerprintManager).registerBiometricStateListener( fingerprintStateListenerArgumentCaptor.capture()); mFaceStateListener = faceStateListenerArgumentCaptor.getValue(); mFingerprintStateListener = fingerprintStateListenerArgumentCaptor.getValue(); mKeyguardUpdateMonitorCallback = updateMonitorCallbackArgumentCaptor.getValue(); mKeyguardStateControllerCallback = stateControllerCallbackArgumentCaptor.getValue(); } @Test public void testShowFingerprintReEnrollNotification() { public void testShowFingerprintReEnrollNotification_onAcquiredReEnroll() { when(mKeyguardStateController.isShowing()).thenReturn(false); mKeyguardUpdateMonitorCallback.onBiometricHelp( Loading @@ -139,7 +161,7 @@ public class BiometricNotificationServiceTest extends SysuiTestCase { .isEqualTo(ACTION_SHOW_FINGERPRINT_REENROLL_DIALOG); } @Test public void testShowFaceReEnrollNotification() { public void testShowFaceReEnrollNotification_onErrorReEnroll() { when(mKeyguardStateController.isShowing()).thenReturn(false); mKeyguardUpdateMonitorCallback.onBiometricError( Loading @@ -161,4 +183,52 @@ public class BiometricNotificationServiceTest extends SysuiTestCase { .isEqualTo(ACTION_SHOW_FACE_REENROLL_DIALOG); } @Test public void testCancelReEnrollmentNotification_onFaceEnrollmentStateChange() { when(mKeyguardStateController.isShowing()).thenReturn(false); mKeyguardUpdateMonitorCallback.onBiometricError( BiometricFaceConstants.BIOMETRIC_ERROR_RE_ENROLL, "Testing Face Re-enrollment" /* errString */, BiometricSourceType.FACE ); mKeyguardStateControllerCallback.onKeyguardShowingChanged(); mLooper.moveTimeForward(SHOW_NOTIFICATION_DELAY_MS); mLooper.processAllMessages(); verify(mNotificationManager).notifyAsUser(eq(TAG), eq(FACE_NOTIFICATION_ID), mNotificationArgumentCaptor.capture(), any()); mFaceStateListener.onEnrollmentsChanged(0 /* userId */, 0 /* sensorId */, false /* hasEnrollments */); verify(mNotificationManager).cancelAsUser(eq(TAG), eq(FACE_NOTIFICATION_ID), eq(UserHandle.CURRENT)); } @Test public void testCancelReEnrollmentNotification_onFingerprintEnrollmentStateChange() { when(mKeyguardStateController.isShowing()).thenReturn(false); mKeyguardUpdateMonitorCallback.onBiometricHelp( FINGERPRINT_ACQUIRED_RE_ENROLL, "Testing Fingerprint Re-enrollment" /* errString */, BiometricSourceType.FINGERPRINT ); mKeyguardStateControllerCallback.onKeyguardShowingChanged(); mLooper.moveTimeForward(SHOW_NOTIFICATION_DELAY_MS); mLooper.processAllMessages(); verify(mNotificationManager).notifyAsUser(eq(TAG), eq(FINGERPRINT_NOTIFICATION_ID), mNotificationArgumentCaptor.capture(), any()); mFingerprintStateListener.onEnrollmentsChanged(0 /* userId */, 0 /* sensorId */, false /* hasEnrollments */); verify(mNotificationManager).cancelAsUser(eq(TAG), eq(FINGERPRINT_NOTIFICATION_ID), eq(UserHandle.CURRENT)); } }
services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java +0 −4 Original line number Diff line number Diff line Loading @@ -43,7 +43,6 @@ import com.android.server.biometrics.log.BiometricLogger; import com.android.server.biometrics.log.OperationContextExt; import com.android.server.biometrics.sensors.AuthSessionCoordinator; import com.android.server.biometrics.sensors.AuthenticationClient; import com.android.server.biometrics.sensors.BiometricNotificationUtils; import com.android.server.biometrics.sensors.ClientMonitorCallback; import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter; import com.android.server.biometrics.sensors.ClientMonitorCompositeCallback; Loading Loading @@ -242,9 +241,6 @@ class FaceAuthenticationClient extends AuthenticationClient<AidlSession, FaceAut vendorCode, getTargetUserId())); if (error == BiometricConstants.BIOMETRIC_ERROR_RE_ENROLL) { BiometricNotificationUtils.showReEnrollmentNotification(getContext()); } super.onError(error, vendorCode); } Loading