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

Commit 4165d336 authored by Winson's avatar Winson
Browse files

Fixing crash when dragging tasks to docked state.

- Also tweaking animation when a task is first picked up.

Change-Id: Idf99c88fdb216823637e2436e54b392b661b9849
parent 42be431c
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);