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

Commit ca2fe46b authored by Austin Delgado's avatar Austin Delgado Committed by Android (Google) Code Review
Browse files

Merge "Add simFingerDown, simFingerUp, onUiReady to UdfpsShell"

parents 1e028209 5cfbe141
Loading
Loading
Loading
Loading
+25 −0
Original line number Diff line number Diff line
@@ -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);
            }
        }
    }

    /**
+69 −0
Original line number Diff line number Diff line
@@ -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)
    }
}
+92 −0
Original line number Diff line number Diff line
/*
 * 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())
    }
}