Merge "Only show auth ripple on keyguard" into sc-dev
This commit is contained in:
@@ -2143,7 +2143,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
final boolean shouldListenUdfpsState = !isUdfps
|
final boolean shouldListenUdfpsState = !isUdfps
|
||||||
|| (!getUserCanSkipBouncer(getCurrentUser())
|
|| (!getUserCanSkipBouncer(getCurrentUser())
|
||||||
&& !isEncryptedOrLockdown(getCurrentUser())
|
&& !isEncryptedOrLockdown(getCurrentUser())
|
||||||
&& mStrongAuthTracker.hasUserAuthenticatedSinceBoot()
|
&& !userNeedsStrongAuth()
|
||||||
&& userDoesNotHaveTrust);
|
&& userDoesNotHaveTrust);
|
||||||
|
|
||||||
return shouldListenKeyguardState && shouldListenUserState && shouldListenBouncerState
|
return shouldListenKeyguardState && shouldListenUserState && shouldListenBouncerState
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import com.android.settingslib.Utils
|
|||||||
import com.android.systemui.statusbar.NotificationShadeWindowController
|
import com.android.systemui.statusbar.NotificationShadeWindowController
|
||||||
import com.android.systemui.statusbar.commandline.Command
|
import com.android.systemui.statusbar.commandline.Command
|
||||||
import com.android.systemui.statusbar.commandline.CommandRegistry
|
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.phone.dagger.StatusBarComponent.StatusBarScope
|
||||||
import com.android.systemui.statusbar.policy.ConfigurationController
|
import com.android.systemui.statusbar.policy.ConfigurationController
|
||||||
import com.android.systemui.util.ViewController
|
import com.android.systemui.util.ViewController
|
||||||
@@ -45,6 +46,7 @@ class AuthRippleController @Inject constructor(
|
|||||||
private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
|
private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
|
||||||
private val commandRegistry: CommandRegistry,
|
private val commandRegistry: CommandRegistry,
|
||||||
private val notificationShadeWindowController: NotificationShadeWindowController,
|
private val notificationShadeWindowController: NotificationShadeWindowController,
|
||||||
|
private val bypassController: KeyguardBypassController,
|
||||||
rippleView: AuthRippleView?
|
rippleView: AuthRippleView?
|
||||||
) : ViewController<AuthRippleView>(rippleView) {
|
) : ViewController<AuthRippleView>(rippleView) {
|
||||||
private var fingerprintSensorLocation: PointF? = null
|
private var fingerprintSensorLocation: PointF? = null
|
||||||
@@ -69,12 +71,20 @@ class AuthRippleController @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun showRipple(biometricSourceType: BiometricSourceType?) {
|
private fun showRipple(biometricSourceType: BiometricSourceType?) {
|
||||||
|
if (!keyguardUpdateMonitor.isKeyguardVisible ||
|
||||||
|
keyguardUpdateMonitor.userNeedsStrongAuth()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if (biometricSourceType == BiometricSourceType.FINGERPRINT &&
|
if (biometricSourceType == BiometricSourceType.FINGERPRINT &&
|
||||||
fingerprintSensorLocation != null) {
|
fingerprintSensorLocation != null) {
|
||||||
mView.setSensorLocation(fingerprintSensorLocation!!)
|
mView.setSensorLocation(fingerprintSensorLocation!!)
|
||||||
showRipple()
|
showRipple()
|
||||||
} else if (biometricSourceType == BiometricSourceType.FACE &&
|
} else if (biometricSourceType == BiometricSourceType.FACE &&
|
||||||
faceSensorLocation != null) {
|
faceSensorLocation != null) {
|
||||||
|
if (!bypassController.canBypass()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
mView.setSensorLocation(faceSensorLocation!!)
|
mView.setSensorLocation(faceSensorLocation!!)
|
||||||
showRipple()
|
showRipple()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ package com.android.keyguard;
|
|||||||
import static android.telephony.SubscriptionManager.DATA_ROAMING_DISABLE;
|
import static android.telephony.SubscriptionManager.DATA_ROAMING_DISABLE;
|
||||||
import static android.telephony.SubscriptionManager.NAME_SOURCE_CARRIER_ID;
|
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 com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
@@ -477,7 +479,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void testFingerprintDoesNotAuth_whenEncrypted() {
|
public void testFingerprintDoesNotAuth_whenEncrypted() {
|
||||||
testFingerprintWhenStrongAuth(
|
testFingerprintWhenStrongAuth(
|
||||||
KeyguardUpdateMonitor.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT);
|
STRONG_AUTH_REQUIRED_AFTER_BOOT);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -576,7 +578,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void skipsAuthentication_whenEncryptedKeyguard() {
|
public void skipsAuthentication_whenEncryptedKeyguard() {
|
||||||
when(mStrongAuthTracker.getStrongAuthForUser(anyInt())).thenReturn(
|
when(mStrongAuthTracker.getStrongAuthForUser(anyInt())).thenReturn(
|
||||||
KeyguardUpdateMonitor.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT);
|
STRONG_AUTH_REQUIRED_AFTER_BOOT);
|
||||||
mKeyguardUpdateMonitor.setKeyguardBypassController(mKeyguardBypassController);
|
mKeyguardUpdateMonitor.setKeyguardBypassController(mKeyguardBypassController);
|
||||||
|
|
||||||
mKeyguardUpdateMonitor.dispatchStartedWakingUp();
|
mKeyguardUpdateMonitor.dispatchStartedWakingUp();
|
||||||
@@ -588,7 +590,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void requiresAuthentication_whenEncryptedKeyguard_andBypass() {
|
public void requiresAuthentication_whenEncryptedKeyguard_andBypass() {
|
||||||
testStrongAuthExceptOnBouncer(
|
testStrongAuthExceptOnBouncer(
|
||||||
KeyguardUpdateMonitor.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT);
|
STRONG_AUTH_REQUIRED_AFTER_BOOT);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -893,7 +895,8 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
|||||||
mStatusBarStateListener.onStateChanged(StatusBarState.KEYGUARD);
|
mStatusBarStateListener.onStateChanged(StatusBarState.KEYGUARD);
|
||||||
|
|
||||||
// WHEN user hasn't authenticated since last boot
|
// 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
|
// THEN we shouldn't listen for udfps
|
||||||
assertThat(mKeyguardUpdateMonitor.shouldListenForFingerprint(true)).isEqualTo(false);
|
assertThat(mKeyguardUpdateMonitor.shouldListenForFingerprint(true)).isEqualTo(false);
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import com.android.keyguard.KeyguardUpdateMonitorCallback
|
|||||||
import com.android.systemui.SysuiTestCase
|
import com.android.systemui.SysuiTestCase
|
||||||
import com.android.systemui.statusbar.NotificationShadeWindowController
|
import com.android.systemui.statusbar.NotificationShadeWindowController
|
||||||
import com.android.systemui.statusbar.commandline.CommandRegistry
|
import com.android.systemui.statusbar.commandline.CommandRegistry
|
||||||
|
import com.android.systemui.statusbar.phone.KeyguardBypassController
|
||||||
import com.android.systemui.statusbar.policy.ConfigurationController
|
import com.android.systemui.statusbar.policy.ConfigurationController
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
@@ -49,6 +50,7 @@ class AuthRippleControllerTest : SysuiTestCase() {
|
|||||||
@Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
|
@Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
|
||||||
@Mock private lateinit var authController: AuthController
|
@Mock private lateinit var authController: AuthController
|
||||||
@Mock private lateinit var notificationShadeWindowController: NotificationShadeWindowController
|
@Mock private lateinit var notificationShadeWindowController: NotificationShadeWindowController
|
||||||
|
@Mock private lateinit var bypassController: KeyguardBypassController
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setUp() {
|
fun setUp() {
|
||||||
@@ -60,45 +62,120 @@ class AuthRippleControllerTest : SysuiTestCase() {
|
|||||||
keyguardUpdateMonitor,
|
keyguardUpdateMonitor,
|
||||||
commandRegistry,
|
commandRegistry,
|
||||||
notificationShadeWindowController,
|
notificationShadeWindowController,
|
||||||
|
bypassController,
|
||||||
rippleView
|
rippleView
|
||||||
)
|
)
|
||||||
controller.init()
|
controller.init()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testFingerprintTriggerRipple() {
|
fun testFingerprintTrigger_Ripple() {
|
||||||
|
// GIVEN fp exists, keyguard is visible, user doesn't need strong auth
|
||||||
val fpsLocation = PointF(5f, 5f)
|
val fpsLocation = PointF(5f, 5f)
|
||||||
`when`(authController.udfpsSensorLocation).thenReturn(fpsLocation)
|
`when`(authController.udfpsSensorLocation).thenReturn(fpsLocation)
|
||||||
controller.onViewAttached()
|
controller.onViewAttached()
|
||||||
|
`when`(keyguardUpdateMonitor.isKeyguardVisible).thenReturn(true)
|
||||||
|
`when`(keyguardUpdateMonitor.userNeedsStrongAuth()).thenReturn(false)
|
||||||
|
|
||||||
|
// WHEN fingerprint authenticated
|
||||||
val captor = ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback::class.java)
|
val captor = ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback::class.java)
|
||||||
verify(keyguardUpdateMonitor).registerCallback(captor.capture())
|
verify(keyguardUpdateMonitor).registerCallback(captor.capture())
|
||||||
|
|
||||||
captor.value.onBiometricAuthenticated(
|
captor.value.onBiometricAuthenticated(
|
||||||
0 /* userId */,
|
0 /* userId */,
|
||||||
BiometricSourceType.FINGERPRINT /* type */,
|
BiometricSourceType.FINGERPRINT /* type */,
|
||||||
false /* isStrongBiometric */)
|
false /* isStrongBiometric */)
|
||||||
|
|
||||||
|
// THEN update sensor location and show ripple
|
||||||
verify(rippleView).setSensorLocation(fpsLocation)
|
verify(rippleView).setSensorLocation(fpsLocation)
|
||||||
verify(rippleView).startRipple(any())
|
verify(rippleView).startRipple(any())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@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)
|
val faceLocation = PointF(5f, 5f)
|
||||||
`when`(authController.faceAuthSensorLocation).thenReturn(faceLocation)
|
`when`(authController.faceAuthSensorLocation).thenReturn(faceLocation)
|
||||||
controller.onViewAttached()
|
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)
|
val captor = ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback::class.java)
|
||||||
verify(keyguardUpdateMonitor).registerCallback(captor.capture())
|
verify(keyguardUpdateMonitor).registerCallback(captor.capture())
|
||||||
|
|
||||||
captor.value.onBiometricAuthenticated(
|
captor.value.onBiometricAuthenticated(
|
||||||
0 /* userId */,
|
0 /* userId */,
|
||||||
BiometricSourceType.FACE /* type */,
|
BiometricSourceType.FACE /* type */,
|
||||||
false /* isStrongBiometric */)
|
false /* isStrongBiometric */)
|
||||||
|
|
||||||
|
// THEN show ripple
|
||||||
verify(rippleView).setSensorLocation(faceLocation)
|
verify(rippleView).setSensorLocation(faceLocation)
|
||||||
verify(rippleView).startRipple(any())
|
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
|
@Test
|
||||||
fun testNullFaceSensorLocationDoesNothing() {
|
fun testNullFaceSensorLocationDoesNothing() {
|
||||||
`when`(authController.faceAuthSensorLocation).thenReturn(null)
|
`when`(authController.faceAuthSensorLocation).thenReturn(null)
|
||||||
|
|||||||
Reference in New Issue
Block a user