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

Commit a5d9247b authored by mattsziklay's avatar mattsziklay
Browse files

Drag task to left or right edge to enter split select.

Adds visual indicators and calls to split select listener when dragging
a task to the left or right edge of the screen.

Bug: 279586624
Test: Manual
Change-Id: Id50e6b7fedb6f00e4944a6e0dbac41d22a4f0c72
parent 839f081b
Loading
Loading
Loading
Loading
+4 −0
Original line number Original line Diff line number Diff line
@@ -432,6 +432,10 @@


    <dimen name="freeform_resize_corner">44dp</dimen>
    <dimen name="freeform_resize_corner">44dp</dimen>


    <!-- The width of the area at the sides of the screen where a freeform task will transition to
    split select if dragged until the touch input is within the range. -->
    <dimen name="desktop_mode_transition_area_width">32dp</dimen>

    <!-- The height of the area at the top of the screen where a freeform task will transition to
    <!-- The height of the area at the top of the screen where a freeform task will transition to
    fullscreen if dragged until the top bound of the task is within the area. -->
    fullscreen if dragged until the top bound of the task is within the area. -->
    <dimen name="desktop_mode_transition_area_height">16dp</dimen>
    <dimen name="desktop_mode_transition_area_height">16dp</dimen>
+144 −50
Original line number Original line Diff line number Diff line
@@ -27,6 +27,7 @@ import android.app.ActivityManager;
import android.content.Context;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.Resources;
import android.graphics.PixelFormat;
import android.graphics.PixelFormat;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.Rect;
import android.util.DisplayMetrics;
import android.util.DisplayMetrics;
import android.view.SurfaceControl;
import android.view.SurfaceControl;
@@ -47,6 +48,15 @@ import com.android.wm.shell.common.SyncTransactionQueue;
 * Animated visual indicator for Desktop Mode windowing transitions.
 * Animated visual indicator for Desktop Mode windowing transitions.
 */
 */
public class DesktopModeVisualIndicator {
public class DesktopModeVisualIndicator {
    public static final int INVALID_INDICATOR = -1;
    /** Indicates impending transition into desktop mode */
    public static final int TO_DESKTOP_INDICATOR = 1;
    /** Indicates impending transition into fullscreen */
    public static final int TO_FULLSCREEN_INDICATOR = 2;
    /** Indicates impending transition into split select on the left side */
    public static final int TO_SPLIT_LEFT_INDICATOR = 3;
    /** Indicates impending transition into split select on the right side */
    public static final int TO_SPLIT_RIGHT_INDICATOR = 4;


    private final Context mContext;
    private final Context mContext;
    private final DisplayController mDisplayController;
    private final DisplayController mDisplayController;
@@ -54,6 +64,7 @@ public class DesktopModeVisualIndicator {
    private final RootTaskDisplayAreaOrganizer mRootTdaOrganizer;
    private final RootTaskDisplayAreaOrganizer mRootTdaOrganizer;
    private final ActivityManager.RunningTaskInfo mTaskInfo;
    private final ActivityManager.RunningTaskInfo mTaskInfo;
    private final SurfaceControl mTaskSurface;
    private final SurfaceControl mTaskSurface;
    private final Rect mIndicatorRange = new Rect();
    private SurfaceControl mLeash;
    private SurfaceControl mLeash;


    private final SyncTransactionQueue mSyncQueue;
    private final SyncTransactionQueue mSyncQueue;
@@ -61,11 +72,12 @@ public class DesktopModeVisualIndicator {


    private View mView;
    private View mView;
    private boolean mIsFullscreen;
    private boolean mIsFullscreen;
    private int mType;


    public DesktopModeVisualIndicator(SyncTransactionQueue syncQueue,
    public DesktopModeVisualIndicator(SyncTransactionQueue syncQueue,
            ActivityManager.RunningTaskInfo taskInfo, DisplayController displayController,
            ActivityManager.RunningTaskInfo taskInfo, DisplayController displayController,
            Context context, SurfaceControl taskSurface, ShellTaskOrganizer taskOrganizer,
            Context context, SurfaceControl taskSurface, ShellTaskOrganizer taskOrganizer,
            RootTaskDisplayAreaOrganizer taskDisplayAreaOrganizer) {
            RootTaskDisplayAreaOrganizer taskDisplayAreaOrganizer, int type) {
        mSyncQueue = syncQueue;
        mSyncQueue = syncQueue;
        mTaskInfo = taskInfo;
        mTaskInfo = taskInfo;
        mDisplayController = displayController;
        mDisplayController = displayController;
@@ -73,9 +85,63 @@ public class DesktopModeVisualIndicator {
        mTaskSurface = taskSurface;
        mTaskSurface = taskSurface;
        mTaskOrganizer = taskOrganizer;
        mTaskOrganizer = taskOrganizer;
        mRootTdaOrganizer = taskDisplayAreaOrganizer;
        mRootTdaOrganizer = taskDisplayAreaOrganizer;
        mType = type;
        defineIndicatorRange();
        createView();
        createView();
    }
    }


    /**
     * If an indicator is warranted based on the input and task bounds, return the type of
     * indicator that should be created.
     */
    public static int determineIndicatorType(PointF inputCoordinates, Rect taskBounds,
            DisplayLayout layout, Context context) {
        int transitionAreaHeight = context.getResources().getDimensionPixelSize(
                com.android.wm.shell.R.dimen.desktop_mode_transition_area_height);
        int transitionAreaWidth = context.getResources().getDimensionPixelSize(
                com.android.wm.shell.R.dimen.desktop_mode_transition_area_width);
        if (taskBounds.top <= transitionAreaHeight) return TO_FULLSCREEN_INDICATOR;
        if (inputCoordinates.x <= transitionAreaWidth) return TO_SPLIT_LEFT_INDICATOR;
        if (inputCoordinates.x >= layout.width() - transitionAreaWidth) {
            return TO_SPLIT_RIGHT_INDICATOR;
        }
        return INVALID_INDICATOR;
    }

    /**
     * Determine range of inputs that will keep this indicator displaying.
     */
    private void defineIndicatorRange() {
        DisplayLayout layout = mDisplayController.getDisplayLayout(mTaskInfo.displayId);
        int captionHeight = mContext.getResources().getDimensionPixelSize(
                com.android.wm.shell.R.dimen.freeform_decor_caption_height);
        int transitionAreaHeight = mContext.getResources().getDimensionPixelSize(
                com.android.wm.shell.R.dimen.desktop_mode_transition_area_height);
        int transitionAreaWidth = mContext.getResources().getDimensionPixelSize(
                com.android.wm.shell.R.dimen.desktop_mode_transition_area_width);
        switch (mType) {
            case TO_DESKTOP_INDICATOR:
                // TO_DESKTOP indicator is only dismissed on release; entire display is valid.
                mIndicatorRange.set(0, 0, layout.width(), layout.height());
                break;
            case TO_FULLSCREEN_INDICATOR:
                // If drag results in caption going above the top edge of the display, we still
                // want to transition to fullscreen.
                mIndicatorRange.set(0, -captionHeight, layout.width(), transitionAreaHeight);
                break;
            case TO_SPLIT_LEFT_INDICATOR:
                mIndicatorRange.set(0, transitionAreaHeight, transitionAreaWidth, layout.height());
                break;
            case TO_SPLIT_RIGHT_INDICATOR:
                mIndicatorRange.set(layout.width() - transitionAreaWidth, transitionAreaHeight,
                        layout.width(), layout.height());
                break;
            default:
                break;
        }
    }


    /**
    /**
     * Create a fullscreen indicator with no animation
     * Create a fullscreen indicator with no animation
     */
     */
@@ -85,11 +151,30 @@ public class DesktopModeVisualIndicator {
        final DisplayMetrics metrics = resources.getDisplayMetrics();
        final DisplayMetrics metrics = resources.getDisplayMetrics();
        final int screenWidth = metrics.widthPixels;
        final int screenWidth = metrics.widthPixels;
        final int screenHeight = metrics.heightPixels;
        final int screenHeight = metrics.heightPixels;

        mView = new View(mContext);
        mView = new View(mContext);
        final SurfaceControl.Builder builder = new SurfaceControl.Builder();
        final SurfaceControl.Builder builder = new SurfaceControl.Builder();
        mRootTdaOrganizer.attachToDisplayArea(mTaskInfo.displayId, builder);
        mRootTdaOrganizer.attachToDisplayArea(mTaskInfo.displayId, builder);
        String description;
        switch (mType) {
            case TO_DESKTOP_INDICATOR:
                description = "Desktop indicator";
                break;
            case TO_FULLSCREEN_INDICATOR:
                description = "Fullscreen indicator";
                break;
            case TO_SPLIT_LEFT_INDICATOR:
                description = "Split Left indicator";
                break;
            case TO_SPLIT_RIGHT_INDICATOR:
                description = "Split Right indicator";
                break;
            default:
                description = "Invalid indicator";
                break;
        }
        mLeash = builder
        mLeash = builder
                .setName("Fullscreen Indicator")
                .setName(description)
                .setContainerLayer()
                .setContainerLayer()
                .build();
                .build();
        t.show(mLeash);
        t.show(mLeash);
@@ -97,14 +182,14 @@ public class DesktopModeVisualIndicator {
                new WindowManager.LayoutParams(screenWidth, screenHeight,
                new WindowManager.LayoutParams(screenWidth, screenHeight,
                        WindowManager.LayoutParams.TYPE_APPLICATION,
                        WindowManager.LayoutParams.TYPE_APPLICATION,
                        WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSPARENT);
                        WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSPARENT);
        lp.setTitle("Fullscreen indicator for Task=" + mTaskInfo.taskId);
        lp.setTitle(description + " for Task=" + mTaskInfo.taskId);
        lp.setTrustedOverlay();
        lp.setTrustedOverlay();
        final WindowlessWindowManager windowManager = new WindowlessWindowManager(
        final WindowlessWindowManager windowManager = new WindowlessWindowManager(
                mTaskInfo.configuration, mLeash,
                mTaskInfo.configuration, mLeash,
                null /* hostInputToken */);
                null /* hostInputToken */);
        mViewHost = new SurfaceControlViewHost(mContext,
        mViewHost = new SurfaceControlViewHost(mContext,
                mDisplayController.getDisplay(mTaskInfo.displayId), windowManager,
                mDisplayController.getDisplay(mTaskInfo.displayId), windowManager,
                "FullscreenVisualIndicator");
                "DesktopModeVisualIndicator");
        mViewHost.setView(mView, lp);
        mViewHost.setView(mView, lp);
        // We want this indicator to be behind the dragged task, but in front of all others.
        // We want this indicator to be behind the dragged task, but in front of all others.
        t.setRelativeLayer(mLeash, mTaskSurface, -1);
        t.setRelativeLayer(mLeash, mTaskSurface, -1);
@@ -116,24 +201,13 @@ public class DesktopModeVisualIndicator {
    }
    }


    /**
    /**
     * Create fullscreen indicator and fades it in.
     * Create an indicator. Animator fades it in while expanding the bounds outwards.
     */
    public void createFullscreenIndicator() {
        mIsFullscreen = true;
        mView.setBackgroundResource(R.drawable.desktop_windowing_transition_background);
        final VisualIndicatorAnimator animator = VisualIndicatorAnimator.toFullscreenAnimator(
                mView, mDisplayController.getDisplayLayout(mTaskInfo.displayId));
        animator.start();
    }

    /**
     * Create a fullscreen indicator. Animator fades it in while expanding the bounds outwards.
     */
     */
    public void createFullscreenIndicatorWithAnimatedBounds() {
    public void createIndicatorWithAnimatedBounds() {
        mIsFullscreen = true;
        mIsFullscreen = mType == TO_FULLSCREEN_INDICATOR;
        mView.setBackgroundResource(R.drawable.desktop_windowing_transition_background);
        mView.setBackgroundResource(R.drawable.desktop_windowing_transition_background);
        final VisualIndicatorAnimator animator = VisualIndicatorAnimator
        final VisualIndicatorAnimator animator = VisualIndicatorAnimator
                .toFullscreenAnimatorWithAnimatedBounds(mView,
                .animateBounds(mView, mType,
                        mDisplayController.getDisplayLayout(mTaskInfo.displayId));
                        mDisplayController.getDisplayLayout(mTaskInfo.displayId));
        animator.start();
        animator.start();
    }
    }
@@ -143,6 +217,7 @@ public class DesktopModeVisualIndicator {
     */
     */
    public void transitionFullscreenIndicatorToFreeform() {
    public void transitionFullscreenIndicatorToFreeform() {
        mIsFullscreen = false;
        mIsFullscreen = false;
        mType = TO_DESKTOP_INDICATOR;
        final VisualIndicatorAnimator animator = VisualIndicatorAnimator.toFreeformAnimator(
        final VisualIndicatorAnimator animator = VisualIndicatorAnimator.toFreeformAnimator(
                mView, mDisplayController.getDisplayLayout(mTaskInfo.displayId));
                mView, mDisplayController.getDisplayLayout(mTaskInfo.displayId));
        animator.start();
        animator.start();
@@ -153,12 +228,21 @@ public class DesktopModeVisualIndicator {
     */
     */
    public void transitionFreeformIndicatorToFullscreen() {
    public void transitionFreeformIndicatorToFullscreen() {
        mIsFullscreen = true;
        mIsFullscreen = true;
        mType = TO_FULLSCREEN_INDICATOR;
        final VisualIndicatorAnimator animator =
        final VisualIndicatorAnimator animator =
                VisualIndicatorAnimator.toFullscreenAnimatorWithAnimatedBounds(
                VisualIndicatorAnimator.toFullscreenAnimatorWithAnimatedBounds(
                mView, mDisplayController.getDisplayLayout(mTaskInfo.displayId));
                mView, mDisplayController.getDisplayLayout(mTaskInfo.displayId));
        animator.start();
        animator.start();
    }
    }


    /**
     * Determine if a MotionEvent is in the same range that enabled the indicator.
     * Used to dismiss the indicator when a transition will no longer result from releasing.
     */
    public boolean eventOutsideRange(float x, float y) {
        return !mIndicatorRange.contains((int) x, (int) y);
    }

    /**
    /**
     * Release the indicator and its components when it is no longer needed.
     * Release the indicator and its components when it is no longer needed.
     */
     */
@@ -210,32 +294,45 @@ public class DesktopModeVisualIndicator {
         * @param view the view for this indicator
         * @param view the view for this indicator
         * @param displayLayout information about the display the transitioning task is currently on
         * @param displayLayout information about the display the transitioning task is currently on
         */
         */
        public static VisualIndicatorAnimator toFullscreenAnimator(@NonNull View view,
        public static VisualIndicatorAnimator toFullscreenAnimatorWithAnimatedBounds(
                @NonNull DisplayLayout displayLayout) {
                @NonNull View view, @NonNull DisplayLayout displayLayout) {
            final Rect bounds = getMaxBounds(displayLayout);
            final int padding = displayLayout.stableInsets().top;
            Rect startBounds = new Rect(padding, padding,
                    displayLayout.width() - padding, displayLayout.height() - padding);
            view.getBackground().setBounds(startBounds);

            final VisualIndicatorAnimator animator = new VisualIndicatorAnimator(
            final VisualIndicatorAnimator animator = new VisualIndicatorAnimator(
                    view, bounds, bounds);
                    view, startBounds, getMaxBounds(startBounds));
            animator.setInterpolator(new DecelerateInterpolator());
            animator.setInterpolator(new DecelerateInterpolator());
            setupIndicatorAnimation(animator);
            setupIndicatorAnimation(animator);
            return animator;
            return animator;
        }
        }



        public static VisualIndicatorAnimator animateBounds(
        /**
                @NonNull View view, int type, @NonNull DisplayLayout displayLayout) {
         * Create animator for visual indicator of fullscreen transition
         *
         * @param view the view for this indicator
         * @param displayLayout information about the display the transitioning task is currently on
         */
        public static VisualIndicatorAnimator toFullscreenAnimatorWithAnimatedBounds(
                @NonNull View view, @NonNull DisplayLayout displayLayout) {
            final int padding = displayLayout.stableInsets().top;
            final int padding = displayLayout.stableInsets().top;
            Rect startBounds = new Rect(padding, padding,
            Rect startBounds = new Rect();
                    displayLayout.width() - padding, displayLayout.height() - padding);
            switch (type) {
                case TO_FULLSCREEN_INDICATOR:
                    startBounds.set(padding, padding,
                            displayLayout.width() - padding,
                            displayLayout.height() - padding);
                    break;
                case TO_SPLIT_LEFT_INDICATOR:
                    startBounds.set(padding, padding,
                            displayLayout.width() / 2 - padding,
                            displayLayout.height() - padding);
                    break;
                case TO_SPLIT_RIGHT_INDICATOR:
                    startBounds.set(displayLayout.width() / 2 + padding, padding,
                            displayLayout.width() - padding,
                            displayLayout.height() - padding);
                    break;
            }
            view.getBackground().setBounds(startBounds);
            view.getBackground().setBounds(startBounds);


            final VisualIndicatorAnimator animator = new VisualIndicatorAnimator(
            final VisualIndicatorAnimator animator = new VisualIndicatorAnimator(
                    view, startBounds, getMaxBounds(displayLayout));
                    view, startBounds, getMaxBounds(startBounds));
            animator.setInterpolator(new DecelerateInterpolator());
            animator.setInterpolator(new DecelerateInterpolator());
            setupIndicatorAnimation(animator);
            setupIndicatorAnimation(animator);
            return animator;
            return animator;
@@ -252,12 +349,13 @@ public class DesktopModeVisualIndicator {
            final float adjustmentPercentage = 1f - FINAL_FREEFORM_SCALE;
            final float adjustmentPercentage = 1f - FINAL_FREEFORM_SCALE;
            final int width = displayLayout.width();
            final int width = displayLayout.width();
            final int height = displayLayout.height();
            final int height = displayLayout.height();
            Rect startBounds = new Rect(0, 0, width, height);
            Rect endBounds = new Rect((int) (adjustmentPercentage * width / 2),
            Rect endBounds = new Rect((int) (adjustmentPercentage * width / 2),
                    (int) (adjustmentPercentage * height / 2),
                    (int) (adjustmentPercentage * height / 2),
                    (int) (displayLayout.width() - (adjustmentPercentage * width / 2)),
                    (int) (displayLayout.width() - (adjustmentPercentage * width / 2)),
                    (int) (displayLayout.height() - (adjustmentPercentage * height / 2)));
                    (int) (displayLayout.height() - (adjustmentPercentage * height / 2)));
            final VisualIndicatorAnimator animator = new VisualIndicatorAnimator(
            final VisualIndicatorAnimator animator = new VisualIndicatorAnimator(
                    view, getMaxBounds(displayLayout), endBounds);
                    view, startBounds, endBounds);
            animator.setInterpolator(new DecelerateInterpolator());
            animator.setInterpolator(new DecelerateInterpolator());
            setupIndicatorAnimation(animator);
            setupIndicatorAnimation(animator);
            return animator;
            return animator;
@@ -310,21 +408,17 @@ public class DesktopModeVisualIndicator {
        }
        }


        /**
        /**
         * Return the max bounds of a fullscreen indicator
         * Return the max bounds of a visual indicator
         */
         */
        private static Rect getMaxBounds(@NonNull DisplayLayout displayLayout) {
        private static Rect getMaxBounds(Rect startBounds) {
            final int padding = displayLayout.stableInsets().top;
            return new Rect((int) (startBounds.left
            final int width = displayLayout.width() - 2 * padding;
                            - (FULLSCREEN_SCALE_ADJUSTMENT_PERCENT * startBounds.width())),
            final int height = displayLayout.height() - 2 * padding;
                    (int) (startBounds.top
            Rect endBounds = new Rect((int) (padding
                            - (FULLSCREEN_SCALE_ADJUSTMENT_PERCENT * startBounds.height())),
                            - (FULLSCREEN_SCALE_ADJUSTMENT_PERCENT * width)),
                    (int) (startBounds.right
                    (int) (padding
                            + (FULLSCREEN_SCALE_ADJUSTMENT_PERCENT * startBounds.width())),
                            - (FULLSCREEN_SCALE_ADJUSTMENT_PERCENT * height)),
                    (int) (startBounds.bottom
                    (int) (displayLayout.width() - padding
                            + (FULLSCREEN_SCALE_ADJUSTMENT_PERCENT * startBounds.height())));
                            + (FULLSCREEN_SCALE_ADJUSTMENT_PERCENT * width)),
                    (int) (displayLayout.height() - padding
                            + (FULLSCREEN_SCALE_ADJUSTMENT_PERCENT * height)));
            return endBounds;
        }
        }
    }
    }
}
}
+63 −23
Original line number Original line Diff line number Diff line
@@ -29,6 +29,7 @@ import android.app.WindowConfiguration.WindowingMode
import android.content.Context
import android.content.Context
import android.content.res.TypedArray
import android.content.res.TypedArray
import android.graphics.Point
import android.graphics.Point
import android.graphics.PointF
import android.graphics.Rect
import android.graphics.Rect
import android.graphics.Region
import android.graphics.Region
import android.os.IBinder
import android.os.IBinder
@@ -55,7 +56,10 @@ import com.android.wm.shell.common.SingleInstanceRemoteListener
import com.android.wm.shell.common.SyncTransactionQueue
import com.android.wm.shell.common.SyncTransactionQueue
import com.android.wm.shell.common.annotations.ExternalThread
import com.android.wm.shell.common.annotations.ExternalThread
import com.android.wm.shell.common.annotations.ShellMainThread
import com.android.wm.shell.common.annotations.ShellMainThread
import com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT
import com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT
import com.android.wm.shell.desktopmode.DesktopModeTaskRepository.VisibleTasksListener
import com.android.wm.shell.desktopmode.DesktopModeTaskRepository.VisibleTasksListener
import com.android.wm.shell.desktopmode.DesktopModeVisualIndicator.TO_DESKTOP_INDICATOR
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.splitscreen.SplitScreenController
import com.android.wm.shell.splitscreen.SplitScreenController
import com.android.wm.shell.sysui.ShellCommandHandler
import com.android.wm.shell.sysui.ShellCommandHandler
@@ -107,6 +111,10 @@ class DesktopTasksController(
        get() = context.resources.getDimensionPixelSize(
        get() = context.resources.getDimensionPixelSize(
            com.android.wm.shell.R.dimen.desktop_mode_transition_area_height)
            com.android.wm.shell.R.dimen.desktop_mode_transition_area_height)


    private val transitionAreaWidth
        get() = context.resources.getDimensionPixelSize(
            com.android.wm.shell.R.dimen.desktop_mode_transition_area_width)

    // This is public to avoid cyclic dependency; it is set by SplitScreenController
    // This is public to avoid cyclic dependency; it is set by SplitScreenController
    lateinit var splitScreenController: SplitScreenController
    lateinit var splitScreenController: SplitScreenController


@@ -755,7 +763,8 @@ class DesktopTasksController(
        ) {
        ) {
            val wct = WindowContainerTransaction()
            val wct = WindowContainerTransaction()
            addMoveToSplitChanges(wct, taskInfo)
            addMoveToSplitChanges(wct, taskInfo)
            splitScreenController.requestEnterSplitSelect(taskInfo, wct)
            splitScreenController.requestEnterSplitSelect(taskInfo, wct,
                SPLIT_POSITION_BOTTOM_OR_RIGHT, taskInfo.configuration.windowConfiguration.bounds)
        }
        }
    }
    }


@@ -779,25 +788,36 @@ class DesktopTasksController(


    /**
    /**
     * Perform checks required on drag move. Create/release fullscreen indicator as needed.
     * Perform checks required on drag move. Create/release fullscreen indicator as needed.
     * Different sources for x and y coordinates are used due to different needs for each:
     * We want split transitions to be based on input coordinates but fullscreen transition
     * to be based on task edge coordinate.
     *
     *
     * @param taskInfo the task being dragged.
     * @param taskInfo the task being dragged.
     * @param taskSurface SurfaceControl of dragged task.
     * @param taskSurface SurfaceControl of dragged task.
     * @param y coordinate of dragged task. Used for checks against status bar height.
     * @param inputCoordinate coordinates of input. Used for checks against left/right edge of screen.
     * @param taskBounds bounds of dragged task. Used for checks against status bar height.
     */
     */
    fun onDragPositioningMove(
    fun onDragPositioningMove(
        taskInfo: RunningTaskInfo,
        taskInfo: RunningTaskInfo,
        taskSurface: SurfaceControl,
        taskSurface: SurfaceControl,
            y: Float
        inputCoordinate: PointF,
        taskBounds: Rect
    ) {
    ) {
        if (taskInfo.windowingMode == WINDOWING_MODE_FREEFORM) {
        val displayLayout = displayController.getDisplayLayout(taskInfo.displayId) ?: return
            if (y <= transitionAreaHeight && visualIndicator == null) {
        if (taskInfo.windowingMode != WINDOWING_MODE_FREEFORM) return
                visualIndicator = DesktopModeVisualIndicator(syncQueue, taskInfo,
        var type = DesktopModeVisualIndicator.determineIndicatorType(inputCoordinate,
            taskBounds, displayLayout, context)
        if (type != DesktopModeVisualIndicator.INVALID_INDICATOR && visualIndicator == null) {
            visualIndicator = DesktopModeVisualIndicator(
                syncQueue, taskInfo,
                displayController, context, taskSurface, shellTaskOrganizer,
                displayController, context, taskSurface, shellTaskOrganizer,
                        rootTaskDisplayAreaOrganizer)
                rootTaskDisplayAreaOrganizer, type)
                visualIndicator?.createFullscreenIndicatorWithAnimatedBounds()
            visualIndicator?.createIndicatorWithAnimatedBounds()
            } else if (y > transitionAreaHeight && visualIndicator != null) {
            return
                releaseVisualIndicator()
        }
        }
        if (visualIndicator?.eventOutsideRange(inputCoordinate.x,
                taskBounds.top.toFloat()) == true) {
            releaseVisualIndicator()
        }
        }
    }
    }


@@ -806,19 +826,39 @@ class DesktopTasksController(
     *
     *
     * @param taskInfo the task being dragged.
     * @param taskInfo the task being dragged.
     * @param position position of surface when drag ends.
     * @param position position of surface when drag ends.
     * @param y the Y position of the top edge of the task
     * @param inputCoordinate the coordinates of the motion event
     * @param taskBounds the updated bounds of the task being dragged.
     * @param windowDecor the window decoration for the task being dragged
     * @param windowDecor the window decoration for the task being dragged
     */
     */
    fun onDragPositioningEnd(
    fun onDragPositioningEnd(
        taskInfo: RunningTaskInfo,
        taskInfo: RunningTaskInfo,
        position: Point,
        position: Point,
            y: Float,
        inputCoordinate: PointF,
        taskBounds: Rect,
        windowDecor: DesktopModeWindowDecoration
        windowDecor: DesktopModeWindowDecoration
    ) {
    ) {
        if (y <= transitionAreaHeight && taskInfo.windowingMode == WINDOWING_MODE_FREEFORM) {
        if (taskInfo.configuration.windowConfiguration.windowingMode != WINDOWING_MODE_FREEFORM) {
            return
        }
        if (taskBounds.top <= transitionAreaHeight) {
            windowDecor.incrementRelayoutBlock()
            windowDecor.incrementRelayoutBlock()
            moveToFullscreenWithAnimation(taskInfo, position)
            moveToFullscreenWithAnimation(taskInfo, position)
        }
        }
        if (inputCoordinate.x <= transitionAreaWidth) {
            releaseVisualIndicator()
            var wct = WindowContainerTransaction()
            addMoveToSplitChanges(wct, taskInfo)
            splitScreenController.requestEnterSplitSelect(taskInfo, wct,
                SPLIT_POSITION_TOP_OR_LEFT, taskBounds)
        }
        if (inputCoordinate.x >= (displayController.getDisplayLayout(taskInfo.displayId)?.width()
            ?.minus(transitionAreaWidth) ?: return)) {
            releaseVisualIndicator()
            var wct = WindowContainerTransaction()
            addMoveToSplitChanges(wct, taskInfo)
            splitScreenController.requestEnterSplitSelect(taskInfo, wct,
                SPLIT_POSITION_BOTTOM_OR_RIGHT, taskBounds)
        }
    }
    }


    /**
    /**
@@ -842,8 +882,8 @@ class DesktopTasksController(
        if (visualIndicator == null) {
        if (visualIndicator == null) {
            visualIndicator = DesktopModeVisualIndicator(syncQueue, taskInfo,
            visualIndicator = DesktopModeVisualIndicator(syncQueue, taskInfo,
                    displayController, context, taskSurface, shellTaskOrganizer,
                    displayController, context, taskSurface, shellTaskOrganizer,
                    rootTaskDisplayAreaOrganizer)
                    rootTaskDisplayAreaOrganizer, TO_DESKTOP_INDICATOR)
            visualIndicator?.createFullscreenIndicator()
            visualIndicator?.createIndicatorWithAnimatedBounds()
        }
        }
        val indicator = visualIndicator ?: return
        val indicator = visualIndicator ?: return
        if (y >= getFreeformTransitionStatusBarDragThreshold(taskInfo)) {
        if (y >= getFreeformTransitionStatusBarDragThreshold(taskInfo)) {
+2 −2
Original line number Original line Diff line number Diff line
@@ -17,7 +17,7 @@
package com.android.wm.shell.splitscreen;
package com.android.wm.shell.splitscreen;


import android.app.ActivityManager.RunningTaskInfo;
import android.app.ActivityManager.RunningTaskInfo;

import android.graphics.Rect;
/**
/**
 * Listener interface that Launcher attaches to SystemUI to get split-select callbacks.
 * Listener interface that Launcher attaches to SystemUI to get split-select callbacks.
 */
 */
@@ -25,5 +25,5 @@ interface ISplitSelectListener {
    /**
    /**
     * Called when a task requests to enter split select
     * Called when a task requests to enter split select
     */
     */
    boolean onRequestSplitSelect(in RunningTaskInfo taskInfo);
    boolean onRequestSplitSelect(in RunningTaskInfo taskInfo, int splitPosition, in Rect taskBounds);
}
}
 No newline at end of file
+2 −1
Original line number Original line Diff line number Diff line
@@ -66,7 +66,8 @@ public interface SplitScreen {


    /** Callback interface for listening to requests to enter split select */
    /** Callback interface for listening to requests to enter split select */
    interface SplitSelectListener {
    interface SplitSelectListener {
        default boolean onRequestEnterSplitSelect(ActivityManager.RunningTaskInfo taskInfo) {
        default boolean onRequestEnterSplitSelect(ActivityManager.RunningTaskInfo taskInfo,
                int splitPosition, Rect taskBounds) {
            return false;
            return false;
        }
        }
    }
    }
Loading