Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9140a682 authored by Austin Delgado's avatar Austin Delgado
Browse files

Accept touches within sensor bounds during ellipse detection

Skip checking for valid ellipse overlap if touch is within the sensor.

Bug: 272200648
Test: atest SystemUITests:com.android.systemui.biometrics
Change-Id: Ice038530bc48b8722d7e8cbf223b86c85fc6b84c
parent f2ec83ae
Loading
Loading
Loading
Loading
+2 −28
Original line number Diff line number Diff line
@@ -22,9 +22,7 @@ import android.util.Log
import com.android.systemui.biometrics.EllipseOverlapDetectorParams
import com.android.systemui.dagger.SysUISingleton
import kotlin.math.cos
import kotlin.math.pow
import kotlin.math.sin
import kotlin.math.sqrt

private enum class SensorPixelPosition {
    OUTSIDE, // Pixel that falls outside of sensor circle
@@ -42,8 +40,8 @@ private val TAG = "EllipseOverlapDetector"
@SysUISingleton
class EllipseOverlapDetector(private val params: EllipseOverlapDetectorParams) : OverlapDetector {
    override fun isGoodOverlap(touchData: NormalizedTouchData, nativeSensorBounds: Rect): Boolean {
        // First, check if entire ellipse is within the sensor
        if (isEllipseWithinSensor(touchData, nativeSensorBounds)) {
        // First, check if touch is within bounding box,
        if (nativeSensorBounds.contains(touchData.x.toInt(), touchData.y.toInt())) {
            return true
        }

@@ -119,28 +117,4 @@ class EllipseOverlapDetector(private val params: EllipseOverlapDetectorParams) :

        return result <= 1
    }

    /** Returns whether the entire ellipse is contained within the sensor area */
    private fun isEllipseWithinSensor(
        touchData: NormalizedTouchData,
        nativeSensorBounds: Rect
    ): Boolean {
        val a2 = (touchData.minor / 2.0).pow(2.0)
        val b2 = (touchData.major / 2.0).pow(2.0)

        val sin2a = sin(touchData.orientation.toDouble()).pow(2.0)
        val cos2a = cos(touchData.orientation.toDouble()).pow(2.0)

        val cx = sqrt(a2 * cos2a + b2 * sin2a)
        val cy = sqrt(a2 * sin2a + b2 * cos2a)

        val ellipseRect =
            Rect(
                (-cx + touchData.x).toInt(),
                (-cy + touchData.y).toInt(),
                (cx + touchData.x).toInt(),
                (cy + touchData.y).toInt()
            )
        return nativeSensorBounds.contains(ellipseRect)
    }
}
+15 −5
Original line number Diff line number Diff line
@@ -61,7 +61,7 @@ class EllipseOverlapDetectorTest(val testCase: TestCase) : SysuiTestCase() {
        @JvmStatic
        fun data(): List<TestCase> =
            listOf(
                    genTestCases(
                    genPositiveTestCases(
                        innerXs = listOf(SENSOR.left, SENSOR.right, SENSOR.centerX()),
                        innerYs = listOf(SENSOR.top, SENSOR.bottom, SENSOR.centerY()),
                        outerXs = listOf(SENSOR.left - 1, SENSOR.right + 1),
@@ -70,9 +70,7 @@ class EllipseOverlapDetectorTest(val testCase: TestCase) : SysuiTestCase() {
                        major = 300f,
                        expected = true
                    ),
                    genTestCases(
                        innerXs = listOf(SENSOR.left, SENSOR.right),
                        innerYs = listOf(SENSOR.top, SENSOR.bottom),
                    genNegativeTestCase(
                        outerXs = listOf(SENSOR.left - 1, SENSOR.right + 1),
                        outerYs = listOf(SENSOR.top - 1, SENSOR.bottom + 1),
                        minor = 100f,
@@ -107,7 +105,7 @@ private val TOUCH_DATA =

private val SENSOR = Rect(100 /* left */, 200 /* top */, 300 /* right */, 400 /* bottom */)

private fun genTestCases(
private fun genPositiveTestCases(
    innerXs: List<Int>,
    innerYs: List<Int>,
    outerXs: List<Int>,
@@ -122,3 +120,15 @@ private fun genTestCases(
        }
    }
}

private fun genNegativeTestCase(
    outerXs: List<Int>,
    outerYs: List<Int>,
    minor: Float,
    major: Float,
    expected: Boolean
): List<EllipseOverlapDetectorTest.TestCase> {
    return outerXs.flatMap { x ->
        outerYs.map { y -> EllipseOverlapDetectorTest.TestCase(x, y, minor, major, expected) }
    }
}