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

Commit 80314dbd authored by Maryam Dehaini's avatar Maryam Dehaini Committed by Android (Google) Code Review
Browse files

Merge "Update positioning during drag using SurfaceControl.Transaction" into udc-dev

parents 785f5485 8aa9d4d2
Loading
Loading
Loading
Loading
+8 −10
Original line number Diff line number Diff line
@@ -16,7 +16,6 @@

package com.android.wm.shell.desktopmode

import android.app.ActivityManager
import android.app.ActivityManager.RunningTaskInfo
import android.app.WindowConfiguration.ACTIVITY_TYPE_HOME
import android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD
@@ -202,16 +201,15 @@ class DesktopTasksController(
        }
    }


    /**
     * Move a task to fullscreen after being dragged from fullscreen and released back into
     * status bar area
     */
    fun cancelMoveToFreeform(task: RunningTaskInfo, startPosition: Point) {
    fun cancelMoveToFreeform(task: RunningTaskInfo, position: Point) {
        val wct = WindowContainerTransaction()
        addMoveToFullscreenChanges(wct, task.token)
        if (Transitions.ENABLE_SHELL_TRANSITIONS) {
            enterDesktopTaskTransitionHandler.startCancelMoveToDesktopMode(wct, startPosition,
            enterDesktopTaskTransitionHandler.startCancelMoveToDesktopMode(wct, position,
                    mOnAnimationFinishedCallback)
        } else {
            shellTaskOrganizer.applyTransaction(wct)
@@ -219,13 +217,13 @@ class DesktopTasksController(
        }
    }

    private fun moveToFullscreenWithAnimation(task: ActivityManager.RunningTaskInfo) {
    private fun moveToFullscreenWithAnimation(task: RunningTaskInfo, position: Point) {
        val wct = WindowContainerTransaction()
        addMoveToFullscreenChanges(wct, task.token)

        if (Transitions.ENABLE_SHELL_TRANSITIONS) {
            exitDesktopTaskTransitionHandler.startTransition(
            Transitions.TRANSIT_EXIT_DESKTOP_MODE, wct, mOnAnimationFinishedCallback)
            Transitions.TRANSIT_EXIT_DESKTOP_MODE, wct, position, mOnAnimationFinishedCallback)
        } else {
            shellTaskOrganizer.applyTransaction(wct)
            releaseVisualIndicator()
@@ -499,15 +497,15 @@ class DesktopTasksController(
     * Perform checks required on drag end. Move to fullscreen if drag ends in status bar area.
     *
     * @param taskInfo the task being dragged.
     * @param y height of drag, to be checked against status bar height.
     * @param position position of surface when drag ends
     */
    fun onDragPositioningEnd(
            taskInfo: RunningTaskInfo,
            y: Float
            position: Point
    ) {
        val statusBarHeight = getStatusBarHeight(taskInfo)
        if (y <= statusBarHeight && taskInfo.windowingMode == WINDOWING_MODE_FREEFORM) {
            moveToFullscreenWithAnimation(taskInfo)
        if (position.y <= statusBarHeight && taskInfo.windowingMode == WINDOWING_MODE_FREEFORM) {
            moveToFullscreenWithAnimation(taskInfo, position)
        }
    }

+7 −7
Original line number Diff line number Diff line
@@ -58,7 +58,7 @@ public class EnterDesktopTaskTransitionHandler implements Transitions.Transition
    public static final int FREEFORM_ANIMATION_DURATION = 336;

    private final List<IBinder> mPendingTransitionTokens = new ArrayList<>();
    private Point mStartPosition;
    private Point mPosition;
    private Consumer<SurfaceControl.Transaction> mOnAnimationFinishedCallback;

    public EnterDesktopTaskTransitionHandler(
@@ -90,15 +90,15 @@ public class EnterDesktopTaskTransitionHandler implements Transitions.Transition
    /**
     * Starts Transition of type TRANSIT_CANCEL_ENTERING_DESKTOP_MODE
     * @param wct WindowContainerTransaction for transition
     * @param startPosition Position of task when transition is triggered
     * @param position Position of task when transition is triggered
     * @param onAnimationEndCallback to be called after animation
     */
    public void startCancelMoveToDesktopMode(@NonNull WindowContainerTransaction wct,
            Point startPosition,
            Point position,
            Consumer<SurfaceControl.Transaction> onAnimationEndCallback) {
        mStartPosition = startPosition;
        mPosition = position;
        startTransition(Transitions.TRANSIT_CANCEL_ENTERING_DESKTOP_MODE, wct,
                mOnAnimationFinishedCallback);
                onAnimationEndCallback);
    }

    @Override
@@ -201,7 +201,7 @@ public class EnterDesktopTaskTransitionHandler implements Transitions.Transition

        if (type == Transitions.TRANSIT_CANCEL_ENTERING_DESKTOP_MODE
                && taskInfo.getWindowingMode() == WINDOWING_MODE_FULLSCREEN
                && mStartPosition != null) {
                && mPosition != null) {
            // This Transition animates a task to fullscreen after being dragged from the status
            // bar and then released back into the status bar area
            final SurfaceControl sc = change.getLeash();
@@ -217,7 +217,7 @@ public class EnterDesktopTaskTransitionHandler implements Transitions.Transition
            final SurfaceControl.Transaction t = mTransactionSupplier.get();
            animator.addUpdateListener(animation -> {
                final float scale = (float) animation.getAnimatedValue();
                t.setPosition(sc, mStartPosition.x * (1 - scale), mStartPosition.y * (1 - scale))
                t.setPosition(sc, mPosition.x * (1 - scale), mPosition.y * (1 - scale))
                        .setScale(sc, scale, scale)
                        .show(sc)
                        .apply();
+7 −4
Original line number Diff line number Diff line
@@ -57,6 +57,7 @@ public class ExitDesktopTaskTransitionHandler implements Transitions.TransitionH
    private final List<IBinder> mPendingTransitionTokens = new ArrayList<>();
    private Consumer<SurfaceControl.Transaction> mOnAnimationFinishedCallback;
    private Supplier<SurfaceControl.Transaction> mTransactionSupplier;
    private Point mPosition;

    public ExitDesktopTaskTransitionHandler(
            Transitions transitions,
@@ -77,11 +78,13 @@ public class ExitDesktopTaskTransitionHandler implements Transitions.TransitionH
     * Starts Transition of a given type
     * @param type Transition type
     * @param wct WindowContainerTransaction for transition
     * @param position Position of the task when transition is started
     * @param onAnimationEndCallback to be called after animation
     */
    public void startTransition(@WindowManager.TransitionType int type,
            @NonNull WindowContainerTransaction wct,
            @NonNull WindowContainerTransaction wct, Point position,
            Consumer<SurfaceControl.Transaction> onAnimationEndCallback) {
        mPosition = position;
        mOnAnimationFinishedCallback = onAnimationEndCallback;
        final IBinder token = mTransitions.startTransition(type, wct, this);
        mPendingTransitionTokens.add(token);
@@ -143,17 +146,17 @@ public class ExitDesktopTaskTransitionHandler implements Transitions.TransitionH
            final ValueAnimator animator = new ValueAnimator();
            animator.setFloatValues(0f, 1f);
            animator.setDuration(FULLSCREEN_ANIMATION_DURATION);
            // The start bounds contain the correct dimensions of the task but hold the positioning
            // before being dragged to the status bar to transition into fullscreen
            final Rect startBounds = change.getStartAbsBounds();
            final float scaleX = (float) startBounds.width() / screenWidth;
            final float scaleY = (float) startBounds.height() / screenHeight;
            final SurfaceControl.Transaction t = mTransactionSupplier.get();
            Point startPos = new Point(startBounds.left,
                    startBounds.top);
            animator.addUpdateListener(animation -> {
                float fraction = animation.getAnimatedFraction();
                float currentScaleX = scaleX + ((1 - scaleX) * fraction);
                float currentScaleY = scaleY + ((1 - scaleY) * fraction);
                t.setPosition(sc, startPos.x * (1 - fraction), startPos.y * (1 - fraction))
                t.setPosition(sc, mPosition.x * (1 - fraction), mPosition.y * (1 - fraction))
                        .setScale(sc, currentScaleX, currentScaleY)
                        .show(sc)
                        .apply();
+16 −4
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;

import android.app.ActivityManager.RunningTaskInfo;
import android.content.Context;
import android.graphics.Rect;
import android.os.Handler;
import android.os.IBinder;
import android.util.SparseArray;
@@ -185,18 +186,29 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
                        mSyncQueue);
        mWindowDecorByTaskId.put(taskInfo.taskId, windowDecoration);

        final FluidResizeTaskPositioner taskPositioner =
                new FluidResizeTaskPositioner(mTaskOrganizer, windowDecoration, mDisplayController);
        final DragPositioningCallback dragPositioningCallback = createDragPositioningCallback(
                windowDecoration, taskInfo);
        final CaptionTouchEventListener touchEventListener =
                new CaptionTouchEventListener(taskInfo, taskPositioner);
                new CaptionTouchEventListener(taskInfo, dragPositioningCallback);
        windowDecoration.setCaptionListeners(touchEventListener, touchEventListener);
        windowDecoration.setDragPositioningCallback(taskPositioner);
        windowDecoration.setDragPositioningCallback(dragPositioningCallback);
        windowDecoration.setDragDetector(touchEventListener.mDragDetector);
        windowDecoration.relayout(taskInfo, startT, finishT,
                false /* applyStartTransactionOnDraw */);
        setupCaptionColor(taskInfo, windowDecoration);
    }

    private FluidResizeTaskPositioner createDragPositioningCallback(
            CaptionWindowDecoration windowDecoration, RunningTaskInfo taskInfo) {
        final int screenWidth = mDisplayController.getDisplayLayout(taskInfo.displayId).width();
        final int statusBarHeight = mDisplayController.getDisplayLayout(taskInfo.displayId)
                .stableInsets().top;
        final Rect disallowedAreaForEndBounds = new Rect(0, 0, screenWidth,
                statusBarHeight);
        return new FluidResizeTaskPositioner(mTaskOrganizer, windowDecoration,
                    mDisplayController, disallowedAreaForEndBounds);
    }

    private class CaptionTouchEventListener implements
            View.OnClickListener, View.OnTouchListener, DragDetector.MotionEventHandler {

+37 −26
Original line number Diff line number Diff line
@@ -33,7 +33,6 @@ import android.app.ActivityManager;
import android.app.ActivityManager.RunningTaskInfo;
import android.app.ActivityTaskManager;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.Region;
@@ -41,7 +40,6 @@ import android.hardware.input.InputManager;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.util.DisplayMetrics;
import android.util.SparseArray;
import android.view.Choreographer;
import android.view.InputChannel;
@@ -63,6 +61,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.wm.shell.R;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.desktopmode.DesktopModeController;
import com.android.wm.shell.desktopmode.DesktopModeStatus;
@@ -392,10 +391,16 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
                case MotionEvent.ACTION_UP:
                case MotionEvent.ACTION_CANCEL: {
                    final int dragPointerIdx = e.findPointerIndex(mDragPointerId);
                    // Position of the task is calculated by subtracting the raw location of the
                    // motion event (the location of the motion relative to the display) by the
                    // location of the motion event relative to the task's bounds
                    final Point position = new Point(
                            (int) (e.getRawX(dragPointerIdx) - e.getX(dragPointerIdx)),
                            (int) (e.getRawY(dragPointerIdx) - e.getY(dragPointerIdx)));
                    mDragPositioningCallback.onDragPositioningEnd(
                            e.getRawX(dragPointerIdx), e.getRawY(dragPointerIdx));
                    mDesktopTasksController.ifPresent(c -> c.onDragPositioningEnd(taskInfo,
                            e.getRawY(dragPointerIdx)));
                            position));
                    final boolean wasDragging = mIsDragging;
                    mIsDragging = false;
                    return wasDragging;
@@ -560,10 +565,10 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
                        mDragToDesktopAnimationStarted = false;
                        return;
                    } else if (mDragToDesktopAnimationStarted) {
                        Point startPosition = new Point((int) ev.getX(), (int) ev.getY());
                        Point position = new Point((int) ev.getX(), (int) ev.getY());
                        mDesktopTasksController.ifPresent(
                                c -> c.cancelMoveToFreeform(relevantDecor.mTaskInfo,
                                        startPosition));
                                        position));
                        mDragToDesktopAnimationStarted = false;
                        return;
                    }
@@ -615,11 +620,10 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
     * Gets bounds of a scaled window centered relative to the screen bounds
     * @param scale the amount to scale to relative to the Screen Bounds
     */
    private Rect calculateFreeformBounds(float scale) {
        final Resources resources = mContext.getResources();
        final DisplayMetrics metrics = resources.getDisplayMetrics();
        final int screenWidth = metrics.widthPixels;
        final int screenHeight = metrics.heightPixels;
    private Rect calculateFreeformBounds(int displayId, float scale) {
        final DisplayLayout displayLayout = mDisplayController.getDisplayLayout(displayId);
        final int screenWidth = displayLayout.width();
        final int screenHeight = displayLayout.height();

        final float adjustmentPercentage = (1f - scale) / 2;
        final Rect endBounds = new Rect((int) (screenWidth * adjustmentPercentage),
@@ -648,7 +652,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
        ValueAnimator animator = ValueAnimator.ofFloat(0f, 1f);
        animator.setDuration(FREEFORM_ANIMATION_DURATION);
        final SurfaceControl sc = relevantDecor.mTaskSurface;
        final Rect endBounds = calculateFreeformBounds(DRAG_FREEFORM_SCALE);
        final Rect endBounds = calculateFreeformBounds(ev.getDisplayId(), DRAG_FREEFORM_SCALE);
        final Transaction t = mTransactionFactory.get();
        final float diffX = endBounds.centerX() - ev.getX();
        final float diffY = endBounds.top - ev.getY();
@@ -665,9 +669,10 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
        animator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                mDesktopTasksController.ifPresent(c ->
                        c.onDragPositioningEndThroughStatusBar(relevantDecor.mTaskInfo,
                            calculateFreeformBounds(FINAL_FREEFORM_SCALE)));
                mDesktopTasksController.ifPresent(
                        c -> c.onDragPositioningEndThroughStatusBar(
                                relevantDecor.mTaskInfo,
                                calculateFreeformBounds(ev.getDisplayId(), FINAL_FREEFORM_SCALE)));
            }
        });
        animator.start();
@@ -783,17 +788,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
                        mSyncQueue);
        mWindowDecorByTaskId.put(taskInfo.taskId, windowDecoration);

        final DragPositioningCallback dragPositioningCallback;
        if (!DesktopModeStatus.isVeiledResizeEnabled()) {
            dragPositioningCallback =
                    new FluidResizeTaskPositioner(mTaskOrganizer, windowDecoration,
                            mDisplayController, mDragStartListener);
        } else {
            windowDecoration.createResizeVeil();
            dragPositioningCallback =
                    new VeiledResizeTaskPositioner(mTaskOrganizer, windowDecoration,
                            mDisplayController, mDragStartListener);
        }
        final DragPositioningCallback dragPositioningCallback = createDragPositioningCallback(
                windowDecoration, taskInfo);
        final DesktopModeTouchEventListener touchEventListener =
                new DesktopModeTouchEventListener(taskInfo, dragPositioningCallback);

@@ -805,7 +801,22 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
                false /* applyStartTransactionOnDraw */);
        incrementEventReceiverTasks(taskInfo.displayId);
    }

    private DragPositioningCallback createDragPositioningCallback(
            @NonNull DesktopModeWindowDecoration windowDecoration,
            @NonNull RunningTaskInfo taskInfo) {
        final int screenWidth = mDisplayController.getDisplayLayout(taskInfo.displayId).width();
        final Rect disallowedAreaForEndBounds = new Rect(0, 0, screenWidth,
                getStatusBarHeight(taskInfo.displayId));
        if (!DesktopModeStatus.isVeiledResizeEnabled()) {
            return new FluidResizeTaskPositioner(mTaskOrganizer, windowDecoration,
                    mDisplayController, disallowedAreaForEndBounds, mDragStartListener,
                    mTransactionFactory);
        } else {
            windowDecoration.createResizeVeil();
            return new VeiledResizeTaskPositioner(mTaskOrganizer, windowDecoration,
                    mDisplayController, disallowedAreaForEndBounds, mDragStartListener);
        }
    }

    private class DragStartListenerImpl
            implements DragPositioningCallbackUtility.DragStartListener {
Loading