diff options
8 files changed, 115 insertions, 25 deletions
diff --git a/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java b/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java index 770448bd594b..fc72db3c5791 100644 --- a/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java +++ b/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java @@ -221,7 +221,8 @@ public interface BiometricFingerprintConstants { FINGERPRINT_ACQUIRED_IMMOBILE, FINGERPRINT_ACQUIRED_TOO_BRIGHT, FINGERPRINT_ACQUIRED_POWER_PRESSED, - FINGERPRINT_ACQUIRED_RE_ENROLL}) + FINGERPRINT_ACQUIRED_RE_ENROLL_OPTIONAL, + FINGERPRINT_ACQUIRED_RE_ENROLL_FORCED}) @Retention(RetentionPolicy.SOURCE) @interface FingerprintAcquired {} @@ -316,7 +317,13 @@ public interface BiometricFingerprintConstants { * This message is sent to encourage the user to re-enroll their fingerprints. * @hide */ - int FINGERPRINT_ACQUIRED_RE_ENROLL = 12; + int FINGERPRINT_ACQUIRED_RE_ENROLL_OPTIONAL = 12; + + /** + * This message is sent to force the user to re-enroll their fingerprints. + * @hide + */ + int FINGERPRINT_ACQUIRED_RE_ENROLL_FORCED = 13; /** * @hide diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricNotificationBroadcastReceiver.java b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricNotificationBroadcastReceiver.java index df27cbb070b6..027f6744d4d7 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricNotificationBroadcastReceiver.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricNotificationBroadcastReceiver.java @@ -35,6 +35,8 @@ public class BiometricNotificationBroadcastReceiver extends BroadcastReceiver { static final String ACTION_SHOW_FINGERPRINT_REENROLL_DIALOG = "fingerprint_action_show_reenroll_dialog"; + static final String EXTRA_IS_REENROLL_FORCED = "is_reenroll_forced"; + private static final String TAG = "BiometricNotificationBroadcastReceiver"; private final Context mContext; @@ -56,14 +58,16 @@ public class BiometricNotificationBroadcastReceiver extends BroadcastReceiver { mNotificationDialogFactory.createReenrollDialog( mContext.getUserId(), mContext::startActivity, - BiometricSourceType.FACE) + BiometricSourceType.FACE, + false) .show(); break; case ACTION_SHOW_FINGERPRINT_REENROLL_DIALOG: mNotificationDialogFactory.createReenrollDialog( mContext.getUserId(), mContext::startActivity, - BiometricSourceType.FINGERPRINT) + BiometricSourceType.FINGERPRINT, + intent.getBooleanExtra(EXTRA_IS_REENROLL_FORCED, false)) .show(); break; default: diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricNotificationDialogFactory.java b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricNotificationDialogFactory.java index fd0feef7689b..4ac5a12dae03 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricNotificationDialogFactory.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricNotificationDialogFactory.java @@ -29,13 +29,12 @@ import android.hardware.fingerprint.FingerprintManager; import android.provider.Settings; import android.util.Log; -import com.android.systemui.res.R; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Main; +import com.android.systemui.res.R; import com.android.systemui.statusbar.phone.SystemUIDialog; import javax.inject.Inject; -import javax.inject.Provider; /** * Manages the creation of dialogs to be shown for biometric re enroll notifications. @@ -61,7 +60,8 @@ public class BiometricNotificationDialogFactory { } Dialog createReenrollDialog( - int userId, ActivityStarter activityStarter, BiometricSourceType biometricSourceType) { + int userId, ActivityStarter activityStarter, BiometricSourceType biometricSourceType, + boolean isReenrollForced) { SystemUIDialog sysuiDialog = mSystemUIDialogFactory.create(); if (biometricSourceType == BiometricSourceType.FACE) { sysuiDialog.setTitle(mResources.getString(R.string.face_re_enroll_dialog_title)); @@ -80,8 +80,12 @@ public class BiometricNotificationDialogFactory { sysuiDialog.setPositiveButton(R.string.biometric_re_enroll_dialog_confirm, (dialog, which) -> onReenrollDialogConfirm( userId, biometricSourceType, activityStarter)); - sysuiDialog.setNegativeButton(R.string.biometric_re_enroll_dialog_cancel, - (dialog, which) -> {}); + if (!isReenrollForced) { + sysuiDialog.setNegativeButton(R.string.biometric_re_enroll_dialog_cancel, + (dialog, which) -> { + }); + } + sysuiDialog.setCanceledOnTouchOutside(!isReenrollForced); return sysuiDialog; } diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricNotificationService.java b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricNotificationService.java index d6a4cbb67487..3b49ce2f10f7 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricNotificationService.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricNotificationService.java @@ -17,6 +17,7 @@ package com.android.systemui.biometrics; import static android.app.PendingIntent.FLAG_IMMUTABLE; +import static android.app.PendingIntent.FLAG_UPDATE_CURRENT; import static com.android.systemui.biometrics.BiometricNotificationBroadcastReceiver.ACTION_SHOW_FACE_REENROLL_DIALOG; import static com.android.systemui.biometrics.BiometricNotificationBroadcastReceiver.ACTION_SHOW_FINGERPRINT_REENROLL_DIALOG; @@ -43,8 +44,8 @@ import android.util.Log; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.KeyguardUpdateMonitorCallback; import com.android.systemui.CoreStartable; -import com.android.systemui.res.R; import com.android.systemui.dagger.SysUISingleton; +import com.android.systemui.res.R; import com.android.systemui.statusbar.policy.KeyguardStateController; import java.util.Optional; @@ -80,6 +81,8 @@ public class BiometricNotificationService implements CoreStartable { private boolean mFingerprintNotificationQueued; private boolean mFingerprintReenrollRequired; + private boolean mIsFingerprintReenrollForced; + private final KeyguardStateController.Callback mKeyguardStateControllerCallback = new KeyguardStateController.Callback() { private boolean mIsShowing = true; @@ -118,9 +121,11 @@ public class BiometricNotificationService implements CoreStartable { public void onBiometricHelp(int msgId, String helpString, BiometricSourceType biometricSourceType) { if (biometricSourceType == BiometricSourceType.FINGERPRINT - && mFingerprintReEnrollNotification.isFingerprintReEnrollRequired( + && mFingerprintReEnrollNotification.isFingerprintReEnrollRequested( msgId)) { mFingerprintReenrollRequired = true; + mIsFingerprintReenrollForced = + mFingerprintReEnrollNotification.isFingerprintReEnrollForced(msgId); } } }; @@ -191,7 +196,7 @@ public class BiometricNotificationService implements CoreStartable { final String name = mContext.getString(R.string.face_re_enroll_notification_name); mHandler.postDelayed( () -> showNotification(ACTION_SHOW_FACE_REENROLL_DIALOG, title, content, name, - FACE_NOTIFICATION_ID), + FACE_NOTIFICATION_ID, false), SHOW_NOTIFICATION_DELAY_MS); } @@ -204,12 +209,12 @@ public class BiometricNotificationService implements CoreStartable { final String name = mContext.getString(R.string.fingerprint_re_enroll_notification_name); mHandler.postDelayed( () -> showNotification(ACTION_SHOW_FINGERPRINT_REENROLL_DIALOG, title, content, - name, FINGERPRINT_NOTIFICATION_ID), + name, FINGERPRINT_NOTIFICATION_ID, mIsFingerprintReenrollForced), SHOW_NOTIFICATION_DELAY_MS); } private void showNotification(String action, CharSequence title, CharSequence content, - CharSequence name, int notificationId) { + CharSequence name, int notificationId, boolean isReenrollForced) { if (notificationId == FACE_NOTIFICATION_ID) { mFaceNotificationQueued = false; } else if (notificationId == FINGERPRINT_NOTIFICATION_ID) { @@ -223,8 +228,12 @@ public class BiometricNotificationService implements CoreStartable { } final Intent onClickIntent = new Intent(action); + onClickIntent.putExtra(BiometricNotificationBroadcastReceiver.EXTRA_IS_REENROLL_FORCED, + isReenrollForced); + final PendingIntent onClickPendingIntent = PendingIntent.getBroadcastAsUser(mContext, - 0 /* requestCode */, onClickIntent, FLAG_IMMUTABLE, UserHandle.CURRENT); + 0 /* requestCode */, onClickIntent, FLAG_IMMUTABLE | FLAG_UPDATE_CURRENT, + UserHandle.CURRENT); final Notification notification = new Notification.Builder(mContext, CHANNEL_ID) .setCategory(Notification.CATEGORY_SYSTEM) diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/FingerprintReEnrollNotification.java b/packages/SystemUI/src/com/android/systemui/biometrics/FingerprintReEnrollNotification.java index 9050f26d39e4..5b9ed483da02 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/FingerprintReEnrollNotification.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/FingerprintReEnrollNotification.java @@ -23,7 +23,16 @@ import android.hardware.biometrics.BiometricFingerprintConstants; */ public interface FingerprintReEnrollNotification { //TODO: Remove this class and add a constant in the HAL API instead (b/281841852) - /** Returns true if msgId corresponds to FINGERPRINT_ACQUIRED_RE_ENROLL. */ - boolean isFingerprintReEnrollRequired( + /** + * Returns true if msgId corresponds to FINGERPRINT_ACQUIRED_RE_ENROLL_OPTIONAL or + * FINGERPRINT_ACQUIRED_RE_ENROLL_FORCED. + */ + boolean isFingerprintReEnrollRequested( + @BiometricFingerprintConstants.FingerprintAcquired int msgId); + + /** + * Returns true if msgId corresponds to FINGERPRINT_ACQUIRED_RE_ENROLL_FORCED. + */ + boolean isFingerprintReEnrollForced( @BiometricFingerprintConstants.FingerprintAcquired int msgId); } diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/FingerprintReEnrollNotificationImpl.java b/packages/SystemUI/src/com/android/systemui/biometrics/FingerprintReEnrollNotificationImpl.java index 1f86bc6ae298..d47e1e67796e 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/FingerprintReEnrollNotificationImpl.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/FingerprintReEnrollNotificationImpl.java @@ -23,7 +23,13 @@ import android.hardware.biometrics.BiometricFingerprintConstants; */ public class FingerprintReEnrollNotificationImpl implements FingerprintReEnrollNotification{ @Override - public boolean isFingerprintReEnrollRequired(int msgId) { - return msgId == BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_RE_ENROLL; + public boolean isFingerprintReEnrollRequested(int msgId) { + return msgId == BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_RE_ENROLL_OPTIONAL + || msgId == BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_RE_ENROLL_FORCED; + } + + @Override + public boolean isFingerprintReEnrollForced(int msgId) { + return msgId == BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_RE_ENROLL_FORCED; } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricNotificationDialogFactoryTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricNotificationDialogFactoryTest.java index 8c8544cd6e5b..d2c695739ea9 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricNotificationDialogFactoryTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricNotificationDialogFactoryTest.java @@ -17,6 +17,7 @@ package com.android.systemui.biometrics; import static com.google.common.truth.Truth.assertThat; + import static org.junit.Assume.assumeTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; @@ -90,7 +91,8 @@ public class BiometricNotificationDialogFactoryTest extends SysuiTestCase { assumeTrue(getContext().getPackageManager() .hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)); - mDialogFactory.createReenrollDialog(0, mActivityStarter, BiometricSourceType.FINGERPRINT); + mDialogFactory.createReenrollDialog(0, mActivityStarter, BiometricSourceType.FINGERPRINT, + false); verify(mDialog).setPositiveButton(anyInt(), mOnClickListenerArgumentCaptor.capture()); @@ -115,7 +117,8 @@ public class BiometricNotificationDialogFactoryTest extends SysuiTestCase { assumeTrue(getContext().getPackageManager() .hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)); - mDialogFactory.createReenrollDialog(0, mActivityStarter, BiometricSourceType.FINGERPRINT); + mDialogFactory.createReenrollDialog(0, mActivityStarter, BiometricSourceType.FINGERPRINT, + false); verify(mDialog).setPositiveButton(anyInt(), mOnClickListenerArgumentCaptor.capture()); @@ -134,11 +137,25 @@ public class BiometricNotificationDialogFactoryTest extends SysuiTestCase { } @Test + public void testFingerprintReEnrollDialog_forced() { + assumeTrue(getContext().getPackageManager() + .hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)); + + mDialogFactory.createReenrollDialog(0, mActivityStarter, BiometricSourceType.FINGERPRINT, + true); + + verify(mDialog).setPositiveButton(anyInt(), mOnClickListenerArgumentCaptor.capture()); + + verify(mDialog, never()).setNegativeButton(anyInt(), any()); + } + + @Test public void testFaceReEnrollDialog_onRemovalSucceeded() { assumeTrue(getContext().getPackageManager() .hasSystemFeature(PackageManager.FEATURE_FACE)); - mDialogFactory.createReenrollDialog(0, mActivityStarter, BiometricSourceType.FACE); + mDialogFactory.createReenrollDialog(0, mActivityStarter, BiometricSourceType.FACE, + false); verify(mDialog).setPositiveButton(anyInt(), mOnClickListenerArgumentCaptor.capture()); @@ -163,7 +180,8 @@ public class BiometricNotificationDialogFactoryTest extends SysuiTestCase { assumeTrue(getContext().getPackageManager() .hasSystemFeature(PackageManager.FEATURE_FACE)); - mDialogFactory.createReenrollDialog(0, mActivityStarter, BiometricSourceType.FACE); + mDialogFactory.createReenrollDialog(0, mActivityStarter, BiometricSourceType.FACE, + false); verify(mDialog).setPositiveButton(anyInt(), mOnClickListenerArgumentCaptor.capture()); diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricNotificationServiceTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricNotificationServiceTest.java index c6771b262114..a279d3ee67e4 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricNotificationServiceTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricNotificationServiceTest.java @@ -18,7 +18,9 @@ package com.android.systemui.biometrics; 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 static com.google.common.truth.Truth.assertThat; + import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.never; @@ -98,7 +100,7 @@ public class BiometricNotificationServiceTest extends SysuiTestCase { public void setUp() { when(mFingerprintReEnrollNotificationOptional.orElse(any())) .thenReturn(mFingerprintReEnrollNotification); - when(mFingerprintReEnrollNotification.isFingerprintReEnrollRequired( + when(mFingerprintReEnrollNotification.isFingerprintReEnrollRequested( FINGERPRINT_ACQUIRED_RE_ENROLL)).thenReturn(true); mLooper = TestableLooper.get(this); @@ -140,8 +142,37 @@ public class BiometricNotificationServiceTest extends SysuiTestCase { } @Test - public void testShowFingerprintReEnrollNotification_onAcquiredReEnroll() { + public void testShowFingerprintReEnrollNotification_onAcquiredReEnroll_Optional() { when(mKeyguardStateController.isShowing()).thenReturn(false); + when(mFingerprintReEnrollNotification.isFingerprintReEnrollForced( + FINGERPRINT_ACQUIRED_RE_ENROLL)).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()); + + Notification fingerprintNotification = mNotificationArgumentCaptor.getValue(); + + assertThat(fingerprintNotification.contentIntent.getIntent().getAction()) + .isEqualTo(ACTION_SHOW_FINGERPRINT_REENROLL_DIALOG); + assertThat(fingerprintNotification.contentIntent.getIntent().getBooleanExtra( + BiometricNotificationBroadcastReceiver.EXTRA_IS_REENROLL_FORCED, false)).isFalse(); + } + + @Test + public void testShowFingerprintReEnrollNotification_onAcquiredReEnroll_force() { + when(mKeyguardStateController.isShowing()).thenReturn(false); + when(mFingerprintReEnrollNotification.isFingerprintReEnrollForced( + FINGERPRINT_ACQUIRED_RE_ENROLL)).thenReturn(true); mKeyguardUpdateMonitorCallback.onBiometricHelp( FINGERPRINT_ACQUIRED_RE_ENROLL, @@ -160,6 +191,8 @@ public class BiometricNotificationServiceTest extends SysuiTestCase { assertThat(fingerprintNotification.contentIntent.getIntent().getAction()) .isEqualTo(ACTION_SHOW_FINGERPRINT_REENROLL_DIALOG); + assertThat(fingerprintNotification.contentIntent.getIntent().getBooleanExtra( + BiometricNotificationBroadcastReceiver.EXTRA_IS_REENROLL_FORCED, false)).isTrue(); } @Test public void testShowFaceReEnrollNotification_onErrorReEnroll() { |