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

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

Merge "Add basic return animation when drag is canceled"

parents e8b200eb d9378317
Loading
Loading
Loading
Loading
+117 −4
Original line number Original line Diff line number Diff line
@@ -15,6 +15,11 @@
 */
 */
package com.android.launcher3.taskbar;
package com.android.launcher3.taskbar;


import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_ALL_APPS;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.content.ClipData;
import android.content.ClipData;
import android.content.ClipDescription;
import android.content.ClipDescription;
import android.content.Intent;
import android.content.Intent;
@@ -27,7 +32,9 @@ import android.graphics.drawable.Drawable;
import android.os.UserHandle;
import android.os.UserHandle;
import android.view.DragEvent;
import android.view.DragEvent;
import android.view.MotionEvent;
import android.view.MotionEvent;
import android.view.SurfaceControl;
import android.view.View;
import android.view.View;
import android.view.ViewRootImpl;


import androidx.annotation.Nullable;
import androidx.annotation.Nullable;


@@ -39,20 +46,25 @@ import com.android.launcher3.DragSource;
import com.android.launcher3.DropTarget;
import com.android.launcher3.DropTarget;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.R;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.accessibility.DragViewStateAnnouncer;
import com.android.launcher3.accessibility.DragViewStateAnnouncer;
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.dragndrop.DragController;
import com.android.launcher3.dragndrop.DragController;
import com.android.launcher3.dragndrop.DragDriver;
import com.android.launcher3.dragndrop.DragDriver;
import com.android.launcher3.dragndrop.DragOptions;
import com.android.launcher3.dragndrop.DragOptions;
import com.android.launcher3.dragndrop.DragView;
import com.android.launcher3.dragndrop.DragView;
import com.android.launcher3.dragndrop.DraggableView;
import com.android.launcher3.dragndrop.DraggableView;
import com.android.launcher3.folder.FolderIcon;
import com.android.launcher3.graphics.DragPreviewProvider;
import com.android.launcher3.graphics.DragPreviewProvider;
import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.model.data.FolderInfo;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.popup.PopupContainerWithArrow;
import com.android.launcher3.popup.PopupContainerWithArrow;
import com.android.launcher3.shortcuts.DeepShortcutView;
import com.android.launcher3.shortcuts.DeepShortcutView;
import com.android.launcher3.shortcuts.ShortcutDragPreviewProvider;
import com.android.launcher3.shortcuts.ShortcutDragPreviewProvider;
import com.android.launcher3.util.LauncherBindableItemsContainer;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.system.ClipDescriptionCompat;
import com.android.systemui.shared.system.ClipDescriptionCompat;
import com.android.systemui.shared.system.LauncherAppsCompat;
import com.android.systemui.shared.system.LauncherAppsCompat;
@@ -66,6 +78,8 @@ import java.util.Arrays;
public class TaskbarDragController extends DragController<TaskbarActivityContext> implements
public class TaskbarDragController extends DragController<TaskbarActivityContext> implements
        TaskbarControllers.LoggableTaskbarController {
        TaskbarControllers.LoggableTaskbarController {


    private static boolean DEBUG_DRAG_SHADOW_SURFACE = false;

    private final int mDragIconSize;
    private final int mDragIconSize;
    private final int[] mTempXY = new int[2];
    private final int[] mTempXY = new int[2];


@@ -78,6 +92,9 @@ public class TaskbarDragController extends DragController<TaskbarActivityContext


    private boolean mIsSystemDragInProgress;
    private boolean mIsSystemDragInProgress;


    // Animation for the drag shadow back into position after an unsuccessful drag
    private ValueAnimator mReturnAnimator;

    public TaskbarDragController(TaskbarActivityContext activity) {
    public TaskbarDragController(TaskbarActivityContext activity) {
        super(activity);
        super(activity);
        Resources resources = mActivity.getResources();
        Resources resources = mActivity.getResources();
@@ -279,6 +296,9 @@ public class TaskbarDragController extends DragController<TaskbarActivityContext
            @Override
            @Override
            public void onDrawShadow(Canvas canvas) {
            public void onDrawShadow(Canvas canvas) {
                canvas.save();
                canvas.save();
                if (DEBUG_DRAG_SHADOW_SURFACE) {
                    canvas.drawColor(0xffff0000);
                }
                float scale = mDragObject.dragView.getScaleX();
                float scale = mDragObject.dragView.getScaleX();
                canvas.scale(scale, scale);
                canvas.scale(scale, scale);
                mDragObject.dragView.draw(canvas);
                mDragObject.dragView.draw(canvas);
@@ -337,8 +357,9 @@ public class TaskbarDragController extends DragController<TaskbarActivityContext


            ClipData clipData = new ClipData(clipDescription, new ClipData.Item(intent));
            ClipData clipData = new ClipData(clipDescription, new ClipData.Item(intent));
            if (btv.startDragAndDrop(clipData, shadowBuilder, null /* localState */,
            if (btv.startDragAndDrop(clipData, shadowBuilder, null /* localState */,
                    View.DRAG_FLAG_GLOBAL | View.DRAG_FLAG_OPAQUE)) {
                    View.DRAG_FLAG_GLOBAL | View.DRAG_FLAG_OPAQUE
                onSystemDragStarted();
                            | View.DRAG_FLAG_REQUEST_SURFACE_FOR_RETURN_ANIMATION)) {
                onSystemDragStarted(btv);


                mActivity.getStatsLogManager().logger().withItemInfo(mDragObject.dragInfo)
                mActivity.getStatsLogManager().logger().withItemInfo(mDragObject.dragInfo)
                        .withInstanceId(launcherInstanceId)
                        .withInstanceId(launcherInstanceId)
@@ -347,7 +368,7 @@ public class TaskbarDragController extends DragController<TaskbarActivityContext
        }
        }
    }
    }


    private void onSystemDragStarted() {
    private void onSystemDragStarted(BubbleTextView btv) {
        mIsSystemDragInProgress = true;
        mIsSystemDragInProgress = true;
        mActivity.getDragLayer().setOnDragListener((view, dragEvent) -> {
        mActivity.getDragLayer().setOnDragListener((view, dragEvent) -> {
            switch (dragEvent.getAction()) {
            switch (dragEvent.getAction()) {
@@ -356,7 +377,12 @@ public class TaskbarDragController extends DragController<TaskbarActivityContext
                    return true;
                    return true;
                case DragEvent.ACTION_DRAG_ENDED:
                case DragEvent.ACTION_DRAG_ENDED:
                    mIsSystemDragInProgress = false;
                    mIsSystemDragInProgress = false;
                    if (dragEvent.getResult()) {
                        maybeOnDragEnd();
                        maybeOnDragEnd();
                    } else {
                        // This will take care of calling maybeOnDragEnd() after the animation
                        animateGlobalDragViewToOriginalPosition(btv, dragEvent);
                    }
                    return true;
                    return true;
            }
            }
            return false;
            return false;
@@ -382,6 +408,93 @@ public class TaskbarDragController extends DragController<TaskbarActivityContext
        maybeOnDragEnd();
        maybeOnDragEnd();
    }
    }


    private void animateGlobalDragViewToOriginalPosition(BubbleTextView btv,
            DragEvent dragEvent) {
        SurfaceControl dragSurface = dragEvent.getDragSurface();

        // For top level icons, the target is the icon itself
        View target = btv;
        Object tag = btv.getTag();
        if (tag instanceof ItemInfo) {
            ItemInfo item = (ItemInfo) tag;
            TaskbarViewController taskbarViewController = mControllers.taskbarViewController;
            if (item.container == CONTAINER_ALL_APPS) {
                // Since all apps closes when the drag starts, target the all apps button instead
                target = taskbarViewController.getAllAppsButtonView();
            } else if (item.container >= 0) {
                // Since folders close when the drag starts, target the folder icon instead
                LauncherBindableItemsContainer.ItemOperator op = (info, v) -> {
                    if (info instanceof FolderInfo && v instanceof FolderIcon) {
                        FolderInfo fi = (FolderInfo) info;
                        for (WorkspaceItemInfo si : fi.contents) {
                            if (si.id == item.id) {
                                // Found the parent
                                return true;
                            }
                        }
                    }
                    return false;
                };
                target = taskbarViewController.mapOverItems(op);
            }
        }

        // Finish any pending return animation before starting a new drag
        if (mReturnAnimator != null) {
            mReturnAnimator.end();
        }

        float fromX = dragEvent.getX() - dragEvent.getOffsetX();
        float fromY = dragEvent.getY() - dragEvent.getOffsetY();
        int[] toPosition = target.getLocationOnScreen();
        float toScale = (float) target.getWidth() / mDragIconSize;
        float toAlpha = (target == btv) ? 1f : 0f;
        final ViewRootImpl viewRoot = target.getViewRootImpl();
        SurfaceControl.Transaction tx = new SurfaceControl.Transaction();
        mReturnAnimator = ValueAnimator.ofFloat(0f, 1f);
        mReturnAnimator.setDuration(300);
        mReturnAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
        mReturnAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float t = animation.getAnimatedFraction();
                float accelT = Interpolators.ACCEL_2.getInterpolation(t);
                float scale = 1f - t * (1f - toScale);
                float alpha = 1f - accelT * (1f - toAlpha);
                tx.setPosition(dragSurface, Utilities.mapRange(t, fromX, toPosition[0]),
                        Utilities.mapRange(t, fromY, toPosition[1]));
                tx.setScale(dragSurface, scale, scale);
                tx.setAlpha(dragSurface, alpha);
                tx.apply();
            }
        });
        mReturnAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationCancel(Animator animation) {
                cleanUpSurface();
            }

            @Override
            public void onAnimationEnd(Animator animation) {
                cleanUpSurface();
            }

            private void cleanUpSurface() {
                maybeOnDragEnd();
                // Synchronize removing the drag surface with the next draw after calling
                // maybeOnDragEnd()
                viewRoot.consumeNextDraw((transaction) -> {
                    transaction.remove(dragSurface);
                    transaction.apply();
                    tx.close();
                });
                viewRoot.getView().invalidate();
                mReturnAnimator = null;
            }
        });
        mReturnAnimator.start();
    }

    @Override
    @Override
    protected float getX(MotionEvent ev) {
    protected float getX(MotionEvent ev) {
        // We will resize to fill the screen while dragging, so use screen coordinates. This ensures
        // We will resize to fill the screen while dragging, so use screen coordinates. This ensures
+14 −2
Original line number Original line Diff line number Diff line
@@ -318,6 +318,13 @@ public class TaskbarView extends FrameLayout implements FolderIcon.FolderIconPar
        return icons;
        return icons;
    }
    }


    /**
     * Returns the all apps button in the taskbar.
     */
    public View getAllAppsButtonView() {
        return mAllAppsButton;
    }

    // FolderIconParent implemented methods.
    // FolderIconParent implemented methods.


    @Override
    @Override
@@ -359,13 +366,18 @@ public class TaskbarView extends FrameLayout implements FolderIcon.FolderIconPar
        return getVisibility() == VISIBLE;
        return getVisibility() == VISIBLE;
    }
    }


    protected void mapOverItems(LauncherBindableItemsContainer.ItemOperator op) {
    /**
     * Maps {@code op} over all the child views, returning the view that {@code op} evaluates
     * {@code true} for, or {@code null} if none satisfy {@code op}.
     */
    protected View mapOverItems(LauncherBindableItemsContainer.ItemOperator op) {
        // map over all the shortcuts on the taskbar
        // map over all the shortcuts on the taskbar
        for (int i = 0; i < getChildCount(); i++) {
        for (int i = 0; i < getChildCount(); i++) {
            View item = getChildAt(i);
            View item = getChildAt(i);
            if (op.evaluate((ItemInfo) item.getTag(), item)) {
            if (op.evaluate((ItemInfo) item.getTag(), item)) {
                return;
                return item;
            }
            }
        }
        }
        return null;
    }
    }
}
}
+6 −2
Original line number Original line Diff line number Diff line
@@ -164,6 +164,10 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar
        return mTaskbarView.getIconViews();
        return mTaskbarView.getIconViews();
    }
    }


    public View getAllAppsButtonView() {
        return mTaskbarView.getAllAppsButtonView();
    }

    public AnimatedFloat getTaskbarIconScaleForStash() {
    public AnimatedFloat getTaskbarIconScaleForStash() {
        return mTaskbarIconScaleForStash;
        return mTaskbarIconScaleForStash;
    }
    }
@@ -270,8 +274,8 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar
        mTaskbarNavButtonTranslationY.updateValue(-deviceProfile.getTaskbarOffsetY());
        mTaskbarNavButtonTranslationY.updateValue(-deviceProfile.getTaskbarOffsetY());
    }
    }


    public void mapOverItems(LauncherBindableItemsContainer.ItemOperator op) {
    public View mapOverItems(LauncherBindableItemsContainer.ItemOperator op) {
        mTaskbarView.mapOverItems(op);
        return mTaskbarView.mapOverItems(op);
    }
    }


    /**
    /**