Loading packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt 0 → 100644 +110 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.systemui.biometrics import android.content.Context import android.hardware.biometrics.BiometricSourceType import android.view.View import android.view.ViewGroup import com.android.internal.annotations.VisibleForTesting import com.android.keyguard.KeyguardUpdateMonitor import com.android.keyguard.KeyguardUpdateMonitorCallback import com.android.settingslib.Utils import com.android.systemui.dagger.SysUISingleton import com.android.systemui.statusbar.commandline.Command import com.android.systemui.statusbar.commandline.CommandRegistry import com.android.systemui.statusbar.policy.ConfigurationController import java.io.PrintWriter import javax.inject.Inject /*** * Controls the ripple effect that shows when authentication is successful. * The ripple uses the accent color of the current theme. */ @SysUISingleton class AuthRippleController @Inject constructor( commandRegistry: CommandRegistry, configurationController: ConfigurationController, private val context: Context, private val keyguardUpdateMonitor: KeyguardUpdateMonitor ) { @VisibleForTesting var rippleView: AuthRippleView = AuthRippleView(context, attrs = null) val keyguardUpdateMonitorCallback = object : KeyguardUpdateMonitorCallback() { override fun onBiometricAuthenticated( userId: Int, biometricSourceType: BiometricSourceType?, isStrongBiometric: Boolean ) { if (biometricSourceType == BiometricSourceType.FINGERPRINT) { rippleView.startRipple() } } } init { val configurationChangedListener = object : ConfigurationController.ConfigurationListener { override fun onUiModeChanged() { updateRippleColor() } override fun onThemeChanged() { updateRippleColor() } override fun onOverlayChanged() { updateRippleColor() } } configurationController.addCallback(configurationChangedListener) commandRegistry.registerCommand("auth-ripple") { AuthRippleCommand() } } fun setSensorLocation(x: Float, y: Float) { rippleView.setSensorLocation(x, y) } fun setViewHost(viewHost: View) { // Add the ripple view to its host layout viewHost.addOnAttachStateChangeListener(object : View.OnAttachStateChangeListener { override fun onViewDetachedFromWindow(view: View?) {} override fun onViewAttachedToWindow(view: View?) { (viewHost as ViewGroup).addView(rippleView) keyguardUpdateMonitor.registerCallback(keyguardUpdateMonitorCallback) viewHost.removeOnAttachStateChangeListener(this) } }) updateRippleColor() } private fun updateRippleColor() { rippleView.setColor( Utils.getColorAttr(context, android.R.attr.colorAccent).defaultColor) } inner class AuthRippleCommand : Command { override fun execute(pw: PrintWriter, args: List<String>) { rippleView.startRipple() } override fun help(pw: PrintWriter) { pw.println("Usage: adb shell cmd statusbar auth-ripple") } } } packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt 0 → 100644 +87 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.systemui.biometrics import android.animation.Animator import android.animation.AnimatorListenerAdapter import android.animation.ValueAnimator import android.content.Context import android.graphics.Canvas import android.graphics.Paint import android.graphics.PointF import android.util.AttributeSet import android.view.View import com.android.systemui.statusbar.charging.RippleShader private const val RIPPLE_ANIMATION_DURATION: Long = 950 private const val RIPPLE_SPARKLE_STRENGTH: Float = 0.4f /** * Expanding ripple effect on the transition from biometric authentication success to showing * launcher. */ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, attrs) { private var rippleInProgress: Boolean = false private val rippleShader = RippleShader() private val defaultColor: Int = 0xffffffff.toInt() private val ripplePaint = Paint() init { rippleShader.color = defaultColor rippleShader.progress = 0f rippleShader.sparkleStrength = RIPPLE_SPARKLE_STRENGTH ripplePaint.shader = rippleShader visibility = View.GONE } fun setSensorLocation(x: Float, y: Float) { rippleShader.origin = PointF(x, y) rippleShader.radius = maxOf(x, y, width - x, height - y).toFloat() } fun startRipple() { if (rippleInProgress) { return // Ignore if ripple effect is already playing } val animator = ValueAnimator.ofFloat(0f, 1f) animator.duration = RIPPLE_ANIMATION_DURATION animator.addUpdateListener { animator -> val now = animator.currentPlayTime val phase = now / 30000f rippleShader.progress = animator.animatedValue as Float rippleShader.noisePhase = phase invalidate() } animator.addListener(object : AnimatorListenerAdapter() { override fun onAnimationEnd(animation: Animator?) { rippleInProgress = false visibility = View.GONE } }) animator.start() visibility = View.VISIBLE rippleInProgress = true } fun setColor(color: Int) { rippleShader.color = color } override fun onDraw(canvas: Canvas?) { // draw over the entire screen canvas?.drawRect(0f, 0f, width.toFloat(), height.toFloat(), ripplePaint) } } packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java +8 −1 Original line number Diff line number Diff line Loading @@ -87,6 +87,7 @@ public class UdfpsController implements DozeReceiver, HbmCallback { @NonNull private final StatusBarStateController mStatusBarStateController; @NonNull private final StatusBarKeyguardViewManager mKeyguardViewManager; @NonNull private final DumpManager mDumpManager; @NonNull private final AuthRippleController mAuthRippleController; // Currently the UdfpsController supports a single UDFPS sensor. If devices have multiple // sensors, this, in addition to a lot of the code here, will be updated. @VisibleForTesting final FingerprintSensorPropertiesInternal mSensorProps; Loading Loading @@ -305,7 +306,8 @@ public class UdfpsController implements DozeReceiver, HbmCallback { @Main DelayableExecutor fgExecutor, @NonNull StatusBar statusBar, @NonNull StatusBarKeyguardViewManager statusBarKeyguardViewManager, @NonNull DumpManager dumpManager) { @NonNull DumpManager dumpManager, @NonNull AuthRippleController authRippleController) { mContext = context; mInflater = inflater; // The fingerprint manager is queried for UDFPS before this class is constructed, so the Loading @@ -317,6 +319,7 @@ public class UdfpsController implements DozeReceiver, HbmCallback { mStatusBarStateController = statusBarStateController; mKeyguardViewManager = statusBarKeyguardViewManager; mDumpManager = dumpManager; mAuthRippleController = authRippleController; mSensorProps = findFirstUdfps(); // At least one UDFPS sensor exists Loading @@ -343,6 +346,10 @@ public class UdfpsController implements DozeReceiver, HbmCallback { final IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); context.registerReceiver(mBroadcastReceiver, filter); mAuthRippleController.setViewHost(mStatusBar.getNotificationShadeWindowView()); mAuthRippleController.setSensorLocation(getSensorLocation().centerX(), getSensorLocation().centerY()); } @Nullable Loading packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt 0 → 100644 +113 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.systemui.biometrics import android.hardware.biometrics.BiometricSourceType import android.testing.AndroidTestingRunner import android.view.View import android.view.ViewGroup import androidx.test.filters.SmallTest import com.android.keyguard.KeyguardUpdateMonitor import com.android.keyguard.KeyguardUpdateMonitorCallback import com.android.systemui.SysuiTestCase import com.android.systemui.statusbar.commandline.CommandRegistry import com.android.systemui.statusbar.policy.ConfigurationController import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentCaptor import org.mockito.ArgumentMatchers import org.mockito.Mock import org.mockito.Mockito.never import org.mockito.Mockito.reset import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations @SmallTest @RunWith(AndroidTestingRunner::class) class AuthRippleControllerTest : SysuiTestCase() { private lateinit var controller: AuthRippleController @Mock private lateinit var commandRegistry: CommandRegistry @Mock private lateinit var configurationController: ConfigurationController @Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor @Mock private lateinit var rippleView: AuthRippleView @Mock private lateinit var viewHost: ViewGroup @Before fun setUp() { MockitoAnnotations.initMocks(this) controller = AuthRippleController( commandRegistry, configurationController, context, keyguardUpdateMonitor) controller.rippleView = rippleView // Replace the real ripple view with a mock instance controller.setViewHost(viewHost) } @Test fun testAddRippleView() { val listenerCaptor = ArgumentCaptor.forClass(View.OnAttachStateChangeListener::class.java) verify(viewHost).addOnAttachStateChangeListener(listenerCaptor.capture()) // Fake attach to window listenerCaptor.value.onViewAttachedToWindow(viewHost) verify(viewHost).addView(rippleView) } @Test fun testTriggerRipple() { // Fake attach to window val listenerCaptor = ArgumentCaptor.forClass(View.OnAttachStateChangeListener::class.java) verify(viewHost).addOnAttachStateChangeListener(listenerCaptor.capture()) listenerCaptor.value.onViewAttachedToWindow(viewHost) val captor = ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback::class.java) verify(keyguardUpdateMonitor).registerCallback(captor.capture()) captor.value.onBiometricAuthenticated( 0 /* userId */, BiometricSourceType.FACE /* type */, false /* isStrongBiometric */) verify(rippleView, never()).startRipple() captor.value.onBiometricAuthenticated( 0 /* userId */, BiometricSourceType.FINGERPRINT /* type */, false /* isStrongBiometric */) verify(rippleView).startRipple() } @Test fun testUpdateRippleColor() { val captor = ArgumentCaptor .forClass(ConfigurationController.ConfigurationListener::class.java) verify(configurationController).addCallback(captor.capture()) reset(rippleView) captor.value.onThemeChanged() verify(rippleView).setColor(ArgumentMatchers.anyInt()) reset(rippleView) captor.value.onUiModeChanged() verify(rippleView).setColor(ArgumentMatchers.anyInt()) } @Test fun testForwardsSensorLocation() { controller.setSensorLocation(5f, 5f) verify(rippleView).setSensorLocation(5f, 5f) } } packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java +4 −1 Original line number Diff line number Diff line Loading @@ -98,6 +98,8 @@ public class UdfpsControllerTest extends SysuiTestCase { @Mock private DumpManager mDumpManager; @Mock private AuthRippleController mAuthRippleController; @Mock private IUdfpsOverlayControllerCallback mUdfpsOverlayControllerCallback; private FakeExecutor mFgExecutor; Loading Loading @@ -148,7 +150,8 @@ public class UdfpsControllerTest extends SysuiTestCase { mFgExecutor, mStatusBar, mStatusBarKeyguardViewManager, mDumpManager); mDumpManager, mAuthRippleController); verify(mFingerprintManager).setUdfpsOverlayController(mOverlayCaptor.capture()); mOverlayController = mOverlayCaptor.getValue(); Loading Loading
packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt 0 → 100644 +110 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.systemui.biometrics import android.content.Context import android.hardware.biometrics.BiometricSourceType import android.view.View import android.view.ViewGroup import com.android.internal.annotations.VisibleForTesting import com.android.keyguard.KeyguardUpdateMonitor import com.android.keyguard.KeyguardUpdateMonitorCallback import com.android.settingslib.Utils import com.android.systemui.dagger.SysUISingleton import com.android.systemui.statusbar.commandline.Command import com.android.systemui.statusbar.commandline.CommandRegistry import com.android.systemui.statusbar.policy.ConfigurationController import java.io.PrintWriter import javax.inject.Inject /*** * Controls the ripple effect that shows when authentication is successful. * The ripple uses the accent color of the current theme. */ @SysUISingleton class AuthRippleController @Inject constructor( commandRegistry: CommandRegistry, configurationController: ConfigurationController, private val context: Context, private val keyguardUpdateMonitor: KeyguardUpdateMonitor ) { @VisibleForTesting var rippleView: AuthRippleView = AuthRippleView(context, attrs = null) val keyguardUpdateMonitorCallback = object : KeyguardUpdateMonitorCallback() { override fun onBiometricAuthenticated( userId: Int, biometricSourceType: BiometricSourceType?, isStrongBiometric: Boolean ) { if (biometricSourceType == BiometricSourceType.FINGERPRINT) { rippleView.startRipple() } } } init { val configurationChangedListener = object : ConfigurationController.ConfigurationListener { override fun onUiModeChanged() { updateRippleColor() } override fun onThemeChanged() { updateRippleColor() } override fun onOverlayChanged() { updateRippleColor() } } configurationController.addCallback(configurationChangedListener) commandRegistry.registerCommand("auth-ripple") { AuthRippleCommand() } } fun setSensorLocation(x: Float, y: Float) { rippleView.setSensorLocation(x, y) } fun setViewHost(viewHost: View) { // Add the ripple view to its host layout viewHost.addOnAttachStateChangeListener(object : View.OnAttachStateChangeListener { override fun onViewDetachedFromWindow(view: View?) {} override fun onViewAttachedToWindow(view: View?) { (viewHost as ViewGroup).addView(rippleView) keyguardUpdateMonitor.registerCallback(keyguardUpdateMonitorCallback) viewHost.removeOnAttachStateChangeListener(this) } }) updateRippleColor() } private fun updateRippleColor() { rippleView.setColor( Utils.getColorAttr(context, android.R.attr.colorAccent).defaultColor) } inner class AuthRippleCommand : Command { override fun execute(pw: PrintWriter, args: List<String>) { rippleView.startRipple() } override fun help(pw: PrintWriter) { pw.println("Usage: adb shell cmd statusbar auth-ripple") } } }
packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt 0 → 100644 +87 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.systemui.biometrics import android.animation.Animator import android.animation.AnimatorListenerAdapter import android.animation.ValueAnimator import android.content.Context import android.graphics.Canvas import android.graphics.Paint import android.graphics.PointF import android.util.AttributeSet import android.view.View import com.android.systemui.statusbar.charging.RippleShader private const val RIPPLE_ANIMATION_DURATION: Long = 950 private const val RIPPLE_SPARKLE_STRENGTH: Float = 0.4f /** * Expanding ripple effect on the transition from biometric authentication success to showing * launcher. */ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, attrs) { private var rippleInProgress: Boolean = false private val rippleShader = RippleShader() private val defaultColor: Int = 0xffffffff.toInt() private val ripplePaint = Paint() init { rippleShader.color = defaultColor rippleShader.progress = 0f rippleShader.sparkleStrength = RIPPLE_SPARKLE_STRENGTH ripplePaint.shader = rippleShader visibility = View.GONE } fun setSensorLocation(x: Float, y: Float) { rippleShader.origin = PointF(x, y) rippleShader.radius = maxOf(x, y, width - x, height - y).toFloat() } fun startRipple() { if (rippleInProgress) { return // Ignore if ripple effect is already playing } val animator = ValueAnimator.ofFloat(0f, 1f) animator.duration = RIPPLE_ANIMATION_DURATION animator.addUpdateListener { animator -> val now = animator.currentPlayTime val phase = now / 30000f rippleShader.progress = animator.animatedValue as Float rippleShader.noisePhase = phase invalidate() } animator.addListener(object : AnimatorListenerAdapter() { override fun onAnimationEnd(animation: Animator?) { rippleInProgress = false visibility = View.GONE } }) animator.start() visibility = View.VISIBLE rippleInProgress = true } fun setColor(color: Int) { rippleShader.color = color } override fun onDraw(canvas: Canvas?) { // draw over the entire screen canvas?.drawRect(0f, 0f, width.toFloat(), height.toFloat(), ripplePaint) } }
packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java +8 −1 Original line number Diff line number Diff line Loading @@ -87,6 +87,7 @@ public class UdfpsController implements DozeReceiver, HbmCallback { @NonNull private final StatusBarStateController mStatusBarStateController; @NonNull private final StatusBarKeyguardViewManager mKeyguardViewManager; @NonNull private final DumpManager mDumpManager; @NonNull private final AuthRippleController mAuthRippleController; // Currently the UdfpsController supports a single UDFPS sensor. If devices have multiple // sensors, this, in addition to a lot of the code here, will be updated. @VisibleForTesting final FingerprintSensorPropertiesInternal mSensorProps; Loading Loading @@ -305,7 +306,8 @@ public class UdfpsController implements DozeReceiver, HbmCallback { @Main DelayableExecutor fgExecutor, @NonNull StatusBar statusBar, @NonNull StatusBarKeyguardViewManager statusBarKeyguardViewManager, @NonNull DumpManager dumpManager) { @NonNull DumpManager dumpManager, @NonNull AuthRippleController authRippleController) { mContext = context; mInflater = inflater; // The fingerprint manager is queried for UDFPS before this class is constructed, so the Loading @@ -317,6 +319,7 @@ public class UdfpsController implements DozeReceiver, HbmCallback { mStatusBarStateController = statusBarStateController; mKeyguardViewManager = statusBarKeyguardViewManager; mDumpManager = dumpManager; mAuthRippleController = authRippleController; mSensorProps = findFirstUdfps(); // At least one UDFPS sensor exists Loading @@ -343,6 +346,10 @@ public class UdfpsController implements DozeReceiver, HbmCallback { final IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); context.registerReceiver(mBroadcastReceiver, filter); mAuthRippleController.setViewHost(mStatusBar.getNotificationShadeWindowView()); mAuthRippleController.setSensorLocation(getSensorLocation().centerX(), getSensorLocation().centerY()); } @Nullable Loading
packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt 0 → 100644 +113 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.systemui.biometrics import android.hardware.biometrics.BiometricSourceType import android.testing.AndroidTestingRunner import android.view.View import android.view.ViewGroup import androidx.test.filters.SmallTest import com.android.keyguard.KeyguardUpdateMonitor import com.android.keyguard.KeyguardUpdateMonitorCallback import com.android.systemui.SysuiTestCase import com.android.systemui.statusbar.commandline.CommandRegistry import com.android.systemui.statusbar.policy.ConfigurationController import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentCaptor import org.mockito.ArgumentMatchers import org.mockito.Mock import org.mockito.Mockito.never import org.mockito.Mockito.reset import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations @SmallTest @RunWith(AndroidTestingRunner::class) class AuthRippleControllerTest : SysuiTestCase() { private lateinit var controller: AuthRippleController @Mock private lateinit var commandRegistry: CommandRegistry @Mock private lateinit var configurationController: ConfigurationController @Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor @Mock private lateinit var rippleView: AuthRippleView @Mock private lateinit var viewHost: ViewGroup @Before fun setUp() { MockitoAnnotations.initMocks(this) controller = AuthRippleController( commandRegistry, configurationController, context, keyguardUpdateMonitor) controller.rippleView = rippleView // Replace the real ripple view with a mock instance controller.setViewHost(viewHost) } @Test fun testAddRippleView() { val listenerCaptor = ArgumentCaptor.forClass(View.OnAttachStateChangeListener::class.java) verify(viewHost).addOnAttachStateChangeListener(listenerCaptor.capture()) // Fake attach to window listenerCaptor.value.onViewAttachedToWindow(viewHost) verify(viewHost).addView(rippleView) } @Test fun testTriggerRipple() { // Fake attach to window val listenerCaptor = ArgumentCaptor.forClass(View.OnAttachStateChangeListener::class.java) verify(viewHost).addOnAttachStateChangeListener(listenerCaptor.capture()) listenerCaptor.value.onViewAttachedToWindow(viewHost) val captor = ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback::class.java) verify(keyguardUpdateMonitor).registerCallback(captor.capture()) captor.value.onBiometricAuthenticated( 0 /* userId */, BiometricSourceType.FACE /* type */, false /* isStrongBiometric */) verify(rippleView, never()).startRipple() captor.value.onBiometricAuthenticated( 0 /* userId */, BiometricSourceType.FINGERPRINT /* type */, false /* isStrongBiometric */) verify(rippleView).startRipple() } @Test fun testUpdateRippleColor() { val captor = ArgumentCaptor .forClass(ConfigurationController.ConfigurationListener::class.java) verify(configurationController).addCallback(captor.capture()) reset(rippleView) captor.value.onThemeChanged() verify(rippleView).setColor(ArgumentMatchers.anyInt()) reset(rippleView) captor.value.onUiModeChanged() verify(rippleView).setColor(ArgumentMatchers.anyInt()) } @Test fun testForwardsSensorLocation() { controller.setSensorLocation(5f, 5f) verify(rippleView).setSensorLocation(5f, 5f) } }
packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java +4 −1 Original line number Diff line number Diff line Loading @@ -98,6 +98,8 @@ public class UdfpsControllerTest extends SysuiTestCase { @Mock private DumpManager mDumpManager; @Mock private AuthRippleController mAuthRippleController; @Mock private IUdfpsOverlayControllerCallback mUdfpsOverlayControllerCallback; private FakeExecutor mFgExecutor; Loading Loading @@ -148,7 +150,8 @@ public class UdfpsControllerTest extends SysuiTestCase { mFgExecutor, mStatusBar, mStatusBarKeyguardViewManager, mDumpManager); mDumpManager, mAuthRippleController); verify(mFingerprintManager).setUdfpsOverlayController(mOverlayCaptor.capture()); mOverlayController = mOverlayCaptor.getValue(); Loading