From 9bb6bec63f018cc47c95bba39bf0117b0ad0739b Mon Sep 17 00:00:00 2001 From: Austin Delgado Date: Tue, 21 Mar 2023 15:51:45 -0700 Subject: [PATCH] Remove unused UdfpsOverlay and UdfpsOverlay View Remove the experimental UdfpsOverlay for testing ellipse that has now been integrated into the exisiting UdfpsControllerOverlay and UdfpsView. Bug: 274637712 Test: atest SystemUITests:com.android.systemui.biometrics Change-Id: Iae013670c8d6885c106f1b931fd311d366f5cefd --- .../systemui/biometrics/UdfpsOverlay.kt | 345 ------------------ .../systemui/biometrics/UdfpsOverlayView.kt | 143 -------- .../android/systemui/biometrics/UdfpsShell.kt | 17 +- .../dagger/SystemUICoreStartableModule.kt | 7 - .../systemui/biometrics/UdfpsShellTest.kt | 3 +- 5 files changed, 2 insertions(+), 513 deletions(-) delete mode 100644 packages/SystemUI/src/com/android/systemui/biometrics/UdfpsOverlay.kt delete mode 100644 packages/SystemUI/src/com/android/systemui/biometrics/UdfpsOverlayView.kt diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsOverlay.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsOverlay.kt deleted file mode 100644 index 079c0b3f69665..0000000000000 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsOverlay.kt +++ /dev/null @@ -1,345 +0,0 @@ -/* - * Copyright (C) 2022 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.annotation.SuppressLint -import android.content.Context -import android.graphics.PixelFormat -import android.graphics.Point -import android.graphics.Rect -import android.hardware.biometrics.BiometricOverlayConstants -import android.hardware.fingerprint.FingerprintManager -import android.hardware.fingerprint.FingerprintSensorPropertiesInternal -import android.hardware.fingerprint.IFingerprintAuthenticatorsRegisteredCallback -import android.hardware.fingerprint.IUdfpsOverlay -import android.os.Handler -import android.provider.Settings -import android.view.MotionEvent -import android.view.WindowManager -import android.view.WindowManager.LayoutParams.INPUT_FEATURE_SPY -import com.android.keyguard.KeyguardUpdateMonitor -import com.android.settingslib.udfps.UdfpsOverlayParams -import com.android.systemui.CoreStartable -import com.android.systemui.dagger.SysUISingleton -import com.android.systemui.dagger.qualifiers.Main -import com.android.systemui.flags.FeatureFlags -import com.android.systemui.flags.Flags -import com.android.systemui.util.concurrency.DelayableExecutor -import com.android.systemui.util.concurrency.Execution -import java.util.Optional -import java.util.concurrent.Executor -import javax.inject.Inject -import javax.inject.Provider -import kotlin.math.cos -import kotlin.math.pow -import kotlin.math.sin - -private const val TAG = "UdfpsOverlay" - -const val SETTING_OVERLAY_DEBUG = "udfps_overlay_debug" - -// Number of sensor points needed inside ellipse for good overlap -private const val NEEDED_POINTS = 2 - -@SuppressLint("ClickableViewAccessibility") -@SysUISingleton -class UdfpsOverlay -@Inject -constructor( - private val context: Context, - private val execution: Execution, - private val windowManager: WindowManager, - private val fingerprintManager: FingerprintManager?, - private val handler: Handler, - private val biometricExecutor: Executor, - private val alternateTouchProvider: Optional>, - @Main private val fgExecutor: DelayableExecutor, - private val keyguardUpdateMonitor: KeyguardUpdateMonitor, - private val authController: AuthController, - private val udfpsLogger: UdfpsLogger, - private var featureFlags: FeatureFlags -) : CoreStartable { - - /** The view, when [isShowing], or null. */ - var overlayView: UdfpsOverlayView? = null - private set - - private var requestId: Long = 0 - private var onFingerDown = false - val size = windowManager.maximumWindowMetrics.bounds - - val udfpsProps: MutableList = mutableListOf() - var points: Array = emptyArray() - var processedMotionEvent = false - var isShowing = false - - private var params: UdfpsOverlayParams = UdfpsOverlayParams() - - private val coreLayoutParams = - WindowManager.LayoutParams( - WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG, - 0 /* flags set in computeLayoutParams() */, - PixelFormat.TRANSLUCENT - ) - .apply { - title = TAG - fitInsetsTypes = 0 - gravity = android.view.Gravity.TOP or android.view.Gravity.LEFT - layoutInDisplayCutoutMode = - WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS - flags = Utils.FINGERPRINT_OVERLAY_LAYOUT_PARAM_FLAGS - privateFlags = WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY - // Avoid announcing window title. - accessibilityTitle = " " - inputFeatures = INPUT_FEATURE_SPY - } - - fun onTouch(event: MotionEvent): Boolean { - val view = overlayView!! - - return when (event.action) { - MotionEvent.ACTION_DOWN, - MotionEvent.ACTION_MOVE -> { - onFingerDown = true - if (!view.isDisplayConfigured && alternateTouchProvider.isPresent) { - view.processMotionEvent(event) - - val goodOverlap = - if (featureFlags.isEnabled(Flags.NEW_ELLIPSE_DETECTION)) { - isGoodEllipseOverlap(event) - } else { - isGoodCentroidOverlap(event) - } - - if (!processedMotionEvent && goodOverlap) { - biometricExecutor.execute { - alternateTouchProvider - .map(Provider::get) - .get() - .onPointerDown( - requestId, - event.rawX.toInt(), - event.rawY.toInt(), - event.touchMinor, - event.touchMajor - ) - } - fgExecutor.execute { - if (keyguardUpdateMonitor.isFingerprintDetectionRunning) { - keyguardUpdateMonitor.onUdfpsPointerDown(requestId.toInt()) - } - - view.configureDisplay { - biometricExecutor.execute { - alternateTouchProvider - .map(Provider::get) - .get() - .onUiReady() - } - } - - processedMotionEvent = true - } - } - - view.invalidate() - } - true - } - MotionEvent.ACTION_UP, - MotionEvent.ACTION_CANCEL -> { - if (processedMotionEvent && alternateTouchProvider.isPresent) { - biometricExecutor.execute { - alternateTouchProvider - .map(Provider::get) - .get() - .onPointerUp(requestId) - } - fgExecutor.execute { - if (keyguardUpdateMonitor.isFingerprintDetectionRunning) { - keyguardUpdateMonitor.onUdfpsPointerUp(requestId.toInt()) - } - } - - processedMotionEvent = false - } - - if (view.isDisplayConfigured) { - view.unconfigureDisplay() - } - - view.invalidate() - true - } - else -> false - } - } - - fun isGoodEllipseOverlap(event: MotionEvent): Boolean { - return points.count { checkPoint(event, it) } >= NEEDED_POINTS - } - - fun isGoodCentroidOverlap(event: MotionEvent): Boolean { - return params.sensorBounds.contains(event.rawX.toInt(), event.rawY.toInt()) - } - - fun checkPoint(event: MotionEvent, point: Point): Boolean { - // Calculate if sensor point is within ellipse - // Formula: ((cos(o)(xE - xS) + sin(o)(yE - yS))^2 / a^2) + ((sin(o)(xE - xS) + cos(o)(yE - - // yS))^2 / b^2) <= 1 - val a: Float = cos(event.orientation) * (point.x - event.rawX) - val b: Float = sin(event.orientation) * (point.y - event.rawY) - val c: Float = sin(event.orientation) * (point.x - event.rawX) - val d: Float = cos(event.orientation) * (point.y - event.rawY) - val result = - (a + b).pow(2) / (event.touchMinor / 2).pow(2) + - (c - d).pow(2) / (event.touchMajor / 2).pow(2) - - return result <= 1 - } - - fun show(requestId: Long) { - if (!featureFlags.isEnabled(Flags.NEW_UDFPS_OVERLAY)) { - return - } - - this.requestId = requestId - fgExecutor.execute { - if (overlayView == null && alternateTouchProvider.isPresent) { - UdfpsOverlayView(context, null).let { - it.overlayParams = params - it.setUdfpsDisplayMode( - UdfpsDisplayMode(context, execution, authController, udfpsLogger) - ) - it.setOnTouchListener { _, event -> onTouch(event) } - it.sensorPoints = points - it.debugOverlay = - Settings.Global.getInt( - context.contentResolver, - SETTING_OVERLAY_DEBUG, - 0 /* def */ - ) != 0 - overlayView = it - } - windowManager.addView(overlayView, coreLayoutParams) - isShowing = true - } - } - } - - fun hide() { - if (!featureFlags.isEnabled(Flags.NEW_UDFPS_OVERLAY)) { - return - } - - fgExecutor.execute { - if (overlayView != null && isShowing && alternateTouchProvider.isPresent) { - if (processedMotionEvent) { - biometricExecutor.execute { - alternateTouchProvider - .map(Provider::get) - .get() - .onPointerUp(requestId) - } - fgExecutor.execute { - if (keyguardUpdateMonitor.isFingerprintDetectionRunning) { - keyguardUpdateMonitor.onUdfpsPointerUp(requestId.toInt()) - } - } - } - - if (overlayView!!.isDisplayConfigured) { - overlayView!!.unconfigureDisplay() - } - - overlayView?.apply { - windowManager.removeView(this) - setOnTouchListener(null) - } - - isShowing = false - overlayView = null - processedMotionEvent = false - } - } - } - - @Override - override fun start() { - fingerprintManager?.addAuthenticatorsRegisteredCallback( - object : IFingerprintAuthenticatorsRegisteredCallback.Stub() { - override fun onAllAuthenticatorsRegistered( - sensors: List - ) { - handler.post { handleAllFingerprintAuthenticatorsRegistered(sensors) } - } - } - ) - - fingerprintManager?.setUdfpsOverlay( - object : IUdfpsOverlay.Stub() { - override fun show( - requestId: Long, - sensorId: Int, - @BiometricOverlayConstants.ShowReason reason: Int - ) = show(requestId) - - override fun hide(sensorId: Int) = hide() - } - ) - } - - private fun handleAllFingerprintAuthenticatorsRegistered( - sensors: List - ) { - for (props in sensors) { - if (props.isAnyUdfpsType) { - udfpsProps.add(props) - } - } - - // Setup param size - if (udfpsProps.isNotEmpty()) { - params = - UdfpsOverlayParams( - sensorBounds = udfpsProps[0].location.rect, - overlayBounds = Rect(0, size.height() / 2, size.width(), size.height()), - naturalDisplayWidth = size.width(), - naturalDisplayHeight = size.height(), - scaleFactor = 1f - ) - - val sensorX = params.sensorBounds.centerX() - val sensorY = params.sensorBounds.centerY() - val cornerOffset: Int = params.sensorBounds.width() / 4 - val sideOffset: Int = params.sensorBounds.width() / 3 - - points = - arrayOf( - Point(sensorX - cornerOffset, sensorY - cornerOffset), - Point(sensorX, sensorY - sideOffset), - Point(sensorX + cornerOffset, sensorY - cornerOffset), - Point(sensorX - sideOffset, sensorY), - Point(sensorX, sensorY), - Point(sensorX + sideOffset, sensorY), - Point(sensorX - cornerOffset, sensorY + cornerOffset), - Point(sensorX, sensorY + sideOffset), - Point(sensorX + cornerOffset, sensorY + cornerOffset) - ) - } - } -} diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsOverlayView.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsOverlayView.kt deleted file mode 100644 index 28ca41d166a8f..0000000000000 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsOverlayView.kt +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (C) 2022 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.graphics.Canvas -import android.graphics.Color -import android.graphics.Paint -import android.graphics.Point -import android.graphics.RectF -import android.util.AttributeSet -import android.view.MotionEvent -import android.widget.FrameLayout -import com.android.settingslib.udfps.UdfpsOverlayParams - -private const val TAG = "UdfpsOverlayView" -private const val POINT_SIZE = 10f - -class UdfpsOverlayView(context: Context, attrs: AttributeSet?) : FrameLayout(context, attrs) { - var overlayParams = UdfpsOverlayParams() - private var mUdfpsDisplayMode: UdfpsDisplayMode? = null - - var debugOverlay = false - - var overlayPaint = Paint() - var sensorPaint = Paint() - var touchPaint = Paint() - var pointPaint = Paint() - val centerPaint = Paint() - - var oval = RectF() - - /** True after the call to [configureDisplay] and before the call to [unconfigureDisplay]. */ - var isDisplayConfigured: Boolean = false - private set - - var touchX: Float = 0f - var touchY: Float = 0f - var touchMinor: Float = 0f - var touchMajor: Float = 0f - var touchOrientation: Double = 0.0 - - var sensorPoints: Array? = null - - init { - this.setWillNotDraw(false) - } - - override fun onAttachedToWindow() { - super.onAttachedToWindow() - - overlayPaint.color = Color.argb(100, 255, 0, 0) - overlayPaint.style = Paint.Style.FILL - - touchPaint.color = Color.argb(200, 255, 255, 255) - touchPaint.style = Paint.Style.FILL - - sensorPaint.color = Color.argb(150, 134, 204, 255) - sensorPaint.style = Paint.Style.FILL - - pointPaint.color = Color.WHITE - pointPaint.style = Paint.Style.FILL - } - - override fun onDraw(canvas: Canvas) { - super.onDraw(canvas) - - if (debugOverlay) { - // Draw overlay and sensor bounds - canvas.drawRect(overlayParams.overlayBounds, overlayPaint) - canvas.drawRect(overlayParams.sensorBounds, sensorPaint) - } - - // Draw sensor circle - canvas.drawCircle( - overlayParams.sensorBounds.exactCenterX(), - overlayParams.sensorBounds.exactCenterY(), - overlayParams.sensorBounds.width().toFloat() / 2, - centerPaint - ) - - if (debugOverlay) { - // Draw Points - sensorPoints?.forEach { - canvas.drawCircle(it.x.toFloat(), it.y.toFloat(), POINT_SIZE, pointPaint) - } - - // Draw touch oval - canvas.save() - canvas.rotate(Math.toDegrees(touchOrientation).toFloat(), touchX, touchY) - - oval.setEmpty() - oval.set( - touchX - touchMinor / 2, - touchY + touchMajor / 2, - touchX + touchMinor / 2, - touchY - touchMajor / 2 - ) - - canvas.drawOval(oval, touchPaint) - - // Draw center point - canvas.drawCircle(touchX, touchY, POINT_SIZE, centerPaint) - canvas.restore() - } - } - - fun setUdfpsDisplayMode(udfpsDisplayMode: UdfpsDisplayMode?) { - mUdfpsDisplayMode = udfpsDisplayMode - } - - fun configureDisplay(onDisplayConfigured: Runnable) { - isDisplayConfigured = true - mUdfpsDisplayMode?.enable(onDisplayConfigured) - } - - fun unconfigureDisplay() { - isDisplayConfigured = false - mUdfpsDisplayMode?.disable(null /* onDisabled */) - } - - fun processMotionEvent(event: MotionEvent) { - touchX = event.rawX - touchY = event.rawY - touchMinor = event.touchMinor - touchMajor = event.touchMajor - touchOrientation = event.orientation.toDouble() - } -} diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsShell.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsShell.kt index fca4cf9bf0826..e3dbcb5232585 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsShell.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsShell.kt @@ -50,8 +50,7 @@ private const val MAJOR = 10F */ @SysUISingleton class UdfpsShell @Inject constructor( - commandRegistry: CommandRegistry, - private val udfpsOverlay: UdfpsOverlay + commandRegistry: CommandRegistry ) : Command { /** @@ -69,10 +68,6 @@ class UdfpsShell @Inject constructor( override fun execute(pw: PrintWriter, args: List) { if (args.size == 1 && args[0] == "hide") { hideOverlay() - } else if (args.size == 2 && args[0] == "udfpsOverlay" && args[1] == "show") { - showUdfpsOverlay() - } else if (args.size == 2 && args[0] == "udfpsOverlay" && args[1] == "hide") { - hideUdfpsOverlay() } else if (args.size == 2 && args[0] == "show") { showOverlay(getEnrollmentReason(args[1])) } else if (args.size == 1 && args[0] == "onUiReady") { @@ -131,16 +126,6 @@ class UdfpsShell @Inject constructor( ) } - private fun showUdfpsOverlay() { - Log.v(TAG, "showUdfpsOverlay") - udfpsOverlay.show(REQUEST_ID) - } - - private fun hideUdfpsOverlay() { - Log.v(TAG, "hideUdfpsOverlay") - udfpsOverlay.hide() - } - private fun hideOverlay() { udfpsOverlayController?.hideUdfpsOverlay(SENSOR_ID) } diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt index b86d419f540f3..9bf6b2a5b42b4 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt +++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt @@ -25,7 +25,6 @@ import com.android.systemui.SliceBroadcastRelayHandler import com.android.systemui.accessibility.SystemActions import com.android.systemui.accessibility.WindowMagnification import com.android.systemui.biometrics.AuthController -import com.android.systemui.biometrics.UdfpsOverlay import com.android.systemui.clipboardoverlay.ClipboardListener import com.android.systemui.controls.dagger.StartControlsStartableModule import com.android.systemui.dagger.qualifiers.PerUser @@ -229,12 +228,6 @@ abstract class SystemUICoreStartableModule { @ClassKey(KeyguardLiftController::class) abstract fun bindKeyguardLiftController(sysui: KeyguardLiftController): CoreStartable - /** Inject into UdfpsOverlay. */ - @Binds - @IntoMap - @ClassKey(UdfpsOverlay::class) - abstract fun bindUdfpsOverlay(sysui: UdfpsOverlay): CoreStartable - /** Inject into MediaTttSenderCoordinator. */ @Binds @IntoMap diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsShellTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsShellTest.kt index 5c0924011259e..c2a129be66a4f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsShellTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsShellTest.kt @@ -49,7 +49,6 @@ class UdfpsShellTest : SysuiTestCase() { private lateinit var udfpsShell: UdfpsShell @Mock lateinit var commandRegistry: CommandRegistry - @Mock lateinit var udfpsOverlay: UdfpsOverlay @Mock lateinit var udfpsOverlayController: UdfpsOverlayController @Captor private lateinit var motionEvent: ArgumentCaptor @@ -60,7 +59,7 @@ class UdfpsShellTest : SysuiTestCase() { fun setup() { whenEver(udfpsOverlayController.sensorBounds).thenReturn(sensorBounds) - udfpsShell = UdfpsShell(commandRegistry, udfpsOverlay) + udfpsShell = UdfpsShell(commandRegistry) udfpsShell.udfpsOverlayController = udfpsOverlayController }