diff options
6 files changed, 126 insertions, 17 deletions
diff --git a/core/java/android/hardware/biometrics/BiometricOverlayConstants.java b/core/java/android/hardware/biometrics/BiometricOverlayConstants.java index 603b06ddabaa..065ae64a92ad 100644 --- a/core/java/android/hardware/biometrics/BiometricOverlayConstants.java +++ b/core/java/android/hardware/biometrics/BiometricOverlayConstants.java @@ -38,13 +38,16 @@ public interface BiometricOverlayConstants { int REASON_AUTH_KEYGUARD = 4; /** Non-specific usage (from FingerprintManager). */ int REASON_AUTH_OTHER = 5; + /** Usage from Settings. */ + int REASON_AUTH_SETTINGS = 6; @IntDef({REASON_UNKNOWN, REASON_ENROLL_FIND_SENSOR, REASON_ENROLL_ENROLLING, REASON_AUTH_BP, REASON_AUTH_KEYGUARD, - REASON_AUTH_OTHER}) + REASON_AUTH_OTHER, + REASON_AUTH_SETTINGS}) @Retention(RetentionPolicy.SOURCE) @interface ShowReason {} } diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/SidefpsController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/SidefpsController.kt index dacc169f85ee..7bb4708443e9 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/SidefpsController.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/SidefpsController.kt @@ -17,6 +17,7 @@ package com.android.systemui.biometrics import android.animation.Animator import android.animation.AnimatorListenerAdapter +import android.app.ActivityTaskManager import android.content.Context import android.graphics.PixelFormat import android.graphics.PorterDuff @@ -24,6 +25,7 @@ import android.graphics.PorterDuffColorFilter import android.graphics.Rect import android.hardware.biometrics.BiometricOverlayConstants import android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_KEYGUARD +import android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_SETTINGS import android.hardware.display.DisplayManager import android.hardware.fingerprint.FingerprintManager import android.hardware.fingerprint.FingerprintSensorPropertiesInternal @@ -61,6 +63,7 @@ class SidefpsController @Inject constructor( private val layoutInflater: LayoutInflater, fingerprintManager: FingerprintManager?, private val windowManager: WindowManager, + private val activityTaskManager: ActivityTaskManager, overviewProxyService: OverviewProxyService, displayManager: DisplayManager, @Main mainExecutor: DelayableExecutor, @@ -130,7 +133,7 @@ class SidefpsController @Inject constructor( override fun show( sensorId: Int, @BiometricOverlayConstants.ShowReason reason: Int - ) = if (reason.isReasonToShow()) doShow() else hide(sensorId) + ) = if (reason.isReasonToShow(activityTaskManager)) doShow() else hide(sensorId) private fun doShow() = mainExecutor.execute { if (overlayView == null) { @@ -228,11 +231,19 @@ class SidefpsController @Inject constructor( } @BiometricOverlayConstants.ShowReason -private fun Int.isReasonToShow(): Boolean = when (this) { +private fun Int.isReasonToShow(activityTaskManager: ActivityTaskManager): Boolean = when (this) { REASON_AUTH_KEYGUARD -> false + 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 + } else -> true } +private fun ActivityTaskManager.topClass(): String = + getTasks(1).firstOrNull()?.topActivity?.className ?: "" + @RawRes private fun Display.asSideFpsAnimation(): Int = when (rotation) { Surface.ROTATION_0 -> R.raw.sfps_pulse diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java index 81a4d590aec6..eb36915f9753 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java @@ -760,10 +760,12 @@ public class UdfpsController implements DozeReceiver { mOnFingerDown = false; mView.setSensorProperties(mSensorProps); mView.setHbmProvider(mHbmProvider); - UdfpsAnimationViewController animation = inflateUdfpsAnimation(reason); + UdfpsAnimationViewController<?> animation = inflateUdfpsAnimation(reason); mAttemptedToDismissKeyguard = false; - animation.init(); - mView.setAnimationViewController(animation); + if (animation != null) { + animation.init(); + mView.setAnimationViewController(animation); + } mOrientationListener.enable(); // This view overlaps the sensor area, so prevent it from being selectable @@ -786,7 +788,8 @@ public class UdfpsController implements DozeReceiver { } } - private UdfpsAnimationViewController inflateUdfpsAnimation(int reason) { + @Nullable + private UdfpsAnimationViewController<?> inflateUdfpsAnimation(int reason) { switch (reason) { case BiometricOverlayConstants.REASON_ENROLL_FIND_SENSOR: case BiometricOverlayConstants.REASON_ENROLL_ENROLLING: @@ -830,6 +833,7 @@ public class UdfpsController implements DozeReceiver { mDumpManager ); case BiometricOverlayConstants.REASON_AUTH_OTHER: + case BiometricOverlayConstants.REASON_AUTH_SETTINGS: UdfpsFpmOtherView authOtherView = (UdfpsFpmOtherView) mInflater.inflate(R.layout.udfps_fpm_other_view, null); mView.addView(authOtherView); @@ -840,7 +844,7 @@ public class UdfpsController implements DozeReceiver { mDumpManager ); default: - Log.d(TAG, "Animation for reason " + reason + " not supported yet"); + Log.e(TAG, "Animation for reason " + reason + " not supported yet"); return null; } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/SidefpsControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/SidefpsControllerTest.kt index c98a504b8784..2d510923b942 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/SidefpsControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/SidefpsControllerTest.kt @@ -18,8 +18,12 @@ package com.android.systemui.biometrics import android.animation.Animator import android.graphics.Insets +import android.app.ActivityManager +import android.app.ActivityTaskManager +import android.content.ComponentName import android.graphics.Rect import android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_KEYGUARD +import android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_SETTINGS import android.hardware.biometrics.BiometricOverlayConstants.REASON_UNKNOWN import android.hardware.biometrics.SensorProperties import android.hardware.display.DisplayManager @@ -60,9 +64,11 @@ import org.mockito.Mockito.`when` import org.mockito.Mockito.any import org.mockito.Mockito.anyFloat import org.mockito.Mockito.anyLong +import org.mockito.Mockito.anyInt import org.mockito.Mockito.mock import org.mockito.Mockito.never import org.mockito.Mockito.reset +import org.mockito.Mockito.times import org.mockito.Mockito.verify import org.mockito.junit.MockitoJUnit @@ -84,6 +90,8 @@ class SidefpsControllerTest : SysuiTestCase() { @Mock lateinit var windowManager: WindowManager @Mock + lateinit var activityTaskManager: ActivityTaskManager + @Mock lateinit var sidefpsView: View @Mock lateinit var displayManager: DisplayManager @@ -144,7 +152,8 @@ class SidefpsControllerTest : SysuiTestCase() { sideFpsController = SidefpsController( context.createDisplayContext(display), layoutInflater, fingerprintManager, - windowManager, overviewProxyService, displayManager, executor, handler + windowManager, activityTaskManager, overviewProxyService, displayManager, executor, + handler ) overlayController = ArgumentCaptor.forClass(ISidefpsController::class.java).apply { @@ -211,12 +220,23 @@ class SidefpsControllerTest : SysuiTestCase() { testIgnoredFor(REASON_AUTH_KEYGUARD) } - private fun testIgnoredFor(reason: Int) { - overlayController.show(SENSOR_ID, reason) + @Test + fun testShowsForMostSettings() = testWithDisplay { + `when`(activityTaskManager.getTasks(anyInt())).thenReturn(listOf(fpEnrollTask())) + testIgnoredFor(REASON_AUTH_SETTINGS, ignored = false) + } + + @Test + fun testIgnoredForVerySpecificSettings() = testWithDisplay { + `when`(activityTaskManager.getTasks(anyInt())).thenReturn(listOf(fpSettingsTask())) + testIgnoredFor(REASON_AUTH_SETTINGS) + } + private fun testIgnoredFor(reason: Int, ignored: Boolean = true) { + overlayController.show(SENSOR_ID, reason) executor.runAllReady() - verify(windowManager, never()).addView(any(), any()) + verify(windowManager, if (ignored) never() else times(1)).addView(any(), any()) } @Test @@ -267,4 +287,9 @@ private fun insetsForSmallNavbar() = insetsWithBottom(60) private fun insetsForLargeNavbar() = insetsWithBottom(100) private fun insetsWithBottom(bottom: Int) = WindowInsets.Builder() .setInsets(WindowInsets.Type.navigationBars(), Insets.of(0, 0, 0, bottom)) - .build()
\ No newline at end of file + .build() +private fun fpEnrollTask() = settingsTask(".biometrics.fingerprint.FingerprintEnrollEnrolling") +private fun fpSettingsTask() = settingsTask(".biometrics.fingerprint.FingerprintSettings") +private fun settingsTask(cls: String) = ActivityManager.RunningTaskInfo().apply { + topActivity = ComponentName.createRelative("com.android.settings", cls) +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java index cfac9cb592a0..d90eb73a1595 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java @@ -405,15 +405,75 @@ public class UdfpsControllerTest extends SysuiTestCase { } @Test - public void showUdfpsOverlay_addsViewToWindow() throws RemoteException { - mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID, - BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback); + public void showUdfpsOverlay_addsViewToWindow_bp() throws RemoteException { + showUdfpsOverlay_addsViewToWindow(BiometricOverlayConstants.REASON_AUTH_BP); + } + + @Test + public void showUdfpsOverlay_addsViewToWindow_keyguard() throws RemoteException { + showUdfpsOverlay_addsViewToWindow(BiometricOverlayConstants.REASON_AUTH_KEYGUARD); + } + + @Test + public void showUdfpsOverlay_addsViewToWindow_settings() throws RemoteException { + showUdfpsOverlay_addsViewToWindow(BiometricOverlayConstants.REASON_AUTH_SETTINGS); + } + + @Test + public void showUdfpsOverlay_addsViewToWindow_enroll_locate() throws RemoteException { + showUdfpsOverlay_addsViewToWindow(BiometricOverlayConstants.REASON_ENROLL_FIND_SENSOR); + } + + @Test + public void showUdfpsOverlay_addsViewToWindow_enroll() throws RemoteException { + showUdfpsOverlay_addsViewToWindow(BiometricOverlayConstants.REASON_ENROLL_ENROLLING); + } + + @Test + public void showUdfpsOverlay_addsViewToWindow_other() throws RemoteException { + showUdfpsOverlay_addsViewToWindow(BiometricOverlayConstants.REASON_AUTH_OTHER); + } + + private void showUdfpsOverlay_addsViewToWindow( + @BiometricOverlayConstants.ShowReason int reason) throws RemoteException { + mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID, reason, + mUdfpsOverlayControllerCallback); mFgExecutor.runAllReady(); verify(mWindowManager).addView(eq(mUdfpsView), any()); } @Test - public void hideUdfpsOverlay_removesViewFromWindow() throws RemoteException { + public void hideUdfpsOverlay_removesViewFromWindow_bp() throws RemoteException { + hideUdfpsOverlay_removesViewFromWindow(BiometricOverlayConstants.REASON_AUTH_BP); + } + + @Test + public void hideUdfpsOverlay_removesViewFromWindow_keyguard() throws RemoteException { + hideUdfpsOverlay_removesViewFromWindow(BiometricOverlayConstants.REASON_AUTH_KEYGUARD); + } + + @Test + public void hideUdfpsOverlay_removesViewFromWindow_settings() throws RemoteException { + hideUdfpsOverlay_removesViewFromWindow(BiometricOverlayConstants.REASON_AUTH_SETTINGS); + } + + @Test + public void hideUdfpsOverlay_removesViewFromWindow_enroll_locate() throws RemoteException { + hideUdfpsOverlay_removesViewFromWindow(BiometricOverlayConstants.REASON_ENROLL_FIND_SENSOR); + } + + @Test + public void hideUdfpsOverlay_removesViewFromWindow_enroll() throws RemoteException { + hideUdfpsOverlay_removesViewFromWindow(BiometricOverlayConstants.REASON_ENROLL_ENROLLING); + } + + @Test + public void hideUdfpsOverlay_removesViewFromWindow_other() throws RemoteException { + hideUdfpsOverlay_removesViewFromWindow(BiometricOverlayConstants.REASON_AUTH_OTHER); + } + + private void hideUdfpsOverlay_removesViewFromWindow( + @BiometricOverlayConstants.ShowReason int reason) throws RemoteException { mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID, BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback); mOverlayController.hideUdfpsOverlay(TEST_UDFPS_SENSOR_ID); diff --git a/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java index 031f6eeeca5f..61b8ded60db7 100644 --- a/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java @@ -168,6 +168,10 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T> return Utils.isKeyguard(getContext(), getOwnerString()); } + private boolean isSettings() { + return Utils.isSettings(getContext(), getOwnerString()); + } + @Override protected boolean isCryptoOperation() { return mOperationId != 0; @@ -499,6 +503,8 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T> protected int getShowOverlayReason() { if (isKeyguard()) { return BiometricOverlayConstants.REASON_AUTH_KEYGUARD; + } else if (isSettings()) { + return BiometricOverlayConstants.REASON_AUTH_SETTINGS; } else if (isBiometricPrompt()) { return BiometricOverlayConstants.REASON_AUTH_BP; } else { |