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

Commit 1dc81d2e authored by lbill's avatar lbill
Browse files

Fix Missing finger up event on UDFPS when the FPS triggered in AoD

When the device is woken up from AOD mode by a long press to
wake up gesture on the fingerprint sensor, FPS HAL set a flag.

This flag allows the kernel driver to track the finger's status and
notify the fingerprint driver when the finger is lifted from sensor.

HAL clear this flag each time the system registers the wake-up gesture.
Previous ag/28551525 change broke the behavor, and where the expected
immediatelyReRegister was always "false"

Flag: android.hardware.biometrics.screen_off_unlock_udfps
Fixes: 410686054
Bug: 373792870

Test: atest DozeSensorsTest
Test: manual disabled tap to wake, enabled AoD
Change-Id: I2e147d6f119a4ddbdc154b5b64d76a29691951af
parent bbedb4d2
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -250,7 +250,7 @@ public class DozeSensors {
                        true /* touchscreen */,
                        false /* ignoresSetting */,
                        dozeParameters.longPressUsesProx(),
                        screenOffUnlockUdfps() /* immediatelyReRegister */,
                        false /* immediatelyReRegister */,
                        !screenOffUnlockUdfps() /* requiresAod */
                ),
                new PluginSensor(
+77 −0
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ import android.app.ActivityManager;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.hardware.Sensor;
import android.hardware.TriggerEvent;
import android.hardware.display.AmbientDisplayConfiguration;
import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
@@ -510,6 +511,53 @@ public class DozeSensorsTest extends SysuiTestCase {
        }
    }

    @Test
    public void testUdfpsLongPress_doesNotImmediatelyReRegister() {
        // GIVEN: UDFPS long press sensor is configured and listening
        Sensor mockUdfpsSensor = mock(Sensor.class);
        int posture = DevicePostureController.DEVICE_POSTURE_UNKNOWN;
        TriggerSensor udfpsLongPressSensor = mDozeSensors.createUdfpsLongPressSensor(
                mockUdfpsSensor,
                /* configured */ true,
                /* immediatelyReRegister */ false // Simulate the config DozeSensors
        );
        udfpsLongPressSensor.setPosture(posture);
        mDozeSensors.addSensor(udfpsLongPressSensor);

        when(mSensorManager.requestTriggerSensor(eq(udfpsLongPressSensor), eq(mockUdfpsSensor)))
                .thenReturn(true);

        udfpsLongPressSensor.setListening(true);
        mTestableLooper.processAllMessages();

        verify(mSensorManager, times(1)).requestTriggerSensor(eq(udfpsLongPressSensor),
                eq(mockUdfpsSensor));
        assertTrue(udfpsLongPressSensor.mRegistered);

        TriggerEvent mockEvent = mock(TriggerEvent.class);
        float[] dummyValues = new float[]{-1f, -1f};

        try {
            Field valuesField = TriggerEvent.class.getField("values");
            valuesField.setAccessible(true);
            valuesField.set(mockEvent, dummyValues);
        } catch (NoSuchFieldException | IllegalAccessException e) {
            throw new RuntimeException("Failed to set final field 'values' via reflection", e);
        }

        mockEvent.sensor = mockUdfpsSensor;
        udfpsLongPressSensor.onTrigger(mockEvent);
        mTestableLooper.processAllMessages();

        // Using -1f, -1f based on the dummy values provided above.
        verify(mCallback).onSensorPulse(eq(REASON_SENSOR_UDFPS_LONG_PRESS), eq(-1f), eq(-1f),
                eq(mockEvent.values));
        assertFalse(udfpsLongPressSensor.mRegistered);

        verify(mSensorManager, times(1)).requestTriggerSensor(eq(udfpsLongPressSensor),
                eq(mockUdfpsSensor));
    }

    private class TestableDozeSensors extends DozeSensors {
        TestableDozeSensors() {
            super(mResources, mSensorManager, mDozeParameters,
@@ -600,6 +648,35 @@ public class DozeSensorsTest extends SysuiTestCase {
            );
        }

        /**
         * Creates a TriggerSensor specifically for UDFPS long press testing.
         */
        public TriggerSensor createUdfpsLongPressSensor(
                Sensor sensor,
                boolean configured,
                boolean immediatelyReRegister) {

            // Assume prox/AOD requirements are false for simplicity unless explicitly tested
            // Or: mDozeParameters.longPressUsesProx();
            boolean requiresProx = false;
            // Or: !mAmbientDisplayConfiguration.screenOffUdfpsEnabled(anyInt());
            boolean requiresAod = false;

            return new TriggerSensor(new Sensor[]{sensor},
                    /* setting name */ "doze_pulse_on_auth", // KEY_DOZE_PULSE_ON_AUTH
                    /* settingDefault */ true,
                    /* configured */ configured,
                    /* pulseReason*/ REASON_SENSOR_UDFPS_LONG_PRESS,
                    /* reportsTouchCoordinate*/ true,
                    /* requiresTouchscreen */ true,
                    /* ignoresSetting */ false,
                    /* requiresProx */ requiresProx,
                    /* immediatelyReRegister */ immediatelyReRegister,
                    /* posture */ DevicePostureController.DEVICE_POSTURE_UNKNOWN, // Default posture
                    /* requiresAod */ requiresAod
            );
        }

        public void addSensor(TriggerSensor sensor) {
            TriggerSensor[] newArray = new TriggerSensor[mTriggerSensors.length + 1];
            for (int i = 0; i < mTriggerSensors.length; i++) {