diff options
28 files changed, 324 insertions, 40 deletions
diff --git a/core/java/android/hardware/biometrics/IBiometricContextListener.aidl b/core/java/android/hardware/biometrics/IBiometricContextListener.aidl index 6ac658144164..2f58f51d5483 100644 --- a/core/java/android/hardware/biometrics/IBiometricContextListener.aidl +++ b/core/java/android/hardware/biometrics/IBiometricContextListener.aidl @@ -38,4 +38,8 @@ oneway interface IBiometricContextListener { // Called when the display state of the device changes. // Where `displayState` is defined in AuthenticateOptions.DisplayState void onDisplayStateChanged(int displayState); + + // Called when the HAL ignoring touches state changes. + // When true, the HAL ignores touches on the sensor. + void onHardwareIgnoreTouchesChanged(boolean shouldIgnore); } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt index b0beab932e21..f7743e2814f0 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt @@ -38,6 +38,7 @@ import com.android.keyguard.KeyguardUpdateMonitor import com.android.systemui.Flags import com.android.systemui.SysuiTestCase import com.android.systemui.animation.ActivityLaunchAnimator +import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams import com.android.systemui.biometrics.ui.viewmodel.DefaultUdfpsTouchOverlayViewModel import com.android.systemui.biometrics.ui.viewmodel.DeviceEntryUdfpsTouchOverlayViewModel @@ -118,6 +119,7 @@ class UdfpsControllerOverlayTest : SysuiTestCase() { @Mock private lateinit var keyguardTransitionInteractor: KeyguardTransitionInteractor @Mock private lateinit var shadeInteractor: ShadeInteractor @Captor private lateinit var layoutParamsCaptor: ArgumentCaptor<WindowManager.LayoutParams> + @Mock private lateinit var udfpsOverlayInteractor: UdfpsOverlayInteractor private val onTouch = { _: View, _: MotionEvent, _: Boolean -> true } private var overlayParams: UdfpsOverlayParams = UdfpsOverlayParams() @@ -174,7 +176,8 @@ class UdfpsControllerOverlayTest : SysuiTestCase() { mSelectedUserInteractor, { deviceEntryUdfpsTouchOverlayViewModel }, { defaultUdfpsTouchOverlayViewModel }, - shadeInteractor + shadeInteractor, + udfpsOverlayInteractor, ) block() } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerTest.java index a59a4b864ac4..90c3c14bbc4f 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerTest.java @@ -76,6 +76,7 @@ import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.Flags; import com.android.systemui.SysuiTestCase; import com.android.systemui.animation.ActivityLaunchAnimator; +import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor; import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams; import com.android.systemui.biometrics.udfps.InteractionEvent; import com.android.systemui.biometrics.udfps.NormalizedTouchData; @@ -214,6 +215,8 @@ public class UdfpsControllerTest extends SysuiTestCase { @Mock private AlternateBouncerInteractor mAlternateBouncerInteractor; @Mock + private UdfpsOverlayInteractor mUdfpsOverlayInteractor; + @Mock private UdfpsKeyguardAccessibilityDelegate mUdfpsKeyguardAccessibilityDelegate; @Mock private SelectedUserInteractor mSelectedUserInteractor; @@ -342,8 +345,8 @@ public class UdfpsControllerTest extends SysuiTestCase { mFpsUnlockTracker, mKeyguardTransitionInteractor, mDeviceEntryUdfpsTouchOverlayViewModel, - mDefaultUdfpsTouchOverlayViewModel - + mDefaultUdfpsTouchOverlayViewModel, + mUdfpsOverlayInteractor ); verify(mFingerprintManager).setUdfpsOverlayController(mOverlayCaptor.capture()); mOverlayController = mOverlayCaptor.getValue(); diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerBaseTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerBaseTest.java index 13b53a896b70..7d9c2f96ef58 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerBaseTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerBaseTest.java @@ -27,6 +27,7 @@ import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.Flags; import com.android.systemui.SysuiTestCase; import com.android.systemui.animation.ActivityLaunchAnimator; +import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor; import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor; import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor; import com.android.systemui.dump.DumpManager; @@ -76,6 +77,7 @@ public class UdfpsKeyguardViewLegacyControllerBaseTest extends SysuiTestCase { protected @Mock UdfpsKeyguardAccessibilityDelegate mUdfpsKeyguardAccessibilityDelegate; protected @Mock SelectedUserInteractor mSelectedUserInteractor; protected @Mock KeyguardTransitionInteractor mKeyguardTransitionInteractor; + protected @Mock UdfpsOverlayInteractor mUdfpsOverlayInteractor; protected FakeFeatureFlags mFeatureFlags = new FakeFeatureFlags(); @@ -152,7 +154,8 @@ public class UdfpsKeyguardViewLegacyControllerBaseTest extends SysuiTestCase { mUdfpsKeyguardAccessibilityDelegate, mSelectedUserInteractor, mKeyguardTransitionInteractor, - mShadeInteractor); + mShadeInteractor, + mUdfpsOverlayInteractor); return controller; } } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerWithCoroutinesTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerWithCoroutinesTest.kt index 335ac9d42e77..0e257bcfecc3 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerWithCoroutinesTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerWithCoroutinesTest.kt @@ -24,6 +24,7 @@ import com.android.keyguard.KeyguardSecurityModel import com.android.systemui.biometrics.UdfpsKeyguardViewLegacy.ANIMATE_APPEAR_ON_SCREEN_OFF import com.android.systemui.biometrics.UdfpsKeyguardViewLegacy.ANIMATION_BETWEEN_AOD_AND_LOCKSCREEN import com.android.systemui.biometrics.data.repository.FakeFingerprintPropertyRepository +import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor import com.android.systemui.bouncer.data.repository.KeyguardBouncerRepository import com.android.systemui.bouncer.data.repository.KeyguardBouncerRepositoryImpl import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor @@ -32,6 +33,7 @@ import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor import com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants import com.android.systemui.bouncer.ui.BouncerView import com.android.systemui.classifier.FalsingCollector +import com.android.systemui.coroutines.collectLastValue import com.android.systemui.deviceentry.domain.interactor.DeviceEntryFaceAuthInteractor import com.android.systemui.keyguard.DismissCallbackRegistry import com.android.systemui.keyguard.data.repository.BiometricSettingsRepository @@ -45,9 +47,11 @@ import com.android.systemui.log.table.TableLogBuffer import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.statusbar.StatusBarState import com.android.systemui.statusbar.policy.KeyguardStateController +import com.android.systemui.user.domain.interactor.SelectedUserInteractor import com.android.systemui.util.mockito.whenever import com.android.systemui.util.time.FakeSystemClock import com.android.systemui.util.time.SystemClock +import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.test.StandardTestDispatcher import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runCurrent @@ -130,6 +134,13 @@ class UdfpsKeyguardViewLegacyControllerWithCoroutinesTest : repository = transitionRepository, ) .keyguardTransitionInteractor + mUdfpsOverlayInteractor = + UdfpsOverlayInteractor( + context, + mock(AuthController::class.java), + mock(SelectedUserInteractor::class.java), + testScope.backgroundScope, + ) return createUdfpsKeyguardViewController(/* useModernBouncer */ true) } @@ -239,6 +250,31 @@ class UdfpsKeyguardViewLegacyControllerWithCoroutinesTest : } @Test + fun shouldHandleTouchesChange() = + testScope.runTest { + val shouldHandleTouches by collectLastValue(mUdfpsOverlayInteractor.shouldHandleTouches) + + // GIVEN view is attached + on the keyguard + mController.onViewAttached() + captureStatusBarStateListeners() + sendStatusBarStateChanged(StatusBarState.KEYGUARD) + whenever(mView.setPauseAuth(true)).thenReturn(true) + whenever(mView.unpausedAlpha).thenReturn(0) + + // WHEN panelViewExpansion changes to expanded + val job = mController.listenForBouncerExpansion(this) + keyguardBouncerRepository.setPrimaryShow(true) + keyguardBouncerRepository.setPanelExpansion(KeyguardBouncerConstants.EXPANSION_VISIBLE) + runCurrent() + + // THEN UDFPS auth is paused and should not handle touches + assertThat(mController.shouldPauseAuth()).isTrue() + assertThat(shouldHandleTouches!!).isFalse() + + job.cancel() + } + + @Test fun fadeFromDialogSuggestedAlpha() = testScope.runTest { // GIVEN view is attached and status bar expansion is 1f diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.kt index 7d9ec08bcb3b..f5603ed732a5 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.kt @@ -23,6 +23,7 @@ import androidx.lifecycle.Lifecycle import androidx.lifecycle.repeatOnLifecycle import com.android.app.animation.Interpolators import com.android.systemui.Dumpable +import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor import com.android.systemui.dump.DumpManager import com.android.systemui.lifecycle.repeatWhenAttached import com.android.systemui.plugins.statusbar.StatusBarStateController @@ -49,7 +50,8 @@ abstract class UdfpsAnimationViewController<T : UdfpsAnimationView>( protected val statusBarStateController: StatusBarStateController, protected val shadeInteractor: ShadeInteractor, protected val dialogManager: SystemUIDialogManager, - private val dumpManager: DumpManager + private val dumpManager: DumpManager, + private val udfpsOverlayInteractor: UdfpsOverlayInteractor, ) : ViewController<T>(view), Dumpable { protected abstract val tag: String @@ -130,11 +132,13 @@ abstract class UdfpsAnimationViewController<T : UdfpsAnimationView>( override fun onViewAttached() { dialogManager.registerListener(dialogListener) dumpManager.registerDumpable(dumpTag, this) + udfpsOverlayInteractor.setHandleTouches(shouldHandle = true) } override fun onViewDetached() { dialogManager.unregisterListener(dialogListener) dumpManager.unregisterDumpable(dumpTag) + udfpsOverlayInteractor.setHandleTouches(shouldHandle = true) } /** @@ -165,6 +169,7 @@ abstract class UdfpsAnimationViewController<T : UdfpsAnimationView>( fun updatePauseAuth() { if (view.setPauseAuth(shouldPauseAuth())) { view.postInvalidate() + udfpsOverlayInteractor.setHandleTouches(shouldHandle = !shouldPauseAuth()) } } diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsBpViewController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsBpViewController.kt index e7b0d9fd9d85..e0455b58b919 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsBpViewController.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsBpViewController.kt @@ -15,6 +15,7 @@ */ package com.android.systemui.biometrics +import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor import com.android.systemui.dump.DumpManager import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.shade.domain.interactor.ShadeInteractor @@ -28,13 +29,15 @@ class UdfpsBpViewController( statusBarStateController: StatusBarStateController, shadeInteractor: ShadeInteractor, systemUIDialogManager: SystemUIDialogManager, - dumpManager: DumpManager + dumpManager: DumpManager, + udfpsOverlayInteractor: UdfpsOverlayInteractor, ) : UdfpsAnimationViewController<UdfpsBpView>( view, statusBarStateController, shadeInteractor, systemUIDialogManager, - dumpManager + dumpManager, + udfpsOverlayInteractor, ) { override val tag = "UdfpsBpViewController" diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java index 81de0a283e88..66fe4b36567d 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java @@ -68,6 +68,7 @@ import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.Dumpable; import com.android.systemui.animation.ActivityLaunchAnimator; import com.android.systemui.biometrics.dagger.BiometricsBackground; +import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor; import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams; import com.android.systemui.biometrics.udfps.InteractionEvent; import com.android.systemui.biometrics.udfps.NormalizedTouchData; @@ -171,6 +172,7 @@ public class UdfpsController implements DozeReceiver, Dumpable { @NonNull private final Lazy<DefaultUdfpsTouchOverlayViewModel> mDefaultUdfpsTouchOverlayViewModel; @NonNull private final AlternateBouncerInteractor mAlternateBouncerInteractor; + @NonNull private final UdfpsOverlayInteractor mUdfpsOverlayInteractor; @NonNull private final InputManager mInputManager; @NonNull private final UdfpsKeyguardAccessibilityDelegate mUdfpsKeyguardAccessibilityDelegate; @NonNull private final SelectedUserInteractor mSelectedUserInteractor; @@ -293,7 +295,8 @@ public class UdfpsController implements DozeReceiver, Dumpable { mSelectedUserInteractor, mDeviceEntryUdfpsTouchOverlayViewModel, mDefaultUdfpsTouchOverlayViewModel, - mShadeInteractor + mShadeInteractor, + mUdfpsOverlayInteractor ))); } @@ -674,7 +677,8 @@ public class UdfpsController implements DozeReceiver, Dumpable { @NonNull FpsUnlockTracker fpsUnlockTracker, @NonNull KeyguardTransitionInteractor keyguardTransitionInteractor, Lazy<DeviceEntryUdfpsTouchOverlayViewModel> deviceEntryUdfpsTouchOverlayViewModel, - Lazy<DefaultUdfpsTouchOverlayViewModel> defaultUdfpsTouchOverlayViewModel) { + Lazy<DefaultUdfpsTouchOverlayViewModel> defaultUdfpsTouchOverlayViewModel, + @NonNull UdfpsOverlayInteractor udfpsOverlayInteractor) { mContext = context; mExecution = execution; mVibrator = vibrator; @@ -715,6 +719,7 @@ public class UdfpsController implements DozeReceiver, Dumpable { mPrimaryBouncerInteractor = primaryBouncerInteractor; mShadeInteractor = shadeInteractor; mAlternateBouncerInteractor = alternateBouncerInteractor; + mUdfpsOverlayInteractor = udfpsOverlayInteractor; mInputManager = inputManager; mUdfpsKeyguardAccessibilityDelegate = udfpsKeyguardAccessibilityDelegate; mSelectedUserInteractor = selectedUserInteractor; diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt index b94a1779e10b..417608336974 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt @@ -45,6 +45,7 @@ import androidx.annotation.LayoutRes import androidx.annotation.VisibleForTesting import com.android.keyguard.KeyguardUpdateMonitor import com.android.systemui.animation.ActivityLaunchAnimator +import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams import com.android.systemui.biometrics.ui.binder.UdfpsTouchOverlayBinder import com.android.systemui.biometrics.ui.view.UdfpsTouchOverlay @@ -109,6 +110,7 @@ class UdfpsControllerOverlay @JvmOverloads constructor( private val deviceEntryUdfpsTouchOverlayViewModel: Lazy<DeviceEntryUdfpsTouchOverlayViewModel>, private val defaultUdfpsTouchOverlayViewModel: Lazy<DefaultUdfpsTouchOverlayViewModel>, private val shadeInteractor: ShadeInteractor, + private val udfpsOverlayInteractor: UdfpsOverlayInteractor, ) { private var overlayViewLegacy: UdfpsView? = null private set @@ -281,7 +283,8 @@ class UdfpsControllerOverlay @JvmOverloads constructor( statusBarStateController, shadeInteractor, dialogManager, - dumpManager + dumpManager, + udfpsOverlayInteractor, ) } REASON_AUTH_KEYGUARD -> { @@ -306,6 +309,7 @@ class UdfpsControllerOverlay @JvmOverloads constructor( selectedUserInteractor, transitionInteractor, shadeInteractor, + udfpsOverlayInteractor, ) } REASON_AUTH_BP -> { @@ -315,7 +319,8 @@ class UdfpsControllerOverlay @JvmOverloads constructor( statusBarStateController, shadeInteractor, dialogManager, - dumpManager + dumpManager, + udfpsOverlayInteractor, ) } REASON_AUTH_OTHER, @@ -325,7 +330,8 @@ class UdfpsControllerOverlay @JvmOverloads constructor( statusBarStateController, shadeInteractor, dialogManager, - dumpManager + dumpManager, + udfpsOverlayInteractor, ) } else -> { diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpmEmptyViewController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpmEmptyViewController.kt index ab3fbb191527..cfbbc26800d2 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpmEmptyViewController.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpmEmptyViewController.kt @@ -15,6 +15,7 @@ */ package com.android.systemui.biometrics +import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor import com.android.systemui.dump.DumpManager import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.shade.domain.interactor.ShadeInteractor @@ -30,13 +31,15 @@ class UdfpsFpmEmptyViewController( statusBarStateController: StatusBarStateController, shadeInteractor: ShadeInteractor, systemUIDialogManager: SystemUIDialogManager, - dumpManager: DumpManager + dumpManager: DumpManager, + udfpsOverlayInteractor: UdfpsOverlayInteractor, ) : UdfpsAnimationViewController<UdfpsFpmEmptyView>( view, statusBarStateController, shadeInteractor, systemUIDialogManager, - dumpManager + dumpManager, + udfpsOverlayInteractor, ) { override val tag = "UdfpsFpmOtherViewController" } diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerLegacy.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerLegacy.kt index 9f170241269d..7020d05350da 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerLegacy.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerLegacy.kt @@ -27,6 +27,7 @@ import com.android.keyguard.BouncerPanelExpansionCalculator.aboutToShowBouncerPr import com.android.keyguard.KeyguardUpdateMonitor import com.android.systemui.animation.ActivityLaunchAnimator import com.android.systemui.biometrics.UdfpsKeyguardViewLegacy.ANIMATE_APPEAR_ON_SCREEN_OFF +import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor import com.android.systemui.dump.DumpManager @@ -75,6 +76,7 @@ open class UdfpsKeyguardViewControllerLegacy( private val selectedUserInteractor: SelectedUserInteractor, private val transitionInteractor: KeyguardTransitionInteractor, shadeInteractor: ShadeInteractor, + udfpsOverlayInteractor: UdfpsOverlayInteractor, ) : UdfpsAnimationViewController<UdfpsKeyguardViewLegacy>( view, @@ -82,6 +84,7 @@ open class UdfpsKeyguardViewControllerLegacy( shadeInteractor, systemUIDialogManager, dumpManager, + udfpsOverlayInteractor, ) { private val uniqueIdentifier = this.toString() private var showingUdfpsBouncer = false diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/LogContextInteractor.kt b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/LogContextInteractor.kt index 863ba8d15b47..70be0f249b33 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/LogContextInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/LogContextInteractor.kt @@ -63,6 +63,9 @@ interface LogContextInteractor { /** Current display state, defined as [AuthenticateOptions.DisplayState] */ val displayState: Flow<Int> + /** If touches on the fingerprint sensor should be ignored by the HAL. */ + val isHardwareIgnoringTouches: Flow<Boolean> + /** * Add a permanent context listener. * @@ -79,12 +82,11 @@ constructor( @Application private val applicationScope: CoroutineScope, private val foldProvider: FoldStateProvider, keyguardTransitionInteractor: KeyguardTransitionInteractor, + udfpsOverlayInteractor: UdfpsOverlayInteractor, ) : LogContextInteractor { init { - applicationScope.launch { - foldProvider.start() - } + applicationScope.launch { foldProvider.start() } } override val displayState = @@ -102,6 +104,9 @@ constructor( } } + override val isHardwareIgnoringTouches: Flow<Boolean> = + udfpsOverlayInteractor.shouldHandleTouches.map { shouldHandle -> !shouldHandle } + override val isAod = displayState.map { it == AuthenticateOptions.DISPLAY_STATE_AOD }.distinctUntilChanged() @@ -159,6 +164,12 @@ constructor( .catch { t -> Log.w(TAG, "failed to notify new display state", t) } .launchIn(this) + isHardwareIgnoringTouches + .distinctUntilChanged() + .onEach { state -> listener.onHardwareIgnoreTouchesChanged(state) } + .catch { t -> Log.w(TAG, "failed to notify new set ignore state", t) } + .launchIn(this) + listener.asBinder().linkToDeath({ cancel() }, 0) } } diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractor.kt b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractor.kt index f4a2811a1b5a..4fc1b5841047 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractor.kt @@ -30,8 +30,10 @@ import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn @@ -56,6 +58,16 @@ constructor( return isUdfpsEnrolled && isWithinOverlayBounds } + /** Sets whether Udfps overlay should handle touches */ + fun setHandleTouches(shouldHandle: Boolean = true) { + _shouldHandleTouches.value = shouldHandle + } + + private var _shouldHandleTouches = MutableStateFlow(true) + + /** Whether Udfps overlay should handle touches */ + val shouldHandleTouches: StateFlow<Boolean> = _shouldHandleTouches.asStateFlow() + /** Returns the current udfpsOverlayParams */ val udfpsOverlayParams: StateFlow<UdfpsOverlayParams> = ConflatedCallbackFlow.conflatedCallbackFlow { diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsBpViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsBpViewControllerTest.kt index 647dae6fd6c2..13306becf6d2 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsBpViewControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsBpViewControllerTest.kt @@ -20,6 +20,7 @@ import android.testing.TestableLooper import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase +import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor import com.android.systemui.dump.DumpManager import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.shade.domain.interactor.ShadeInteractor @@ -44,6 +45,7 @@ class UdfpsBpViewControllerTest : SysuiTestCase() { @Mock lateinit var shadeInteractor: ShadeInteractor @Mock lateinit var systemUIDialogManager: SystemUIDialogManager @Mock lateinit var dumpManager: DumpManager + @Mock lateinit var udfpsOverlayInteractor: UdfpsOverlayInteractor private lateinit var udfpsBpViewController: UdfpsBpViewController @@ -55,7 +57,8 @@ class UdfpsBpViewControllerTest : SysuiTestCase() { statusBarStateController, shadeInteractor, systemUIDialogManager, - dumpManager + dumpManager, + udfpsOverlayInteractor, ) } diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/LogContextInteractorImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/LogContextInteractorImplTest.kt index 8f8004f1cbb8..b1e471af2e71 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/LogContextInteractorImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/LogContextInteractorImplTest.kt @@ -5,6 +5,7 @@ import android.hardware.biometrics.IBiometricContextListener import android.hardware.biometrics.IBiometricContextListener.FoldState import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase +import com.android.systemui.biometrics.AuthController import com.android.systemui.coroutines.collectLastValue import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractorFactory @@ -17,6 +18,7 @@ import com.android.systemui.unfold.updates.FOLD_UPDATE_FINISH_HALF_OPEN import com.android.systemui.unfold.updates.FOLD_UPDATE_START_CLOSING import com.android.systemui.unfold.updates.FOLD_UPDATE_START_OPENING import com.android.systemui.unfold.updates.FoldStateProvider +import com.android.systemui.user.domain.interactor.SelectedUserInteractor import com.android.systemui.util.mockito.withArgCaptor import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -42,7 +44,10 @@ class LogContextInteractorImplTest : SysuiTestCase() { private val testScope = TestScope() @Mock private lateinit var foldProvider: FoldStateProvider + @Mock private lateinit var authController: AuthController + @Mock private lateinit var selectedUserInteractor: SelectedUserInteractor + private lateinit var udfpsOverlayInteractor: UdfpsOverlayInteractor private lateinit var keyguardTransitionRepository: FakeKeyguardTransitionRepository private lateinit var interactor: LogContextInteractorImpl @@ -50,6 +55,13 @@ class LogContextInteractorImplTest : SysuiTestCase() { @Before fun setup() { keyguardTransitionRepository = FakeKeyguardTransitionRepository() + udfpsOverlayInteractor = + UdfpsOverlayInteractor( + context, + authController, + selectedUserInteractor, + testScope.backgroundScope, + ) interactor = LogContextInteractorImpl( testScope.backgroundScope, @@ -59,6 +71,7 @@ class LogContextInteractorImplTest : SysuiTestCase() { scope = testScope.backgroundScope, ) .keyguardTransitionInteractor, + udfpsOverlayInteractor, ) } @@ -162,6 +175,18 @@ class LogContextInteractorImplTest : SysuiTestCase() { } @Test + fun isHardwareIgnoringTouchesChanges() = + testScope.runTest { + val isHardwareIgnoringTouches by collectLastValue(interactor.isHardwareIgnoringTouches) + + udfpsOverlayInteractor.setHandleTouches(true) + assertThat(isHardwareIgnoringTouches).isFalse() + + udfpsOverlayInteractor.setHandleTouches(false) + assertThat(isHardwareIgnoringTouches).isTrue() + } + + @Test fun foldStateChanges() = testScope.runTest { val foldState = collectLastValue(interactor.foldState) @@ -195,6 +220,7 @@ class LogContextInteractorImplTest : SysuiTestCase() { var folded: Int? = null var displayState: Int? = null + var ignoreTouches: Boolean? = null val job = interactor.addBiometricContextListener( object : IBiometricContextListener.Stub() { @@ -205,12 +231,17 @@ class LogContextInteractorImplTest : SysuiTestCase() { override fun onDisplayStateChanged(newDisplayState: Int) { displayState = newDisplayState } + + override fun onHardwareIgnoreTouchesChanged(newIgnoreTouches: Boolean) { + ignoreTouches = newIgnoreTouches + } } ) runCurrent() assertThat(folded).isEqualTo(FoldState.FULLY_CLOSED) assertThat(displayState).isEqualTo(AuthenticateOptions.DISPLAY_STATE_AOD) + assertThat(ignoreTouches).isFalse() foldListener.onFoldUpdate(FOLD_UPDATE_START_OPENING) foldListener.onFoldUpdate(FOLD_UPDATE_FINISH_HALF_OPEN) @@ -220,6 +251,11 @@ class LogContextInteractorImplTest : SysuiTestCase() { assertThat(folded).isEqualTo(FoldState.HALF_OPENED) assertThat(displayState).isEqualTo(AuthenticateOptions.DISPLAY_STATE_LOCKSCREEN) + udfpsOverlayInteractor.setHandleTouches(false) + runCurrent() + + assertThat(ignoreTouches).isTrue() + job.cancel() // stale updates should be ignored diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractorTest.kt index 6a686726b959..c0e108ef75f8 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractorTest.kt @@ -68,7 +68,7 @@ class UdfpsOverlayInteractorTest : SysuiTestCase() { @Test fun testShouldInterceptTouch() = testScope.runTest { - createUdpfsOverlayInteractor() + createUdfpsOverlayInteractor() // When fingerprint enrolled and touch is within bounds verify(authController).addCallback(authControllerCallback.capture()) @@ -92,7 +92,7 @@ class UdfpsOverlayInteractorTest : SysuiTestCase() { @Test fun testUdfpsOverlayParamsChange() = testScope.runTest { - createUdpfsOverlayInteractor() + createUdfpsOverlayInteractor() val udfpsOverlayParams = collectLastValue(underTest.udfpsOverlayParams) runCurrent() @@ -105,7 +105,7 @@ class UdfpsOverlayInteractorTest : SysuiTestCase() { assertThat(udfpsOverlayParams()).isEqualTo(firstParams) } - private fun createUdpfsOverlayInteractor() { + private fun createUdfpsOverlayInteractor() { underTest = UdfpsOverlayInteractor( context, diff --git a/services/core/java/com/android/server/biometrics/log/BiometricContext.java b/services/core/java/com/android/server/biometrics/log/BiometricContext.java index 3dcea19b6077..f8a98675c0c7 100644 --- a/services/core/java/com/android/server/biometrics/log/BiometricContext.java +++ b/services/core/java/com/android/server/biometrics/log/BiometricContext.java @@ -77,6 +77,9 @@ public interface BiometricContext { @AuthenticateOptions.DisplayState int getDisplayState(); + /** Gets whether touches on sensor are ignored by HAL */ + boolean isHardwareIgnoringTouches(); + /** * Subscribe to context changes. * diff --git a/services/core/java/com/android/server/biometrics/log/BiometricContextProvider.java b/services/core/java/com/android/server/biometrics/log/BiometricContextProvider.java index 95a047faef07..535b7b743625 100644 --- a/services/core/java/com/android/server/biometrics/log/BiometricContextProvider.java +++ b/services/core/java/com/android/server/biometrics/log/BiometricContextProvider.java @@ -86,8 +86,8 @@ public final class BiometricContextProvider implements BiometricContext { @Nullable private final Handler mHandler; private int mDockState = Intent.EXTRA_DOCK_STATE_UNDOCKED; private int mFoldState = IBiometricContextListener.FoldState.UNKNOWN; - private int mDisplayState = AuthenticateOptions.DISPLAY_STATE_UNKNOWN; + private boolean mIsHardwareIgnoringTouches = false; @VisibleForTesting final BroadcastReceiver mDockStateReceiver = new BroadcastReceiver() { @Override @@ -129,6 +129,14 @@ public final class BiometricContextProvider implements BiometricContext { notifyChanged(); } } + + @Override + public void onHardwareIgnoreTouchesChanged(boolean shouldIgnore) { + if (mIsHardwareIgnoringTouches != shouldIgnore) { + mIsHardwareIgnoringTouches = shouldIgnore; + notifyChanged(); + } + } }); service.registerSessionListener(SESSION_TYPES, new ISessionListener.Stub() { @Override @@ -215,6 +223,11 @@ public final class BiometricContextProvider implements BiometricContext { } @Override + public boolean isHardwareIgnoringTouches() { + return mIsHardwareIgnoringTouches; + } + + @Override public void subscribe(@NonNull OperationContextExt context, @NonNull Consumer<OperationContext> consumer) { mSubscribers.put(context, consumer); @@ -254,6 +267,7 @@ public final class BiometricContextProvider implements BiometricContext { + "bp session: " + getBiometricPromptSessionInfo() + ", " + "displayState: " + getDisplayState() + ", " + "isAwake: " + isAwake() + ", " + + "isHardwareIgnoring: " + isHardwareIgnoringTouches() + ", " + "isDisplayOn: " + isDisplayOn() + ", " + "dock: " + getDockedState() + ", " + "rotation: " + getCurrentRotation() + ", " diff --git a/services/core/java/com/android/server/biometrics/log/OperationContextExt.java b/services/core/java/com/android/server/biometrics/log/OperationContextExt.java index b4e0dff615f5..0045d44af9a1 100644 --- a/services/core/java/com/android/server/biometrics/log/OperationContextExt.java +++ b/services/core/java/com/android/server/biometrics/log/OperationContextExt.java @@ -20,12 +20,14 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Intent; import android.hardware.biometrics.AuthenticateOptions; +import android.hardware.biometrics.BiometricAuthenticator; import android.hardware.biometrics.IBiometricContextListener; import android.hardware.biometrics.common.AuthenticateReason; import android.hardware.biometrics.common.DisplayState; import android.hardware.biometrics.common.FoldState; import android.hardware.biometrics.common.OperationContext; import android.hardware.biometrics.common.OperationReason; +import android.hardware.biometrics.common.OperationState; import android.hardware.biometrics.common.WakeReason; import android.hardware.face.FaceAuthenticateOptions; import android.hardware.fingerprint.FingerprintAuthenticateOptions; @@ -51,13 +53,26 @@ public class OperationContextExt { /** Create a context. */ public OperationContextExt(boolean isBP) { - this(new OperationContext(), isBP); + this(new OperationContext(), isBP, BiometricAuthenticator.TYPE_NONE); + } + + public OperationContextExt(boolean isBP, @BiometricAuthenticator.Modality int modality) { + this(new OperationContext(), isBP, modality); } /** Create a wrapped context. */ - public OperationContextExt(@NonNull OperationContext context, boolean isBP) { + public OperationContextExt(@NonNull OperationContext context, boolean isBP, + @BiometricAuthenticator.Modality int modality) { mAidlContext = context; mIsBP = isBP; + + if (modality == BiometricAuthenticator.TYPE_FINGERPRINT) { + mAidlContext.operationState = OperationState.fingerprintOperationState( + new OperationState.FingerprintOperationState()); + } else if (modality == BiometricAuthenticator.TYPE_FACE) { + mAidlContext.operationState = OperationState.faceOperationState( + new OperationState.FaceOperationState()); + } } /** @@ -247,12 +262,23 @@ public class OperationContextExt { return mOrientation; } + /** The current operation state */ + public OperationState getOperationState() { + return mAidlContext.operationState; + } + /** Update this object with the latest values from the given context. */ OperationContextExt update(@NonNull BiometricContext biometricContext, boolean isCrypto) { mAidlContext.isAod = biometricContext.isAod(); mAidlContext.displayState = toAidlDisplayState(biometricContext.getDisplayState()); mAidlContext.foldState = toAidlFoldState(biometricContext.getFoldState()); mAidlContext.isCrypto = isCrypto; + + if (mAidlContext.operationState != null && mAidlContext.operationState.getTag() + == OperationState.fingerprintOperationState) { + mAidlContext.operationState.getFingerprintOperationState().isHardwareIgnoringTouches = + biometricContext.isHardwareIgnoringTouches(); + } setFirstSessionId(biometricContext); mIsDisplayOn = biometricContext.isDisplayOn(); diff --git a/services/core/java/com/android/server/biometrics/sensors/ClientMonitorCallbackConverter.java b/services/core/java/com/android/server/biometrics/sensors/ClientMonitorCallbackConverter.java index 1a682a9ffefa..1fc7c70de8fb 100644 --- a/services/core/java/com/android/server/biometrics/sensors/ClientMonitorCallbackConverter.java +++ b/services/core/java/com/android/server/biometrics/sensors/ClientMonitorCallbackConverter.java @@ -41,22 +41,42 @@ import android.os.RemoteException; * a common interface. */ public class ClientMonitorCallbackConverter { - private IBiometricSensorReceiver mSensorReceiver; // BiometricService - private IFaceServiceReceiver mFaceServiceReceiver; // FaceManager - private IFingerprintServiceReceiver mFingerprintServiceReceiver; // FingerprintManager + private final IBiometricSensorReceiver mSensorReceiver; // BiometricService + private final IFaceServiceReceiver mFaceServiceReceiver; // FaceManager + private final IFingerprintServiceReceiver mFingerprintServiceReceiver; // FingerprintManager public ClientMonitorCallbackConverter(IBiometricSensorReceiver sensorReceiver) { mSensorReceiver = sensorReceiver; + mFaceServiceReceiver = null; + mFingerprintServiceReceiver = null; } public ClientMonitorCallbackConverter(IFaceServiceReceiver faceServiceReceiver) { + mSensorReceiver = null; mFaceServiceReceiver = faceServiceReceiver; + mFingerprintServiceReceiver = null; } public ClientMonitorCallbackConverter(IFingerprintServiceReceiver fingerprintServiceReceiver) { + mSensorReceiver = null; + mFaceServiceReceiver = null; mFingerprintServiceReceiver = fingerprintServiceReceiver; } + /** + * Returns an int representing the {@link BiometricAuthenticator.Modality} of the active + * ServiceReceiver + */ + @BiometricAuthenticator.Modality + public int getModality() { + if (mFaceServiceReceiver != null) { + return BiometricAuthenticator.TYPE_FACE; + } else if (mFingerprintServiceReceiver != null) { + return BiometricAuthenticator.TYPE_FINGERPRINT; + } + return BiometricAuthenticator.TYPE_NONE; + } + // The following apply to all clients public void onAcquired(int sensorId, int acquiredInfo, int vendorCode) throws RemoteException { diff --git a/services/core/java/com/android/server/biometrics/sensors/HalClientMonitor.java b/services/core/java/com/android/server/biometrics/sensors/HalClientMonitor.java index 03658ce21fc2..0f01510bd908 100644 --- a/services/core/java/com/android/server/biometrics/sensors/HalClientMonitor.java +++ b/services/core/java/com/android/server/biometrics/sensors/HalClientMonitor.java @@ -19,6 +19,7 @@ package com.android.server.biometrics.sensors; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; +import android.hardware.biometrics.BiometricAuthenticator; import android.os.IBinder; import com.android.server.biometrics.log.BiometricContext; @@ -58,7 +59,8 @@ public abstract class HalClientMonitor<T> extends BaseClientMonitor { super(context, token, listener, userId, owner, cookie, sensorId, biometricLogger, biometricContext); mLazyDaemon = lazyDaemon; - mOperationContext = new OperationContextExt(isBiometricPrompt()); + int modality = listener != null ? listener.getModality() : BiometricAuthenticator.TYPE_NONE; + mOperationContext = new OperationContextExt(isBiometricPrompt(), modality); } @Nullable diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java index 29c5a3de3a80..145885de5c32 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java @@ -28,6 +28,7 @@ import android.hardware.biometrics.BiometricFingerprintConstants; import android.hardware.biometrics.BiometricFingerprintConstants.FingerprintAcquired; import android.hardware.biometrics.BiometricManager.Authenticators; import android.hardware.biometrics.common.ICancellationSignal; +import android.hardware.biometrics.common.OperationState; import android.hardware.biometrics.fingerprint.PointerContext; import android.hardware.fingerprint.FingerprintAuthenticateOptions; import android.hardware.fingerprint.FingerprintManager; @@ -326,6 +327,12 @@ public class FingerprintAuthenticationClient if (session.hasContextMethods()) { try { session.getSession().onContextChanged(ctx); + // TODO(b/317414324): Deprecate setIgnoreDisplayTouches + if (ctx.operationState != null && ctx.operationState.getTag() + == OperationState.fingerprintOperationState) { + session.getSession().setIgnoreDisplayTouches( + ctx.operationState.getFingerprintOperationState().isHardwareIgnoringTouches); + } } catch (RemoteException e) { Slog.e(TAG, "Unable to notify context changed", e); } diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java index e58e5ae117b5..3aab7b300a87 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java @@ -23,6 +23,7 @@ import android.annotation.Nullable; import android.content.Context; import android.hardware.biometrics.BiometricRequestConstants; import android.hardware.biometrics.common.ICancellationSignal; +import android.hardware.biometrics.common.OperationState; import android.hardware.fingerprint.FingerprintAuthenticateOptions; import android.hardware.fingerprint.IUdfpsOverlayController; import android.os.IBinder; @@ -122,6 +123,12 @@ public class FingerprintDetectClient extends AcquisitionClient<AidlSession> getBiometricContext().subscribe(opContext, ctx -> { try { session.getSession().onContextChanged(ctx); + // TODO(b/317414324): Deprecate setIgnoreDisplayTouches + if (ctx.operationState != null && ctx.operationState.getTag() + == OperationState.fingerprintOperationState) { + session.getSession().setIgnoreDisplayTouches( + ctx.operationState.getFingerprintOperationState().isHardwareIgnoringTouches); + } } catch (RemoteException e) { Slog.e(TAG, "Unable to notify context changed", e); } diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java index c0761ed8f32b..bf5011de1e59 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java @@ -26,6 +26,7 @@ import android.hardware.biometrics.BiometricFingerprintConstants; import android.hardware.biometrics.BiometricFingerprintConstants.FingerprintAcquired; import android.hardware.biometrics.BiometricStateListener; import android.hardware.biometrics.common.ICancellationSignal; +import android.hardware.biometrics.common.OperationState; import android.hardware.biometrics.fingerprint.PointerContext; import android.hardware.fingerprint.Fingerprint; import android.hardware.fingerprint.FingerprintManager; @@ -220,6 +221,12 @@ public class FingerprintEnrollClient extends EnrollClient<AidlSession> implement getBiometricContext().subscribe(opContext, ctx -> { try { session.getSession().onContextChanged(ctx); + // TODO(b/317414324): Deprecate setIgnoreDisplayTouches + if (ctx.operationState != null && ctx.operationState.getTag() + == OperationState.fingerprintOperationState) { + session.getSession().setIgnoreDisplayTouches( + ctx.operationState.getFingerprintOperationState().isHardwareIgnoringTouches); + } } catch (RemoteException e) { Slog.e(TAG, "Unable to notify context changed", e); } diff --git a/services/tests/servicestests/src/com/android/server/biometrics/log/BiometricContextProviderTest.java b/services/tests/servicestests/src/com/android/server/biometrics/log/BiometricContextProviderTest.java index 1b9e6fb6e247..a8eace05de97 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/log/BiometricContextProviderTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/log/BiometricContextProviderTest.java @@ -153,6 +153,15 @@ public class BiometricContextProviderTest { } @Test + public void testGetIsHardwareIgnoringTouches() throws RemoteException { + mListener.onHardwareIgnoreTouchesChanged(true); + assertThat(mProvider.isHardwareIgnoringTouches()).isTrue(); + + mListener.onHardwareIgnoreTouchesChanged(false); + assertThat(mProvider.isHardwareIgnoringTouches()).isFalse(); + } + + @Test public void testGetDockedState() { final List<Integer> states = List.of(Intent.EXTRA_DOCK_STATE_DESK, Intent.EXTRA_DOCK_STATE_CAR, Intent.EXTRA_DOCK_STATE_UNDOCKED); diff --git a/services/tests/servicestests/src/com/android/server/biometrics/log/BiometricFrameworkStatsLoggerTest.java b/services/tests/servicestests/src/com/android/server/biometrics/log/BiometricFrameworkStatsLoggerTest.java index 5cff48dc3c2a..41193527503b 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/log/BiometricFrameworkStatsLoggerTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/log/BiometricFrameworkStatsLoggerTest.java @@ -18,6 +18,7 @@ package com.android.server.biometrics.log; import static com.google.common.truth.Truth.assertThat; +import android.hardware.biometrics.BiometricAuthenticator; import android.hardware.biometrics.BiometricsProtoEnums; import android.hardware.biometrics.common.AuthenticateReason; import android.hardware.biometrics.common.OperationContext; @@ -48,11 +49,13 @@ public class BiometricFrameworkStatsLoggerTest { public void testConvertsWakeReason_whenPowerReason() { final OperationContext context = new OperationContext(); context.wakeReason = WakeReason.WAKE_MOTION; - final OperationContextExt ctx = new OperationContextExt(context, false); + final OperationContextExt ctx = new OperationContextExt(context, false, + BiometricAuthenticator.TYPE_NONE); final int reason = BiometricFrameworkStatsLogger.toProtoWakeReason(ctx); final int[] reasonDetails = BiometricFrameworkStatsLogger - .toProtoWakeReasonDetails(new OperationContextExt(context, false)); + .toProtoWakeReasonDetails( + new OperationContextExt(context, false, BiometricAuthenticator.TYPE_NONE)); assertThat(reason).isEqualTo(BiometricsProtoEnums.WAKE_REASON_WAKE_MOTION); assertThat(reasonDetails).isEmpty(); @@ -63,7 +66,8 @@ public class BiometricFrameworkStatsLoggerTest { final OperationContext context = new OperationContext(); context.authenticateReason = AuthenticateReason.faceAuthenticateReason( AuthenticateReason.Face.ASSISTANT_VISIBLE); - final OperationContextExt ctx = new OperationContextExt(context, false); + final OperationContextExt ctx = new OperationContextExt(context, false, + BiometricAuthenticator.TYPE_NONE); final int reason = BiometricFrameworkStatsLogger.toProtoWakeReason(ctx); final int[] reasonDetails = BiometricFrameworkStatsLogger @@ -79,7 +83,8 @@ public class BiometricFrameworkStatsLoggerTest { final OperationContext context = new OperationContext(); context.authenticateReason = AuthenticateReason.vendorAuthenticateReason( new AuthenticateReason.Vendor()); - final OperationContextExt ctx = new OperationContextExt(context, false); + final OperationContextExt ctx = new OperationContextExt(context, false, + BiometricAuthenticator.TYPE_NONE); final int reason = BiometricFrameworkStatsLogger.toProtoWakeReason(ctx); final int[] reasonDetails = BiometricFrameworkStatsLogger @@ -96,7 +101,8 @@ public class BiometricFrameworkStatsLoggerTest { context.wakeReason = WakeReason.WAKE_KEY; context.authenticateReason = AuthenticateReason.faceAuthenticateReason( AuthenticateReason.Face.PRIMARY_BOUNCER_SHOWN); - final OperationContextExt ctx = new OperationContextExt(context, false); + final OperationContextExt ctx = new OperationContextExt(context, false, + BiometricAuthenticator.TYPE_NONE); final int reason = BiometricFrameworkStatsLogger.toProtoWakeReason(ctx); final int[] reasonDetails = BiometricFrameworkStatsLogger @@ -113,7 +119,8 @@ public class BiometricFrameworkStatsLoggerTest { context.wakeReason = WakeReason.LID; context.authenticateReason = AuthenticateReason.vendorAuthenticateReason( new AuthenticateReason.Vendor()); - final OperationContextExt ctx = new OperationContextExt(context, false); + final OperationContextExt ctx = new OperationContextExt(context, false, + BiometricAuthenticator.TYPE_NONE); final int reason = BiometricFrameworkStatsLogger.toProtoWakeReason(ctx); final int[] reasonDetails = BiometricFrameworkStatsLogger diff --git a/services/tests/servicestests/src/com/android/server/biometrics/log/OperationContextExtTest.java b/services/tests/servicestests/src/com/android/server/biometrics/log/OperationContextExtTest.java index 32284fd7541a..767b4262bb18 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/log/OperationContextExtTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/log/OperationContextExtTest.java @@ -18,17 +18,19 @@ package com.android.server.biometrics.log; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.when; + import android.content.Intent; import android.hardware.biometrics.AuthenticateOptions; +import android.hardware.biometrics.BiometricAuthenticator; import android.hardware.biometrics.IBiometricContextListener; import android.hardware.biometrics.common.DisplayState; import android.hardware.biometrics.common.OperationContext; import android.hardware.biometrics.common.OperationReason; +import android.hardware.biometrics.common.OperationState; import android.platform.test.annotations.Presubmit; import android.view.Surface; -import static org.mockito.Mockito.when; - import androidx.test.filters.SmallTest; import com.android.internal.logging.InstanceId; @@ -58,7 +60,7 @@ public class OperationContextExtTest { final OperationContext aidlContext = newAidlContext(); - context = new OperationContextExt(aidlContext, false); + context = new OperationContextExt(aidlContext, false, BiometricAuthenticator.TYPE_NONE); assertThat(context.toAidlContext()).isSameInstanceAs(aidlContext); final int id = 5; @@ -96,7 +98,8 @@ public class OperationContextExtTest { ); for (Map.Entry<Integer, Integer> entry : map.entrySet()) { - final OperationContextExt context = new OperationContextExt(newAidlContext(), true); + final OperationContextExt context = new OperationContextExt(newAidlContext(), true, + BiometricAuthenticator.TYPE_NONE); when(mBiometricContext.getDisplayState()).thenReturn(entry.getKey()); assertThat(context.update(mBiometricContext, context.isCrypto()).getDisplayState()) .isEqualTo(entry.getValue()); @@ -124,7 +127,7 @@ public class OperationContextExtTest { updatesFromSource(null, OperationReason.UNKNOWN); } - private void updatesFromSource(BiometricContextSessionInfo sessionInfo, int sessionType) { + private void updatesFromSource(BiometricContextSessionInfo sessionInfo, int sessionType) { final int rotation = Surface.ROTATION_270; final int foldState = IBiometricContextListener.FoldState.HALF_OPENED; final int dockState = Intent.EXTRA_DOCK_STATE_CAR; @@ -135,9 +138,11 @@ public class OperationContextExtTest { when(mBiometricContext.getDockedState()).thenReturn(dockState); when(mBiometricContext.isDisplayOn()).thenReturn(true); when(mBiometricContext.getDisplayState()).thenReturn(displayState); + when(mBiometricContext.isHardwareIgnoringTouches()).thenReturn(true); final OperationContextExt context = new OperationContextExt(newAidlContext(), - sessionType == OperationReason.BIOMETRIC_PROMPT); + sessionType == OperationReason.BIOMETRIC_PROMPT, + BiometricAuthenticator.TYPE_FINGERPRINT); assertThat(context.update(mBiometricContext, context.isCrypto())).isSameInstanceAs(context); @@ -154,6 +159,46 @@ public class OperationContextExtTest { assertThat(context.getOrientation()).isEqualTo(rotation); assertThat(context.isDisplayOn()).isTrue(); assertThat(context.getDisplayState()).isEqualTo(DisplayState.AOD); + assertThat( + context.getOperationState().getFingerprintOperationState().isHardwareIgnoringTouches + ).isTrue(); + } + + @Test + public void hasNullOperationState() { + OperationContextExt context = new OperationContextExt(false); + assertThat(context.toAidlContext()).isNotNull(); + + final OperationContext aidlContext = newAidlContext(); + + context = new OperationContextExt(aidlContext, false, BiometricAuthenticator.TYPE_NONE); + assertThat(context.getOperationState()).isNull(); + } + + @Test + public void hasFaceOperationState() { + OperationContextExt context = new OperationContextExt(false); + assertThat(context.toAidlContext()).isNotNull(); + + final OperationContext aidlContext = newAidlContext(); + + context = new OperationContextExt(aidlContext, false, + BiometricAuthenticator.TYPE_FACE); + assertThat(context.getOperationState().getTag()).isEqualTo( + OperationState.faceOperationState); + } + + @Test + public void hasFingerprintOperationState() { + OperationContextExt context = new OperationContextExt(false); + assertThat(context.toAidlContext()).isNotNull(); + + final OperationContext aidlContext = newAidlContext(); + + context = new OperationContextExt(aidlContext, false, + BiometricAuthenticator.TYPE_FINGERPRINT); + assertThat(context.getOperationState().getTag()).isEqualTo( + OperationState.fingerprintOperationState); } private static OperationContext newAidlContext() { diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/AcquisitionClientTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/AcquisitionClientTest.java index 2d9d868f2f74..4604b310edf7 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/AcquisitionClientTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/AcquisitionClientTest.java @@ -72,6 +72,7 @@ public class AcquisitionClientTest { mToken, mClientCallback); client.start(mSchedulerCallback); assertTrue(client.mHalOperationRunning); + verify(mClientCallback).getModality(); verify(mSchedulerCallback).onClientStarted(eq(client)); // Pretend that it got canceled by the user. |