Do not show side fingerprint sensor overlay when used from settings.

This is an alternative to ag/16124814 with the additional fix for udfps.

Fix: 203789357
Test: atest SidefpsControllerTest
Test: manual (open settings and verify no overlay shown with list of fingerprint)
Test: manual (open settings and verify overlay shown during enrollment)

Change-Id: Iee33cbb66d86d4f033d6acc9cf2284a3845f22de
This commit is contained in:
Joe Bolinger
2021-10-29 22:36:38 +00:00
parent 9a9430beb0
commit 7f6ff9092f
6 changed files with 126 additions and 17 deletions

View File

@@ -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 {}
}

View File

@@ -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

View File

@@ -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;
}
}

View File

@@ -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()
.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)
}

View File

@@ -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);

View File

@@ -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 {