Merge "Add simFingerDown, simFingerUp, onUiReady to UdfpsShell"

This commit is contained in:
Austin Delgado
2022-11-02 17:15:25 +00:00
committed by Android (Google) Code Review
3 changed files with 186 additions and 0 deletions

View File

@@ -30,6 +30,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Point;
import android.graphics.Rect;
import android.hardware.biometrics.BiometricFingerprintConstants;
import android.hardware.display.DisplayManager;
import android.hardware.fingerprint.FingerprintManager;
@@ -299,6 +300,30 @@ public class UdfpsController implements DozeReceiver {
mOverlay.getOverlayView().setDebugMessage(message);
});
}
public Rect getSensorBounds() {
return mOverlayParams.getSensorBounds();
}
/**
* Passes a mocked MotionEvent to OnTouch.
*
* @param event MotionEvent to simulate in onTouch
*/
public void debugOnTouch(long requestId, MotionEvent event) {
UdfpsController.this.onTouch(requestId, event, false);
}
/**
* Debug to run onUiReady
*/
public void debugOnUiReady(long requestId, int sensorId) {
if (UdfpsController.this.mAlternateTouchProvider != null) {
UdfpsController.this.mAlternateTouchProvider.onUiReady();
} else {
UdfpsController.this.mFingerprintManager.onUiReady(requestId, sensorId);
}
}
}
/**

View File

@@ -17,6 +17,7 @@
package com.android.systemui.biometrics
import android.content.Context
import android.graphics.Rect
import android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_BP
import android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_KEYGUARD
import android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_OTHER
@@ -27,6 +28,11 @@ import android.hardware.biometrics.BiometricOverlayConstants.REASON_UNKNOWN
import android.hardware.fingerprint.IUdfpsOverlayControllerCallback
import android.util.Log
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.MotionEvent.ACTION_DOWN
import android.view.MotionEvent.ACTION_MOVE
import android.view.MotionEvent.ACTION_UP
import com.android.internal.annotations.VisibleForTesting
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.statusbar.commandline.Command
import com.android.systemui.statusbar.commandline.CommandRegistry
@@ -36,6 +42,8 @@ import javax.inject.Inject
private const val TAG = "UdfpsShell"
private const val REQUEST_ID = 2L
private const val SENSOR_ID = 0
private const val MINOR = 10F
private const val MAJOR = 10F
/**
* Used to show and hide the UDFPS overlay with statusbar commands.
@@ -67,6 +75,12 @@ class UdfpsShell @Inject constructor(
hideUdfpsOverlay()
} else if (args.size == 2 && args[0] == "show") {
showOverlay(getEnrollmentReason(args[1]))
} else if (args.size == 1 && args[0] == "onUiReady") {
onUiReady()
} else if (args.size == 1 && args[0] == "simFingerDown") {
simFingerDown()
} else if (args.size == 1 && args[0] == "simFingerUp") {
simFingerUp()
} else {
invalidCommand(pw)
}
@@ -80,6 +94,11 @@ class UdfpsShell @Inject constructor(
"auth-keyguard, auth-other, auth-settings]")
pw.println(" -> reason otherwise defaults to unknown")
pw.println(" - hide")
pw.println(" - onUiReady")
pw.println(" - simFingerDown")
pw.println(" -> Simulates onFingerDown on sensor")
pw.println(" - simFingerUp")
pw.println(" -> Simulates onFingerUp on sensor")
}
private fun invalidCommand(pw: PrintWriter) {
@@ -125,4 +144,54 @@ class UdfpsShell @Inject constructor(
private fun hideOverlay() {
udfpsOverlayController?.hideUdfpsOverlay(SENSOR_ID)
}
@VisibleForTesting
fun onUiReady() {
udfpsOverlayController?.debugOnUiReady(REQUEST_ID, SENSOR_ID)
}
@VisibleForTesting
fun simFingerDown() {
val sensorBounds: Rect = udfpsOverlayController!!.sensorBounds
val downEvent: MotionEvent? = obtainMotionEvent(ACTION_DOWN, sensorBounds.exactCenterX(),
sensorBounds.exactCenterY(), MINOR, MAJOR)
udfpsOverlayController?.debugOnTouch(REQUEST_ID, downEvent)
val moveEvent: MotionEvent? = obtainMotionEvent(ACTION_MOVE, sensorBounds.exactCenterX(),
sensorBounds.exactCenterY(), MINOR, MAJOR)
udfpsOverlayController?.debugOnTouch(REQUEST_ID, moveEvent)
downEvent?.recycle()
moveEvent?.recycle()
}
@VisibleForTesting
fun simFingerUp() {
val sensorBounds: Rect = udfpsOverlayController!!.sensorBounds
val upEvent: MotionEvent? = obtainMotionEvent(ACTION_UP, sensorBounds.exactCenterX(),
sensorBounds.exactCenterY(), MINOR, MAJOR)
udfpsOverlayController?.debugOnTouch(REQUEST_ID, upEvent)
upEvent?.recycle()
}
private fun obtainMotionEvent(
action: Int,
x: Float,
y: Float,
minor: Float,
major: Float
): MotionEvent? {
val pp = MotionEvent.PointerProperties()
pp.id = 1
val pc = MotionEvent.PointerCoords()
pc.x = x
pc.y = y
pc.touchMinor = minor
pc.touchMajor = major
return MotionEvent.obtain(0, 0, action, 1, arrayOf(pp), arrayOf(pc),
0, 0, 1f, 1f, 0, 0, 0, 0)
}
}

View File

@@ -0,0 +1,92 @@
/*
* Copyright (C) 2021 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.graphics.Rect
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import android.view.MotionEvent
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.biometrics.UdfpsController.UdfpsOverlayController
import com.android.systemui.statusbar.commandline.CommandRegistry
import com.android.systemui.util.mockito.any
import junit.framework.Assert.assertEquals
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentCaptor
import org.mockito.Captor
import org.mockito.Mock
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
import org.mockito.Mockito.`when` as whenEver
import org.mockito.junit.MockitoJUnit
@SmallTest
@RunWith(AndroidTestingRunner::class)
@TestableLooper.RunWithLooper
class UdfpsShellTest : SysuiTestCase() {
@JvmField @Rule var rule = MockitoJUnit.rule()
// Unit under test
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>
private val sensorBounds = Rect()
@Before
fun setup() {
whenEver(udfpsOverlayController.sensorBounds).thenReturn(sensorBounds)
udfpsShell = UdfpsShell(commandRegistry, udfpsOverlay)
udfpsShell.udfpsOverlayController = udfpsOverlayController
}
@Test
fun testSimFingerDown() {
udfpsShell.simFingerDown()
verify(udfpsOverlayController, times(2)).debugOnTouch(any(), motionEvent.capture())
assertEquals(motionEvent.allValues[0].action, MotionEvent.ACTION_DOWN) // ACTION_MOVE
assertEquals(motionEvent.allValues[1].action, MotionEvent.ACTION_MOVE) // ACTION_MOVE
}
@Test
fun testSimFingerUp() {
udfpsShell.simFingerUp()
verify(udfpsOverlayController).debugOnTouch(any(), motionEvent.capture())
assertEquals(motionEvent.value.action, MotionEvent.ACTION_UP)
}
@Test
fun testOnUiReady() {
udfpsShell.onUiReady()
verify(udfpsOverlayController).debugOnUiReady(any(), any())
}
}