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

Commit 3cc1b9f8 authored by Austin Delgado's avatar Austin Delgado
Browse files

RESTRICT AUTOMERGE Fix BP shouldPauseAuth when pulling down notification shade

Test: atest UdfpsBpViewControllerTest
Bug: 299589449
Change-Id: I501fc6ecd9285428047d285e3974918c0bd13d71
parent 2cc81371
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -58,6 +58,7 @@ abstract class UdfpsAnimationViewController<T : UdfpsAnimationView>(
        // Notification shade can be expanded but not visible (fraction: 0.0), for example
        // when a heads-up notification (HUN) is showing.
        notificationShadeVisible = event.expanded && event.fraction > 0f
        notificationShadeTracking = event.tracking
        view.onExpansionChanged(event.fraction)
        updatePauseAuth()
    }
@@ -65,6 +66,9 @@ abstract class UdfpsAnimationViewController<T : UdfpsAnimationView>(
    /** If the notification shade is visible. */
    var notificationShadeVisible: Boolean = false

    /** If the notification shade is currently being dragged */
    var notificationShadeTracking: Boolean = false

    /**
     * The amount of translation needed if the view currently requires the user to touch
     * somewhere other than the exact center of the sensor. For example, this can happen
+8 −1
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
 */
package com.android.systemui.biometrics

import com.android.internal.annotations.VisibleForTesting
import com.android.systemui.dump.DumpManager
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.shade.ShadeExpansionStateManager
@@ -39,6 +40,12 @@ class UdfpsBpViewController(
    override val tag = "UdfpsBpViewController"

    override fun shouldPauseAuth(): Boolean {
        return false
        // Do not auth while notification shade is being dragged
        return notificationShadeTracking
    }

    @VisibleForTesting
    public override fun onViewAttached() {
        super.onViewAttached()
    }
}
+6 −2
Original line number Diff line number Diff line
@@ -549,8 +549,12 @@ public class UdfpsController implements DozeReceiver, Dumpable {
            Log.e(TAG, "ignoring the touch injected from outside of UdfpsView");
            return false;
        }
        if (mOverlay == null) {
            Log.w(TAG, "ignoring onTouch with null overlay");
        if (mOverlay == null || mOverlay.getAnimationViewController() == null) {
            Log.w(TAG, "ignoring onTouch with null overlay or animation view controller");
            return false;
        }
        if (mOverlay.getAnimationViewController().shouldPauseAuth()) {
            Log.w(TAG, "ignoring onTouch with shouldPauseAuth = true");
            return false;
        }
        if (!mOverlay.matchesRequestId(requestId)) {
+33 −1
Original line number Diff line number Diff line
@@ -23,14 +23,19 @@ import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.dump.DumpManager
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.shade.ShadeExpansionChangeEvent
import com.android.systemui.shade.ShadeExpansionStateManager
import com.android.systemui.statusbar.phone.SystemUIDialogManager
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.whenever
import com.android.systemui.util.mockito.withArgCaptor
import org.junit.Assert.assertFalse
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.Mockito.verify
import org.mockito.junit.MockitoJUnit

@SmallTest
@@ -51,6 +56,8 @@ class UdfpsBpViewControllerTest : SysuiTestCase() {

    @Before
    fun setup() {
        whenever(shadeExpansionStateManager.addExpansionListener(any()))
            .thenReturn(ShadeExpansionChangeEvent(0f, false, false, 0f))
        udfpsBpViewController =
            UdfpsBpViewController(
                udfpsBpView,
@@ -62,7 +69,32 @@ class UdfpsBpViewControllerTest : SysuiTestCase() {
    }

    @Test
    fun testShouldNeverPauseAuth() {
    fun testPauseAuthWhenNotificationShadeDragging() {
        udfpsBpViewController.onViewAttached()
        val shadeExpansionListener = withArgCaptor {
            verify(shadeExpansionStateManager).addExpansionListener(capture())
        }

        // When shade is tracking, should pause auth
        shadeExpansionListener.onPanelExpansionChanged(
            ShadeExpansionChangeEvent(
                fraction = 0f,
                expanded = false,
                tracking = true,
                dragDownPxAmount = 10f
            )
        )
        assert(udfpsBpViewController.shouldPauseAuth())

        // When shade is not tracking, don't pause auth even if expanded
        shadeExpansionListener.onPanelExpansionChanged(
            ShadeExpansionChangeEvent(
                fraction = 0f,
                expanded = true,
                tracking = false,
                dragDownPxAmount = 10f
            )
        )
        assertFalse(udfpsBpViewController.shouldPauseAuth())
    }
}
+47 −0
Original line number Diff line number Diff line
@@ -207,6 +207,8 @@ public class UdfpsControllerTest extends SysuiTestCase {
    private final UdfpsAnimationViewController mUdfpsKeyguardViewController =
            mock(UdfpsKeyguardViewControllerLegacy.class);
    @Mock
    private UdfpsAnimationViewController mUdfpsAnimationViewController;
    @Mock
    private SystemUIDialogManager mSystemUIDialogManager;
    @Mock
    private ActivityLaunchAnimator mActivityLaunchAnimator;
@@ -267,6 +269,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
        when(mSessionTracker.getSessionId(anyInt())).thenReturn(
                (new InstanceIdSequence(1 << 20)).newInstanceId());
        when(mUdfpsView.getViewRootImpl()).thenReturn(mViewRootImpl);
        when(mUdfpsView.getAnimationViewController()).thenReturn(mUdfpsAnimationViewController);

        final List<ComponentInfoInternal> componentInfo = new ArrayList<>();
        componentInfo.add(new ComponentInfoInternal("faceSensor" /* componentId */,
@@ -1379,6 +1382,50 @@ public class UdfpsControllerTest extends SysuiTestCase {
        downEvent.recycle();
    }

    @Test
    public void onTouch_withNewTouchDetection_ignoreIfAuthPaused() throws RemoteException {
        final NormalizedTouchData touchData = new NormalizedTouchData(0, 0f, 0f, 0f, 0f, 0f, 0L,
                0L);
        final TouchProcessorResult processorResultDown =
                new TouchProcessorResult.ProcessedTouch(InteractionEvent.DOWN,
                        1 /* pointerId */, touchData);

        // Enable new touch detection.
        when(mFeatureFlags.isEnabled(Flags.UDFPS_NEW_TOUCH_DETECTION)).thenReturn(true);

        // Configure UdfpsController to use FingerprintManager as opposed to AlternateTouchProvider.
        initUdfpsController(mOpticalProps, false /* hasAlternateTouchProvider */);

        // Configure UdfpsView to not accept the ACTION_DOWN event
        when(mUdfpsView.isDisplayConfigured()).thenReturn(true);
        when(mUdfpsView.isWithinSensorArea(anyFloat(), anyFloat())).thenReturn(true);

        // GIVEN that auth is paused
        when(mUdfpsAnimationViewController.shouldPauseAuth()).thenReturn(true);

        // GIVEN that the overlay is showing and a11y touch exploration NOT enabled
        when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(false);
        mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, mOpticalProps.sensorId,
                BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback);
        mFgExecutor.runAllReady();

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

        // WHEN ACTION_DOWN is received and touch is within sensor
        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();

        // THEN the touch is ignored
        verify(mInputManager, never()).pilferPointers(any());
        verify(mFingerprintManager, never()).onPointerDown(anyLong(), anyInt(), anyInt(),
                anyFloat(), anyFloat(), anyFloat(), anyFloat(), anyFloat(), anyLong(), anyLong(),
                anyBoolean());
    }

    @Test
    public void onTouch_withNewTouchDetection_pilferPointer() throws RemoteException {
        final NormalizedTouchData touchData = new NormalizedTouchData(0, 0f, 0f, 0f, 0f, 0f, 0L,