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

Commit a36605ee authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Preventing parallel motion event dispatching from view system and event...

Merge "Preventing parallel motion event dispatching from view system and event proxy" into ub-launcher3-rvc-dev
parents dc122e81 b10e865e
Loading
Loading
Loading
Loading
+2 −18
Original line number Diff line number Diff line
@@ -36,8 +36,6 @@ import com.android.quickstep.util.ActiveGestureLog;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.InputMonitorCompat;

import java.util.function.Predicate;

/**
 * Input consumer for handling touch on the recents/Launcher activity.
 */
@@ -50,8 +48,6 @@ public class OverviewInputConsumer<T extends StatefulActivity<?>>
    private final InputMonitorCompat mInputMonitor;

    private final int[] mLocationOnScreen = new int[2];
    private final boolean mProxyTouch;
    private final Predicate<MotionEvent> mEventReceiver;

    private final boolean mStartingInActivityBounds;
    private boolean mTargetHandledTouch;
@@ -64,15 +60,7 @@ public class OverviewInputConsumer<T extends StatefulActivity<?>>
        mActivityInterface = gestureState.getActivityInterface();

        mTarget = activity.getDragLayer();
        if (startingInActivityBounds) {
            mEventReceiver = mTarget::dispatchTouchEvent;
            mProxyTouch = true;
        } else {
            // Only proxy touches to controllers if we are starting touch from nav bar.
            mEventReceiver = mTarget::proxyTouchEvent;
        mTarget.getLocationOnScreen(mLocationOnScreen);
            mProxyTouch = mTarget.prepareProxyEventStarting();
        }
    }

    @Override
@@ -87,10 +75,6 @@ public class OverviewInputConsumer<T extends StatefulActivity<?>>

    @Override
    public void onMotionEvent(MotionEvent ev) {
        if (!mProxyTouch) {
            return;
        }

        int flags = ev.getEdgeFlags();
        if (!mStartingInActivityBounds) {
            ev.setEdgeFlags(flags | Utilities.EDGE_NAV_BAR);
@@ -99,7 +83,7 @@ public class OverviewInputConsumer<T extends StatefulActivity<?>>
        if (TestProtocol.sDebugTracing) {
            Log.d(TestProtocol.PAUSE_NOT_DETECTED, "OverviewInputConsumer");
        }
        boolean handled = mEventReceiver.test(ev);
        boolean handled = mTarget.proxyTouchEvent(ev, mStartingInActivityBounds);
        ev.offsetLocation(mLocationOnScreen[0], mLocationOnScreen[1]);
        ev.setEdgeFlags(flags);

+75 −45
Original line number Diff line number Diff line
@@ -90,13 +90,23 @@ public abstract class BaseDragLayer<T extends Context & ActivityContext>
                }
            };

    // Touch is being dispatched through the normal view dispatch system
    private static final int TOUCH_DISPATCHING_VIEW = 1 << 0;
    // Touch coming from normal view system is being dispatched.
    private static final int TOUCH_DISPATCHING_FROM_VIEW = 1 << 0;
    // Touch is being dispatched through the normal view dispatch system, and started at the
    // system gesture region
    private static final int TOUCH_DISPATCHING_GESTURE = 1 << 1;
    // Touch is being dispatched through a proxy from InputMonitor
    private static final int TOUCH_DISPATCHING_PROXY = 1 << 2;
    // system gesture region. In this case we prevent internal gesture handling and only allow
    // normal view event handling.
    private static final int TOUCH_DISPATCHING_FROM_VIEW_GESTURE_REGION = 1 << 1;
    // Touch coming from InputMonitor proxy is being dispatched 'only to gestures'. Note that both
    // this and view-system can be active at the same time where view-system would go to the views,
    // and this would go to the gestures.
    // Note that this is not set when events are coming from proxy, but going through full dispatch
    // process (both views and gestures) to allow view-system to easily take over in case it
    // comes later.
    private static final int TOUCH_DISPATCHING_FROM_PROXY = 1 << 2;
    // ACTION_DOWN has been dispatched to child views and ACTION_UP or ACTION_CANCEL is pending.
    // Note that the event source can either be view-dispatching or proxy-dispatching based on if
    // TOUCH_DISPATCHING_VIEW is present or not.
    private static final int TOUCH_DISPATCHING_TO_VIEW_IN_PROGRESS = 1 << 3;

    protected final float[] mTmpXY = new float[2];
    protected final float[] mTmpRectPoints = new float[4];
@@ -204,7 +214,8 @@ public abstract class BaseDragLayer<T extends Context & ActivityContext>

    protected boolean findActiveController(MotionEvent ev) {
        mActiveController = null;
        if ((mTouchDispatchState & (TOUCH_DISPATCHING_GESTURE | TOUCH_DISPATCHING_PROXY)) == 0) {
        if ((mTouchDispatchState & (TOUCH_DISPATCHING_FROM_VIEW_GESTURE_REGION
                | TOUCH_DISPATCHING_FROM_PROXY)) == 0) {
            // Only look for controllers if we are not dispatching from gesture area and proxy is
            // not active
            mActiveController = findControllerToHandleTouch(ev);
@@ -283,19 +294,28 @@ public abstract class BaseDragLayer<T extends Context & ActivityContext>
    public boolean dispatchTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case ACTION_DOWN: {
                mTouchDispatchState |= TOUCH_DISPATCHING_VIEW;
                if ((mTouchDispatchState & TOUCH_DISPATCHING_TO_VIEW_IN_PROGRESS) != 0) {
                    // Cancel the previous touch
                    int action = ev.getAction();
                    ev.setAction(ACTION_CANCEL);
                    super.dispatchTouchEvent(ev);
                    ev.setAction(action);
                }
                mTouchDispatchState |= TOUCH_DISPATCHING_FROM_VIEW
                        | TOUCH_DISPATCHING_TO_VIEW_IN_PROGRESS;

                if (isEventInLauncher(ev)) {
                    mTouchDispatchState &= ~TOUCH_DISPATCHING_GESTURE;
                    mTouchDispatchState &= ~TOUCH_DISPATCHING_FROM_VIEW_GESTURE_REGION;
                } else {
                    mTouchDispatchState |= TOUCH_DISPATCHING_GESTURE;
                    mTouchDispatchState |= TOUCH_DISPATCHING_FROM_VIEW_GESTURE_REGION;
                }
                break;
            }
            case ACTION_CANCEL:
            case ACTION_UP:
                mTouchDispatchState &= ~TOUCH_DISPATCHING_GESTURE;
                mTouchDispatchState &= ~TOUCH_DISPATCHING_VIEW;
                mTouchDispatchState &= ~TOUCH_DISPATCHING_FROM_VIEW_GESTURE_REGION;
                mTouchDispatchState &= ~TOUCH_DISPATCHING_FROM_VIEW;
                mTouchDispatchState &= ~TOUCH_DISPATCHING_TO_VIEW_IN_PROGRESS;
                break;
        }
        super.dispatchTouchEvent(ev);
@@ -305,44 +325,54 @@ public abstract class BaseDragLayer<T extends Context & ActivityContext>
    }

    /**
     * Called before we are about to receive proxy events.
     *
     * @return false if we can't handle proxy at this time
     * Proxies the touch events to the gesture handlers
     */
    public boolean prepareProxyEventStarting() {
        mProxyTouchController = null;
        if ((mTouchDispatchState & TOUCH_DISPATCHING_VIEW) != 0 && mActiveController != null) {
            // We are already dispatching using view system and have an active controller, we can't
            // handle another controller.
    public boolean proxyTouchEvent(MotionEvent ev, boolean allowViewDispatch) {
        int actionMasked = ev.getActionMasked();
        boolean isViewDispatching = (mTouchDispatchState & TOUCH_DISPATCHING_FROM_VIEW) != 0;

        // Only do view dispatch if another view-dispatching is not running, or we already started
        // proxy-dispatching before. Note that view-dispatching can always take over the proxy
        // dispatching at anytime, but not vice-versa.
        allowViewDispatch = allowViewDispatch && !isViewDispatching
                && (actionMasked == ACTION_DOWN
                    || ((mTouchDispatchState & TOUCH_DISPATCHING_TO_VIEW_IN_PROGRESS) != 0));

        if (allowViewDispatch) {
            mTouchDispatchState |= TOUCH_DISPATCHING_TO_VIEW_IN_PROGRESS;
            super.dispatchTouchEvent(ev);

            // This flag was already cleared in proxy ACTION_UP or ACTION_CANCEL. Added here just
            // to be safe
            mTouchDispatchState &= ~TOUCH_DISPATCHING_PROXY;
            return false;
            if (actionMasked == ACTION_UP || actionMasked == ACTION_CANCEL) {
                mTouchDispatchState &= ~TOUCH_DISPATCHING_TO_VIEW_IN_PROGRESS;
                mTouchDispatchState &= ~TOUCH_DISPATCHING_FROM_PROXY;
            }

        mTouchDispatchState |= TOUCH_DISPATCHING_PROXY;
            return true;
    }

    /**
     * Proxies the touch events to the gesture handlers
     */
    public boolean proxyTouchEvent(MotionEvent ev) {
        } else {
            boolean handled;
            if (mProxyTouchController != null) {
                handled = mProxyTouchController.onControllerTouchEvent(ev);
            } else {
                if (actionMasked == ACTION_DOWN) {
                    if (isViewDispatching && mActiveController != null) {
                        // A controller is already active, we can't initiate our own controller
                        mTouchDispatchState &= ~TOUCH_DISPATCHING_FROM_PROXY;
                    } else {
                        // We will control the handler via proxy
                        mTouchDispatchState |= TOUCH_DISPATCHING_FROM_PROXY;
                    }
                }
                if ((mTouchDispatchState & TOUCH_DISPATCHING_FROM_PROXY) != 0) {
                    mProxyTouchController = findControllerToHandleTouch(ev);
                }
                handled = mProxyTouchController != null;
            }
        int action = ev.getAction();
        if (action == ACTION_UP || action == ACTION_CANCEL) {
            if (actionMasked == ACTION_UP || actionMasked == ACTION_CANCEL) {
                mProxyTouchController = null;
            mTouchDispatchState &= ~TOUCH_DISPATCHING_PROXY;
                mTouchDispatchState &= ~TOUCH_DISPATCHING_FROM_PROXY;
            }
            return handled;
        }
    }

    /**
     * Determine the rect of the descendant in this DragLayer's coordinates