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

Commit c1e17d0d authored by Gustav Sennton's avatar Gustav Sennton Committed by Android (Google) Code Review
Browse files

Merge changes I7b7c0f40,Id0ea7f57 into main

* changes:
  [3/N] Report home visibility update on cancelling DragToDesktop transition
  [2/N] Interrupt DragToDesktop before bookend request -> move to Home
parents 68f764be 82a602a2
Loading
Loading
Loading
Loading
+2 −2
Original line number Original line Diff line number Diff line
@@ -32,8 +32,6 @@ import android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED
import android.app.WindowConfiguration.WindowingMode
import android.app.WindowConfiguration.WindowingMode
import android.content.Context
import android.content.Context
import android.content.Intent
import android.content.Intent
import android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK
import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
import android.graphics.Point
import android.graphics.Point
import android.graphics.PointF
import android.graphics.PointF
import android.graphics.Rect
import android.graphics.Rect
@@ -654,6 +652,7 @@ class DesktopTasksController(
        taskInfo: RunningTaskInfo,
        taskInfo: RunningTaskInfo,
        dragToDesktopValueAnimator: MoveToDesktopAnimator,
        dragToDesktopValueAnimator: MoveToDesktopAnimator,
        taskSurface: SurfaceControl,
        taskSurface: SurfaceControl,
        dragInterruptedCallback: Runnable,
    ) {
    ) {
        logV("startDragToDesktop taskId=%d", taskInfo.taskId)
        logV("startDragToDesktop taskId=%d", taskInfo.taskId)
        val jankConfigBuilder =
        val jankConfigBuilder =
@@ -669,6 +668,7 @@ class DesktopTasksController(
            taskInfo,
            taskInfo,
            dragToDesktopValueAnimator,
            dragToDesktopValueAnimator,
            visualIndicator,
            visualIndicator,
            dragInterruptedCallback,
        )
        )
    }
    }


+76 −12
Original line number Original line Diff line number Diff line
@@ -2,6 +2,7 @@ package com.android.wm.shell.desktopmode


import android.animation.Animator
import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.animation.AnimatorListenerAdapter
import android.animation.AnimatorSet
import android.animation.RectEvaluator
import android.animation.RectEvaluator
import android.animation.ValueAnimator
import android.animation.ValueAnimator
import android.app.ActivityManager.RunningTaskInfo
import android.app.ActivityManager.RunningTaskInfo
@@ -23,6 +24,7 @@ import android.os.IBinder
import android.os.SystemClock
import android.os.SystemClock
import android.os.SystemProperties
import android.os.SystemProperties
import android.os.UserHandle
import android.os.UserHandle
import android.view.Choreographer
import android.view.SurfaceControl
import android.view.SurfaceControl
import android.view.SurfaceControl.Transaction
import android.view.SurfaceControl.Transaction
import android.view.WindowManager.TRANSIT_CLOSE
import android.view.WindowManager.TRANSIT_CLOSE
@@ -48,6 +50,7 @@ import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_DESKT
import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_DESKTOP_MODE_START_DRAG_TO_DESKTOP
import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_DESKTOP_MODE_START_DRAG_TO_DESKTOP
import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
import com.android.wm.shell.shared.TransitionUtil
import com.android.wm.shell.shared.TransitionUtil
import com.android.wm.shell.shared.animation.Interpolators
import com.android.wm.shell.shared.animation.PhysicsAnimator
import com.android.wm.shell.shared.animation.PhysicsAnimator
import com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT
import com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT
import com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT
import com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT
@@ -122,6 +125,7 @@ sealed class DragToDesktopTransitionHandler(
        taskInfo: RunningTaskInfo,
        taskInfo: RunningTaskInfo,
        dragToDesktopAnimator: MoveToDesktopAnimator,
        dragToDesktopAnimator: MoveToDesktopAnimator,
        visualIndicator: DesktopModeVisualIndicator?,
        visualIndicator: DesktopModeVisualIndicator?,
        dragCancelCallback: Runnable,
    ) {
    ) {
        if (inProgress) {
        if (inProgress) {
            logV("Drag to desktop transition already in progress.")
            logV("Drag to desktop transition already in progress.")
@@ -168,6 +172,7 @@ sealed class DragToDesktopTransitionHandler(
                    startTransitionToken = startTransitionToken,
                    startTransitionToken = startTransitionToken,
                    otherSplitTask = otherTask,
                    otherSplitTask = otherTask,
                    visualIndicator = visualIndicator,
                    visualIndicator = visualIndicator,
                    dragCancelCallback = dragCancelCallback,
                )
                )
            } else {
            } else {
                TransitionState.FromFullscreen(
                TransitionState.FromFullscreen(
@@ -175,6 +180,7 @@ sealed class DragToDesktopTransitionHandler(
                    dragAnimator = dragToDesktopAnimator,
                    dragAnimator = dragToDesktopAnimator,
                    startTransitionToken = startTransitionToken,
                    startTransitionToken = startTransitionToken,
                    visualIndicator = visualIndicator,
                    visualIndicator = visualIndicator,
                    dragCancelCallback = dragCancelCallback,
                )
                )
            }
            }
    }
    }
@@ -203,8 +209,9 @@ sealed class DragToDesktopTransitionHandler(
        }
        }
        if (state.startInterrupted) {
        if (state.startInterrupted) {
            logV("finishDragToDesktop: start was interrupted, returning")
            logV("finishDragToDesktop: start was interrupted, returning")
            // We should only have interrupted the start transition after receiving a cancel/end
            // If start was interrupted we've either already requested a cancel/end transition - so
            // request, let that existing request play out and just return here.
            // we should let that request play out, or we're cancelling the drag-to-desktop
            // transition altogether, so just return here.
            return null
            return null
        }
        }
        state.endTransitionToken =
        state.endTransitionToken =
@@ -221,6 +228,7 @@ sealed class DragToDesktopTransitionHandler(
     */
     */
    fun cancelDragToDesktopTransition(cancelState: CancelState) {
    fun cancelDragToDesktopTransition(cancelState: CancelState) {
        if (!inProgress) {
        if (!inProgress) {
            logV("cancelDragToDesktop: not in progress, returning")
            // Don't attempt to cancel a drag to desktop transition since there is no transition in
            // Don't attempt to cancel a drag to desktop transition since there is no transition in
            // progress which means that the drag to desktop transition was never successfully
            // progress which means that the drag to desktop transition was never successfully
            // started.
            // started.
@@ -228,14 +236,17 @@ sealed class DragToDesktopTransitionHandler(
        }
        }
        val state = requireTransitionState()
        val state = requireTransitionState()
        if (state.startAborted) {
        if (state.startAborted) {
            logV("cancelDragToDesktop: start was aborted, clearing state")
            // Don't attempt to cancel the drag-to-desktop since the start transition didn't
            // Don't attempt to cancel the drag-to-desktop since the start transition didn't
            // succeed as expected. Just reset the state as if nothing happened.
            // succeed as expected. Just reset the state as if nothing happened.
            clearState()
            clearState()
            return
            return
        }
        }
        if (state.startInterrupted) {
        if (state.startInterrupted) {
            // We should only have interrupted the start transition after receiving a cancel/end
            logV("cancelDragToDesktop: start was interrupted, returning")
            // request, let that existing request play out and just return here.
            // If start was interrupted we've either already requested a cancel/end transition - so
            // we should let that request play out, or we're cancelling the drag-to-desktop
            // transition altogether, so just return here.
            return
            return
        }
        }
        state.cancelState = cancelState
        state.cancelState = cancelState
@@ -706,11 +717,7 @@ sealed class DragToDesktopTransitionHandler(
        // end-transition, or if the end-transition is running on its own, then just wait until that
        // end-transition, or if the end-transition is running on its own, then just wait until that
        // finishes instead. If we've merged the cancel-transition we've finished the
        // finishes instead. If we've merged the cancel-transition we've finished the
        // start-transition and won't reach this code.
        // start-transition and won't reach this code.
        if (
        if (mergeTarget == state.startTransitionToken && !state.mergedEndTransition) {
            mergeTarget == state.startTransitionToken &&
                isCancelOrEndTransitionRequested(state) &&
                !state.mergedEndTransition
        ) {
            interruptStartTransition(state)
            interruptStartTransition(state)
        }
        }
    }
    }
@@ -722,9 +729,23 @@ sealed class DragToDesktopTransitionHandler(
        if (!ENABLE_DRAG_TO_DESKTOP_INCOMING_TRANSITIONS_BUGFIX.isTrue) {
        if (!ENABLE_DRAG_TO_DESKTOP_INCOMING_TRANSITIONS_BUGFIX.isTrue) {
            return
            return
        }
        }
        logV("interruptStartTransition")
        if (isCancelOrEndTransitionRequested(state)) {
            logV("interruptStartTransition, bookend requested -> finish start transition")
            // Finish the start-drag transition, we will finish the overall transition properly when
            // receiving #startAnimation for Cancel/End.
            state.startTransitionFinishCb?.onTransitionFinished(/* wct= */ null)
            state.startTransitionFinishCb?.onTransitionFinished(/* wct= */ null)
            state.dragAnimator.cancelAnimator()
            state.dragAnimator.cancelAnimator()
        } else {
            logV("interruptStartTransition, bookend not requested -> animate to Home")
            // Animate to Home, and then finish the start-drag transition. Since there is no other
            // (end/cancel) transition requested that will be the end of the overall transition.
            state.dragAnimator.cancelAnimator()
            state.dragCancelCallback?.run()
            createInterruptToHomeAnimator(transactionSupplier.get(), state) {
                state.startTransitionFinishCb?.onTransitionFinished(/* wct= */ null)
                clearState()
            }
        }
        state.activeCancelAnimation?.removeAllListeners()
        state.activeCancelAnimation?.removeAllListeners()
        state.activeCancelAnimation?.cancel()
        state.activeCancelAnimation?.cancel()
        state.activeCancelAnimation = null
        state.activeCancelAnimation = null
@@ -738,6 +759,46 @@ sealed class DragToDesktopTransitionHandler(
            .onActionCancel(LatencyTracker.ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG)
            .onActionCancel(LatencyTracker.ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG)
    }
    }


    private fun createInterruptToHomeAnimator(
        transaction: Transaction,
        state: TransitionState,
        endCallback: Runnable,
    ) {
        val homeLeash = state.homeChange?.leash ?: error("Expected home leash to be non-null")
        val draggedTaskLeash =
            state.draggedTaskChange?.leash ?: error("Expected dragged leash to be non-null")
        val homeAnimator = createInterruptAlphaAnimator(transaction, homeLeash, toShow = true)
        val draggedTaskAnimator =
            createInterruptAlphaAnimator(transaction, draggedTaskLeash, toShow = false)
        val animatorSet = AnimatorSet()
        animatorSet.playTogether(homeAnimator, draggedTaskAnimator)
        animatorSet.addListener(
            object : AnimatorListenerAdapter() {
                override fun onAnimationEnd(animation: Animator) {
                    endCallback.run()
                }
            }
        )
        animatorSet.start()
    }

    private fun createInterruptAlphaAnimator(
        transaction: Transaction,
        leash: SurfaceControl,
        toShow: Boolean,
    ) =
        ValueAnimator.ofFloat(if (toShow) 0f else 1f, if (toShow) 1f else 0f).apply {
            transaction.show(leash)
            duration = DRAG_TO_DESKTOP_FINISH_ANIM_DURATION_MS
            interpolator = Interpolators.LINEAR
            addUpdateListener { animation ->
                transaction
                    .setAlpha(leash, animation.animatedValue as Float)
                    .setFrameTimeline(Choreographer.getInstance().vsyncId)
                    .apply()
            }
        }

    protected open fun setupEndDragToDesktop(
    protected open fun setupEndDragToDesktop(
        info: TransitionInfo,
        info: TransitionInfo,
        startTransaction: SurfaceControl.Transaction,
        startTransaction: SurfaceControl.Transaction,
@@ -1060,6 +1121,7 @@ sealed class DragToDesktopTransitionHandler(
        abstract var endTransitionToken: IBinder?
        abstract var endTransitionToken: IBinder?
        abstract var mergedEndTransition: Boolean
        abstract var mergedEndTransition: Boolean
        abstract var activeCancelAnimation: Animator?
        abstract var activeCancelAnimation: Animator?
        abstract var dragCancelCallback: Runnable?


        data class FromFullscreen(
        data class FromFullscreen(
            override val draggedTaskId: Int,
            override val draggedTaskId: Int,
@@ -1079,6 +1141,7 @@ sealed class DragToDesktopTransitionHandler(
            override var endTransitionToken: IBinder? = null,
            override var endTransitionToken: IBinder? = null,
            override var mergedEndTransition: Boolean = false,
            override var mergedEndTransition: Boolean = false,
            override var activeCancelAnimation: Animator? = null,
            override var activeCancelAnimation: Animator? = null,
            override var dragCancelCallback: Runnable? = null,
            var otherRootChanges: MutableList<Change> = mutableListOf(),
            var otherRootChanges: MutableList<Change> = mutableListOf(),
        ) : TransitionState()
        ) : TransitionState()


@@ -1100,6 +1163,7 @@ sealed class DragToDesktopTransitionHandler(
            override var endTransitionToken: IBinder? = null,
            override var endTransitionToken: IBinder? = null,
            override var mergedEndTransition: Boolean = false,
            override var mergedEndTransition: Boolean = false,
            override var activeCancelAnimation: Animator? = null,
            override var activeCancelAnimation: Animator? = null,
            override var dragCancelCallback: Runnable? = null,
            var splitRootChange: Change? = null,
            var splitRootChange: Change? = null,
            var otherSplitTask: Int,
            var otherSplitTask: Int,
        ) : TransitionState()
        ) : TransitionState()
+51 −38
Original line number Original line Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.wm.shell.transition;


import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.window.DesktopModeFlags.ENABLE_DRAG_TO_DESKTOP_INCOMING_TRANSITIONS_BUGFIX;
import static android.window.TransitionInfo.FLAG_BACK_GESTURE_ANIMATED;
import static android.window.TransitionInfo.FLAG_BACK_GESTURE_ANIMATED;


import static com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_DESKTOP_MODE_START_DRAG_TO_DESKTOP;
import static com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_DESKTOP_MODE_START_DRAG_TO_DESKTOP;
@@ -50,6 +51,7 @@ public class HomeTransitionObserver implements TransitionObserver,


    private @NonNull final Context mContext;
    private @NonNull final Context mContext;
    private @NonNull final ShellExecutor mMainExecutor;
    private @NonNull final ShellExecutor mMainExecutor;
    private IBinder mPendingStartDragTransition;
    private Boolean mPendingHomeVisibilityUpdate;
    private Boolean mPendingHomeVisibilityUpdate;


    public HomeTransitionObserver(@NonNull Context context,
    public HomeTransitionObserver(@NonNull Context context,
@@ -63,31 +65,42 @@ public class HomeTransitionObserver implements TransitionObserver,
            @NonNull TransitionInfo info,
            @NonNull TransitionInfo info,
            @NonNull SurfaceControl.Transaction startTransaction,
            @NonNull SurfaceControl.Transaction startTransaction,
            @NonNull SurfaceControl.Transaction finishTransaction) {
            @NonNull SurfaceControl.Transaction finishTransaction) {
        if (BubbleAnythingFlagHelper.enableBubbleToFullscreen()) {
        Boolean homeVisibilityUpdate = getHomeVisibilityUpdate(info);
            handleTransitionReadyWithBubbleAnything(info);

        } else {
        if (info.getType() == TRANSIT_DESKTOP_MODE_START_DRAG_TO_DESKTOP) {
            handleTransitionReady(info);
            // Do not apply at the start of desktop drag as that updates launcher UI visibility.
        }
            // Store the value and apply with a next transition or when cancelling the
            // desktop-drag transition.
            storePendingHomeVisibilityUpdate(transition, homeVisibilityUpdate);
            return;
        }
        }


    private void handleTransitionReady(@NonNull TransitionInfo info) {
        if (BubbleAnythingFlagHelper.enableBubbleToFullscreen()
        for (TransitionInfo.Change change : info.getChanges()) {
                && info.getType() == TRANSIT_CONVERT_TO_BUBBLE
            final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
                && homeVisibilityUpdate == null) {
            if (taskInfo == null
            // We are converting to bubble and we did not get a change to home visibility in this
                    || info.getType() == TRANSIT_DESKTOP_MODE_START_DRAG_TO_DESKTOP
            // transition. Apply the value from start of drag.
                    || taskInfo.displayId != DEFAULT_DISPLAY
            homeVisibilityUpdate = mPendingHomeVisibilityUpdate;
                    || taskInfo.taskId == -1
                    || !taskInfo.isRunning) {
                continue;
        }
        }
            Boolean homeVisibilityUpdate = getHomeVisibilityUpdate(info, change, taskInfo);

        if (homeVisibilityUpdate != null) {
        if (homeVisibilityUpdate != null) {
            mPendingHomeVisibilityUpdate = null;
            mPendingStartDragTransition = null;
            notifyHomeVisibilityChanged(homeVisibilityUpdate);
            notifyHomeVisibilityChanged(homeVisibilityUpdate);
        }
        }
    }
    }

    private void storePendingHomeVisibilityUpdate(
            IBinder transition, Boolean homeVisibilityUpdate) {
        if (!BubbleAnythingFlagHelper.enableBubbleToFullscreen()
                && !ENABLE_DRAG_TO_DESKTOP_INCOMING_TRANSITIONS_BUGFIX.isTrue()) {
            return;
        }
        mPendingHomeVisibilityUpdate = homeVisibilityUpdate;
        mPendingStartDragTransition = transition;
    }
    }


    private void handleTransitionReadyWithBubbleAnything(@NonNull TransitionInfo info) {
    private Boolean getHomeVisibilityUpdate(TransitionInfo info) {
        Boolean homeVisibilityUpdate = null;
        Boolean homeVisibilityUpdate = null;
        for (TransitionInfo.Change change : info.getChanges()) {
        for (TransitionInfo.Change change : info.getChanges()) {
            final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
            final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
@@ -97,29 +110,12 @@ public class HomeTransitionObserver implements TransitionObserver,
                    || !taskInfo.isRunning) {
                    || !taskInfo.isRunning) {
                continue;
                continue;
            }
            }

            Boolean update = getHomeVisibilityUpdate(info, change, taskInfo);
            Boolean update = getHomeVisibilityUpdate(info, change, taskInfo);
            if (update != null) {
            if (update != null) {
                homeVisibilityUpdate = update;
                homeVisibilityUpdate = update;
            }
            }
        }
        }

        return homeVisibilityUpdate;
        if (info.getType() == TRANSIT_DESKTOP_MODE_START_DRAG_TO_DESKTOP) {
            // Do not apply at the start of desktop drag as that updates launcher UI visibility.
            // Store the value and apply with a next transition if needed.
            mPendingHomeVisibilityUpdate = homeVisibilityUpdate;
            return;
        }

        if (info.getType() == TRANSIT_CONVERT_TO_BUBBLE && homeVisibilityUpdate == null) {
            // We are converting to bubble and we did not get a change to home visibility in this
            // transition. Apply the value from start of drag.
            homeVisibilityUpdate = mPendingHomeVisibilityUpdate;
        }
        if (homeVisibilityUpdate != null) {
            mPendingHomeVisibilityUpdate = null;
            notifyHomeVisibilityChanged(homeVisibilityUpdate);
        }
    }
    }


    private Boolean getHomeVisibilityUpdate(TransitionInfo info,
    private Boolean getHomeVisibilityUpdate(TransitionInfo info,
@@ -146,7 +142,24 @@ public class HomeTransitionObserver implements TransitionObserver,


    @Override
    @Override
    public void onTransitionFinished(@NonNull IBinder transition,
    public void onTransitionFinished(@NonNull IBinder transition,
            boolean aborted) {}
            boolean aborted) {
        if (!ENABLE_DRAG_TO_DESKTOP_INCOMING_TRANSITIONS_BUGFIX.isTrue()) {
            return;
        }
        // Handle the case where the DragToDesktop START transition is interrupted and we never
        // receive a CANCEL/END transition.
        if (mPendingStartDragTransition == null
                || mPendingStartDragTransition != transition) {
            return;
        }
        mPendingStartDragTransition = null;
        if (aborted) return;

        if (mPendingHomeVisibilityUpdate != null) {
            notifyHomeVisibilityChanged(mPendingHomeVisibilityUpdate);
            mPendingHomeVisibilityUpdate = null;
        }
    }


    /**
    /**
     * Sets the home transition listener that receives any transitions resulting in a change of
     * Sets the home transition listener that receives any transitions resulting in a change of
+24 −5
Original line number Original line Diff line number Diff line
@@ -979,6 +979,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
        private boolean mIsCustomHeaderGesture;
        private boolean mIsCustomHeaderGesture;
        private boolean mIsResizeGesture;
        private boolean mIsResizeGesture;
        private boolean mIsDragging;
        private boolean mIsDragging;
        private boolean mDragInterrupted;
        private boolean mLongClickDisabled;
        private boolean mLongClickDisabled;
        private int mDragPointerId = -1;
        private int mDragPointerId = -1;
        private MotionEvent mMotionEvent;
        private MotionEvent mMotionEvent;
@@ -1216,7 +1217,12 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
                View v, MotionEvent e) {
                View v, MotionEvent e) {
            final int id = v.getId();
            final int id = v.getId();
            if (id == R.id.caption_handle) {
            if (id == R.id.caption_handle) {
                handleCaptionThroughStatusBar(e, decoration);
                handleCaptionThroughStatusBar(e, decoration,
                        /* interruptDragCallback= */
                        () -> {
                            mDragInterrupted = true;
                            setIsDragging(decoration, /* isDragging= */ false);
                        });
                final boolean wasDragging = mIsDragging;
                final boolean wasDragging = mIsDragging;
                updateDragStatus(decoration, e);
                updateDragStatus(decoration, e);
                final boolean upOrCancel = e.getActionMasked() == ACTION_UP
                final boolean upOrCancel = e.getActionMasked() == ACTION_UP
@@ -1333,11 +1339,14 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
                case MotionEvent.ACTION_DOWN:
                case MotionEvent.ACTION_DOWN:
                case MotionEvent.ACTION_UP:
                case MotionEvent.ACTION_UP:
                case MotionEvent.ACTION_CANCEL: {
                case MotionEvent.ACTION_CANCEL: {
                    mDragInterrupted = false;
                    setIsDragging(decor, false /* isDragging */);
                    setIsDragging(decor, false /* isDragging */);
                    break;
                    break;
                }
                }
                case MotionEvent.ACTION_MOVE: {
                case MotionEvent.ACTION_MOVE: {
                    if (!mDragInterrupted) {
                        setIsDragging(decor, true /* isDragging */);
                        setIsDragging(decor, true /* isDragging */);
                    }
                    break;
                    break;
                }
                }
            }
            }
@@ -1458,7 +1467,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
            if (!mInImmersiveMode && (relevantDecor == null
            if (!mInImmersiveMode && (relevantDecor == null
                    || relevantDecor.mTaskInfo.getWindowingMode() != WINDOWING_MODE_FREEFORM
                    || relevantDecor.mTaskInfo.getWindowingMode() != WINDOWING_MODE_FREEFORM
                    || mTransitionDragActive)) {
                    || mTransitionDragActive)) {
                handleCaptionThroughStatusBar(ev, relevantDecor);
                handleCaptionThroughStatusBar(ev, relevantDecor,
                        /* interruptDragCallback= */ () -> {});
            }
            }
        }
        }
        handleEventOutsideCaption(ev, relevantDecor);
        handleEventOutsideCaption(ev, relevantDecor);
@@ -1498,7 +1508,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
     * Turn on desktop mode if handle is dragged below status bar.
     * Turn on desktop mode if handle is dragged below status bar.
     */
     */
    private void handleCaptionThroughStatusBar(MotionEvent ev,
    private void handleCaptionThroughStatusBar(MotionEvent ev,
            DesktopModeWindowDecoration relevantDecor) {
            DesktopModeWindowDecoration relevantDecor, Runnable interruptDragCallback) {
        if (relevantDecor == null) {
        if (relevantDecor == null) {
            if (ev.getActionMasked() == ACTION_UP) {
            if (ev.getActionMasked() == ACTION_UP) {
                mMoveToDesktopAnimator = null;
                mMoveToDesktopAnimator = null;
@@ -1599,7 +1609,16 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
                                    mContext, mDragToDesktopAnimationStartBounds,
                                    mContext, mDragToDesktopAnimationStartBounds,
                                    relevantDecor.mTaskInfo, relevantDecor.mTaskSurface);
                                    relevantDecor.mTaskInfo, relevantDecor.mTaskSurface);
                            mDesktopTasksController.startDragToDesktop(relevantDecor.mTaskInfo,
                            mDesktopTasksController.startDragToDesktop(relevantDecor.mTaskInfo,
                                    mMoveToDesktopAnimator, relevantDecor.mTaskSurface);
                                    mMoveToDesktopAnimator, relevantDecor.mTaskSurface,
                                    /* dragInterruptedCallback= */ () -> {
                                        // Don't call into DesktopTasksController to cancel the
                                        // transition here - the transition handler already handles
                                        // that (including removing the visual indicator).
                                        mTransitionDragActive = false;
                                        mMoveToDesktopAnimator = null;
                                        relevantDecor.handleDragInterrupted();
                                        interruptDragCallback.run();
                                    });
                        }
                        }
                    }
                    }
                    if (mMoveToDesktopAnimator != null) {
                    if (mMoveToDesktopAnimator != null) {
+11 −0
Original line number Original line Diff line number Diff line
@@ -1683,6 +1683,17 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
        }
        }
    }
    }


    /**
     * Indicates that an app handle drag has been interrupted, this can happen e.g. if we receive an
     * unknown transition during the drag-to-desktop transition.
     */
    void handleDragInterrupted() {
        if (mResult.mRootView == null) return;
        final View handle = mResult.mRootView.findViewById(R.id.caption_handle);
        handle.setHovered(false);
        handle.setPressed(false);
    }

    private boolean pointInView(View v, float x, float y) {
    private boolean pointInView(View v, float x, float y) {
        return v != null && v.getLeft() <= x && v.getRight() >= x
        return v != null && v.getLeft() <= x && v.getRight() >= x
                && v.getTop() <= y && v.getBottom() >= y;
                && v.getTop() <= y && v.getBottom() >= y;
Loading