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

Commit f3806ec8 authored by Lucas Silva's avatar Lucas Silva
Browse files

Revert "Fix ShadeTouchHandler over the lock screen"

This reverts commit 86fa77ab.

Bug: 340296594
Test: revert - exiting unit tests still pass
Flag: NONE
Change-Id: I01838cd3a72e945c3ff5dae07346d69078743ad6
parent 402f8f20
Loading
Loading
Loading
Loading
+38 −63
Original line number Diff line number Diff line
@@ -18,10 +18,8 @@ package com.android.systemui.ambient.touch;

import static com.google.common.truth.Truth.assertThat;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.view.GestureDetector;
import android.view.MotionEvent;
@@ -30,6 +28,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;

import com.android.systemui.SysuiTestCase;
import com.android.systemui.shade.ShadeViewController;
import com.android.systemui.shared.system.InputChannelCompat;
import com.android.systemui.statusbar.phone.CentralSurfaces;

@@ -37,7 +36,6 @@ import org.junit.Before;
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;
import org.mockito.MockitoAnnotations;
@@ -50,90 +48,67 @@ public class ShadeTouchHandlerTest extends SysuiTestCase {
    @Mock
    CentralSurfaces mCentralSurfaces;

    @Mock
    ShadeViewController mShadeViewController;

    @Mock
    TouchHandler.TouchSession mTouchSession;

    ShadeTouchHandler mTouchHandler;

    @Captor
    ArgumentCaptor<GestureDetector.OnGestureListener> mGestureListenerCaptor;
    @Captor
    ArgumentCaptor<InputChannelCompat.InputEventListener> mInputListenerCaptor;

    private static final int TOUCH_HEIGHT = 20;

    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);

        mTouchHandler = new ShadeTouchHandler(Optional.of(mCentralSurfaces), TOUCH_HEIGHT);
    }

    // Verifies that a swipe down in the gesture region is captured by the shade touch handler.
    @Test
    public void testSwipeDown_captured() {
        final boolean captured = swipe(Direction.DOWN);

        assertThat(captured).isTrue();
        mTouchHandler = new ShadeTouchHandler(Optional.of(mCentralSurfaces), mShadeViewController,
                TOUCH_HEIGHT);
    }

    // Verifies that a swipe in the upward direction is not catpured.
    /**
     * Verify that touches aren't handled when the bouncer is showing.
     */
    @Test
    public void testSwipeUp_notCaptured() {
        final boolean captured = swipe(Direction.UP);

        // Motion events not captured as the swipe is going in the wrong direction.
        assertThat(captured).isFalse();
    public void testInactiveOnBouncer() {
        when(mCentralSurfaces.isBouncerShowing()).thenReturn(true);
        mTouchHandler.onSessionStart(mTouchSession);
        verify(mTouchSession).pop();
    }

    // Verifies that a swipe down forwards captured touches to the shade window for handling.
    /**
     * Make sure {@link ShadeTouchHandler}
     */
    @Test
    public void testSwipeDown_sentToShadeWindow() {
        swipe(Direction.DOWN);
    public void testTouchPilferingOnScroll() {
        final MotionEvent motionEvent1 = Mockito.mock(MotionEvent.class);
        final MotionEvent motionEvent2 = Mockito.mock(MotionEvent.class);

        // Both motion events are sent for the shade window to process.
        verify(mCentralSurfaces, times(2)).handleExternalShadeWindowTouch(any());
    }
        final ArgumentCaptor<GestureDetector.OnGestureListener> gestureListenerArgumentCaptor =
                ArgumentCaptor.forClass(GestureDetector.OnGestureListener.class);

    // Verifies that a swipe down is not forwarded to the shade window.
    @Test
    public void testSwipeUp_touchesNotSent() {
        swipe(Direction.UP);
        mTouchHandler.onSessionStart(mTouchSession);
        verify(mTouchSession).registerGestureListener(gestureListenerArgumentCaptor.capture());

        // Motion events are not sent for the shade window to process as the swipe is going in the
        // wrong direction.
        verify(mCentralSurfaces, never()).handleExternalShadeWindowTouch(any());
        assertThat(gestureListenerArgumentCaptor.getValue()
                .onScroll(motionEvent1, motionEvent2, 1, 1))
                .isTrue();
    }

    /**
     * Simulates a swipe in the given direction and returns true if the touch was intercepted by the
     * touch handler's gesture listener.
     * <p>
     * Swipe down starts from a Y coordinate of 0 and goes downward. Swipe up starts from the edge
     * of the gesture region, {@link #TOUCH_HEIGHT}, and goes upward to 0.
     * Ensure touches are propagated to the {@link ShadeViewController}.
     */
    private boolean swipe(Direction direction) {
        Mockito.clearInvocations(mTouchSession);
        mTouchHandler.onSessionStart(mTouchSession);

        verify(mTouchSession).registerGestureListener(mGestureListenerCaptor.capture());
        verify(mTouchSession).registerInputListener(mInputListenerCaptor.capture());

        final float startY = direction == Direction.UP ? TOUCH_HEIGHT : 0;
        final float endY = direction == Direction.UP ? 0 : TOUCH_HEIGHT;
    @Test
    public void testEventPropagation() {
        final MotionEvent motionEvent = Mockito.mock(MotionEvent.class);

        // Send touches to the input and gesture listener.
        final MotionEvent event1 = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, 0, startY, 0);
        final MotionEvent event2 = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, 0, endY, 0);
        mInputListenerCaptor.getValue().onInputEvent(event1);
        mInputListenerCaptor.getValue().onInputEvent(event2);
        final boolean captured = mGestureListenerCaptor.getValue().onScroll(event1, event2, 0,
                startY - endY);
        final ArgumentCaptor<InputChannelCompat.InputEventListener>
                inputEventListenerArgumentCaptor =
                    ArgumentCaptor.forClass(InputChannelCompat.InputEventListener.class);

        return captured;
        mTouchHandler.onSessionStart(mTouchSession);
        verify(mTouchSession).registerInputListener(inputEventListenerArgumentCaptor.capture());
        inputEventListenerArgumentCaptor.getValue().onInputEvent(motionEvent);
        verify(mShadeViewController).handleExternalTouch(motionEvent);
    }

    private enum Direction {
        DOWN, UP,
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -108,7 +108,7 @@ public class CommunalTouchHandlerTest extends SysuiTestCase {
        mTouchHandler.onSessionStart(mTouchSession);
        verify(mTouchSession).registerInputListener(inputEventListenerArgumentCaptor.capture());
        inputEventListenerArgumentCaptor.getValue().onInputEvent(motionEvent);
        verify(mCentralSurfaces).handleExternalShadeWindowTouch(motionEvent);
        verify(mCentralSurfaces).handleDreamTouch(motionEvent);
    }

    @Test
+11 −27
Original line number Diff line number Diff line
@@ -23,8 +23,7 @@ import android.graphics.Region;
import android.view.GestureDetector;
import android.view.MotionEvent;

import androidx.annotation.NonNull;

import com.android.systemui.shade.ShadeViewController;
import com.android.systemui.statusbar.phone.CentralSurfaces;

import java.util.Optional;
@@ -38,34 +37,29 @@ import javax.inject.Named;
 */
public class ShadeTouchHandler implements TouchHandler {
    private final Optional<CentralSurfaces> mSurfaces;
    private final ShadeViewController mShadeViewController;
    private final int mInitiationHeight;

    /**
     * Tracks whether or not we are capturing a given touch. Will be null before and after a touch.
     */
    private Boolean mCapture;

    @Inject
    ShadeTouchHandler(Optional<CentralSurfaces> centralSurfaces,
            ShadeViewController shadeViewController,
            @Named(NOTIFICATION_SHADE_GESTURE_INITIATION_HEIGHT) int initiationHeight) {
        mSurfaces = centralSurfaces;
        mShadeViewController = shadeViewController;
        mInitiationHeight = initiationHeight;
    }

    @Override
    public void onSessionStart(TouchSession session) {
        if (mSurfaces.isEmpty()) {
        if (mSurfaces.map(CentralSurfaces::isBouncerShowing).orElse(false)) {
            session.pop();
            return;
        }

        session.registerCallback(() -> mCapture = null);

        session.registerInputListener(ev -> {
            mShadeViewController.handleExternalTouch((MotionEvent) ev);

            if (ev instanceof MotionEvent) {
                if (mCapture != null && mCapture) {
                    mSurfaces.get().handleExternalShadeWindowTouch((MotionEvent) ev);
                }
                if (((MotionEvent) ev).getAction() == MotionEvent.ACTION_UP) {
                    session.pop();
                }
@@ -74,25 +68,15 @@ public class ShadeTouchHandler implements TouchHandler {

        session.registerGestureListener(new GestureDetector.SimpleOnGestureListener() {
            @Override
            public boolean onScroll(MotionEvent e1, @NonNull MotionEvent e2, float distanceX,
            public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
                    float distanceY) {
                if (mCapture == null) {
                    // Only capture swipes that are going downwards.
                    mCapture = Math.abs(distanceY) > Math.abs(distanceX) && distanceY < 0;
                    if (mCapture) {
                        // Send the initial touches over, as the input listener has already
                        // processed these touches.
                        mSurfaces.get().handleExternalShadeWindowTouch(e1);
                        mSurfaces.get().handleExternalShadeWindowTouch(e2);
                    }
                }
                return mCapture;
                return true;
            }

            @Override
            public boolean onFling(MotionEvent e1, @NonNull MotionEvent e2, float velocityX,
            public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
                    float velocityY) {
                return mCapture;
                return true;
            }
        });
    }
+1 −1
Original line number Diff line number Diff line
@@ -98,7 +98,7 @@ public class CommunalTouchHandler implements TouchHandler {
        // Notification shade window has its own logic to be visible if the hub is open, no need to
        // do anything here other than send touch events over.
        session.registerInputListener(ev -> {
            surfaces.handleExternalShadeWindowTouch((MotionEvent) ev);
            surfaces.handleDreamTouch((MotionEvent) ev);
            if (ev != null && ((MotionEvent) ev).getAction() == MotionEvent.ACTION_UP) {
                var unused = session.pop();
            }
+2 −8
Original line number Diff line number Diff line
@@ -123,15 +123,9 @@ constructor(
    private var anyBouncerShowing = false

    /**
     * True if the shade is fully expanded and the user is not interacting with it anymore, meaning
     * the hub should not receive any touch input.
     * True if the shade is fully expanded, meaning the hub should not receive any touch input.
     *
     * We need to not pause the touch handling lifecycle as soon as the shade opens because if the
     * user swipes down, then back up without lifting their finger, the lifecycle will be paused
     * then resumed, and resuming force-stops all active touch sessions. This means the shade will
     * not receive the end of the gesture and will be stuck open.
     *
     * Based on [ShadeInteractor.isAnyFullyExpanded] and [ShadeInteractor.isUserInteracting].
     * Tracks [ShadeInteractor.isAnyFullyExpanded].
     */
    private var shadeShowing = false

Loading