Merge "Remove unused UdfpsOverlay and UdfpsOverlay View" into udc-dev am: c46d48e7b2 am: 7254af180c

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/22189362

Change-Id: I5b4f6d22aae4d4f5f598898341293acb13f435d9
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Austin Delgado
2023-03-23 03:09:41 +00:00
committed by Automerger Merge Worker
5 changed files with 2 additions and 513 deletions

View File

@@ -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<Provider<AlternateUdfpsTouchProvider>>,
@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<FingerprintSensorPropertiesInternal> = mutableListOf()
var points: Array<Point> = 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<AlternateUdfpsTouchProvider>::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<AlternateUdfpsTouchProvider>::get)
.get()
.onUiReady()
}
}
processedMotionEvent = true
}
}
view.invalidate()
}
true
}
MotionEvent.ACTION_UP,
MotionEvent.ACTION_CANCEL -> {
if (processedMotionEvent && alternateTouchProvider.isPresent) {
biometricExecutor.execute {
alternateTouchProvider
.map(Provider<AlternateUdfpsTouchProvider>::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<AlternateUdfpsTouchProvider>::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<FingerprintSensorPropertiesInternal>
) {
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<FingerprintSensorPropertiesInternal>
) {
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)
)
}
}
}

View File

@@ -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<Point>? = 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()
}
}

View File

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

View File

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

View File

@@ -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<MotionEvent>
@@ -60,7 +59,7 @@ class UdfpsShellTest : SysuiTestCase() {
fun setup() {
whenEver(udfpsOverlayController.sensorBounds).thenReturn(sensorBounds)
udfpsShell = UdfpsShell(commandRegistry, udfpsOverlay)
udfpsShell = UdfpsShell(commandRegistry)
udfpsShell.udfpsOverlayController = udfpsOverlayController
}