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

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

Merge "Couple fixes for drag and drop" into tm-dev

parents b6a560c1 93f75de6
Loading
Loading
Loading
Loading
+5 −4
Original line number Diff line number Diff line
@@ -35,6 +35,9 @@ import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMA
import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.content.ClipDescription;
import android.content.Context;
import android.content.res.Configuration;
@@ -54,6 +57,7 @@ import com.android.internal.logging.UiEventLogger;
import com.android.internal.protolog.common.ProtoLog;
import com.android.launcher3.icons.IconProvider;
import com.android.wm.shell.R;
import com.android.wm.shell.animation.Interpolators;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
@@ -205,6 +209,7 @@ public class DragAndDropController implements DisplayController.OnDisplaysChange
                break;
            case ACTION_DRAG_ENTERED:
                pd.dragLayout.show();
                pd.dragLayout.update(event);
                break;
            case ACTION_DRAG_LOCATION:
                pd.dragLayout.update(event);
@@ -250,10 +255,6 @@ public class DragAndDropController implements DisplayController.OnDisplaysChange
                // Hide the window if another drag hasn't been started while animating the drop
                setDropTargetWindowVisibility(pd, View.INVISIBLE);
            }

            // Clean up the drag surface
            mTransaction.reparent(dragSurface, null);
            mTransaction.apply();
        });
    }

+7 −0
Original line number Diff line number Diff line
@@ -122,6 +122,13 @@ public class DragAndDropPolicy {
        return mSession.runningTaskInfo;
    }

    /**
     * Returns the number of targets.
     */
    int getNumTargets() {
        return mTargets.size();
    }

    /**
     * Returns the target's regions based on the current state of the device and display.
     */
+101 −9
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.wm.shell.draganddrop;

import static android.app.StatusBarManager.DISABLE_NONE;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;

import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
@@ -24,6 +25,7 @@ import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSIT

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.app.ActivityManager;
import android.app.StatusBarManager;
@@ -44,6 +46,7 @@ import com.android.internal.logging.InstanceId;
import com.android.internal.protolog.common.ProtoLog;
import com.android.launcher3.icons.IconProvider;
import com.android.wm.shell.R;
import com.android.wm.shell.animation.Interpolators;
import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
import com.android.wm.shell.splitscreen.SplitScreenController;
@@ -135,6 +138,12 @@ public class DragLayout extends LinearLayout {
        }
    }

    private void updateContainerMarginsForSingleTask() {
        mDropZoneView1.setContainerMargin(
                mDisplayMargin, mDisplayMargin, mDisplayMargin, mDisplayMargin);
        mDropZoneView2.setContainerMargin(0, 0, 0, 0);
    }

    private void updateContainerMargins(int orientation) {
        final float halfMargin = mDisplayMargin / 2f;
        if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
@@ -165,11 +174,20 @@ public class DragLayout extends LinearLayout {
        if (!alreadyInSplit) {
            ActivityManager.RunningTaskInfo taskInfo1 = mPolicy.getLatestRunningTask();
            if (taskInfo1 != null) {
                final int activityType = taskInfo1.getActivityType();
                if (activityType == ACTIVITY_TYPE_STANDARD) {
                    Drawable icon1 = mIconProvider.getIcon(taskInfo1.topActivityInfo);
                    int bgColor1 = getResizingBackgroundColor(taskInfo1);
                    mDropZoneView1.setAppInfo(bgColor1, icon1);
                    mDropZoneView2.setAppInfo(bgColor1, icon1);
                    updateDropZoneSizes(null, null); // passing null splits the views evenly
                } else {
                    // We use the first drop zone to show the fullscreen highlight, and don't need
                    // to set additional info
                    mDropZoneView1.setForceIgnoreBottomMargin(true);
                    updateDropZoneSizesForSingleTask();
                    updateContainerMarginsForSingleTask();
                }
            }
        } else {
            // We're already in split so get taskInfo from the controller to populate icon / color.
@@ -195,6 +213,21 @@ public class DragLayout extends LinearLayout {
        }
    }

    private void updateDropZoneSizesForSingleTask() {
        final LinearLayout.LayoutParams dropZoneView1 =
                (LayoutParams) mDropZoneView1.getLayoutParams();
        final LinearLayout.LayoutParams dropZoneView2 =
                (LayoutParams) mDropZoneView2.getLayoutParams();
        dropZoneView1.width = MATCH_PARENT;
        dropZoneView1.height = MATCH_PARENT;
        dropZoneView2.width = 0;
        dropZoneView2.height = 0;
        dropZoneView1.weight = 1;
        dropZoneView2.weight = 0;
        mDropZoneView1.setLayoutParams(dropZoneView1);
        mDropZoneView2.setLayoutParams(dropZoneView2);
    }

    /**
     * Sets the size of the two drop zones based on the provided bounds. The divider sits between
     * the views and its size is included in the calculations.
@@ -265,9 +298,12 @@ public class DragLayout extends LinearLayout {
                // Animating to no target
                animateSplitContainers(false, null /* animCompleteCallback */);
            } else if (mCurrentTarget == null) {
                // Animating to first target
                if (mPolicy.getNumTargets() == 1) {
                    animateFullscreenContainer(true);
                } else {
                    animateSplitContainers(true, null /* animCompleteCallback */);
                    animateHighlight(target);
                }
            } else {
                // Switching between targets
                mDropZoneView1.animateSwitch();
@@ -283,6 +319,10 @@ public class DragLayout extends LinearLayout {
    public void hide(DragEvent event, Runnable hideCompleteCallback) {
        mIsShowing = false;
        animateSplitContainers(false, hideCompleteCallback);
        // Reset the state if we previously force-ignore the bottom margin
        mDropZoneView1.setForceIgnoreBottomMargin(false);
        mDropZoneView2.setForceIgnoreBottomMargin(false);
        updateContainerMargins(getResources().getConfiguration().orientation);
        mCurrentTarget = null;
    }

@@ -297,11 +337,63 @@ public class DragLayout extends LinearLayout {
        // Process the drop
        mPolicy.handleDrop(mCurrentTarget, event.getClipData());

        // TODO(b/169894807): Coordinate with dragSurface
        // Start animating the drop UI out with the drag surface
        hide(event, dropCompleteCallback);
        hideDragSurface(dragSurface);
        return handledDrop;
    }

    private void hideDragSurface(SurfaceControl dragSurface) {
        final SurfaceControl.Transaction tx = new SurfaceControl.Transaction();
        final ValueAnimator dragSurfaceAnimator = ValueAnimator.ofFloat(0f, 1f);
        // Currently the splash icon animation runs with the default ValueAnimator duration of
        // 300ms
        dragSurfaceAnimator.setDuration(300);
        dragSurfaceAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
        dragSurfaceAnimator.addUpdateListener(animation -> {
            float t = animation.getAnimatedFraction();
            float alpha = 1f - t;
            // TODO: Scale the drag surface as well once we make all the source surfaces
            //       consistent
            tx.setAlpha(dragSurface, alpha);
            tx.apply();
        });
        dragSurfaceAnimator.addListener(new AnimatorListenerAdapter() {
            private boolean mCanceled = false;

            @Override
            public void onAnimationCancel(Animator animation) {
                cleanUpSurface();
                mCanceled = true;
            }

            @Override
            public void onAnimationEnd(Animator animation) {
                if (mCanceled) {
                    // Already handled above
                    return;
                }
                cleanUpSurface();
            }

            private void cleanUpSurface() {
                // Clean up the drag surface
                tx.remove(dragSurface);
                tx.apply();
            }
        });
        dragSurfaceAnimator.start();
    }

    private void animateFullscreenContainer(boolean visible) {
        mStatusBarManager.disable(visible
                ? HIDE_STATUS_BAR_FLAGS
                : DISABLE_NONE);
        // We're only using the first drop zone if there is one fullscreen target
        mDropZoneView1.setShowingMargin(visible);
        mDropZoneView1.setShowingHighlight(visible);
    }

    private void animateSplitContainers(boolean visible, Runnable animCompleteCallback) {
        mStatusBarManager.disable(visible
                ? HIDE_STATUS_BAR_FLAGS
+11 −1
Original line number Diff line number Diff line
@@ -65,6 +65,7 @@ public class DropZoneView extends FrameLayout {
    private final float[] mContainerMargin = new float[4];
    private float mCornerRadius;
    private float mBottomInset;
    private boolean mIgnoreBottomMargin;
    private int mMarginColor; // i.e. color used for negative space like the container insets

    private boolean mShowingHighlight;
@@ -141,6 +142,14 @@ public class DropZoneView extends FrameLayout {
        }
    }

    /** Ignores the bottom margin provided by the insets. */
    public void setForceIgnoreBottomMargin(boolean ignoreBottomMargin) {
        mIgnoreBottomMargin = ignoreBottomMargin;
        if (mMarginPercent > 0) {
            mMarginView.invalidate();
        }
    }

    /** Sets the bottom inset so the drop zones are above bottom navigation. */
    public void setBottomInset(float bottom) {
        mBottomInset = bottom;
@@ -257,7 +266,8 @@ public class DropZoneView extends FrameLayout {
            mPath.addRoundRect(mContainerMargin[0] * mMarginPercent,
                    mContainerMargin[1] * mMarginPercent,
                    getWidth() - (mContainerMargin[2] * mMarginPercent),
                    getHeight() - (mContainerMargin[3] * mMarginPercent) - mBottomInset,
                    getHeight() - (mContainerMargin[3] * mMarginPercent)
                            - (mIgnoreBottomMargin ? 0 : mBottomInset),
                    mCornerRadius * mMarginPercent,
                    mCornerRadius * mMarginPercent,
                    Path.Direction.CW);
+3 −0
Original line number Diff line number Diff line
@@ -2407,4 +2407,7 @@
    <string name="add_user_supervised" translatable="false">@*android:string/supervised_user_creation_label</string>
    <!-- Manage users - For system user management [CHAR LIMIT=40]  -->
    <string name="manage_users">Manage users</string>

    <!-- Toast shown when a notification does not support dragging to split [CHAR LIMIT=NONE] -->
    <string name="drag_split_not_supported">This notification does not support dragging to Splitscreen.</string>
</resources>
Loading