From e6cafe984e2ea68b159d7e0f159708d7b3385289 Mon Sep 17 00:00:00 2001 From: Nicolo' Mazzucato Date: Wed, 6 Jul 2022 14:02:31 +0000 Subject: [PATCH] Show side fps hint on large screen bouncer This adds an hint regarding the possibility to unlock with the fingerprint while on bouncer, only when sided bouncer is enabled (so only on large screens). The hint is visible while the sensor is running. Bug: 226610828 Test: atest KeyguardSecurityContainerControllerTest Change-Id: I961ae6fe67e92620e955a5e297052e255fddd80d --- .../keyguard/KeyguardHostViewController.java | 5 + .../KeyguardSecurityContainerController.java | 69 ++++++++- .../dagger/KeyguardBouncerModule.java | 21 +++ .../systemui/biometrics/SidefpsController.kt | 54 ++++--- .../statusbar/phone/KeyguardBouncer.java | 5 +- .../KeyguardHostViewControllerTest.java | 14 ++ ...yguardSecurityContainerControllerTest.java | 145 +++++++++++++++++- .../biometrics/SidefpsControllerTest.kt | 44 ++++-- .../statusbar/phone/KeyguardBouncerTest.java | 9 ++ 9 files changed, 318 insertions(+), 48 deletions(-) diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardHostViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardHostViewController.java index 12fa401d7fea9..d32219a9817f8 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardHostViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardHostViewController.java @@ -336,6 +336,11 @@ public class KeyguardHostViewController extends ViewController mKeyguardSecurityContainerController.onStartingToHide(); } + /** Called when bouncer visibility changes. */ + public void onBouncerVisibilityChanged(@View.Visibility int visibility) { + mKeyguardSecurityContainerController.onBouncerVisibilityChanged(visibility); + } + public boolean hasDismissActions() { return mDismissAction != null || mCancelAction != null; } diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java index 61e2624406079..5ee659be6dd28 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java @@ -17,6 +17,7 @@ package com.android.keyguard; import static android.app.StatusBarManager.SESSION_KEYGUARD; +import static android.hardware.biometrics.BiometricSourceType.FINGERPRINT; import static com.android.keyguard.KeyguardSecurityContainer.BOUNCER_DISMISS_BIOMETRIC; import static com.android.keyguard.KeyguardSecurityContainer.BOUNCER_DISMISS_EXTENDED_ACCESS; @@ -32,11 +33,13 @@ import android.app.admin.DevicePolicyManager; import android.content.Intent; import android.content.res.ColorStateList; import android.content.res.Configuration; +import android.hardware.biometrics.BiometricSourceType; import android.metrics.LogMaker; import android.os.UserHandle; import android.util.Log; import android.util.Slog; import android.view.MotionEvent; +import android.view.View; import androidx.annotation.Nullable; @@ -55,6 +58,7 @@ import com.android.keyguard.dagger.KeyguardBouncerScope; import com.android.settingslib.utils.ThreadUtils; import com.android.systemui.Gefingerpoken; import com.android.systemui.R; +import com.android.systemui.biometrics.SidefpsController; import com.android.systemui.classifier.FalsingCollector; import com.android.systemui.flags.FeatureFlags; import com.android.systemui.flags.Flags; @@ -67,6 +71,8 @@ import com.android.systemui.statusbar.policy.UserSwitcherController; import com.android.systemui.util.ViewController; import com.android.systemui.util.settings.GlobalSettings; +import java.util.Optional; + import javax.inject.Inject; /** Controller for {@link KeyguardSecurityContainer} */ @@ -93,6 +99,7 @@ public class KeyguardSecurityContainerController extends ViewController mSidefpsController; private int mLastOrientation = Configuration.ORIENTATION_UNDEFINED; @@ -236,13 +243,27 @@ public class KeyguardSecurityContainerController extends ViewController sidefpsController) { super(view); mLockPatternUtils = lockPatternUtils; mUpdateMonitor = keyguardUpdateMonitor; @@ -280,6 +302,7 @@ public class KeyguardSecurityContainerController extends ViewController mSidefpsController; @Inject Factory(KeyguardSecurityContainer view, @@ -673,7 +723,8 @@ public class KeyguardSecurityContainerController extends ViewController sidefpsController) { mView = view; mAdminSecondaryLockScreenControllerFactory = adminSecondaryLockScreenControllerFactory; mLockPatternUtils = lockPatternUtils; @@ -690,6 +741,7 @@ public class KeyguardSecurityContainerController extends ViewController providesOptionalSidefpsController( + @Nullable FingerprintManager fingerprintManager, + Provider sidefpsControllerProvider) { + if (!hasSideFpsSensor(fingerprintManager)) { + return Optional.empty(); + } + return Optional.of(sidefpsControllerProvider.get()); + } } diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/SidefpsController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/SidefpsController.kt index 04e2dccda5284..bbffb73b7503d 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/SidefpsController.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/SidefpsController.kt @@ -34,16 +34,16 @@ import android.hardware.fingerprint.ISidefpsController import android.os.Handler import android.util.Log import android.util.RotationUtils -import android.view.View.AccessibilityDelegate -import android.view.accessibility.AccessibilityEvent import android.view.Display import android.view.Gravity import android.view.LayoutInflater import android.view.Surface import android.view.View +import android.view.View.AccessibilityDelegate import android.view.ViewPropertyAnimator import android.view.WindowInsets import android.view.WindowManager +import android.view.accessibility.AccessibilityEvent import androidx.annotation.RawRes import com.airbnb.lottie.LottieAnimationView import com.airbnb.lottie.LottieProperty @@ -70,13 +70,12 @@ class SidefpsController @Inject constructor( private val activityTaskManager: ActivityTaskManager, overviewProxyService: OverviewProxyService, displayManager: DisplayManager, - @Main mainExecutor: DelayableExecutor, + @Main private val mainExecutor: DelayableExecutor, @Main private val handler: Handler ) { @VisibleForTesting val sensorProps: FingerprintSensorPropertiesInternal = fingerprintManager - ?.sensorPropertiesInternal - ?.firstOrNull { it.isAnySidefpsType } + ?.sideFpsSensorProperties ?: throw IllegalStateException("no side fingerprint sensor") @VisibleForTesting @@ -135,25 +134,34 @@ class SidefpsController @Inject constructor( } init { - fingerprintManager?.setSidefpsController(object : ISidefpsController.Stub() { - override fun show( - sensorId: Int, - @BiometricOverlayConstants.ShowReason reason: Int - ) = if (reason.isReasonToShow(activityTaskManager)) doShow() else hide(sensorId) + fingerprintManager?.setSidefpsController( + object : ISidefpsController.Stub() { + override fun show( + sensorId: Int, + @BiometricOverlayConstants.ShowReason reason: Int + ) = if (reason.isReasonToShow(activityTaskManager)) show() else hide() - private fun doShow() = mainExecutor.execute { - if (overlayView == null) { - createOverlayForDisplay() - } else { - Log.v(TAG, "overlay already shown") - } - } - - override fun hide(sensorId: Int) = mainExecutor.execute { overlayView = null } - }) + override fun hide(sensorId: Int) = hide() + }) overviewProxyService.addCallback(overviewProxyListener) } + /** Shows the side fps overlay if not already shown. */ + fun show() { + mainExecutor.execute { + if (overlayView == null) { + createOverlayForDisplay() + } else { + Log.v(TAG, "overlay already shown") + } + } + } + + /** Hides the fps overlay if shown. */ + fun hide() { + mainExecutor.execute { overlayView = null } + } + private fun onOrientationChanged() { if (overlayView != null) { createOverlayForDisplay() @@ -266,6 +274,12 @@ class SidefpsController @Inject constructor( } } +private val FingerprintManager?.sideFpsSensorProperties: FingerprintSensorPropertiesInternal? + get() = this?.sensorPropertiesInternal?.firstOrNull { it.isAnySidefpsType } + +/** Returns [True] when the device has a side fingerprint sensor. */ +fun FingerprintManager?.hasSideFpsSensor(): Boolean = this?.sideFpsSensorProperties != null + @BiometricOverlayConstants.ShowReason private fun Int.isReasonToShow(activityTaskManager: ActivityTaskManager): Boolean = when (this) { REASON_AUTH_KEYGUARD -> false diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java index ed3d4ad8ad5d8..4ddaffcb57618 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java @@ -266,6 +266,9 @@ public class KeyguardBouncer { private void setVisibility(@View.Visibility int visibility) { mContainer.setVisibility(visibility); + if (mKeyguardViewController != null) { + mKeyguardViewController.onBouncerVisibilityChanged(visibility); + } dispatchVisibilityChanged(); } @@ -645,7 +648,7 @@ public class KeyguardBouncer { /** * Invoked when the bouncer expansion reaches {@link KeyguardBouncer#EXPANSION_VISIBLE}. * This is NOT called each time the bouncer is shown, but rather only when the fully - * shown amount has changed based on the panel expansion. The bouncer is visibility + * shown amount has changed based on the panel expansion. The bouncer's visibility * can still change when the expansion amount hasn't changed. * See {@link KeyguardBouncer#isShowing()} for the checks for the bouncer showing state. */ diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardHostViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardHostViewControllerTest.java index ac1a83c269e0e..4021652295c10 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardHostViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardHostViewControllerTest.java @@ -20,6 +20,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -31,6 +32,7 @@ import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.testing.TestableResources; import android.view.Gravity; +import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; @@ -42,6 +44,7 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; @@ -103,6 +106,17 @@ public class KeyguardHostViewControllerTest extends SysuiTestCase { verify(mKeyguardSecurityContainerController).onStartingToHide(); } + @Test + public void onBouncerVisible_propagatesToKeyguardSecurityContainerController() { + mKeyguardHostViewController.onBouncerVisibilityChanged(ViewGroup.VISIBLE); + mKeyguardHostViewController.onBouncerVisibilityChanged(ViewGroup.INVISIBLE); + + InOrder order = inOrder(mKeyguardSecurityContainerController); + order.verify(mKeyguardSecurityContainerController).onBouncerVisibilityChanged(View.VISIBLE); + order.verify(mKeyguardSecurityContainerController).onBouncerVisibilityChanged( + View.INVISIBLE); + } + @Test public void testGravityReappliedOnConfigurationChange() { FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams( diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java index bc351427310dd..68e49c0a1d4b6 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java @@ -25,17 +25,21 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; +import static org.mockito.Mockito.reset; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.res.Configuration; import android.content.res.Resources; +import android.hardware.biometrics.BiometricSourceType; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.view.MotionEvent; +import android.view.View; import android.view.WindowInsetsController; import androidx.test.filters.SmallTest; @@ -46,6 +50,7 @@ import com.android.internal.widget.LockPatternUtils; import com.android.keyguard.KeyguardSecurityModel.SecurityMode; import com.android.systemui.R; import com.android.systemui.SysuiTestCase; +import com.android.systemui.biometrics.SidefpsController; import com.android.systemui.classifier.FalsingCollector; import com.android.systemui.flags.FeatureFlags; import com.android.systemui.log.SessionTracker; @@ -59,10 +64,14 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; import org.mockito.Mock; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; +import java.util.Optional; + @SmallTest @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper() @@ -124,6 +133,14 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase { private SessionTracker mSessionTracker; @Mock private KeyguardViewController mKeyguardViewController; + @Mock + private SidefpsController mSidefpsController; + @Mock + private KeyguardPasswordViewController mKeyguardPasswordViewControllerMock; + + @Captor + private ArgumentCaptor mKeyguardUpdateMonitorCallback; + private Configuration mConfiguration; private KeyguardSecurityContainerController mKeyguardSecurityContainerController; @@ -160,7 +177,7 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase { mKeyguardStateController, mKeyguardSecurityViewFlipperController, mConfigurationController, mFalsingCollector, mFalsingManager, mUserSwitcherController, mFeatureFlags, mGlobalSettings, - mSessionTracker).create(mSecurityCallback); + mSessionTracker, Optional.of(mSidefpsController)).create(mSecurityCallback); } @Test @@ -258,9 +275,7 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase { @Test public void showSecurityScreen_twoHandedMode_flagEnabled_noOneHandedMode() { when(mResources.getBoolean(R.bool.can_use_one_handed_bouncer)).thenReturn(true); - when(mKeyguardSecurityViewFlipperController.getSecurityView( - eq(SecurityMode.Password), any(KeyguardSecurityCallback.class))) - .thenReturn((KeyguardInputViewController) mKeyguardPasswordViewController); + setupGetSecurityView(); mKeyguardSecurityContainerController.showSecurityScreen(SecurityMode.Password); verify(mView).initMode(MODE_DEFAULT, mGlobalSettings, mFalsingManager, @@ -276,4 +291,126 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase { verify(mUserSwitcherController) .removeUserSwitchCallback(any(UserSwitcherController.UserSwitchCallback.class)); } + + @Test + public void onBouncerVisibilityChanged_allConditionsGood_sideFpsHintShown() { + setupConditionsToEnableSideFpsHint(); + reset(mSidefpsController); + + mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE); + + verify(mSidefpsController).show(); + verify(mSidefpsController, never()).hide(); + } + + @Test + public void onBouncerVisibilityChanged_fpsSensorNotRunning_sideFpsHintHidden() { + setupConditionsToEnableSideFpsHint(); + setFingerprintDetectionRunning(false); + reset(mSidefpsController); + + mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE); + + verify(mSidefpsController).hide(); + verify(mSidefpsController, never()).show(); + } + + @Test + public void onBouncerVisibilityChanged_withoutSidedSecurity_sideFpsHintHidden() { + setupConditionsToEnableSideFpsHint(); + setSidedSecurityMode(false); + reset(mSidefpsController); + + mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE); + + verify(mSidefpsController).hide(); + verify(mSidefpsController, never()).show(); + } + + @Test + public void onBouncerVisibilityChanged_needsStrongAuth_sideFpsHintHidden() { + setupConditionsToEnableSideFpsHint(); + setNeedsStrongAuth(true); + reset(mSidefpsController); + + mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE); + + verify(mSidefpsController).hide(); + verify(mSidefpsController, never()).show(); + } + + @Test + public void onBouncerVisibilityChanged_sideFpsHintShown_sideFpsHintHidden() { + setupGetSecurityView(); + setupConditionsToEnableSideFpsHint(); + mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE); + verify(mSidefpsController, atLeastOnce()).show(); + reset(mSidefpsController); + + mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.INVISIBLE); + + verify(mSidefpsController).hide(); + verify(mSidefpsController, never()).show(); + } + + @Test + public void onStartingToHide_sideFpsHintShown_sideFpsHintHidden() { + setupGetSecurityView(); + setupConditionsToEnableSideFpsHint(); + mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE); + verify(mSidefpsController, atLeastOnce()).show(); + reset(mSidefpsController); + + mKeyguardSecurityContainerController.onStartingToHide(); + + verify(mSidefpsController).hide(); + verify(mSidefpsController, never()).show(); + } + + @Test + public void onPause_sideFpsHintShown_sideFpsHintHidden() { + setupGetSecurityView(); + setupConditionsToEnableSideFpsHint(); + mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE); + verify(mSidefpsController, atLeastOnce()).show(); + reset(mSidefpsController); + + mKeyguardSecurityContainerController.onPause(); + + verify(mSidefpsController).hide(); + verify(mSidefpsController, never()).show(); + } + + private void setupConditionsToEnableSideFpsHint() { + attachView(); + setSidedSecurityMode(true); + setFingerprintDetectionRunning(true); + setNeedsStrongAuth(false); + } + + private void attachView() { + mKeyguardSecurityContainerController.onViewAttached(); + verify(mKeyguardUpdateMonitor).registerCallback(mKeyguardUpdateMonitorCallback.capture()); + } + + private void setFingerprintDetectionRunning(boolean running) { + when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(running); + mKeyguardUpdateMonitorCallback.getValue().onBiometricRunningStateChanged(running, + BiometricSourceType.FINGERPRINT); + } + + private void setSidedSecurityMode(boolean sided) { + when(mView.isSidedSecurityMode()).thenReturn(sided); + } + + private void setNeedsStrongAuth(boolean needed) { + when(mKeyguardUpdateMonitor.userNeedsStrongAuth()).thenReturn(needed); + mKeyguardUpdateMonitorCallback.getValue().onStrongAuthStateChanged(/* userId= */ 0); + } + + private void setupGetSecurityView() { + when(mKeyguardSecurityViewFlipperController.getSecurityView( + any(), any(KeyguardSecurityCallback.class))) + .thenReturn((KeyguardInputViewController) mKeyguardPasswordViewControllerMock); + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/SidefpsControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/SidefpsControllerTest.kt index dec2b82ed88f6..6157ccbd597a1 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/SidefpsControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/SidefpsControllerTest.kt @@ -62,7 +62,6 @@ import org.mockito.ArgumentCaptor import org.mockito.ArgumentMatchers.eq import org.mockito.Captor import org.mockito.Mock -import org.mockito.Mockito.`when` import org.mockito.Mockito.any import org.mockito.Mockito.anyFloat import org.mockito.Mockito.anyInt @@ -72,6 +71,7 @@ import org.mockito.Mockito.never import org.mockito.Mockito.reset import org.mockito.Mockito.times import org.mockito.Mockito.verify +import org.mockito.Mockito.`when` as whenEver import org.mockito.junit.MockitoJUnit private const val DISPLAY_ID = 2 @@ -126,15 +126,15 @@ class SidefpsControllerTest : SysuiTestCase() { context.addMockSystemService(DisplayManager::class.java, displayManager) context.addMockSystemService(WindowManager::class.java, windowManager) - `when`(layoutInflater.inflate(R.layout.sidefps_view, null, false)).thenReturn(sidefpsView) - `when`(sidefpsView.findViewById(eq(R.id.sidefps_animation))) + whenEver(layoutInflater.inflate(R.layout.sidefps_view, null, false)).thenReturn(sidefpsView) + whenEver(sidefpsView.findViewById(eq(R.id.sidefps_animation))) .thenReturn(mock(LottieAnimationView::class.java)) with(mock(ViewPropertyAnimator::class.java)) { - `when`(sidefpsView.animate()).thenReturn(this) - `when`(alpha(anyFloat())).thenReturn(this) - `when`(setStartDelay(anyLong())).thenReturn(this) - `when`(setDuration(anyLong())).thenReturn(this) - `when`(setListener(any())).thenAnswer { + whenEver(sidefpsView.animate()).thenReturn(this) + whenEver(alpha(anyFloat())).thenReturn(this) + whenEver(setStartDelay(anyLong())).thenReturn(this) + whenEver(setDuration(anyLong())).thenReturn(this) + whenEver(setListener(any())).thenAnswer { (it.arguments[0] as Animator.AnimatorListener) .onAnimationEnd(mock(Animator::class.java)) this @@ -177,7 +177,7 @@ class SidefpsControllerTest : SysuiTestCase() { displayBounds = Rect(0, 0, displayWidth, displayHeight) var locations = listOf(sensorLocation) - `when`(fingerprintManager.sensorPropertiesInternal).thenReturn( + whenEver(fingerprintManager.sensorPropertiesInternal).thenReturn( listOf( FingerprintSensorPropertiesInternal( SENSOR_ID, @@ -196,12 +196,12 @@ class SidefpsControllerTest : SysuiTestCase() { displayInfo.initInfo() val dmGlobal = mock(DisplayManagerGlobal::class.java) val display = Display(dmGlobal, DISPLAY_ID, displayInfo, DEFAULT_DISPLAY_ADJUSTMENTS) - `when`(dmGlobal.getDisplayInfo(eq(DISPLAY_ID))).thenReturn(displayInfo) - `when`(windowManager.defaultDisplay).thenReturn(display) - `when`(windowManager.maximumWindowMetrics).thenReturn( + whenEver(dmGlobal.getDisplayInfo(eq(DISPLAY_ID))).thenReturn(displayInfo) + whenEver(windowManager.defaultDisplay).thenReturn(display) + whenEver(windowManager.maximumWindowMetrics).thenReturn( WindowMetrics(displayBounds, WindowInsets.CONSUMED) ) - `when`(windowManager.currentWindowMetrics).thenReturn( + whenEver(windowManager.currentWindowMetrics).thenReturn( WindowMetrics(displayBounds, windowInsets) ) @@ -277,13 +277,13 @@ class SidefpsControllerTest : SysuiTestCase() { @Test fun testShowsForMostSettings() = testWithDisplay { - `when`(activityTaskManager.getTasks(anyInt())).thenReturn(listOf(fpEnrollTask())) + whenEver(activityTaskManager.getTasks(anyInt())).thenReturn(listOf(fpEnrollTask())) testIgnoredFor(REASON_AUTH_SETTINGS, ignored = false) } @Test fun testIgnoredForVerySpecificSettings() = testWithDisplay { - `when`(activityTaskManager.getTasks(anyInt())).thenReturn(listOf(fpSettingsTask())) + whenEver(activityTaskManager.getTasks(anyInt())).thenReturn(listOf(fpSettingsTask())) testIgnoredFor(REASON_AUTH_SETTINGS) } @@ -424,6 +424,20 @@ class SidefpsControllerTest : SysuiTestCase() { assertThat(overlayViewParamsCaptor.value.x).isEqualTo(displayWidth - boundsWidth) assertThat(overlayViewParamsCaptor.value.y).isEqualTo(sensorLocation.sensorLocationY) } + + @Test + fun hasSideFpsSensor_withSensorProps_returnsTrue() = testWithDisplay { + // By default all those tests assume the side fps sensor is available. + + assertThat(fingerprintManager.hasSideFpsSensor()).isTrue() + } + + @Test + fun hasSideFpsSensor_withoutSensorProps_returnsFalse() { + whenEver(fingerprintManager.sensorPropertiesInternal).thenReturn(null) + + assertThat(fingerprintManager.hasSideFpsSensor()).isFalse() + } } private fun insetsForSmallNavbar() = insetsWithBottom(60) diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java index 39021d8732d37..60a3d95e24f6c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java @@ -229,6 +229,15 @@ public class KeyguardBouncerTest extends SysuiTestCase { verify(mContainer).announceForAccessibility(any()); } + @Test + public void show_notifiesKeyguardViewController() { + mBouncer.ensureView(); + + mBouncer.show(/* resetSecuritySelection= */ false); + + verify(mKeyguardHostViewController).onBouncerVisibilityChanged(View.VISIBLE); + } + @Test public void testHide_notifiesFalsingManager() { mBouncer.hide(false);