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

Commit 8636ab2e authored by Ilya Matyukhin's avatar Ilya Matyukhin Committed by Automerger Merge Worker
Browse files

Merge "Add a setting to remove UDFPS overlay enrollment UI" into tm-qpr-dev am: 8ee656b9

parents 4382439a 8ee656b9
Loading
Loading
Loading
Loading
+48 −15
Original line number Diff line number Diff line
@@ -21,13 +21,18 @@ import android.annotation.UiThread
import android.content.Context
import android.graphics.PixelFormat
import android.graphics.Rect
import android.hardware.biometrics.BiometricOverlayConstants
import android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_BP
import android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_KEYGUARD
import android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_OTHER
import android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_SETTINGS
import android.hardware.biometrics.BiometricOverlayConstants.REASON_ENROLL_ENROLLING
import android.hardware.biometrics.BiometricOverlayConstants.REASON_ENROLL_FIND_SENSOR
import android.hardware.biometrics.BiometricOverlayConstants.ShowReason
import android.hardware.fingerprint.FingerprintManager
import android.hardware.fingerprint.IUdfpsOverlayControllerCallback
import android.os.Build
import android.os.RemoteException
import android.provider.Settings
import android.util.Log
import android.util.RotationUtils
import android.view.LayoutInflater
@@ -38,6 +43,7 @@ import android.view.WindowManager
import android.view.accessibility.AccessibilityManager
import android.view.accessibility.AccessibilityManager.TouchExplorationStateChangeListener
import androidx.annotation.LayoutRes
import androidx.annotation.VisibleForTesting
import com.android.keyguard.KeyguardUpdateMonitor
import com.android.systemui.R
import com.android.systemui.animation.ActivityLaunchAnimator
@@ -54,13 +60,16 @@ import com.android.systemui.util.time.SystemClock

private const val TAG = "UdfpsControllerOverlay"

@VisibleForTesting
const val SETTING_REMOVE_ENROLLMENT_UI = "udfps_overlay_remove_enrollment_ui"

/**
 * Keeps track of the overlay state and UI resources associated with a single FingerprintService
 * request. This state can persist across configuration changes via the [show] and [hide]
 * methods.
 */
@UiThread
class UdfpsControllerOverlay(
class UdfpsControllerOverlay @JvmOverloads constructor(
    private val context: Context,
    fingerprintManager: FingerprintManager,
    private val inflater: LayoutInflater,
@@ -82,7 +91,8 @@ class UdfpsControllerOverlay(
    @ShowReason val requestReason: Int,
    private val controllerCallback: IUdfpsOverlayControllerCallback,
    private val onTouch: (View, MotionEvent, Boolean) -> Boolean,
    private val activityLaunchAnimator: ActivityLaunchAnimator
    private val activityLaunchAnimator: ActivityLaunchAnimator,
    private val isDebuggable: Boolean = Build.IS_DEBUGGABLE
) {
    /** The view, when [isShowing], or null. */
    var overlayView: UdfpsView? = null
@@ -109,7 +119,8 @@ class UdfpsControllerOverlay(
    }

    /** A helper if the [requestReason] was due to enrollment. */
    val enrollHelper: UdfpsEnrollHelper? = if (requestReason.isEnrollmentReason()) {
    val enrollHelper: UdfpsEnrollHelper? =
        if (requestReason.isEnrollmentReason() && !shouldRemoveEnrollmentUi()) {
            UdfpsEnrollHelper(context, fingerprintManager, requestReason)
        } else {
            null
@@ -129,6 +140,17 @@ class UdfpsControllerOverlay(

    private var touchExplorationEnabled = false

    private fun shouldRemoveEnrollmentUi(): Boolean {
        if (isDebuggable) {
            return Settings.Global.getInt(
                context.contentResolver,
                SETTING_REMOVE_ENROLLMENT_UI,
                0 /* def */
            ) != 0
        }
        return false
    }

    /** Show the overlay or return false and do nothing if it is already showing. */
    @SuppressLint("ClickableViewAccessibility")
    fun show(controller: UdfpsController, params: UdfpsOverlayParams): Boolean {
@@ -183,7 +205,18 @@ class UdfpsControllerOverlay(
        view: UdfpsView,
        controller: UdfpsController
    ): UdfpsAnimationViewController<*>? {
        return when (requestReason) {
        val isEnrollment = when (requestReason) {
            REASON_ENROLL_FIND_SENSOR, REASON_ENROLL_ENROLLING -> true
            else -> false
        }

        val filteredRequestReason = if (isEnrollment && shouldRemoveEnrollmentUi()) {
            REASON_AUTH_OTHER
        } else {
            requestReason
        }

        return when (filteredRequestReason) {
            REASON_ENROLL_FIND_SENSOR,
            REASON_ENROLL_ENROLLING -> {
                UdfpsEnrollViewController(
@@ -198,7 +231,7 @@ class UdfpsControllerOverlay(
                    overlayParams.scaleFactor
                )
            }
            BiometricOverlayConstants.REASON_AUTH_KEYGUARD -> {
            REASON_AUTH_KEYGUARD -> {
                UdfpsKeyguardViewController(
                    view.addUdfpsView(R.layout.udfps_keyguard_view),
                    statusBarStateController,
@@ -216,7 +249,7 @@ class UdfpsControllerOverlay(
                    activityLaunchAnimator
                )
            }
            BiometricOverlayConstants.REASON_AUTH_BP -> {
            REASON_AUTH_BP -> {
                // note: empty controller, currently shows no visual affordance
                UdfpsBpViewController(
                    view.addUdfpsView(R.layout.udfps_bp_view),
@@ -226,8 +259,8 @@ class UdfpsControllerOverlay(
                    dumpManager
                )
            }
            BiometricOverlayConstants.REASON_AUTH_OTHER,
            BiometricOverlayConstants.REASON_AUTH_SETTINGS -> {
            REASON_AUTH_OTHER,
            REASON_AUTH_SETTINGS -> {
                UdfpsFpmOtherViewController(
                    view.addUdfpsView(R.layout.udfps_fpm_other_view),
                    statusBarStateController,
@@ -440,4 +473,4 @@ private fun Int.isEnrollmentReason() =
private fun Int.isImportantForAccessibility() =
    this == REASON_ENROLL_FIND_SENSOR ||
            this == REASON_ENROLL_ENROLLING ||
            this == BiometricOverlayConstants.REASON_AUTH_BP
            this == REASON_AUTH_BP
+97 −38
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import android.hardware.biometrics.BiometricOverlayConstants.REASON_ENROLL_FIND_
import android.hardware.biometrics.BiometricOverlayConstants.ShowReason
import android.hardware.fingerprint.FingerprintManager
import android.hardware.fingerprint.IUdfpsOverlayControllerCallback
import android.provider.Settings
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper.RunWithLooper
import android.view.LayoutInflater
@@ -124,14 +125,18 @@ class UdfpsControllerOverlayTest : SysuiTestCase() {
        whenever(udfpsEnrollView.context).thenReturn(context)
    }

    private fun withReason(@ShowReason reason: Int, block: () -> Unit) {
    private fun withReason(
        @ShowReason reason: Int,
        isDebuggable: Boolean = false,
        block: () -> Unit
    ) {
        controllerOverlay = UdfpsControllerOverlay(
            context, fingerprintManager, inflater, windowManager, accessibilityManager,
            statusBarStateController, shadeExpansionStateManager, statusBarKeyguardViewManager,
            keyguardUpdateMonitor, dialogManager, dumpManager, transitionController,
            configurationController, systemClock, keyguardStateController,
            unlockedScreenOffAnimationController, udfpsDisplayMode, REQUEST_ID, reason,
            controllerCallback, onTouch, activityLaunchAnimator
            controllerCallback, onTouch, activityLaunchAnimator, isDebuggable
        )
        block()
    }
@@ -150,11 +155,29 @@ class UdfpsControllerOverlayTest : SysuiTestCase() {
        showUdfpsOverlay(isEnrollUseCase = true)
    }

    @Test
    fun showUdfpsOverlay_locate_withEnrollmentUiRemoved() {
        Settings.Global.putInt(mContext.contentResolver, SETTING_REMOVE_ENROLLMENT_UI, 1)
        withReason(REASON_ENROLL_FIND_SENSOR, isDebuggable = true) {
            showUdfpsOverlay(isEnrollUseCase = false)
        }
        Settings.Global.putInt(mContext.contentResolver, SETTING_REMOVE_ENROLLMENT_UI, 0)
    }

    @Test
    fun showUdfpsOverlay_enroll() = withReason(REASON_ENROLL_ENROLLING) {
        showUdfpsOverlay(isEnrollUseCase = true)
    }

    @Test
    fun showUdfpsOverlay_enroll_withEnrollmentUiRemoved() {
        Settings.Global.putInt(mContext.contentResolver, SETTING_REMOVE_ENROLLMENT_UI, 1)
        withReason(REASON_ENROLL_ENROLLING, isDebuggable = true) {
            showUdfpsOverlay(isEnrollUseCase = false)
        }
        Settings.Global.putInt(mContext.contentResolver, SETTING_REMOVE_ENROLLMENT_UI, 0)
    }

    @Test
    fun showUdfpsOverlay_other() = withReason(REASON_AUTH_OTHER) { showUdfpsOverlay() }

@@ -372,21 +395,33 @@ class UdfpsControllerOverlayTest : SysuiTestCase() {
            context.resources.getStringArray(R.array.udfps_accessibility_touch_hints)
        val rotation = Surface.ROTATION_0
        // touch at 0 degrees
        assertThat(controllerOverlay.onTouchOutsideOfSensorAreaImpl(0.0f /* x */, 0.0f /* y */,
                0.0f /* sensorX */, 0.0f /* sensorY */, rotation))
                .isEqualTo(touchHints[0])
        assertThat(
            controllerOverlay.onTouchOutsideOfSensorAreaImpl(
                0.0f /* x */, 0.0f /* y */,
                0.0f /* sensorX */, 0.0f /* sensorY */, rotation
            )
        ).isEqualTo(touchHints[0])
        // touch at 90 degrees
        assertThat(controllerOverlay.onTouchOutsideOfSensorAreaImpl(0.0f /* x */, -1.0f /* y */,
                0.0f /* sensorX */, 0.0f /* sensorY */, rotation))
                .isEqualTo(touchHints[1])
        assertThat(
            controllerOverlay.onTouchOutsideOfSensorAreaImpl(
                0.0f /* x */, -1.0f /* y */,
                0.0f /* sensorX */, 0.0f /* sensorY */, rotation
            )
        ).isEqualTo(touchHints[1])
        // touch at 180 degrees
        assertThat(controllerOverlay.onTouchOutsideOfSensorAreaImpl(-1.0f /* x */, 0.0f /* y */,
                0.0f /* sensorX */, 0.0f /* sensorY */, rotation))
                .isEqualTo(touchHints[2])
        assertThat(
            controllerOverlay.onTouchOutsideOfSensorAreaImpl(
                -1.0f /* x */, 0.0f /* y */,
                0.0f /* sensorX */, 0.0f /* sensorY */, rotation
            )
        ).isEqualTo(touchHints[2])
        // touch at 270 degrees
        assertThat(controllerOverlay.onTouchOutsideOfSensorAreaImpl(0.0f /* x */, 1.0f /* y */,
                0.0f /* sensorX */, 0.0f /* sensorY */, rotation))
                .isEqualTo(touchHints[3])
        assertThat(
            controllerOverlay.onTouchOutsideOfSensorAreaImpl(
                0.0f /* x */, 1.0f /* y */,
                0.0f /* sensorX */, 0.0f /* sensorY */, rotation
            )
        ).isEqualTo(touchHints[3])
    }

    fun testTouchOutsideAreaNoRotation90Degrees() = withReason(REASON_ENROLL_ENROLLING) {
@@ -394,21 +429,33 @@ class UdfpsControllerOverlayTest : SysuiTestCase() {
            context.resources.getStringArray(R.array.udfps_accessibility_touch_hints)
        val rotation = Surface.ROTATION_90
        // touch at 0 degrees -> 90 degrees
        assertThat(controllerOverlay.onTouchOutsideOfSensorAreaImpl(0.0f /* x */, 0.0f /* y */,
                0.0f /* sensorX */, 0.0f /* sensorY */, rotation))
                .isEqualTo(touchHints[1])
        assertThat(
            controllerOverlay.onTouchOutsideOfSensorAreaImpl(
                0.0f /* x */, 0.0f /* y */,
                0.0f /* sensorX */, 0.0f /* sensorY */, rotation
            )
        ).isEqualTo(touchHints[1])
        // touch at 90 degrees -> 180 degrees
        assertThat(controllerOverlay.onTouchOutsideOfSensorAreaImpl(0.0f /* x */, -1.0f /* y */,
                0.0f /* sensorX */, 0.0f /* sensorY */, rotation))
                .isEqualTo(touchHints[2])
        assertThat(
            controllerOverlay.onTouchOutsideOfSensorAreaImpl(
                0.0f /* x */, -1.0f /* y */,
                0.0f /* sensorX */, 0.0f /* sensorY */, rotation
            )
        ).isEqualTo(touchHints[2])
        // touch at 180 degrees -> 270 degrees
        assertThat(controllerOverlay.onTouchOutsideOfSensorAreaImpl(-1.0f /* x */, 0.0f /* y */,
                0.0f /* sensorX */, 0.0f /* sensorY */, rotation))
                .isEqualTo(touchHints[3])
        assertThat(
            controllerOverlay.onTouchOutsideOfSensorAreaImpl(
                -1.0f /* x */, 0.0f /* y */,
                0.0f /* sensorX */, 0.0f /* sensorY */, rotation
            )
        ).isEqualTo(touchHints[3])
        // touch at 270 degrees -> 0 degrees
        assertThat(controllerOverlay.onTouchOutsideOfSensorAreaImpl(0.0f /* x */, 1.0f /* y */,
                0.0f /* sensorX */, 0.0f /* sensorY */, rotation))
                .isEqualTo(touchHints[0])
        assertThat(
            controllerOverlay.onTouchOutsideOfSensorAreaImpl(
                0.0f /* x */, 1.0f /* y */,
                0.0f /* sensorX */, 0.0f /* sensorY */, rotation
            )
        ).isEqualTo(touchHints[0])
    }

    fun testTouchOutsideAreaNoRotation270Degrees() = withReason(REASON_ENROLL_ENROLLING) {
@@ -416,21 +463,33 @@ class UdfpsControllerOverlayTest : SysuiTestCase() {
            context.resources.getStringArray(R.array.udfps_accessibility_touch_hints)
        val rotation = Surface.ROTATION_270
        // touch at 0 degrees -> 270 degrees
        assertThat(controllerOverlay.onTouchOutsideOfSensorAreaImpl(0.0f /* x */, 0.0f /* y */,
                0.0f /* sensorX */, 0.0f /* sensorY */, rotation))
                .isEqualTo(touchHints[3])
        assertThat(
            controllerOverlay.onTouchOutsideOfSensorAreaImpl(
                0.0f /* x */, 0.0f /* y */,
                0.0f /* sensorX */, 0.0f /* sensorY */, rotation
            )
        ).isEqualTo(touchHints[3])
        // touch at 90 degrees -> 0 degrees
        assertThat(controllerOverlay.onTouchOutsideOfSensorAreaImpl(0.0f /* x */, -1.0f /* y */,
                0.0f /* sensorX */, 0.0f /* sensorY */, rotation))
                .isEqualTo(touchHints[0])
        assertThat(
            controllerOverlay.onTouchOutsideOfSensorAreaImpl(
                0.0f /* x */, -1.0f /* y */,
                0.0f /* sensorX */, 0.0f /* sensorY */, rotation
            )
        ).isEqualTo(touchHints[0])
        // touch at 180 degrees -> 90 degrees
        assertThat(controllerOverlay.onTouchOutsideOfSensorAreaImpl(-1.0f /* x */, 0.0f /* y */,
                0.0f /* sensorX */, 0.0f /* sensorY */, rotation))
                .isEqualTo(touchHints[1])
        assertThat(
            controllerOverlay.onTouchOutsideOfSensorAreaImpl(
                -1.0f /* x */, 0.0f /* y */,
                0.0f /* sensorX */, 0.0f /* sensorY */, rotation
            )
        ).isEqualTo(touchHints[1])
        // touch at 270 degrees -> 180 degrees
        assertThat(controllerOverlay.onTouchOutsideOfSensorAreaImpl(0.0f /* x */, 1.0f /* y */,
                0.0f /* sensorX */, 0.0f /* sensorY */, rotation))
                .isEqualTo(touchHints[2])
        assertThat(
            controllerOverlay.onTouchOutsideOfSensorAreaImpl(
                0.0f /* x */, 1.0f /* y */,
                0.0f /* sensorX */, 0.0f /* sensorY */, rotation
            )
        ).isEqualTo(touchHints[2])
    }
}