Merge "Remove unused UdfpsOverlay and UdfpsOverlay View" into udc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
c46d48e7b2
@@ -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)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user