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

Commit e4300edc authored by Beverly's avatar Beverly Committed by Android Build Coastguard Worker
Browse files

Inform the falsing manager about UDFPS touches on down

Instead of up/cancel. The new UDFPS touch handling doesn't
receive the up/cancel events until after the falsing manager
has already evaluated the touch as a false vs valid touch,
so UDFPS touches were penalizing the falsing confidence
too much.

Test: atest UdfpsControllerTest
Test: manually enable falsing logs and see that UDFPS touches
don't greatly increase the falsing confidence of the FalsingManager
(adb shell setprop log.tag.FalsingManager DEBUG)
Fixes: 288235975

(cherry picked from commit 061feddf)
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:bb97142670fbf85a9b8f1f2896f937d74fe88fff)
Merged-In: Ic4b8b0b52343d357e0c807bede64598836d159b0
Change-Id: Ic4b8b0b52343d357e0c807bede64598836d159b0
parent 2b1e90dd
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -589,6 +589,13 @@ public class UdfpsController implements DozeReceiver, Dumpable {

                // Pilfer if valid overlap, don't allow following events to reach keyguard
                shouldPilfer = true;

                // Touch is a valid UDFPS touch. Inform the falsing manager so that the touch
                // isn't counted against the falsing algorithm as an accidental touch.
                // We do this on the DOWN event instead of CANCEL/UP because the CANCEL/UP events
                // get sent too late to this receiver (after the actual cancel/up motions occur),
                // and therefore wouldn't end up being used as part of the falsing algo.
                mFalsingManager.isFalseTouch(UDFPS_AUTHENTICATION);
                break;

            case UP:
@@ -608,7 +615,6 @@ public class UdfpsController implements DozeReceiver, Dumpable {
                        data.getTime(),
                        data.getGestureStart(),
                        mStatusBarStateController.isDozing());
                mFalsingManager.isFalseTouch(UDFPS_AUTHENTICATION);
                break;

            case UNCHANGED:
+48 −21
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import static android.view.MotionEvent.ACTION_MOVE;
import static android.view.MotionEvent.ACTION_UP;

import static com.android.internal.util.FunctionalUtils.ThrowingConsumer;
import static com.android.systemui.classifier.Classifier.UDFPS_AUTHENTICATION;

import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
@@ -59,6 +60,7 @@ import android.os.PowerManager;
import android.os.RemoteException;
import android.os.VibrationAttributes;
import android.testing.TestableLooper.RunWithLooper;
import android.util.Pair;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.Surface;
@@ -1183,9 +1185,54 @@ public class UdfpsControllerTest extends SysuiTestCase {
        verify(mFingerprintManager).onPointerUp(anyLong(), anyInt());
    }

    @Test
    public void fingerDown_falsingManagerInformed() throws RemoteException {
        final Pair<TouchProcessorResult, TouchProcessorResult> touchProcessorResult =
                givenAcceptFingerDownEvent();

        // WHEN ACTION_DOWN is received
        when(mSinglePointerTouchProcessor.processTouch(any(), anyInt(), any())).thenReturn(
                touchProcessorResult.first);
        MotionEvent downEvent = MotionEvent.obtain(0, 0, ACTION_DOWN, 0, 0, 0);
        mTouchListenerCaptor.getValue().onTouch(mUdfpsView, downEvent);
        mBiometricExecutor.runAllReady();
        downEvent.recycle();

        // THEN falsing manager is informed of the touch
        verify(mFalsingManager).isFalseTouch(UDFPS_AUTHENTICATION);
    }

    @Test
    public void onTouch_withNewTouchDetection_shouldCallNewFingerprintManagerPath()
            throws RemoteException {
        final Pair<TouchProcessorResult, TouchProcessorResult> processorResultDownAndUp =
                givenAcceptFingerDownEvent();

        // WHEN ACTION_DOWN is received
        when(mSinglePointerTouchProcessor.processTouch(any(), anyInt(), any())).thenReturn(
                processorResultDownAndUp.first);
        MotionEvent downEvent = MotionEvent.obtain(0, 0, ACTION_DOWN, 0, 0, 0);
        mTouchListenerCaptor.getValue().onTouch(mUdfpsView, downEvent);
        mBiometricExecutor.runAllReady();
        downEvent.recycle();

        // AND ACTION_UP is received
        when(mSinglePointerTouchProcessor.processTouch(any(), anyInt(), any())).thenReturn(
                processorResultDownAndUp.second);
        MotionEvent upEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_UP, 0, 0, 0);
        mTouchListenerCaptor.getValue().onTouch(mUdfpsView, upEvent);
        mBiometricExecutor.runAllReady();
        upEvent.recycle();

        // THEN the new FingerprintManager path is invoked.
        verify(mFingerprintManager).onPointerDown(anyLong(), anyInt(), anyInt(), anyFloat(),
                anyFloat(), anyFloat(), anyFloat(), anyFloat(), anyLong(), anyLong(), anyBoolean());
        verify(mFingerprintManager).onPointerUp(anyLong(), anyInt(), anyInt(), anyFloat(),
                anyFloat(), anyFloat(), anyFloat(), anyFloat(), anyLong(), anyLong(), anyBoolean());
    }

    private Pair<TouchProcessorResult, TouchProcessorResult> givenAcceptFingerDownEvent()
            throws RemoteException {
        final NormalizedTouchData touchData = new NormalizedTouchData(0, 0f, 0f, 0f, 0f, 0f, 0L,
                0L);
        final TouchProcessorResult processorResultDown = new TouchProcessorResult.ProcessedTouch(
@@ -1211,27 +1258,7 @@ public class UdfpsControllerTest extends SysuiTestCase {

        verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture());

        // WHEN ACTION_DOWN is received
        when(mSinglePointerTouchProcessor.processTouch(any(), anyInt(), any())).thenReturn(
                processorResultDown);
        MotionEvent downEvent = MotionEvent.obtain(0, 0, ACTION_DOWN, 0, 0, 0);
        mTouchListenerCaptor.getValue().onTouch(mUdfpsView, downEvent);
        mBiometricExecutor.runAllReady();
        downEvent.recycle();

        // AND ACTION_UP is received
        when(mSinglePointerTouchProcessor.processTouch(any(), anyInt(), any())).thenReturn(
                processorResultUp);
        MotionEvent upEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_UP, 0, 0, 0);
        mTouchListenerCaptor.getValue().onTouch(mUdfpsView, upEvent);
        mBiometricExecutor.runAllReady();
        upEvent.recycle();

        // THEN the new FingerprintManager path is invoked.
        verify(mFingerprintManager).onPointerDown(anyLong(), anyInt(), anyInt(), anyFloat(),
                anyFloat(), anyFloat(), anyFloat(), anyFloat(), anyLong(), anyLong(), anyBoolean());
        verify(mFingerprintManager).onPointerUp(anyLong(), anyInt(), anyInt(), anyFloat(),
                anyFloat(), anyFloat(), anyFloat(), anyFloat(), anyLong(), anyLong(), anyBoolean());
        return new Pair<>(processorResultDown, processorResultUp);
    }

    @Test