Loading packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java +10 −9 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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; Loading @@ -311,7 +312,7 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard mFeatureFlags = featureFlags; mGlobalSettings = globalSettings; mSessionTracker = sessionTracker; mSidefpsController = sidefpsController; mSideFpsController = sideFpsController; mFalsingA11yDelegate = falsingA11yDelegate; } Loading Loading @@ -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( Loading @@ -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); } } Loading Loading @@ -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 Loading @@ -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; Loading packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerModule.java +5 −5 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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(); } Loading packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java +5 −5 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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(); Loading Loading @@ -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, Loading Loading @@ -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; } Loading packages/SystemUI/src/com/android/systemui/biometrics/SidefpsController.kt→packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt +164 −104 Original line number Diff line number Diff line Loading @@ -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?, Loading @@ -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, Loading @@ -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) Loading Loading @@ -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 } Loading @@ -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() Loading @@ -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() { Loading @@ -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}") } Loading @@ -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 Loading @@ -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, Loading Loading @@ -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 Loading @@ -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 Loading @@ -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 Loading @@ -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) } } } Loading @@ -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, } packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java +34 −33 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading Loading @@ -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); } Loading Loading @@ -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 Loading @@ -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 Loading @@ -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 Loading @@ -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 Loading @@ -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 Loading @@ -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 Loading
packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java +10 −9 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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; Loading @@ -311,7 +312,7 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard mFeatureFlags = featureFlags; mGlobalSettings = globalSettings; mSessionTracker = sessionTracker; mSidefpsController = sidefpsController; mSideFpsController = sideFpsController; mFalsingA11yDelegate = falsingA11yDelegate; } Loading Loading @@ -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( Loading @@ -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); } } Loading Loading @@ -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 Loading @@ -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; Loading
packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerModule.java +5 −5 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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(); } Loading
packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java +5 −5 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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(); Loading Loading @@ -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, Loading Loading @@ -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; } Loading
packages/SystemUI/src/com/android/systemui/biometrics/SidefpsController.kt→packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt +164 −104 Original line number Diff line number Diff line Loading @@ -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?, Loading @@ -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, Loading @@ -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) Loading Loading @@ -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 } Loading @@ -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() Loading @@ -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() { Loading @@ -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}") } Loading @@ -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 Loading @@ -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, Loading Loading @@ -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 Loading @@ -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 Loading @@ -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 Loading @@ -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) } } } Loading @@ -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, }
packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java +34 −33 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading Loading @@ -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); } Loading Loading @@ -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 Loading @@ -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 Loading @@ -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 Loading @@ -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 Loading @@ -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 Loading @@ -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