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

Commit caed9472 authored by Winson Chung's avatar Winson Chung Committed by Android (Google) Code Review
Browse files

Merge "Fixing crash when dragging tasks to docked state."

parents b53abe74 4165d336
Loading
Loading
Loading
Loading
+20 −12
Original line number Diff line number Diff line
@@ -183,16 +183,18 @@ public class TaskStack {


    public enum DockState {
        LEFT(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
                new RectF(0, 0, 0.25f, 1), new RectF(0, 0, 0.35f, 1), new RectF(0.65f, 0, 1, 1)),
        TOP(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
                new RectF(0, 0, 1, 0.25f), new RectF(0, 0, 1, 0.35f), new RectF(0, 0.65f, 1, 1)),
        RIGHT(DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT,
                new RectF(0.75f, 0, 1, 1), new RectF(0.65f, 0, 1, 1), new RectF(0, 0, 0.35f, 1)),
        BOTTOM(DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT,
                new RectF(0, 0.75f, 1, 1), new RectF(0, 0.65f, 1, 1), new RectF(0, 0, 1, 0.35f));
        NONE(-1, 96, null, null, null),
        LEFT(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT, 192,
                new RectF(0, 0, 0.3f, 1), new RectF(0, 0, 0.3f, 1), new RectF(0.7f, 0, 1, 1)),
        TOP(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT, 192,
                new RectF(0, 0, 1, 0.3f), new RectF(0, 0, 1, 0.3f), new RectF(0, 0.7f, 1, 1)),
        RIGHT(DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT, 192,
                new RectF(0.7f, 0, 1, 1), new RectF(0.7f, 0, 1, 1), new RectF(0, 0, 0.3f, 1)),
        BOTTOM(DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT, 192,
                new RectF(0, 0.7f, 1, 1), new RectF(0, 0.7f, 1, 1), new RectF(0, 0, 1, 0.3f));

        public final int createMode;
        public final int dockAreaAlpha;
        private final RectF touchArea;
        private final RectF dockArea;
        private final RectF stackArea;
@@ -202,8 +204,10 @@ public class TaskStack {
         * @param touchArea the area in which touch will initiate this dock state
         * @param stackArea the area for the stack if a task is docked
         */
        DockState(int createMode, RectF touchArea, RectF dockArea, RectF stackArea) {
        DockState(int createMode, int dockAreaAlpha, RectF touchArea, RectF dockArea,
                RectF stackArea) {
            this.createMode = createMode;
            this.dockAreaAlpha = dockAreaAlpha;
            this.touchArea = touchArea;
            this.dockArea = dockArea;
            this.stackArea = stackArea;
@@ -232,9 +236,13 @@ public class TaskStack {
        /**
         * Returns the stack bounds with the given {@param width} and {@param height}.
         */
        public Rect getStackBounds(int width, int height) {
            return new Rect((int) (stackArea.left * width), (int) (stackArea.top * height),
                    (int) (stackArea.right * width), (int) (stackArea.bottom * height));
        public Rect getStackBounds(Rect stackRect) {
            int width = stackRect.width();
            int height = stackRect.height();
            return new Rect((int) (stackRect.left + stackArea.left * width),
                    (int) (stackRect.top + stackArea.top * height),
                    (int) (stackRect.left + (stackArea.right - stackArea.left) * width),
                    (int) (stackRect.top + (stackArea.bottom - stackArea.top) * height));
        }
    }

+46 −16
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.systemui.recents.views;

import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.content.Context;
@@ -23,6 +25,7 @@ import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.IRemoteCallback;
import android.os.RemoteException;
@@ -89,6 +92,7 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV
    RecentsViewTouchHandler mTouchHandler;
    DragView mDragView;
    ColorDrawable mDockRegionOverlay;
    ObjectAnimator mDockRegionOverlayAnimator;

    Interpolator mFastOutSlowInInterpolator;

@@ -114,8 +118,9 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV
        mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
                com.android.internal.R.interpolator.fast_out_slow_in);
        mTouchHandler = new RecentsViewTouchHandler(this);
        mDockRegionOverlay = new ColorDrawable(0x66000000);
        mDockRegionOverlay = new ColorDrawable(0xFFffffff);
        mDockRegionOverlay.setAlpha(0);
        mDockRegionOverlay.setCallback(this);
    }

    /** Sets the callbacks */
@@ -383,6 +388,11 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV
        }
    }

    @Override
    protected boolean verifyDrawable(Drawable who) {
        return super.verifyDrawable(who) || who == mDockRegionOverlay;
    }

    /** Notifies each task view of the user interaction. */
    public void onUserInteraction() {
        // Get the first stack view
@@ -764,19 +774,12 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV
        // Add the drag view
        mDragView = event.dragView;
        addView(mDragView);

        updateDockRegion(TaskStack.DockState.NONE);
    }

    public final void onBusEvent(DragDockStateChangedEvent event) {
        // Update the task stack positions, and then
        if (event.dockState != null) {
            // Draw an overlay on the bounds of the dock task
            mDockRegionOverlay.setBounds(
                    event.dockState.getDockedBounds(getMeasuredWidth(), getMeasuredHeight()));
            mDockRegionOverlay.setAlpha(255);
        } else {
            mDockRegionOverlay.setAlpha(0);
        }
        invalidate();
        updateDockRegion(event.dockState);
    }

    public final void onBusEvent(final DragEndEvent event) {
@@ -791,7 +794,7 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV
                invalidate();

                // Dock the new task if we are hovering over a valid dock state
                if (event.dockState != null) {
                if (event.dockState != TaskStack.DockState.NONE) {
                    SystemServicesProxy ssp = RecentsTaskLoader.getInstance().getSystemServicesProxy();
                    ssp.setTaskResizeable(event.task.key.id);
                    ssp.dockTask(event.task.key.id, event.dockState.createMode);
@@ -799,22 +802,49 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV
                }
            }
        });
        if (event.dockState == null) {
        if (event.dockState == TaskStack.DockState.NONE) {
            // Animate the alpha back to what it was before
            Rect taskBounds = mTaskStackView.getStackAlgorithm().getUntransformedTaskViewBounds();
            int left = taskBounds.left + (int) ((1f - event.taskView.getScaleX()) * taskBounds.width()) / 2;
            int top = taskBounds.top + (int) ((1f - event.taskView.getScaleY()) * taskBounds.height()) / 2;
            event.dragView.animate()
                    .alpha(1f)
                    .scaleX(1f)
                    .scaleY(1f)
                    .translationX(left + event.taskView.getTranslationX())
                    .translationY(top + event.taskView.getTranslationY())
                    .setDuration(175)
                    .setInterpolator(new AccelerateInterpolator(1.5f))
                    .setInterpolator(mFastOutSlowInInterpolator)
                    .withEndAction(event.postAnimationTrigger.decrementAsRunnable())
                    .withLayer()
                    .start();

            // Animate the overlay alpha back to 0
            updateDockRegionAlpha(0);
        } else {
            event.postAnimationTrigger.decrement();
        }
    }

    /**
     * Updates the dock region to match the specified dock state.
     */
    private void updateDockRegion(TaskStack.DockState dockState) {
        TaskStack.DockState boundsDockState = dockState;
        if (dockState == TaskStack.DockState.NONE) {
            // If the dock state is null, then use the bounds of the preferred dock state for this
            // orientation
            boundsDockState = mTouchHandler.getPreferredDockStateForCurrentOrientation();
        }
        mDockRegionOverlay.setBounds(
                boundsDockState.getDockedBounds(getMeasuredWidth(), getMeasuredHeight()));
        updateDockRegionAlpha(dockState.dockAreaAlpha);
    }

    private void updateDockRegionAlpha(int alpha) {
        if (mDockRegionOverlayAnimator != null) {
            mDockRegionOverlayAnimator.cancel();
        }
        mDockRegionOverlayAnimator = ObjectAnimator.ofInt(mDockRegionOverlay, "alpha", alpha);
        mDockRegionOverlayAnimator.setDuration(150);
        mDockRegionOverlayAnimator.start();
    }
}
+69 −57
Original line number Diff line number Diff line
@@ -36,7 +36,8 @@ class DockRegion {
            TaskStack.DockState.LEFT, TaskStack.DockState.RIGHT
    };
    public static TaskStack.DockState[] PORTRAIT = {
            TaskStack.DockState.TOP, TaskStack.DockState.BOTTOM
            // We only allow docking to the top for now
            TaskStack.DockState.TOP
    };
}

@@ -53,27 +54,60 @@ class RecentsViewTouchHandler {

    private Point mDownPos = new Point();
    private boolean mDragging;
    private TaskStack.DockState mLastDockState;
    private TaskStack.DockState mLastDockState = TaskStack.DockState.NONE;

    public RecentsViewTouchHandler(RecentsView rv) {
        mRv = rv;
    }

    public TaskStack.DockState getPreferredDockStateForCurrentOrientation() {
        boolean isLandscape = mRv.getResources().getConfiguration().orientation ==
                Configuration.ORIENTATION_LANDSCAPE;
        TaskStack.DockState[] dockStates = isLandscape ?
                DockRegion.LANDSCAPE : DockRegion.PORTRAIT;
        return dockStates[0];
    }

    /** Touch preprocessing for handling below */
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        int action = ev.getAction();
        switch (action & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN:
                mDownPos.set((int) ev.getX(), (int) ev.getY());
                break;
        }
        handleTouchEvent(ev);
        return mDragging;
    }

    /** Handles touch events once we have intercepted them */
    public boolean onTouchEvent(MotionEvent ev) {
        if (!mDragging) return false;
        handleTouchEvent(ev);
        return mDragging;
    }

    /**** Events ****/

    public final void onBusEvent(DragStartEvent event) {
        mRv.getParent().requestDisallowInterceptTouchEvent(true);
        mDragging = true;
        mDragTask = event.task;
        mTaskView = event.taskView;
        mDragView = event.dragView;

        float x = mDownPos.x - mDragView.getTopLeftOffset().x;
        float y = mDownPos.y - mDragView.getTopLeftOffset().y;
        mDragView.setTranslationX(x);
        mDragView.setTranslationY(y);
    }

    public final void onBusEvent(DragEndEvent event) {
        mDragging = false;
        mDragTask = null;
        mTaskView = null;
        mDragView = null;
        mLastDockState = TaskStack.DockState.NONE;
    }

    /**
     * Handles dragging touch events
     * @param ev
     */
    private void handleTouchEvent(MotionEvent ev) {
        boolean isLandscape = mRv.getResources().getConfiguration().orientation ==
                Configuration.ORIENTATION_LANDSCAPE;
        int action = ev.getAction();
@@ -82,6 +116,7 @@ class RecentsViewTouchHandler {
                mDownPos.set((int) ev.getX(), (int) ev.getY());
                break;
            case MotionEvent.ACTION_MOVE: {
                if (mDragging) {
                    int width = mRv.getMeasuredWidth();
                    int height = mRv.getMeasuredHeight();
                    float evX = ev.getX();
@@ -92,7 +127,7 @@ class RecentsViewTouchHandler {
                    // Update the dock state
                    TaskStack.DockState[] dockStates = isLandscape ?
                            DockRegion.LANDSCAPE : DockRegion.PORTRAIT;
                TaskStack.DockState foundDockState = null;
                    TaskStack.DockState foundDockState = TaskStack.DockState.NONE;
                    for (int i = 0; i < dockStates.length; i++) {
                        TaskStack.DockState state = dockStates[i];
                        if (state.touchAreaContainsPoint(width, height, evX, evY)) {
@@ -108,6 +143,7 @@ class RecentsViewTouchHandler {

                    mDragView.setTranslationX(x);
                    mDragView.setTranslationY(y);
                }
                break;
            }
            case MotionEvent.ACTION_UP:
@@ -121,29 +157,5 @@ class RecentsViewTouchHandler {
                break;
            }
        }
        return true;
    }

    /**** Events ****/

    public final void onBusEvent(DragStartEvent event) {
        mRv.getParent().requestDisallowInterceptTouchEvent(true);
        mDragging = true;
        mDragTask = event.task;
        mTaskView = event.taskView;
        mDragView = event.dragView;

        float x = mDownPos.x - mDragView.getTopLeftOffset().x;
        float y = mDownPos.y - mDragView.getTopLeftOffset().y;
        mDragView.setTranslationX(x);
        mDragView.setTranslationY(y);
    }

    public final void onBusEvent(DragEndEvent event) {
        mDragging = false;
        mDragTask = null;
        mTaskView = null;
        mDragView = null;
        mLastDockState = null;
    }
}
+4 −3
Original line number Diff line number Diff line
@@ -807,15 +807,16 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks,
                    dragView.setElevation(getElevation());
                    dragView.setTranslationZ(getTranslationZ());
                    dragView.animate()
                            .alpha(0.75f)
                            .scaleX(1.05f)
                            .scaleY(1.05f)
                            .setDuration(175)
                            .setInterpolator(new AccelerateInterpolator(1.5f))
                            .withLayer()
                            .setInterpolator(mFastOutSlowInInterpolator)
                            .start();
                }

                @Override
                public void onViewDetachedFromWindow(View v) {
                    // Do nothing
                }
            });
            EventBus.getDefault().register(this, RecentsActivity.EVENT_BUS_PRIORITY + 1);