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

Commit b5cc1567 authored by Matt Pietal's avatar Matt Pietal Committed by Android (Google) Code Review
Browse files

Merge "Intercept swipe up touches" into main

parents f751c394 ad03d308
Loading
Loading
Loading
Loading
+38 −3
Original line number Diff line number Diff line
@@ -586,6 +586,8 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
    private boolean mGestureWaitForTouchSlop;
    private boolean mIgnoreXTouchSlop;
    private boolean mExpandLatencyTracking;
    private boolean mUseExternalTouch = false;

    /**
     * Whether we're waking up and will play the delayed doze animation in
     * {@link NotificationWakeUpCoordinator}. If so, we'll want to keep the clock centered until the
@@ -4114,12 +4116,22 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump

    /** Sends an external (e.g. Status Bar) intercept touch event to the Shade touch handler. */
    boolean handleExternalInterceptTouch(MotionEvent event) {
        try {
            mUseExternalTouch = true;
            return mTouchHandler.onInterceptTouchEvent(event);
        } finally {
            mUseExternalTouch = false;
        }
    }

    @Override
    public boolean handleExternalTouch(MotionEvent event) {
        try {
            mUseExternalTouch = true;
            return mTouchHandler.onTouchEvent(event);
        } finally {
            mUseExternalTouch = false;
        }
    }

    @Override
@@ -4706,9 +4718,20 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
    public final class TouchHandler implements View.OnTouchListener, Gefingerpoken {
        private long mLastTouchDownTime = -1L;

        /** @see ViewGroup#onInterceptTouchEvent(MotionEvent) */
        /**
         * With the shade and lockscreen being separated in the view hierarchy, touch handling now
         * originates with the parent window through {@link #handleExternalTouch}. This allows for
         * parity with the legacy hierarchy while not undertaking a massive refactoring of touch
         * handling.
         *
         * @see NotificationShadeWindowViewController#didNotificationPanelInterceptEvent
         */
        @Override
        public boolean onInterceptTouchEvent(MotionEvent event) {
            if (mFeatureFlags.isEnabled(Flags.MIGRATE_NSSL) && !mUseExternalTouch) {
                return false;
            }

            mShadeLog.logMotionEvent(event, "NPVC onInterceptTouchEvent");
            if (mQsController.disallowTouches()) {
                mShadeLog.logMotionEvent(event,
@@ -4861,8 +4884,20 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
            return onTouchEvent(event);
        }

        /**
         * With the shade and lockscreen being separated in the view hierarchy, touch handling now
         * originates with the parent window through {@link #handleExternalTouch}. This allows for
         * parity with the legacy hierarchy while not undertaking a massive refactoring of touch
         * handling.
         *
         * @see NotificationShadeWindowViewController#didNotificationPanelInterceptEvent
         */
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            if (mFeatureFlags.isEnabled(Flags.MIGRATE_NSSL) && !mUseExternalTouch) {
                return false;
            }

            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                if (event.getDownTime() == mLastTouchDownTime) {
                    // An issue can occur when swiping down after unlock, where multiple down
+72 −20
Original line number Diff line number Diff line
@@ -267,6 +267,9 @@ public class NotificationShadeWindowViewController implements Dumpable {
        }
        mView.setLayoutInsetsController(mNotificationInsetsController);
        mView.setInteractionEventHandler(new NotificationShadeWindowView.InteractionEventHandler() {
            boolean mUseDragDownHelperForTouch = false;
            boolean mLastInterceptWasDragDownHelper = false;

            @Override
            public Boolean handleDispatchTouchEvent(MotionEvent ev) {
                if (mStatusBarViewController == null) { // Fix for b/192490822
@@ -360,10 +363,8 @@ public class NotificationShadeWindowViewController implements Dumpable {
                );

                // In case we start outside of the view bounds (below the status bar), we need to
                // dispatch
                // the touch manually as the view system can't accommodate for touches outside of
                // the
                // regular view bounds.
                // dispatch the touch manually as the view system can't accommodate for touches
                // outside of the regular view bounds.
                if (isDown && ev.getY() >= mView.getBottom()) {
                    mExpandingBelowNotch = true;
                    expandingBelowNotch = true;
@@ -405,6 +406,15 @@ public class NotificationShadeWindowViewController implements Dumpable {

            @Override
            public boolean shouldInterceptTouchEvent(MotionEvent ev) {
                boolean intercepted = shouldInterceptTouchEventInternal(ev);
                if (intercepted) {
                    mUseDragDownHelperForTouch = mLastInterceptWasDragDownHelper;
                }
                return intercepted;
            }

            private boolean shouldInterceptTouchEventInternal(MotionEvent ev) {
                mLastInterceptWasDragDownHelper = false;
                if (mStatusBarStateController.isDozing() && !mDozeServiceHost.isPulsing()
                        && !mDockManager.isDocked()) {
                    if (ev.getAction() == MotionEvent.ACTION_DOWN) {
@@ -431,27 +441,46 @@ public class NotificationShadeWindowViewController implements Dumpable {
                }

                if (mNotificationPanelViewController.isFullyExpanded()
                        && mDragDownHelper.isDragDownEnabled()
                        && !mService.isBouncerShowing()
                        && !mStatusBarStateController.isDozing()) {
                    if (mDragDownHelper.isDragDownEnabled()) {
                        // This handles drag down over lockscreen
                        boolean result = mDragDownHelper.onInterceptTouchEvent(ev);
                        if (mFeatureFlags.isEnabled(Flags.MIGRATE_NSSL)) {
                            if (result) {
                                mLastInterceptWasDragDownHelper = true;
                                if (ev.getAction() == MotionEvent.ACTION_DOWN) {
                                    mShadeLogger.d("NSWVC: drag down helper intercepted");
                                }
                            } else if (didNotificationPanelInterceptEvent(ev)) {
                                return true;
                            }
                        } else {
                            if (result) {
                                if (ev.getAction() == MotionEvent.ACTION_DOWN) {
                                    mShadeLogger.d("NSWVC: drag down helper intercepted");
                                }
                            }
                        }
                        return result;
                    } else {
                    return false;
                        // This else handles interactions on the full shade while unlocked
                        if (didNotificationPanelInterceptEvent(ev)) {
                            return true;
                        }
                    }
                }
                return false;
            }

            @Override
            public void didIntercept(MotionEvent ev) {
                MotionEvent cancellation = MotionEvent.obtain(ev);
                cancellation.setAction(MotionEvent.ACTION_CANCEL);
                mStackScrollLayout.onInterceptTouchEvent(cancellation);
                if (!mFeatureFlags.isEnabled(Flags.MIGRATE_NSSL)) {
                    mNotificationPanelViewController.handleExternalInterceptTouch(cancellation);
                }
                cancellation.recycle();
            }

@@ -461,11 +490,18 @@ public class NotificationShadeWindowViewController implements Dumpable {
                if (mStatusBarStateController.isDozing()) {
                    handled = !mDozeServiceHost.isPulsing();
                }

                if (mStatusBarKeyguardViewManager.onTouch(ev)) {
                    return true;
                }

                if (mFeatureFlags.isEnabled(Flags.MIGRATE_NSSL)) {
                    if (mLastInterceptWasDragDownHelper && (mDragDownHelper.isDraggingDown())) {
                        // we still want to finish our drag down gesture when locking the screen
                        handled |= mDragDownHelper.onTouchEvent(ev) || handled;
                    }
                    if (!handled && mNotificationPanelViewController.handleExternalTouch(ev)) {
                        return true;
                    }
                } else {
                    if (mDragDownHelper.isDragDownEnabled()
                            || mDragDownHelper.isDraggingDown()) {
                        // we still want to finish our drag down gesture when locking the screen
@@ -474,6 +510,8 @@ public class NotificationShadeWindowViewController implements Dumpable {
                        return handled;
                    }
                }
                return handled;
            }

            @Override
            public void didNotHandleTouchEvent(MotionEvent ev) {
@@ -520,6 +558,20 @@ public class NotificationShadeWindowViewController implements Dumpable {
        mDepthController.onPanelExpansionChanged(currentState);
    }

    private boolean didNotificationPanelInterceptEvent(MotionEvent ev) {
        if (mFeatureFlags.isEnabled(Flags.MIGRATE_NSSL)) {
            // Since NotificationStackScrollLayout is now a sibling of notification_panel, we need
            // to also ask NotificationPanelViewController directly, in order to process swipe up
            // events originating from notifications
            if (mNotificationPanelViewController.handleExternalInterceptTouch(ev)) {
                mShadeLogger.d("NSWVC: NPVC intercepted");
                return true;
            }
        }

        return false;
    }

    public NotificationShadeWindowView getView() {
        return mView;
    }
+7 −2
Original line number Diff line number Diff line
@@ -70,6 +70,7 @@ import com.android.systemui.classifier.Classifier;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.flags.Flags;
import com.android.systemui.fragments.FragmentHostManager;
import com.android.systemui.keyguard.domain.interactor.KeyguardFaceAuthInteractor;
import com.android.systemui.media.controls.pipeline.MediaDataManager;
@@ -1776,8 +1777,10 @@ public class QuickSettingsController implements Dumpable {
                    // Dragging down on the lockscreen statusbar should prohibit other interactions
                    // immediately, otherwise we'll wait on the touchslop. This is to allow
                    // dragging down to expanded quick settings directly on the lockscreen.
                    if (!mFeatureFlags.isEnabled(Flags.MIGRATE_NSSL)) {
                        mPanelView.getParent().requestDisallowInterceptTouchEvent(true);
                    }
                }
                if (mExpansionAnimator != null) {
                    mInitialHeightOnTouch = mExpansionHeight;
                    mShadeLog.logMotionEvent(event,
@@ -1819,7 +1822,9 @@ public class QuickSettingsController implements Dumpable {
                        && Math.abs(h) > Math.abs(x - mInitialTouchX)
                        && shouldQuickSettingsIntercept(
                        mInitialTouchX, mInitialTouchY, h)) {
                    if (!mFeatureFlags.isEnabled(Flags.MIGRATE_NSSL)) {
                        mPanelView.getParent().requestDisallowInterceptTouchEvent(true);
                    }
                    mShadeLog.onQsInterceptMoveQsTrackingEnabled(h);
                    setTracking(true);
                    traceQsJank(true, false);
+3 −1
Original line number Diff line number Diff line
@@ -1545,7 +1545,9 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
        return (v, event) -> {
            mAutoHideController.checkUserAutoHide(event);
            mRemoteInputManager.checkRemoteInputOutside(event);
            if (!mFeatureFlags.isEnabled(Flags.MIGRATE_NSSL)) {
                mShadeController.onStatusBarTouch(event);
            }
            return getNotificationShadeWindowView().onTouchEvent(event);
        };
    }
+12 −0
Original line number Diff line number Diff line
@@ -59,6 +59,7 @@ import androidx.test.filters.SmallTest;
import com.android.keyguard.FaceAuthApiRequestReason;
import com.android.systemui.DejankUtils;
import com.android.systemui.R;
import com.android.systemui.flags.Flags;
import com.android.systemui.keyguard.shared.model.WakeSleepReason;
import com.android.systemui.keyguard.shared.model.WakefulnessModel;
import com.android.systemui.keyguard.shared.model.WakefulnessState;
@@ -1064,7 +1065,18 @@ public class NotificationPanelViewControllerTest extends NotificationPanelViewCo
        mEmptySpaceClickListenerCaptor.getValue().onEmptySpaceClicked(0, 0);

        verify(mUpdateMonitor, never()).requestFaceAuth(anyString());
    }

    @Test
    public void nsslFlagEnabled_allowOnlyExternalTouches() {
        when(mFeatureFlags.isEnabled(Flags.MIGRATE_NSSL)).thenReturn(true);

        // This sets the dozing state that is read when onMiddleClicked is eventually invoked.
        mTouchHandler.onTouch(mock(View.class), mDownMotionEvent);
        verify(mQsController, never()).disallowTouches();

        mNotificationPanelViewController.handleExternalInterceptTouch(mDownMotionEvent);
        verify(mQsController).disallowTouches();
    }

    @Test
Loading