Merge "Ignore touches outside of Udfps Overlay bounds" into udc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
aee24a214f
@@ -36,6 +36,9 @@ data class UdfpsOverlayParams(
|
||||
/** Same as [sensorBounds], but in native resolution. */
|
||||
val nativeSensorBounds = Rect(sensorBounds).apply { scale(1f / scaleFactor) }
|
||||
|
||||
/** Same as [overlayBounds], but in native resolution. */
|
||||
val nativeOverlayBounds = Rect(overlayBounds).apply { scale(1f / scaleFactor) }
|
||||
|
||||
/** See [android.view.DisplayInfo.logicalWidth] */
|
||||
val logicalDisplayWidth =
|
||||
if (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270) {
|
||||
|
||||
@@ -636,7 +636,7 @@ public class UdfpsController implements DozeReceiver, Dumpable {
|
||||
mOverlay.getOverlayView().getViewRootImpl().getInputToken());
|
||||
}
|
||||
|
||||
return processedTouch.getTouchData().isWithinSensor(mOverlayParams.getNativeSensorBounds());
|
||||
return processedTouch.getTouchData().isWithinBounds(mOverlayParams.getNativeSensorBounds());
|
||||
}
|
||||
|
||||
private boolean oldOnTouch(long requestId, @NonNull MotionEvent event, boolean fromUdfpsView) {
|
||||
|
||||
@@ -22,6 +22,11 @@ import com.android.systemui.dagger.SysUISingleton
|
||||
/** Returns whether the touch coordinates are within the sensor's bounding box. */
|
||||
@SysUISingleton
|
||||
class BoundingBoxOverlapDetector : OverlapDetector {
|
||||
override fun isGoodOverlap(touchData: NormalizedTouchData, nativeSensorBounds: Rect): Boolean =
|
||||
touchData.isWithinSensor(nativeSensorBounds)
|
||||
override fun isGoodOverlap(
|
||||
touchData: NormalizedTouchData,
|
||||
nativeSensorBounds: Rect,
|
||||
nativeOverlayBounds: Rect,
|
||||
): Boolean =
|
||||
touchData.isWithinBounds(nativeOverlayBounds) &&
|
||||
touchData.isWithinBounds(nativeSensorBounds)
|
||||
}
|
||||
|
||||
@@ -30,8 +30,8 @@ private enum class SensorPixelPosition {
|
||||
TARGET // Pixel within sensor center target
|
||||
}
|
||||
|
||||
private val isDebug = true
|
||||
private val TAG = "EllipseOverlapDetector"
|
||||
private const val isDebug = false
|
||||
private const val TAG = "EllipseOverlapDetector"
|
||||
|
||||
/**
|
||||
* Approximates the touch as an ellipse and determines whether the ellipse has a sufficient overlap
|
||||
@@ -39,12 +39,21 @@ private val TAG = "EllipseOverlapDetector"
|
||||
*/
|
||||
@SysUISingleton
|
||||
class EllipseOverlapDetector(private val params: EllipseOverlapDetectorParams) : OverlapDetector {
|
||||
override fun isGoodOverlap(touchData: NormalizedTouchData, nativeSensorBounds: Rect): Boolean {
|
||||
// First, check if touch is within bounding box,
|
||||
if (nativeSensorBounds.contains(touchData.x.toInt(), touchData.y.toInt())) {
|
||||
override fun isGoodOverlap(
|
||||
touchData: NormalizedTouchData,
|
||||
nativeSensorBounds: Rect,
|
||||
nativeOverlayBounds: Rect,
|
||||
): Boolean {
|
||||
// First, check if touch is within bounding box to exit early
|
||||
if (touchData.isWithinBounds(nativeSensorBounds)) {
|
||||
return true
|
||||
}
|
||||
|
||||
// Check touch is within overlay bounds, not worth checking if outside
|
||||
if (!touchData.isWithinBounds(nativeOverlayBounds)) {
|
||||
return false
|
||||
}
|
||||
|
||||
var isTargetTouched = false
|
||||
var sensorPixels = 0
|
||||
var coveredPixels = 0
|
||||
@@ -77,7 +86,7 @@ class EllipseOverlapDetector(private val params: EllipseOverlapDetectorParams) :
|
||||
|
||||
val percentage: Float = coveredPixels.toFloat() / sensorPixels
|
||||
if (isDebug) {
|
||||
Log.v(
|
||||
Log.d(
|
||||
TAG,
|
||||
"covered: $coveredPixels, sensor: $sensorPixels, " +
|
||||
"percentage: $percentage, isCenterTouched: $isTargetTouched"
|
||||
|
||||
@@ -51,16 +51,16 @@ data class NormalizedTouchData(
|
||||
) {
|
||||
|
||||
/**
|
||||
* [nativeSensorBounds] contains the location and dimensions of the sensor area in native
|
||||
* resolution and natural orientation.
|
||||
* [nativeBounds] contains the location and dimensions of the area in native resolution and
|
||||
* natural orientation.
|
||||
*
|
||||
* Returns whether the coordinates of the given pointer are within the sensor's bounding box.
|
||||
* Returns whether the coordinates of the given pointer are within the bounding box.
|
||||
*/
|
||||
fun isWithinSensor(nativeSensorBounds: Rect): Boolean {
|
||||
return nativeSensorBounds.left <= x &&
|
||||
nativeSensorBounds.right >= x &&
|
||||
nativeSensorBounds.top <= y &&
|
||||
nativeSensorBounds.bottom >= y
|
||||
fun isWithinBounds(nativeBounds: Rect): Boolean {
|
||||
return nativeBounds.left <= x &&
|
||||
nativeBounds.right >= x &&
|
||||
nativeBounds.top <= y &&
|
||||
nativeBounds.bottom >= y
|
||||
}
|
||||
|
||||
@JvmOverloads
|
||||
|
||||
@@ -20,5 +20,9 @@ import android.graphics.Rect
|
||||
|
||||
/** Determines whether the touch has a sufficient overlap with the sensor. */
|
||||
interface OverlapDetector {
|
||||
fun isGoodOverlap(touchData: NormalizedTouchData, nativeSensorBounds: Rect): Boolean
|
||||
fun isGoodOverlap(
|
||||
touchData: NormalizedTouchData,
|
||||
nativeSensorBounds: Rect,
|
||||
nativeOverlayBounds: Rect
|
||||
): Boolean
|
||||
}
|
||||
|
||||
@@ -46,7 +46,13 @@ class SinglePointerTouchProcessor @Inject constructor(val overlapDetector: Overl
|
||||
val touchData = List(event.pointerCount) { event.normalize(it, overlayParams) }
|
||||
val pointersOnSensor =
|
||||
touchData
|
||||
.filter { overlapDetector.isGoodOverlap(it, overlayParams.nativeSensorBounds) }
|
||||
.filter {
|
||||
overlapDetector.isGoodOverlap(
|
||||
it,
|
||||
overlayParams.nativeSensorBounds,
|
||||
overlayParams.nativeOverlayBounds
|
||||
)
|
||||
}
|
||||
.map { it.pointerId }
|
||||
return PreprocessedTouch(touchData, previousPointerOnSensorId, pointersOnSensor)
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ class BoundingBoxOverlapDetectorTest(val testCase: TestCase) : SysuiTestCase() {
|
||||
@Test
|
||||
fun isGoodOverlap() {
|
||||
val touchData = TOUCH_DATA.copy(x = testCase.x.toFloat(), y = testCase.y.toFloat())
|
||||
val actual = underTest.isGoodOverlap(touchData, SENSOR)
|
||||
val actual = underTest.isGoodOverlap(touchData, SENSOR, OVERLAY)
|
||||
|
||||
assertThat(actual).isEqualTo(testCase.expected)
|
||||
}
|
||||
@@ -50,8 +50,10 @@ class BoundingBoxOverlapDetectorTest(val testCase: TestCase) : SysuiTestCase() {
|
||||
validYs = listOf(SENSOR.top, SENSOR.bottom, SENSOR.centerY())
|
||||
),
|
||||
genNegativeTestCases(
|
||||
invalidXs = listOf(SENSOR.left - 1, SENSOR.right + 1),
|
||||
invalidYs = listOf(SENSOR.top - 1, SENSOR.bottom + 1),
|
||||
invalidXs =
|
||||
listOf(SENSOR.left - 1, SENSOR.right + 1, OVERLAY.left, OVERLAY.right),
|
||||
invalidYs =
|
||||
listOf(SENSOR.top - 1, SENSOR.bottom + 1, OVERLAY.top, OVERLAY.bottom),
|
||||
validXs = listOf(SENSOR.left, SENSOR.right, SENSOR.centerX()),
|
||||
validYs = listOf(SENSOR.top, SENSOR.bottom, SENSOR.centerY())
|
||||
)
|
||||
@@ -82,6 +84,7 @@ private val TOUCH_DATA =
|
||||
)
|
||||
|
||||
private val SENSOR = Rect(100 /* left */, 200 /* top */, 300 /* right */, 500 /* bottom */)
|
||||
private val OVERLAY = Rect(0 /* left */, 100 /* top */, 400 /* right */, 600 /* bottom */)
|
||||
|
||||
private fun genTestCases(
|
||||
xs: List<Int>,
|
||||
|
||||
@@ -43,7 +43,7 @@ class EllipseOverlapDetectorTest(val testCase: TestCase) : SysuiTestCase() {
|
||||
minor = testCase.minor,
|
||||
major = testCase.major
|
||||
)
|
||||
val actual = underTest.isGoodOverlap(touchData, SENSOR)
|
||||
val actual = underTest.isGoodOverlap(touchData, SENSOR, OVERLAY)
|
||||
|
||||
assertThat(actual).isEqualTo(testCase.expected)
|
||||
}
|
||||
@@ -71,8 +71,10 @@ class EllipseOverlapDetectorTest(val testCase: TestCase) : SysuiTestCase() {
|
||||
expected = true
|
||||
),
|
||||
genNegativeTestCase(
|
||||
outerXs = listOf(SENSOR.left - 1, SENSOR.right + 1),
|
||||
outerYs = listOf(SENSOR.top - 1, SENSOR.bottom + 1),
|
||||
outerXs =
|
||||
listOf(SENSOR.left - 1, SENSOR.right + 1, OVERLAY.left, OVERLAY.right),
|
||||
outerYs =
|
||||
listOf(SENSOR.top - 1, SENSOR.bottom + 1, OVERLAY.top, OVERLAY.bottom),
|
||||
minor = 100f,
|
||||
major = 100f,
|
||||
expected = false
|
||||
@@ -104,6 +106,7 @@ private val TOUCH_DATA =
|
||||
)
|
||||
|
||||
private val SENSOR = Rect(100 /* left */, 200 /* top */, 300 /* right */, 400 /* bottom */)
|
||||
private val OVERLAY = Rect(0 /* left */, 100 /* top */, 400 /* right */, 600 /* bottom */)
|
||||
|
||||
private fun genPositiveTestCases(
|
||||
innerXs: List<Int>,
|
||||
|
||||
@@ -16,7 +16,7 @@ class NormalizedTouchDataTest(val testCase: TestCase) : SysuiTestCase() {
|
||||
@Test
|
||||
fun isWithinSensor() {
|
||||
val touchData = TOUCH_DATA.copy(x = testCase.x.toFloat(), y = testCase.y.toFloat())
|
||||
val actual = touchData.isWithinSensor(SENSOR)
|
||||
val actual = touchData.isWithinBounds(SENSOR)
|
||||
|
||||
assertThat(actual).isEqualTo(testCase.expected)
|
||||
}
|
||||
|
||||
@@ -21,7 +21,11 @@ import android.graphics.Rect
|
||||
class FakeOverlapDetector : OverlapDetector {
|
||||
var shouldReturn: Map<Int, Boolean> = mapOf()
|
||||
|
||||
override fun isGoodOverlap(touchData: NormalizedTouchData, nativeSensorBounds: Rect): Boolean {
|
||||
override fun isGoodOverlap(
|
||||
touchData: NormalizedTouchData,
|
||||
nativeSensorBounds: Rect,
|
||||
nativeOverlayBounds: Rect
|
||||
): Boolean {
|
||||
return shouldReturn[touchData.pointerId]
|
||||
?: error("Unexpected PointerId not declared in TestCase currentPointers")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user