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

Commit 7160f840 authored by Garfield Tan's avatar Garfield Tan Committed by Android (Google) Code Review
Browse files

Merge "Refactor DragDetector and fix a few resizing bugs" into tm-qpr-dev

parents 6e355aa7 7ea23aa2
Loading
Loading
Loading
Loading
+12 −7
Original line number Diff line number Diff line
@@ -175,16 +175,18 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
                new CaptionTouchEventListener(taskInfo, taskPositioner);
        windowDecoration.setCaptionListeners(touchEventListener, touchEventListener);
        windowDecoration.setDragResizeCallback(taskPositioner);
        windowDecoration.setDragDetector(touchEventListener.mDragDetector);
        windowDecoration.relayout(taskInfo, startT, finishT);
        setupCaptionColor(taskInfo, windowDecoration);
    }

    private class CaptionTouchEventListener implements
            View.OnClickListener, View.OnTouchListener {
            View.OnClickListener, View.OnTouchListener, DragDetector.MotionEventHandler {

        private final int mTaskId;
        private final WindowContainerToken mTaskToken;
        private final DragResizeCallback mDragResizeCallback;
        private final DragDetector mDragDetector;

        private int mDragPointerId = -1;

@@ -194,6 +196,7 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
            mTaskId = taskInfo.taskId;
            mTaskToken = taskInfo.token;
            mDragResizeCallback = dragResizeCallback;
            mDragDetector = new DragDetector(this);
        }

        @Override
@@ -216,7 +219,7 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
            if (v.getId() != R.id.caption) {
                return false;
            }
            handleEventForMove(e);
            mDragDetector.onMotionEvent(e);

            if (e.getAction() != MotionEvent.ACTION_DOWN) {
                return false;
@@ -235,10 +238,11 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
         * @param e {@link MotionEvent} to process
         * @return {@code true} if a drag is happening; or {@code false} if it is not
         */
        private void handleEventForMove(MotionEvent e) {
        @Override
        public boolean handleMotionEvent(MotionEvent e) {
            final RunningTaskInfo taskInfo = mTaskOrganizer.getRunningTaskInfo(mTaskId);
            if (taskInfo.getWindowingMode() == WINDOWING_MODE_FULLSCREEN) {
                return;
                return false;
            }
            switch (e.getActionMasked()) {
                case MotionEvent.ACTION_DOWN: {
@@ -261,6 +265,7 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
                    break;
                }
            }
            return true;
        }
    }
}
 No newline at end of file
+6 −2
Original line number Diff line number Diff line
@@ -49,7 +49,7 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
    private View.OnTouchListener mOnCaptionTouchListener;
    private DragResizeCallback mDragResizeCallback;
    private DragResizeInputListener mDragResizeListener;
    private final DragDetector mDragDetector;
    private DragDetector mDragDetector;

    private RelayoutParams mRelayoutParams = new RelayoutParams();
    private final RelayoutResult<WindowDecorLinearLayout> mResult =
@@ -69,7 +69,6 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
        mHandler = handler;
        mChoreographer = choreographer;
        mSyncQueue = syncQueue;
        mDragDetector = new DragDetector(ViewConfiguration.get(context).getScaledTouchSlop());
    }

    void setCaptionListeners(
@@ -83,6 +82,11 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
        mDragResizeCallback = dragResizeCallback;
    }

    void setDragDetector(DragDetector dragDetector) {
        mDragDetector = dragDetector;
        mDragDetector.setTouchSlop(ViewConfiguration.get(mContext).getScaledTouchSlop());
    }

    @Override
    void relayout(RunningTaskInfo taskInfo) {
        final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
+13 −14
Original line number Diff line number Diff line
@@ -205,7 +205,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
    }

    private class DesktopModeTouchEventListener implements
            View.OnClickListener, View.OnTouchListener {
            View.OnClickListener, View.OnTouchListener, DragDetector.MotionEventHandler {

        private final int mTaskId;
        private final WindowContainerToken mTaskToken;
@@ -216,12 +216,11 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {

        private DesktopModeTouchEventListener(
                RunningTaskInfo taskInfo,
                DragResizeCallback dragResizeCallback,
                DragDetector dragDetector) {
                DragResizeCallback dragResizeCallback) {
            mTaskId = taskInfo.taskId;
            mTaskToken = taskInfo.token;
            mDragResizeCallback = dragResizeCallback;
            mDragDetector = dragDetector;
            mDragDetector = new DragDetector(this);
        }

        @Override
@@ -254,8 +253,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
                return false;
            }
            if (id == R.id.caption_handle) {
                isDrag = mDragDetector.detectDragEvent(e);
                handleEventForMove(e);
                isDrag = mDragDetector.onMotionEvent(e);
            }
            if (e.getAction() != MotionEvent.ACTION_DOWN) {
                return isDrag;
@@ -272,19 +270,19 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {

        /**
         * @param e {@link MotionEvent} to process
         * @return {@code true} if a drag is happening; or {@code false} if it is not
         * @return {@code true} if the motion event is handled.
         */
        private void handleEventForMove(MotionEvent e) {
        @Override
        public boolean handleMotionEvent(MotionEvent e) {
            final RunningTaskInfo taskInfo = mTaskOrganizer.getRunningTaskInfo(mTaskId);
            if (DesktopModeStatus.isProto2Enabled()
                    && taskInfo.getWindowingMode() == WINDOWING_MODE_FULLSCREEN) {
                return;
                return false;
            }
            if (DesktopModeStatus.isProto1Enabled() && mDesktopModeController.isPresent()
                    && mDesktopModeController.get().getDisplayAreaWindowingMode(
                    taskInfo.displayId)
                    && mDesktopModeController.get().getDisplayAreaWindowingMode(taskInfo.displayId)
                    == WINDOWING_MODE_FULLSCREEN) {
                return;
                return false;
            }
            switch (e.getActionMasked()) {
                case MotionEvent.ACTION_DOWN: {
@@ -324,6 +322,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
                    break;
                }
            }
            return true;
        }
    }

@@ -560,10 +559,10 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
        final TaskPositioner taskPositioner =
                new TaskPositioner(mTaskOrganizer, windowDecoration, mDragStartListener);
        final DesktopModeTouchEventListener touchEventListener =
                new DesktopModeTouchEventListener(
                        taskInfo, taskPositioner, windowDecoration.getDragDetector());
                new DesktopModeTouchEventListener(taskInfo, taskPositioner);
        windowDecoration.setCaptionListeners(touchEventListener, touchEventListener);
        windowDecoration.setDragResizeCallback(taskPositioner);
        windowDecoration.setDragDetector(touchEventListener.mDragDetector);
        windowDecoration.relayout(taskInfo, startT, finishT);
        incrementEventReceiverTasks(taskInfo.displayId);
    }
+4 −4
Original line number Diff line number Diff line
@@ -57,7 +57,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
    private View.OnTouchListener mOnCaptionTouchListener;
    private DragResizeCallback mDragResizeCallback;
    private DragResizeInputListener mDragResizeListener;
    private final DragDetector mDragDetector;
    private DragDetector mDragDetector;

    private RelayoutParams mRelayoutParams = new RelayoutParams();
    private final WindowDecoration.RelayoutResult<WindowDecorLinearLayout> mResult =
@@ -81,7 +81,6 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
        mChoreographer = choreographer;
        mSyncQueue = syncQueue;
        mDesktopActive = DesktopModeStatus.isActive(mContext);
        mDragDetector = new DragDetector(ViewConfiguration.get(context).getScaledTouchSlop());
    }

    void setCaptionListeners(
@@ -95,8 +94,9 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
        mDragResizeCallback = dragResizeCallback;
    }

    DragDetector getDragDetector() {
        return mDragDetector;
    void setDragDetector(DragDetector dragDetector) {
        mDragDetector = dragDetector;
        mDragDetector.setTouchSlop(ViewConfiguration.get(mContext).getScaledTouchSlop());
    }

    @Override
+51 −31
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.wm.shell.windowdecor;

import static android.view.InputDevice.SOURCE_TOUCHSCREEN;
import static android.view.MotionEvent.ACTION_CANCEL;
import static android.view.MotionEvent.ACTION_DOWN;
import static android.view.MotionEvent.ACTION_MOVE;
@@ -25,63 +26,82 @@ import android.graphics.PointF;
import android.view.MotionEvent;

/**
 * A detector for touch inputs that differentiates between drag and click inputs.
 * A detector for touch inputs that differentiates between drag and click inputs. It receives a flow
 * of {@link MotionEvent} and generates a new flow of motion events with slop in consideration to
 * the event handler. In particular, it always passes down, up and cancel events. It'll pass move
 * events only when there is at least one move event that's beyond the slop threshold. For the
 * purpose of convenience it also passes all events of other actions.
 *
 * All touch events must be passed through this class to track a drag event.
 */
public class DragDetector {
class DragDetector {
    private final MotionEventHandler mEventHandler;

    private final PointF mInputDownPoint = new PointF();
    private int mTouchSlop;
    private PointF mInputDownPoint;
    private boolean mIsDragEvent;
    private int mDragPointerId;
    public DragDetector(int touchSlop) {
        mTouchSlop = touchSlop;
        mInputDownPoint = new PointF();
        mIsDragEvent = false;
        mDragPointerId = -1;

    private boolean mResultOfDownAction;

    DragDetector(MotionEventHandler eventHandler) {
        resetState();
        mEventHandler = eventHandler;
    }

    /**
     * Determine if {@link MotionEvent} is part of a drag event.
     * @return {@code true} if this is a drag event, {@code false} if not
     * The receiver of the {@link MotionEvent} flow.
     *
     * @return the result returned by {@link #mEventHandler}, or the result when
     * {@link #mEventHandler} handles the previous down event if the event shouldn't be passed
    */
    public boolean detectDragEvent(MotionEvent ev) {
        switch (ev.getAction()) {
    boolean onMotionEvent(MotionEvent ev) {
        switch (ev.getActionMasked()) {
            case ACTION_DOWN: {
                // Only touch screens generate noisy moves.
                mIsDragEvent = (ev.getSource() & SOURCE_TOUCHSCREEN) != SOURCE_TOUCHSCREEN;
                mDragPointerId = ev.getPointerId(0);
                float rawX = ev.getRawX(0);
                float rawY = ev.getRawY(0);
                mInputDownPoint.set(rawX, rawY);
                return false;
                mResultOfDownAction = mEventHandler.handleMotionEvent(ev);
                return mResultOfDownAction;
            }
            case ACTION_MOVE: {
                if (!mIsDragEvent) {
                    int dragPointerIndex = ev.findPointerIndex(mDragPointerId);
                    float dx = ev.getRawX(dragPointerIndex) - mInputDownPoint.x;
                    float dy = ev.getRawY(dragPointerIndex) - mInputDownPoint.y;
                    if (Math.hypot(dx, dy) > mTouchSlop) {
                        mIsDragEvent = true;
                    }
                    mIsDragEvent = Math.hypot(dx, dy) > mTouchSlop;
                }
                return mIsDragEvent;
                if (mIsDragEvent) {
                    return mEventHandler.handleMotionEvent(ev);
                } else {
                    return mResultOfDownAction;
                }
            case ACTION_UP: {
                boolean result = mIsDragEvent;
                mIsDragEvent = false;
                mInputDownPoint.set(0, 0);
                mDragPointerId = -1;
                return result;
            }
            case ACTION_UP:
            case ACTION_CANCEL: {
                mIsDragEvent = false;
                mInputDownPoint.set(0, 0);
                mDragPointerId = -1;
                return false;
                resetState();
                return mEventHandler.handleMotionEvent(ev);
            }
            default:
                return mEventHandler.handleMotionEvent(ev);
        }
        return mIsDragEvent;
    }

    public void setTouchSlop(int touchSlop) {
    void setTouchSlop(int touchSlop) {
        mTouchSlop = touchSlop;
    }

    private void resetState() {
        mIsDragEvent = false;
        mInputDownPoint.set(0, 0);
        mDragPointerId = -1;
        mResultOfDownAction = false;
    }

    interface MotionEventHandler {
        boolean handleMotionEvent(MotionEvent ev);
    }
}
Loading