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

Commit 9935dae6 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Add SideFpsController dump" into tm-qpr-dev

parents dc72403d 11674494
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