Allow alternateBouncer if at least once source has ui available

When the device enters the keyguard in landscape, the last UDFPS
view is removed and a new one is added. The timing of events
was detaching the previous view after the new view was attached,
which was causing setAlternateBouncerUiAvailable to end up in the
wrong "false" state. Guard against this by tracking the source
of who is saying the alternateBouncerUiIsAvaiable.

Fixes: 293979249
Test: on the homescreen or in app, get into landscape, then
go the lockscreen and trigger the alternate bouncer (tap
on a notification or press the ... on the volume UI). Observe
that the alternate bouncer shows if UDFPS or SFPS is enrolled.
Test: atest AlternateBouncerInteractorTest

Change-Id: I16edc54c0d0ab693c2425ebcc136dbd2ef0ffc56
This commit is contained in:
Beverly
2023-08-04 20:26:21 +00:00
parent 07702af285
commit 5d49248b10
5 changed files with 39 additions and 7 deletions

View File

@@ -186,7 +186,7 @@ constructor(
}
private fun listenForAlternateBouncerVisibility() {
alternateBouncerInteractor.setAlternateBouncerUIAvailable(true)
alternateBouncerInteractor.setAlternateBouncerUIAvailable(true, "SideFpsController")
scope.launch {
alternateBouncerInteractor.isVisible.collect { isVisible: Boolean ->
if (isVisible) {

View File

@@ -83,6 +83,7 @@ constructor(
dumpManager,
),
UdfpsKeyguardViewControllerAdapter {
private val uniqueIdentifier = this.toString()
private val useExpandedOverlay: Boolean =
featureFlags.isEnabled(Flags.UDFPS_NEW_TOUCH_DETECTION)
private var showingUdfpsBouncer = false
@@ -282,7 +283,7 @@ constructor(
public override fun onViewAttached() {
super.onViewAttached()
alternateBouncerInteractor.setAlternateBouncerUIAvailable(true)
alternateBouncerInteractor.setAlternateBouncerUIAvailable(true, uniqueIdentifier)
val dozeAmount = statusBarStateController.dozeAmount
lastDozeAmount = dozeAmount
stateListener.onDozeAmountChanged(dozeAmount, dozeAmount)
@@ -312,7 +313,7 @@ constructor(
override fun onViewDetached() {
super.onViewDetached()
alternateBouncerInteractor.setAlternateBouncerUIAvailable(false)
alternateBouncerInteractor.setAlternateBouncerUIAvailable(false, uniqueIdentifier)
faceDetectRunning = false
keyguardStateController.removeCallback(keyguardStateControllerCallback)
statusBarStateController.removeCallback(stateListener)

View File

@@ -46,6 +46,7 @@ open class UdfpsKeyguardViewController(
dumpManager,
),
UdfpsKeyguardViewControllerAdapter {
private val uniqueIdentifier = this.toString()
override val tag: String
get() = TAG
@@ -55,12 +56,12 @@ open class UdfpsKeyguardViewController(
public override fun onViewAttached() {
super.onViewAttached()
alternateBouncerInteractor.setAlternateBouncerUIAvailable(true)
alternateBouncerInteractor.setAlternateBouncerUIAvailable(true, uniqueIdentifier)
}
public override fun onViewDetached() {
super.onViewDetached()
alternateBouncerInteractor.setAlternateBouncerUIAvailable(false)
alternateBouncerInteractor.setAlternateBouncerUIAvailable(false, uniqueIdentifier)
}
override fun shouldPauseAuth(): Boolean {

View File

@@ -40,6 +40,7 @@ constructor(
) {
var receivedDownTouch = false
val isVisible: Flow<Boolean> = bouncerRepository.alternateBouncerVisible
private val alternateBouncerUiAvailableFromSource: HashSet<String> = HashSet()
/**
* Sets the correct bouncer states to show the alternate bouncer if it can show.
@@ -69,8 +70,15 @@ constructor(
return bouncerRepository.alternateBouncerVisible.value
}
fun setAlternateBouncerUIAvailable(isAvailable: Boolean) {
bouncerRepository.setAlternateBouncerUIAvailable(isAvailable)
fun setAlternateBouncerUIAvailable(isAvailable: Boolean, token: String) {
if (isAvailable) {
alternateBouncerUiAvailableFromSource.add(token)
} else {
alternateBouncerUiAvailableFromSource.remove(token)
}
bouncerRepository.setAlternateBouncerUIAvailable(
alternateBouncerUiAvailableFromSource.isNotEmpty()
)
}
fun canShowAlternateBouncerForFingerprint(): Boolean {

View File

@@ -165,6 +165,28 @@ class AlternateBouncerInteractorTest : SysuiTestCase() {
assertFalse(bouncerRepository.alternateBouncerVisible.value)
}
@Test
fun alternateBouncerUiAvailable_fromMultipleSources() {
assertFalse(bouncerRepository.alternateBouncerUIAvailable.value)
// GIVEN there are two different sources indicating the alternate bouncer is available
underTest.setAlternateBouncerUIAvailable(true, "source1")
underTest.setAlternateBouncerUIAvailable(true, "source2")
assertTrue(bouncerRepository.alternateBouncerUIAvailable.value)
// WHEN one of the sources no longer says the UI is available
underTest.setAlternateBouncerUIAvailable(false, "source1")
// THEN alternate bouncer UI is still available (from the other source)
assertTrue(bouncerRepository.alternateBouncerUIAvailable.value)
// WHEN all sources say the UI is not available
underTest.setAlternateBouncerUIAvailable(false, "source2")
// THEN alternate boucer UI is not available
assertFalse(bouncerRepository.alternateBouncerUIAvailable.value)
}
private fun givenCanShowAlternateBouncer() {
bouncerRepository.setAlternateBouncerUIAvailable(true)
biometricSettingsRepository.setFingerprintEnrolled(true)