Only show auth ripple on keyguard

- Don't show the ripple on the biometric prompt
- Don't show the ripple on face auth if bypass is disabled
- Don't show the ripple if we're not authenticating (ie: brought to
bouncer for strong auth requirement)

- Never show the udfps icon if strong auth is required

Fixes: 185394442
Fixes: 188373007
Test: manual
Test: atest KeyguardUpdateMonitorTest
Test: atest AuthRippleControllerTest
Change-Id: If3141e4812528f635946fe1dd036b065a188d975
This commit is contained in:
Beverly
2021-05-19 15:47:57 -04:00
committed by Beverly Tai
parent 11b487709d
commit 3ab0be3407
4 changed files with 99 additions and 9 deletions

View File

@@ -2143,7 +2143,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
final boolean shouldListenUdfpsState = !isUdfps
|| (!getUserCanSkipBouncer(getCurrentUser())
&& !isEncryptedOrLockdown(getCurrentUser())
&& mStrongAuthTracker.hasUserAuthenticatedSinceBoot()
&& !userNeedsStrongAuth()
&& userDoesNotHaveTrust);
return shouldListenKeyguardState && shouldListenUserState && shouldListenBouncerState

View File

@@ -27,6 +27,7 @@ import com.android.settingslib.Utils
import com.android.systemui.statusbar.NotificationShadeWindowController
import com.android.systemui.statusbar.commandline.Command
import com.android.systemui.statusbar.commandline.CommandRegistry
import com.android.systemui.statusbar.phone.KeyguardBypassController
import com.android.systemui.statusbar.phone.dagger.StatusBarComponent.StatusBarScope
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.util.ViewController
@@ -45,6 +46,7 @@ class AuthRippleController @Inject constructor(
private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
private val commandRegistry: CommandRegistry,
private val notificationShadeWindowController: NotificationShadeWindowController,
private val bypassController: KeyguardBypassController,
rippleView: AuthRippleView?
) : ViewController<AuthRippleView>(rippleView) {
private var fingerprintSensorLocation: PointF? = null
@@ -69,12 +71,20 @@ class AuthRippleController @Inject constructor(
}
private fun showRipple(biometricSourceType: BiometricSourceType?) {
if (!keyguardUpdateMonitor.isKeyguardVisible ||
keyguardUpdateMonitor.userNeedsStrongAuth()) {
return
}
if (biometricSourceType == BiometricSourceType.FINGERPRINT &&
fingerprintSensorLocation != null) {
mView.setSensorLocation(fingerprintSensorLocation!!)
showRipple()
} else if (biometricSourceType == BiometricSourceType.FACE &&
faceSensorLocation != null) {
if (!bypassController.canBypass()) {
return
}
mView.setSensorLocation(faceSensorLocation!!)
showRipple()
}

View File

@@ -19,6 +19,8 @@ package com.android.keyguard;
import static android.telephony.SubscriptionManager.DATA_ROAMING_DISABLE;
import static android.telephony.SubscriptionManager.NAME_SOURCE_CARRIER_ID;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
@@ -477,7 +479,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
@Test
public void testFingerprintDoesNotAuth_whenEncrypted() {
testFingerprintWhenStrongAuth(
KeyguardUpdateMonitor.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT);
STRONG_AUTH_REQUIRED_AFTER_BOOT);
}
@Test
@@ -576,7 +578,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
@Test
public void skipsAuthentication_whenEncryptedKeyguard() {
when(mStrongAuthTracker.getStrongAuthForUser(anyInt())).thenReturn(
KeyguardUpdateMonitor.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT);
STRONG_AUTH_REQUIRED_AFTER_BOOT);
mKeyguardUpdateMonitor.setKeyguardBypassController(mKeyguardBypassController);
mKeyguardUpdateMonitor.dispatchStartedWakingUp();
@@ -588,7 +590,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
@Test
public void requiresAuthentication_whenEncryptedKeyguard_andBypass() {
testStrongAuthExceptOnBouncer(
KeyguardUpdateMonitor.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT);
STRONG_AUTH_REQUIRED_AFTER_BOOT);
}
@Test
@@ -893,7 +895,8 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
mStatusBarStateListener.onStateChanged(StatusBarState.KEYGUARD);
// WHEN user hasn't authenticated since last boot
when(mStrongAuthTracker.hasUserAuthenticatedSinceBoot()).thenReturn(false);
when(mStrongAuthTracker.getStrongAuthForUser(KeyguardUpdateMonitor.getCurrentUser()))
.thenReturn(STRONG_AUTH_REQUIRED_AFTER_BOOT);
// THEN we shouldn't listen for udfps
assertThat(mKeyguardUpdateMonitor.shouldListenForFingerprint(true)).isEqualTo(false);

View File

@@ -25,6 +25,7 @@ import com.android.keyguard.KeyguardUpdateMonitorCallback
import com.android.systemui.SysuiTestCase
import com.android.systemui.statusbar.NotificationShadeWindowController
import com.android.systemui.statusbar.commandline.CommandRegistry
import com.android.systemui.statusbar.phone.KeyguardBypassController
import com.android.systemui.statusbar.policy.ConfigurationController
import org.junit.Before
import org.junit.Test
@@ -49,6 +50,7 @@ class AuthRippleControllerTest : SysuiTestCase() {
@Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
@Mock private lateinit var authController: AuthController
@Mock private lateinit var notificationShadeWindowController: NotificationShadeWindowController
@Mock private lateinit var bypassController: KeyguardBypassController
@Before
fun setUp() {
@@ -60,45 +62,120 @@ class AuthRippleControllerTest : SysuiTestCase() {
keyguardUpdateMonitor,
commandRegistry,
notificationShadeWindowController,
bypassController,
rippleView
)
controller.init()
}
@Test
fun testFingerprintTriggerRipple() {
fun testFingerprintTrigger_Ripple() {
// GIVEN fp exists, keyguard is visible, user doesn't need strong auth
val fpsLocation = PointF(5f, 5f)
`when`(authController.udfpsSensorLocation).thenReturn(fpsLocation)
controller.onViewAttached()
`when`(keyguardUpdateMonitor.isKeyguardVisible).thenReturn(true)
`when`(keyguardUpdateMonitor.userNeedsStrongAuth()).thenReturn(false)
// WHEN fingerprint authenticated
val captor = ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback::class.java)
verify(keyguardUpdateMonitor).registerCallback(captor.capture())
captor.value.onBiometricAuthenticated(
0 /* userId */,
BiometricSourceType.FINGERPRINT /* type */,
false /* isStrongBiometric */)
// THEN update sensor location and show ripple
verify(rippleView).setSensorLocation(fpsLocation)
verify(rippleView).startRipple(any())
}
@Test
fun testFaceTriggerRipple() {
fun testFingerprintTrigger_KeyguardNotVisible_NoRipple() {
// GIVEN fp exists & user doesn't need strong auth
val fpsLocation = PointF(5f, 5f)
`when`(authController.udfpsSensorLocation).thenReturn(fpsLocation)
controller.onViewAttached()
`when`(keyguardUpdateMonitor.userNeedsStrongAuth()).thenReturn(false)
// WHEN keyguard is NOT visible & fingerprint authenticated
`when`(keyguardUpdateMonitor.isKeyguardVisible).thenReturn(false)
val captor = ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback::class.java)
verify(keyguardUpdateMonitor).registerCallback(captor.capture())
captor.value.onBiometricAuthenticated(
0 /* userId */,
BiometricSourceType.FINGERPRINT /* type */,
false /* isStrongBiometric */)
// THEN no ripple
verify(rippleView, never()).startRipple(any())
}
@Test
fun testFingerprintTrigger_StrongAuthRequired_NoRipple() {
// GIVEN fp exists & keyguard is visible
val fpsLocation = PointF(5f, 5f)
`when`(authController.udfpsSensorLocation).thenReturn(fpsLocation)
controller.onViewAttached()
`when`(keyguardUpdateMonitor.isKeyguardVisible).thenReturn(true)
// WHEN user needs strong auth & fingerprint authenticated
`when`(keyguardUpdateMonitor.userNeedsStrongAuth()).thenReturn(true)
val captor = ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback::class.java)
verify(keyguardUpdateMonitor).registerCallback(captor.capture())
captor.value.onBiometricAuthenticated(
0 /* userId */,
BiometricSourceType.FINGERPRINT /* type */,
false /* isStrongBiometric */)
// THEN no ripple
verify(rippleView, never()).startRipple(any())
}
@Test
fun testFaceTriggerBypassEnabled_Ripple() {
// GIVEN face auth sensor exists, keyguard is visible & strong auth isn't required
val faceLocation = PointF(5f, 5f)
`when`(authController.faceAuthSensorLocation).thenReturn(faceLocation)
controller.onViewAttached()
`when`(keyguardUpdateMonitor.isKeyguardVisible).thenReturn(true)
`when`(keyguardUpdateMonitor.userNeedsStrongAuth()).thenReturn(false)
// WHEN bypass is enabled & face authenticated
`when`(bypassController.canBypass()).thenReturn(true)
val captor = ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback::class.java)
verify(keyguardUpdateMonitor).registerCallback(captor.capture())
captor.value.onBiometricAuthenticated(
0 /* userId */,
BiometricSourceType.FACE /* type */,
false /* isStrongBiometric */)
// THEN show ripple
verify(rippleView).setSensorLocation(faceLocation)
verify(rippleView).startRipple(any())
}
@Test
fun testFaceTriggerNonBypass_NoRipple() {
// GIVEN face auth sensor exists
val faceLocation = PointF(5f, 5f)
`when`(authController.faceAuthSensorLocation).thenReturn(faceLocation)
controller.onViewAttached()
// WHEN bypass isn't enabled & face authenticated
`when`(bypassController.canBypass()).thenReturn(false)
val captor = ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback::class.java)
verify(keyguardUpdateMonitor).registerCallback(captor.capture())
captor.value.onBiometricAuthenticated(
0 /* userId */,
BiometricSourceType.FACE /* type */,
false /* isStrongBiometric */)
// THEN no ripple
verify(rippleView, never()).startRipple(any())
}
@Test
fun testNullFaceSensorLocationDoesNothing() {
`when`(authController.faceAuthSensorLocation).thenReturn(null)