diff options
| author | 2022-08-29 14:44:09 +0000 | |
|---|---|---|
| committer | 2022-08-29 14:44:09 +0000 | |
| commit | 35208a6f7696dbf3bb47f09d47591c7b4c5840d7 (patch) | |
| tree | 3752a208458f7f22bcfd94afa0855b213032d88d | |
| parent | 2aa1e6e809d6bb6f4a6791ecd648945009168c60 (diff) | |
| parent | c121056f312c12ea2bf5541a311e341a5d9d8c83 (diff) | |
Merge "Update FP failure bouncer & messaging logic" into tm-qpr-dev am: 5cdb41a8cb am: c121056f31
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/19681152
Change-Id: I0f1cef692466cb94f3cad831c967ba0b99c0414d
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
5 files changed, 73 insertions, 26 deletions
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java index d75285283cbc..98bc28d21a59 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -206,7 +206,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab */ private static final int BIOMETRIC_STATE_CANCELLING_RESTARTING = 3; - private static final int BIOMETRIC_HELP_FINGERPRINT_NOT_RECOGNIZED = -1; + @VisibleForTesting + public static final int BIOMETRIC_HELP_FINGERPRINT_NOT_RECOGNIZED = -1; public static final int BIOMETRIC_HELP_FACE_NOT_RECOGNIZED = -2; /** diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java index c98364473f71..87f8a03098f5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java @@ -122,6 +122,7 @@ public class KeyguardIndicationController { private static final int MSG_HIDE_TRANSIENT = 1; private static final int MSG_SHOW_ACTION_TO_UNLOCK = 2; private static final int MSG_HIDE_BIOMETRIC_MESSAGE = 3; + private static final int MSG_RESET_ERROR_MESSAGE_ON_SCREEN_ON = 4; private static final long TRANSIENT_BIOMETRIC_ERROR_TIMEOUT = 1300; public static final long DEFAULT_HIDE_DELAY_MS = 3500 + KeyguardIndicationTextView.Y_IN_DURATION; @@ -188,9 +189,11 @@ public class KeyguardIndicationController { } }; private ScreenLifecycle mScreenLifecycle; - private final ScreenLifecycle.Observer mScreenObserver = new ScreenLifecycle.Observer() { + private final ScreenLifecycle.Observer mScreenObserver = + new ScreenLifecycle.Observer() { @Override public void onScreenTurnedOn() { + mHandler.removeMessages(MSG_RESET_ERROR_MESSAGE_ON_SCREEN_ON); if (mBiometricErrorMessageToShowOnScreenOn != null) { showBiometricMessage(mBiometricErrorMessageToShowOnScreenOn); // We want to keep this message around in case the screen was off @@ -259,6 +262,8 @@ public class KeyguardIndicationController { showActionToUnlock(); } else if (msg.what == MSG_HIDE_BIOMETRIC_MESSAGE) { hideBiometricMessage(); + } else if (msg.what == MSG_RESET_ERROR_MESSAGE_ON_SCREEN_ON) { + mBiometricErrorMessageToShowOnScreenOn = null; } } }; @@ -1060,6 +1065,11 @@ public class KeyguardIndicationController { } else if (showActionToUnlock) { mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_SHOW_ACTION_TO_UNLOCK), TRANSIENT_BIOMETRIC_ERROR_TIMEOUT); + } else { + mBiometricErrorMessageToShowOnScreenOn = helpString; + mHandler.sendMessageDelayed( + mHandler.obtainMessage(MSG_RESET_ERROR_MESSAGE_ON_SCREEN_ON), + 1000); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java index 33c1f99c6f4c..7bef844f7c78 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java @@ -23,6 +23,7 @@ import android.content.res.Resources; import android.hardware.biometrics.BiometricFaceConstants; import android.hardware.biometrics.BiometricFingerprintConstants; import android.hardware.biometrics.BiometricSourceType; +import android.hardware.face.FaceManager; import android.hardware.fingerprint.FingerprintManager; import android.metrics.LogMaker; import android.os.Handler; @@ -64,7 +65,6 @@ import com.android.systemui.shade.ShadeController; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.NotificationMediaManager; import com.android.systemui.statusbar.NotificationShadeWindowController; -import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.VibratorHelper; import com.android.systemui.statusbar.policy.KeyguardStateController; @@ -87,7 +87,7 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp private static final long BIOMETRIC_WAKELOCK_TIMEOUT_MS = 15 * 1000; private static final String BIOMETRIC_WAKE_LOCK_NAME = "wake-and-unlock:wakelock"; private static final UiEventLogger UI_EVENT_LOGGER = new UiEventLoggerImpl(); - private static final int FP_ATTEMPTS_BEFORE_SHOW_BOUNCER = 2; + private static final int UDFPS_ATTEMPTS_BEFORE_SHOW_BOUNCER = 3; private static final VibrationEffect SUCCESS_VIBRATION_EFFECT = VibrationEffect.get(VibrationEffect.EFFECT_CLICK); private static final VibrationEffect ERROR_VIBRATION_EFFECT = @@ -450,7 +450,7 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp // During wake and unlock, we need to draw black before waking up to avoid abrupt // brightness changes due to display state transitions. Runnable wakeUp = ()-> { - if (!wasDeviceInteractive) { + if (!wasDeviceInteractive || mUpdateMonitor.isDreaming()) { if (DEBUG_BIO_WAKELOCK) { Log.i(TAG, "bio wakelock: Authenticated, waking up..."); } @@ -653,7 +653,7 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp if (!mVibratorHelper.hasVibrator() && (!mUpdateMonitor.isDeviceInteractive() || mUpdateMonitor.isDreaming())) { - startWakeAndUnlock(MODE_SHOW_BOUNCER); + startWakeAndUnlock(MODE_ONLY_WAKE); } else if (biometricSourceType == BiometricSourceType.FINGERPRINT && mUpdateMonitor.isUdfpsSupported()) { long currUptimeMillis = SystemClock.uptimeMillis(); @@ -664,7 +664,7 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp } mLastFpFailureUptimeMillis = currUptimeMillis; - if (mNumConsecutiveFpFailures >= FP_ATTEMPTS_BEFORE_SHOW_BOUNCER) { + if (mNumConsecutiveFpFailures >= UDFPS_ATTEMPTS_BEFORE_SHOW_BOUNCER) { startWakeAndUnlock(MODE_SHOW_BOUNCER); UI_EVENT_LOGGER.log(BiometricUiEvent.BIOMETRIC_BOUNCER_SHOWN, getSessionId()); mNumConsecutiveFpFailures = 0; @@ -690,13 +690,13 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp Optional.ofNullable(BiometricUiEvent.ERROR_EVENT_BY_SOURCE_TYPE.get(biometricSourceType)) .ifPresent(event -> UI_EVENT_LOGGER.log(event, getSessionId())); - // if we're on the shade and we're locked out, immediately show the bouncer - if (biometricSourceType == BiometricSourceType.FINGERPRINT + final boolean fingerprintLockout = biometricSourceType == BiometricSourceType.FINGERPRINT && (msgId == FingerprintManager.FINGERPRINT_ERROR_LOCKOUT - || msgId == FingerprintManager.FINGERPRINT_ERROR_LOCKOUT_PERMANENT) - && mUpdateMonitor.isUdfpsSupported() - && (mStatusBarStateController.getState() == StatusBarState.SHADE - || mStatusBarStateController.getState() == StatusBarState.SHADE_LOCKED)) { + || msgId == FingerprintManager.FINGERPRINT_ERROR_LOCKOUT_PERMANENT); + final boolean faceLockout = biometricSourceType == BiometricSourceType.FACE + && (msgId == FaceManager.FACE_ERROR_LOCKOUT + || msgId == FaceManager.FACE_ERROR_LOCKOUT_PERMANENT); + if (fingerprintLockout || faceLockout) { startWakeAndUnlock(MODE_SHOW_BOUNCER); UI_EVENT_LOGGER.log(BiometricUiEvent.BIOMETRIC_BOUNCER_SHOWN, getSessionId()); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java index 22d61a71b93e..351dd0c49519 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java @@ -20,6 +20,7 @@ import static android.app.admin.DevicePolicyManager.DEVICE_OWNER_TYPE_DEFAULT; import static android.app.admin.DevicePolicyManager.DEVICE_OWNER_TYPE_FINANCED; import static android.content.pm.UserInfo.FLAG_MANAGED_PROFILE; +import static com.android.keyguard.KeyguardUpdateMonitor.BIOMETRIC_HELP_FINGERPRINT_NOT_RECOGNIZED; import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_ALIGNMENT; import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_BATTERY; import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_BIOMETRIC_MESSAGE; @@ -31,6 +32,7 @@ import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewCont import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_TRANSIENT; import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_TRUST; import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_USER_LOCKED; +import static com.android.systemui.keyguard.ScreenLifecycle.SCREEN_OFF; import static com.android.systemui.keyguard.ScreenLifecycle.SCREEN_ON; import static com.google.common.truth.Truth.assertThat; @@ -178,9 +180,12 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase { private ArgumentCaptor<KeyguardUpdateMonitorCallback> mKeyguardUpdateMonitorCallbackCaptor; @Captor private ArgumentCaptor<KeyguardStateController.Callback> mKeyguardStateControllerCallbackCaptor; + @Captor + private ArgumentCaptor<ScreenLifecycle.Observer> mScreenObserverCaptor; private KeyguardStateController.Callback mKeyguardStateControllerCallback; private KeyguardUpdateMonitorCallback mKeyguardUpdateMonitorCallback; private StatusBarStateController.StateListener mStatusBarStateListener; + private ScreenLifecycle.Observer mScreenObserver; private BroadcastReceiver mBroadcastReceiver; private FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock()); private TestableLooper mTestableLooper; @@ -273,6 +278,9 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase { mKeyguardUpdateMonitorCallbackCaptor.capture()); mKeyguardUpdateMonitorCallback = mKeyguardUpdateMonitorCallbackCaptor.getValue(); + verify(mScreenLifecycle).addObserver(mScreenObserverCaptor.capture()); + mScreenObserver = mScreenObserverCaptor.getValue(); + mExecutor.runAllReady(); reset(mRotateTextViewController); } @@ -537,6 +545,31 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase { } @Test + public void transientIndication_visibleWhenWokenUp() { + createController(); + when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false); + final String message = "helpMsg"; + + // GIVEN screen is off + when(mScreenLifecycle.getScreenState()).thenReturn(SCREEN_OFF); + + // WHEN fingeprint help message received + mController.setVisible(true); + mController.getKeyguardCallback().onBiometricHelp(BIOMETRIC_HELP_FINGERPRINT_NOT_RECOGNIZED, + message, BiometricSourceType.FINGERPRINT); + + // THEN message isn't shown right away + verifyNoMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE); + + // WHEN the screen turns on + mScreenObserver.onScreenTurnedOn(); + mTestableLooper.processAllMessages(); + + // THEN the message is shown + verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE, message); + } + + @Test public void transientIndication_visibleWhenDozing_unlessSwipeUp_fromError() { createController(); String message = mContext.getString(R.string.keyguard_unlock); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java index d2680eb5d8bb..a6808e01a081 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java @@ -22,6 +22,8 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyFloat; import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; @@ -395,15 +397,19 @@ public class BiometricsUnlockControllerTest extends SysuiTestCase { } @Test - public void onUdfpsConsecutivelyFailedTwoTimes_showBouncer() { + public void onUdfpsConsecutivelyFailedThreeTimes_showBouncer() { // GIVEN UDFPS is supported when(mUpdateMonitor.isUdfpsSupported()).thenReturn(true); - // WHEN udfps fails once - then don't show the bouncer + // WHEN udfps fails once - then don't show the bouncer yet mBiometricUnlockController.onBiometricAuthFailed(BiometricSourceType.FINGERPRINT); verify(mStatusBarKeyguardViewManager, never()).showBouncer(anyBoolean()); - // WHEN udfps fails the second time + // WHEN udfps fails the second time - then don't show the bouncer yet + mBiometricUnlockController.onBiometricAuthFailed(BiometricSourceType.FINGERPRINT); + verify(mStatusBarKeyguardViewManager, never()).showBouncer(anyBoolean()); + + // WHEN udpfs fails the third time mBiometricUnlockController.onBiometricAuthFailed(BiometricSourceType.FINGERPRINT); // THEN show the bouncer @@ -427,8 +433,8 @@ public class BiometricsUnlockControllerTest extends SysuiTestCase { } @Test - public void onFPFailureNoHaptics_notDeviceInteractive_showBouncer() { - // GIVEN no vibrator and the screen is off + public void onFPFailureNoHaptics_notInteractive_showLockScreen() { + // GIVEN no vibrator and device is dreaming when(mVibratorHelper.hasVibrator()).thenReturn(false); when(mUpdateMonitor.isDeviceInteractive()).thenReturn(false); when(mUpdateMonitor.isDreaming()).thenReturn(false); @@ -436,15 +442,12 @@ public class BiometricsUnlockControllerTest extends SysuiTestCase { // WHEN FP fails mBiometricUnlockController.onBiometricAuthFailed(BiometricSourceType.FINGERPRINT); - // after device is finished waking up - mBiometricUnlockController.mWakefulnessObserver.onFinishedWakingUp(); - - // THEN show the bouncer - verify(mStatusBarKeyguardViewManager).showBouncer(true); + // THEN wakeup the device + verify(mPowerManager).wakeUp(anyLong(), anyInt(), anyString()); } @Test - public void onFPFailureNoHaptics_dreaming_showBouncer() { + public void onFPFailureNoHaptics_dreaming_showLockScreen() { // GIVEN no vibrator and device is dreaming when(mVibratorHelper.hasVibrator()).thenReturn(false); when(mUpdateMonitor.isDeviceInteractive()).thenReturn(true); @@ -453,7 +456,7 @@ public class BiometricsUnlockControllerTest extends SysuiTestCase { // WHEN FP fails mBiometricUnlockController.onBiometricAuthFailed(BiometricSourceType.FINGERPRINT); - // THEN show the bouncer - verify(mStatusBarKeyguardViewManager).showBouncer(true); + // THEN wakeup the device + verify(mPowerManager).wakeUp(anyLong(), anyInt(), anyString()); } } |