Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 11674494 authored by Beverly's avatar Beverly Committed by Beverly Tai
Browse files

Add SideFpsController dump

In the SideFpsController dump, dump the
current sideFps indicator requests.

This CL also renames SidefpsController => SideFpsController.

Test: atest SideFpsControllerTest
Bug: 237362467
Change-Id: I7dcb1649e5790ec36232cb48ac5649b7b0439d83
Merged-In: I7dcb1649e5790ec36232cb48ac5649b7b0439d83
parent d8c18690
Loading
Loading
Loading
Loading
+10 −9
Original line number Diff line number Diff line
@@ -58,7 +58,8 @@ 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.biometrics.SideFpsController;
import com.android.systemui.biometrics.SideFpsUiRequestSource;
import com.android.systemui.classifier.FalsingA11yDelegate;
import com.android.systemui.classifier.FalsingCollector;
import com.android.systemui.flags.FeatureFlags;
@@ -100,7 +101,7 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
    private final GlobalSettings mGlobalSettings;
    private final FeatureFlags mFeatureFlags;
    private final SessionTracker mSessionTracker;
    private final Optional<SidefpsController> mSidefpsController;
    private final Optional<SideFpsController> mSideFpsController;
    private final FalsingA11yDelegate mFalsingA11yDelegate;

    private int mLastOrientation = Configuration.ORIENTATION_UNDEFINED;
@@ -290,7 +291,7 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
            FeatureFlags featureFlags,
            GlobalSettings globalSettings,
            SessionTracker sessionTracker,
            Optional<SidefpsController> sidefpsController,
            Optional<SideFpsController> sideFpsController,
            FalsingA11yDelegate falsingA11yDelegate) {
        super(view);
        mLockPatternUtils = lockPatternUtils;
@@ -311,7 +312,7 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
        mFeatureFlags = featureFlags;
        mGlobalSettings = globalSettings;
        mSessionTracker = sessionTracker;
        mSidefpsController = sidefpsController;
        mSideFpsController = sideFpsController;
        mFalsingA11yDelegate = falsingA11yDelegate;
    }

@@ -351,7 +352,7 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
    }

    private void updateSideFpsVisibility() {
        if (!mSidefpsController.isPresent()) {
        if (!mSideFpsController.isPresent()) {
            return;
        }
        final boolean sfpsEnabled = getResources().getBoolean(
@@ -369,9 +370,9 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
                    + "needsStrongAuth=" + needsStrongAuth);
        }
        if (toShow) {
            mSidefpsController.get().show();
            mSideFpsController.get().show(SideFpsUiRequestSource.PRIMARY_BOUNCER);
        } else {
            mSidefpsController.get().hide();
            mSideFpsController.get().hide(SideFpsUiRequestSource.PRIMARY_BOUNCER);
        }
    }

@@ -745,7 +746,7 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
        private final FeatureFlags mFeatureFlags;
        private final UserSwitcherController mUserSwitcherController;
        private final SessionTracker mSessionTracker;
        private final Optional<SidefpsController> mSidefpsController;
        private final Optional<SideFpsController> mSidefpsController;
        private final FalsingA11yDelegate mFalsingA11yDelegate;

        @Inject
@@ -766,7 +767,7 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
                FeatureFlags featureFlags,
                GlobalSettings globalSettings,
                SessionTracker sessionTracker,
                Optional<SidefpsController> sidefpsController,
                Optional<SideFpsController> sidefpsController,
                FalsingA11yDelegate falsingA11yDelegate) {
            mView = view;
            mAdminSecondaryLockScreenControllerFactory = adminSecondaryLockScreenControllerFactory;
+5 −5
Original line number Diff line number Diff line
@@ -16,7 +16,7 @@

package com.android.keyguard.dagger;

import static com.android.systemui.biometrics.SidefpsControllerKt.hasSideFpsSensor;
import static com.android.systemui.biometrics.SideFpsControllerKt.hasSideFpsSensor;

import android.annotation.Nullable;
import android.hardware.fingerprint.FingerprintManager;
@@ -27,7 +27,7 @@ import com.android.keyguard.KeyguardHostView;
import com.android.keyguard.KeyguardSecurityContainer;
import com.android.keyguard.KeyguardSecurityViewFlipper;
import com.android.systemui.R;
import com.android.systemui.biometrics.SidefpsController;
import com.android.systemui.biometrics.SideFpsController;
import com.android.systemui.dagger.qualifiers.RootView;
import com.android.systemui.statusbar.phone.KeyguardBouncer;

@@ -70,12 +70,12 @@ public interface KeyguardBouncerModule {
        return containerView.findViewById(R.id.view_flipper);
    }

    /** Provides {@link SidefpsController} if the device has the side fingerprint sensor. */
    /** Provides {@link SideFpsController} if the device has the side fingerprint sensor. */
    @Provides
    @KeyguardBouncerScope
    static Optional<SidefpsController> providesOptionalSidefpsController(
    static Optional<SideFpsController> providesOptionalSidefpsController(
            @Nullable FingerprintManager fingerprintManager,
            Provider<SidefpsController> sidefpsControllerProvider) {
            Provider<SideFpsController> sidefpsControllerProvider) {
        if (!hasSideFpsSensor(fingerprintManager)) {
            return Optional.empty();
        }
+5 −5
Original line number Diff line number Diff line
@@ -119,7 +119,7 @@ public class AuthController implements CoreStartable, CommandQueue.Callbacks,
    @Nullable private final FingerprintManager mFingerprintManager;
    @Nullable private final FaceManager mFaceManager;
    private final Provider<UdfpsController> mUdfpsControllerFactory;
    private final Provider<SidefpsController> mSidefpsControllerFactory;
    private final Provider<SideFpsController> mSidefpsControllerFactory;

    private final Display mDisplay;
    private float mScaleFactor = 1f;
@@ -141,7 +141,7 @@ public class AuthController implements CoreStartable, CommandQueue.Callbacks,
    @NonNull private final DisplayManager mDisplayManager;
    @Nullable private UdfpsController mUdfpsController;
    @Nullable private IUdfpsHbmListener mUdfpsHbmListener;
    @Nullable private SidefpsController mSidefpsController;
    @Nullable private SideFpsController mSideFpsController;
    @Nullable private IBiometricContextListener mBiometricContextListener;
    @VisibleForTesting IBiometricSysuiReceiver mReceiver;
    @VisibleForTesting @NonNull final BiometricDisplayListener mOrientationListener;
@@ -316,7 +316,7 @@ public class AuthController implements CoreStartable, CommandQueue.Callbacks,

        mSidefpsProps = !sidefpsProps.isEmpty() ? sidefpsProps : null;
        if (mSidefpsProps != null) {
            mSidefpsController = mSidefpsControllerFactory.get();
            mSideFpsController = mSidefpsControllerFactory.get();
        }

        updateSensorLocations();
@@ -677,7 +677,7 @@ public class AuthController implements CoreStartable, CommandQueue.Callbacks,
            @Nullable FingerprintManager fingerprintManager,
            @Nullable FaceManager faceManager,
            Provider<UdfpsController> udfpsControllerFactory,
            Provider<SidefpsController> sidefpsControllerFactory,
            Provider<SideFpsController> sidefpsControllerFactory,
            @NonNull DisplayManager displayManager,
            @NonNull WakefulnessLifecycle wakefulnessLifecycle,
            @NonNull UserManager userManager,
@@ -1054,7 +1054,7 @@ public class AuthController implements CoreStartable, CommandQueue.Callbacks,
     * Whether the passed userId has enrolled SFPS.
     */
    public boolean isSfpsEnrolled(int userId) {
        if (mSidefpsController == null) {
        if (mSideFpsController == null) {
            return false;
        }

+164 −104
Original line number Diff line number Diff line
@@ -51,20 +51,25 @@ import com.airbnb.lottie.LottieAnimationView
import com.airbnb.lottie.LottieProperty
import com.airbnb.lottie.model.KeyPath
import com.android.internal.annotations.VisibleForTesting
import com.android.systemui.Dumpable
import com.android.systemui.R
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.dump.DumpManager
import com.android.systemui.recents.OverviewProxyService
import com.android.systemui.util.concurrency.DelayableExecutor
import java.io.PrintWriter
import javax.inject.Inject

private const val TAG = "SidefpsController"
private const val TAG = "SideFpsController"

/**
 * Shows and hides the side fingerprint sensor (side-fps) overlay and handles side fps touch events.
 */
@SysUISingleton
class SidefpsController @Inject constructor(
class SideFpsController
@Inject
constructor(
    private val context: Context,
    private val layoutInflater: LayoutInflater,
    fingerprintManager: FingerprintManager?,
@@ -73,15 +78,19 @@ class SidefpsController @Inject constructor(
    overviewProxyService: OverviewProxyService,
    displayManager: DisplayManager,
    @Main private val mainExecutor: DelayableExecutor,
    @Main private val handler: Handler
) {
    @Main private val handler: Handler,
    dumpManager: DumpManager
) : Dumpable {
    val requests: HashSet<SideFpsUiRequestSource> = HashSet()

    @VisibleForTesting
    val sensorProps: FingerprintSensorPropertiesInternal = fingerprintManager
        ?.sideFpsSensorProperties
    val sensorProps: FingerprintSensorPropertiesInternal =
        fingerprintManager?.sideFpsSensorProperties
            ?: throw IllegalStateException("no side fingerprint sensor")

    @VisibleForTesting
    val orientationListener = BiometricDisplayListener(
    val orientationListener =
        BiometricDisplayListener(
            context,
            displayManager,
            handler,
@@ -89,7 +98,8 @@ class SidefpsController @Inject constructor(
        ) { onOrientationChanged() }

    @VisibleForTesting
    val overviewProxyListener = object : OverviewProxyService.OverviewProxyListener {
    val overviewProxyListener =
        object : OverviewProxyService.OverviewProxyListener {
            override fun onTaskbarStatusUpdated(visible: Boolean, stashed: Boolean) {
                overlayView?.let { view ->
                    handler.postDelayed({ updateOverlayVisibility(view) }, 500)
@@ -121,17 +131,20 @@ class SidefpsController @Inject constructor(
    @VisibleForTesting
    internal var overlayOffsets: SensorLocationInternal = SensorLocationInternal.DEFAULT

    private val overlayViewParams = WindowManager.LayoutParams(
    private val overlayViewParams =
        WindowManager.LayoutParams(
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.TYPE_SYSTEM_ERROR,
                Utils.FINGERPRINT_OVERLAY_LAYOUT_PARAM_FLAGS,
                PixelFormat.TRANSLUCENT
    ).apply {
            )
            .apply {
                title = TAG
                fitInsetsTypes = 0 // overrides default, avoiding status bars during layout
                gravity = Gravity.TOP or Gravity.LEFT
        layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
                layoutInDisplayCutoutMode =
                    WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
                privateFlags = PRIVATE_FLAG_TRUSTED_OVERLAY or PRIVATE_FLAG_NO_MOVE_ANIMATION
            }

@@ -141,15 +154,23 @@ class SidefpsController @Inject constructor(
                override fun show(
                    sensorId: Int,
                    @BiometricOverlayConstants.ShowReason reason: Int
                ) = if (reason.isReasonToShow(activityTaskManager)) show() else hide()
                ) =
                    if (reason.isReasonToAutoShow(activityTaskManager)) {
                        show(SideFpsUiRequestSource.AUTO_SHOW)
                    } else {
                        hide(SideFpsUiRequestSource.AUTO_SHOW)
                    }

                override fun hide(sensorId: Int) = hide()
            })
                override fun hide(sensorId: Int) = hide(SideFpsUiRequestSource.AUTO_SHOW)
            }
        )
        overviewProxyService.addCallback(overviewProxyListener)
        dumpManager.registerDumpable(this)
    }

    /** Shows the side fps overlay if not already shown. */
    fun show() {
    fun show(request: SideFpsUiRequestSource) {
        requests.add(request)
        mainExecutor.execute {
            if (overlayView == null) {
                createOverlayForDisplay()
@@ -160,8 +181,20 @@ class SidefpsController @Inject constructor(
    }

    /** Hides the fps overlay if shown. */
    fun hide() {
        mainExecutor.execute { overlayView = null }
    fun hide(request: SideFpsUiRequestSource) {
        requests.remove(request)
        mainExecutor.execute {
            if (requests.isEmpty()) {
                overlayView = null
            }
        }
    }

    override fun dump(pw: PrintWriter, args: Array<out String>) {
        pw.println("requests:")
        for (requestSource in requests) {
            pw.println("     $requestSource.name")
        }
    }

    private fun onOrientationChanged() {
@@ -174,7 +207,8 @@ class SidefpsController @Inject constructor(
        val view = layoutInflater.inflate(R.layout.sidefps_view, null, false)
        overlayView = view
        val display = context.display!!
        val offsets = sensorProps.getLocation(display.uniqueId).let { location ->
        val offsets =
            sensorProps.getLocation(display.uniqueId).let { location ->
                if (location == null) {
                    Log.w(TAG, "No location specified for display: ${display.uniqueId}")
                }
@@ -195,21 +229,25 @@ class SidefpsController @Inject constructor(

        /**
         * Intercepts TYPE_WINDOW_STATE_CHANGED accessibility event, preventing Talkback from
         * speaking @string/accessibility_fingerprint_label twice when sensor location indicator
         * is in focus
         * speaking @string/accessibility_fingerprint_label twice when sensor location indicator is
         * in focus
         */
        view.setAccessibilityDelegate(object : AccessibilityDelegate() {
        view.setAccessibilityDelegate(
            object : AccessibilityDelegate() {
                override fun dispatchPopulateAccessibilityEvent(
                    host: View,
                    event: AccessibilityEvent
                ): Boolean {
                return if (event.getEventType() === AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
                    return if (
                        event.getEventType() === AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED
                    ) {
                        true
                    } else {
                        super.dispatchPopulateAccessibilityEvent(host, event)
                    }
                }
        })
            }
        )
    }

    @VisibleForTesting
@@ -220,7 +258,8 @@ class SidefpsController @Inject constructor(
        val displayHeight = if (isNaturalOrientation) size.height() else size.width()
        val boundsWidth = if (isNaturalOrientation) bounds.width() else bounds.height()
        val boundsHeight = if (isNaturalOrientation) bounds.height() else bounds.width()
        val sensorBounds = if (overlayOffsets.isYAligned()) {
        val sensorBounds =
            if (overlayOffsets.isYAligned()) {
                Rect(
                    displayWidth - boundsWidth,
                    overlayOffsets.sensorLocationY,
@@ -254,19 +293,25 @@ class SidefpsController @Inject constructor(
        // hide after a few seconds if the sensor is oriented down and there are
        // large overlapping system bars
        val rotation = context.display?.rotation
        if (windowManager.currentWindowMetrics.windowInsets.hasBigNavigationBar() &&
        if (
            windowManager.currentWindowMetrics.windowInsets.hasBigNavigationBar() &&
                ((rotation == Surface.ROTATION_270 && overlayOffsets.isYAligned()) ||
                    (rotation == Surface.ROTATION_180 && !overlayOffsets.isYAligned()))) {
            overlayHideAnimator = view.animate()
                    (rotation == Surface.ROTATION_180 && !overlayOffsets.isYAligned()))
        ) {
            overlayHideAnimator =
                view
                    .animate()
                    .alpha(0f)
                    .setStartDelay(3_000)
                    .setDuration(animationDuration)
                .setListener(object : AnimatorListenerAdapter() {
                    .setListener(
                        object : AnimatorListenerAdapter() {
                            override fun onAnimationEnd(animation: Animator) {
                                view.visibility = View.GONE
                                overlayHideAnimator = null
                            }
                })
                        }
                    )
        } else {
            overlayHideAnimator?.cancel()
            overlayHideAnimator = null
@@ -283,9 +328,11 @@ private val FingerprintManager?.sideFpsSensorProperties: FingerprintSensorProper
fun FingerprintManager?.hasSideFpsSensor(): Boolean = this?.sideFpsSensorProperties != null

@BiometricOverlayConstants.ShowReason
private fun Int.isReasonToShow(activityTaskManager: ActivityTaskManager): Boolean = when (this) {
private fun Int.isReasonToAutoShow(activityTaskManager: ActivityTaskManager): Boolean =
    when (this) {
        REASON_AUTH_KEYGUARD -> false
    REASON_AUTH_SETTINGS -> when (activityTaskManager.topClass()) {
        REASON_AUTH_SETTINGS ->
            when (activityTaskManager.topClass()) {
                // TODO(b/186176653): exclude fingerprint overlays from this list view
                "com.android.settings.biometrics.fingerprint.FingerprintSettings" -> false
                else -> true
@@ -297,13 +344,15 @@ private fun ActivityTaskManager.topClass(): String =
    getTasks(1).firstOrNull()?.topActivity?.className ?: ""

@RawRes
private fun Display.asSideFpsAnimation(yAligned: Boolean): Int = when (rotation) {
private fun Display.asSideFpsAnimation(yAligned: Boolean): Int =
    when (rotation) {
        Surface.ROTATION_0 -> if (yAligned) R.raw.sfps_pulse else R.raw.sfps_pulse_landscape
        Surface.ROTATION_180 -> if (yAligned) R.raw.sfps_pulse else R.raw.sfps_pulse_landscape
        else -> if (yAligned) R.raw.sfps_pulse_landscape else R.raw.sfps_pulse
    }

private fun Display.asSideFpsAnimationRotation(yAligned: Boolean): Float = when (rotation) {
private fun Display.asSideFpsAnimationRotation(yAligned: Boolean): Float =
    when (rotation) {
        Surface.ROTATION_90 -> if (yAligned) 0f else 180f
        Surface.ROTATION_180 -> 180f
        Surface.ROTATION_270 -> if (yAligned) 180f else 0f
@@ -322,10 +371,9 @@ private fun LottieAnimationView.addOverlayDynamicColor(context: Context) {
    fun update() {
        val c = context.getColor(R.color.biometric_dialog_accent)
        for (key in listOf(".blue600", ".blue400")) {
            addValueCallback(
                KeyPath(key, "**"),
                LottieProperty.COLOR_FILTER
            ) { PorterDuffColorFilter(c, PorterDuff.Mode.SRC_ATOP) }
            addValueCallback(KeyPath(key, "**"), LottieProperty.COLOR_FILTER) {
                PorterDuffColorFilter(c, PorterDuff.Mode.SRC_ATOP)
            }
        }
    }

@@ -335,3 +383,15 @@ private fun LottieAnimationView.addOverlayDynamicColor(context: Context) {
        addLottieOnCompositionLoadedListener { update() }
    }
}

/**
 * The source of a request to show the side fps visual indicator. This is distinct from
 * [BiometricOverlayConstants] which corrresponds with the reason fingerprint authentication is
 * requested.
 */
enum class SideFpsUiRequestSource {
    /** see [isReasonToAutoShow] */
    AUTO_SHOW,
    /** Pin, pattern or password bouncer */
    PRIMARY_BOUNCER,
}
+34 −33
Original line number Diff line number Diff line
@@ -54,7 +54,8 @@ 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.biometrics.SideFpsController;
import com.android.systemui.biometrics.SideFpsUiRequestSource;
import com.android.systemui.classifier.FalsingA11yDelegate;
import com.android.systemui.classifier.FalsingCollector;
import com.android.systemui.flags.FeatureFlags;
@@ -141,7 +142,7 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase {
    @Mock
    private KeyguardViewController mKeyguardViewController;
    @Mock
    private SidefpsController mSidefpsController;
    private SideFpsController mSideFpsController;
    @Mock
    private KeyguardPasswordViewController mKeyguardPasswordViewControllerMock;
    @Mock
@@ -189,7 +190,7 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase {
                mKeyguardStateController, mKeyguardSecurityViewFlipperController,
                mConfigurationController, mFalsingCollector, mFalsingManager,
                mUserSwitcherController, mFeatureFlags, mGlobalSettings,
                mSessionTracker, Optional.of(mSidefpsController), mFalsingA11yDelegate).create(
                mSessionTracker, Optional.of(mSideFpsController), mFalsingA11yDelegate).create(
                mSecurityCallback);
    }

@@ -345,48 +346,48 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase {
    @Test
    public void onBouncerVisibilityChanged_allConditionsGood_sideFpsHintShown() {
        setupConditionsToEnableSideFpsHint();
        reset(mSidefpsController);
        reset(mSideFpsController);

        mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);

        verify(mSidefpsController).show();
        verify(mSidefpsController, never()).hide();
        verify(mSideFpsController).show(SideFpsUiRequestSource.PRIMARY_BOUNCER);
        verify(mSideFpsController, never()).hide(any());
    }

    @Test
    public void onBouncerVisibilityChanged_fpsSensorNotRunning_sideFpsHintHidden() {
        setupConditionsToEnableSideFpsHint();
        setFingerprintDetectionRunning(false);
        reset(mSidefpsController);
        reset(mSideFpsController);

        mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);

        verify(mSidefpsController).hide();
        verify(mSidefpsController, never()).show();
        verify(mSideFpsController).hide(SideFpsUiRequestSource.PRIMARY_BOUNCER);
        verify(mSideFpsController, never()).show(any());
    }

    @Test
    public void onBouncerVisibilityChanged_withoutSidedSecurity_sideFpsHintHidden() {
        setupConditionsToEnableSideFpsHint();
        setSideFpsHintEnabledFromResources(false);
        reset(mSidefpsController);
        reset(mSideFpsController);

        mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);

        verify(mSidefpsController).hide();
        verify(mSidefpsController, never()).show();
        verify(mSideFpsController).hide(SideFpsUiRequestSource.PRIMARY_BOUNCER);
        verify(mSideFpsController, never()).show(any());
    }

    @Test
    public void onBouncerVisibilityChanged_needsStrongAuth_sideFpsHintHidden() {
        setupConditionsToEnableSideFpsHint();
        setNeedsStrongAuth(true);
        reset(mSidefpsController);
        reset(mSideFpsController);

        mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);

        verify(mSidefpsController).hide();
        verify(mSidefpsController, never()).show();
        verify(mSideFpsController).hide(SideFpsUiRequestSource.PRIMARY_BOUNCER);
        verify(mSideFpsController, never()).show(any());
    }

    @Test
@@ -394,13 +395,13 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase {
        setupGetSecurityView();
        setupConditionsToEnableSideFpsHint();
        mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);
        verify(mSidefpsController, atLeastOnce()).show();
        reset(mSidefpsController);
        verify(mSideFpsController, atLeastOnce()).show(SideFpsUiRequestSource.PRIMARY_BOUNCER);
        reset(mSideFpsController);

        mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.INVISIBLE);

        verify(mSidefpsController).hide();
        verify(mSidefpsController, never()).show();
        verify(mSideFpsController).hide(SideFpsUiRequestSource.PRIMARY_BOUNCER);
        verify(mSideFpsController, never()).show(any());
    }

    @Test
@@ -408,13 +409,13 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase {
        setupGetSecurityView();
        setupConditionsToEnableSideFpsHint();
        mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);
        verify(mSidefpsController, atLeastOnce()).show();
        reset(mSidefpsController);
        verify(mSideFpsController, atLeastOnce()).show(SideFpsUiRequestSource.PRIMARY_BOUNCER);
        reset(mSideFpsController);

        mKeyguardSecurityContainerController.onStartingToHide();

        verify(mSidefpsController).hide();
        verify(mSidefpsController, never()).show();
        verify(mSideFpsController).hide(SideFpsUiRequestSource.PRIMARY_BOUNCER);
        verify(mSideFpsController, never()).show(any());
    }

    @Test
@@ -422,13 +423,13 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase {
        setupGetSecurityView();
        setupConditionsToEnableSideFpsHint();
        mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);
        verify(mSidefpsController, atLeastOnce()).show();
        reset(mSidefpsController);
        verify(mSideFpsController, atLeastOnce()).show(SideFpsUiRequestSource.PRIMARY_BOUNCER);
        reset(mSideFpsController);

        mKeyguardSecurityContainerController.onPause();

        verify(mSidefpsController).hide();
        verify(mSidefpsController, never()).show();
        verify(mSideFpsController).hide(SideFpsUiRequestSource.PRIMARY_BOUNCER);
        verify(mSideFpsController, never()).show(any());
    }

    @Test
@@ -436,12 +437,12 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase {
        setupGetSecurityView();
        setupConditionsToEnableSideFpsHint();
        mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);
        reset(mSidefpsController);
        reset(mSideFpsController);

        mKeyguardSecurityContainerController.onResume(0);

        verify(mSidefpsController).show();
        verify(mSidefpsController, never()).hide();
        verify(mSideFpsController).show(SideFpsUiRequestSource.PRIMARY_BOUNCER);
        verify(mSideFpsController, never()).hide(any());
    }

    @Test
@@ -450,12 +451,12 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase {
        setupConditionsToEnableSideFpsHint();
        setSideFpsHintEnabledFromResources(false);
        mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);
        reset(mSidefpsController);
        reset(mSideFpsController);

        mKeyguardSecurityContainerController.onResume(0);

        verify(mSidefpsController).hide();
        verify(mSidefpsController, never()).show();
        verify(mSideFpsController).hide(SideFpsUiRequestSource.PRIMARY_BOUNCER);
        verify(mSideFpsController, never()).show(any());
    }

    @Test
Loading