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

Commit 6dd73e98 authored by Winson Chung's avatar Winson Chung
Browse files

6/ Fix some flakey issues with dragging to split

- Ensure that the task info activity type always matches the actual task
  activity type (can be different than the window configuration type)
- Ensure that the targets hit rects respect the insets, and that dragging
  out of all targets (but still within the window) will hide the last
  target
- Work around race with launching secondary task when splitting, wait
  until the split screen task org has moved existing tasks to secondary
  split root before starting the new task, and also update the home task
  position when going home (b/172686383)
- Add a timeout to clean up drag surfaces if SysUI crashes while
  mid-drag
- Clean up some other calls to get activity type/win mode

Bug: 169894807
Test: atest DragDropControllerTests
Test: atest DragAndDropPolicyTest
Test: atest SplitScreenTests
Change-Id: I7ae11cc38b1e927d955798ef1056e17c9e435758
parent e3d75ac2
Loading
Loading
Loading
Loading
+1 −7
Original line number Diff line number Diff line
@@ -346,15 +346,9 @@ public class ShellTaskOrganizer extends TaskOrganizer {
        return mTaskListeners.get(taskListenerType);
    }

    @WindowingMode
    public static int getWindowingMode(RunningTaskInfo taskInfo) {
        return taskInfo.configuration.windowConfiguration.getWindowingMode();
    }

    @VisibleForTesting
    static @TaskListenerType int taskInfoToTaskListenerType(RunningTaskInfo runningTaskInfo) {
        final int windowingMode = getWindowingMode(runningTaskInfo);
        switch (windowingMode) {
        switch (runningTaskInfo.getWindowingMode()) {
            case WINDOWING_MODE_FULLSCREEN:
                return runningTaskInfo.letterboxActivityBounds != null
                        ? TASK_LISTENER_TYPE_LETTERBOX
+41 −18
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.wm.shell.draganddrop;

import static android.app.ActivityTaskManager.INVALID_TASK_ID;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.content.ClipDescription.EXTRA_ACTIVITY_OPTIONS;
@@ -67,6 +68,7 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

/**
 * The policy for handling drag and drop operations to shell.
@@ -133,20 +135,20 @@ public class DragAndDropPolicy {
                // TODO(b/169894807): For now, only allow splitting to the right/bottom until we
                //                    have split pairs
                mTargets.add(new Target(TYPE_FULLSCREEN,
                        new Rect(0, 0, w, h / 2),
                        new Rect(l, t, l + iw, t + ih / 2),
                        new Rect(l, t, l + iw, t + ih),
                        new Rect(0, 0, w, h)));
                mTargets.add(new Target(TYPE_SPLIT_BOTTOM,
                        new Rect(0, h / 2, w, h),
                        new Rect(l, t + ih / 2, l + iw, t + ih),
                        new Rect(l, t + ih / 2, l + iw, t + ih),
                        new Rect(0, h / 2, w, h)));
            } else {
                mTargets.add(new Target(TYPE_FULLSCREEN,
                        new Rect(0, 0, w / 2, h),
                        new Rect(l, t, l + iw / 2, t + ih),
                        new Rect(l, t, l + iw, t + ih),
                        new Rect(0, 0, w, h)));
                mTargets.add(new Target(TYPE_SPLIT_RIGHT,
                        new Rect(w / 2, 0, w, h),
                        new Rect(l + iw / 2, t, l + iw, t + ih),
                        new Rect(l + iw / 2, t, l + iw, t + ih),
                        new Rect(w / 2, 0, w, h)));
            }
@@ -162,12 +164,12 @@ public class DragAndDropPolicy {
            secondarySplitBounds.intersect(new Rect(l, t, l + iw, t + ih));
            if (isVerticalSplit) {
                mTargets.add(new Target(TYPE_FULLSCREEN,
                        new Rect(0, 0, w, secondarySplitRawBounds.top),
                        new Rect(l, t, l + iw, secondarySplitRawBounds.top),
                        new Rect(l, t, l + iw, t + ih),
                        new Rect(0, 0, w, secondarySplitRawBounds.top)));
            } else {
                mTargets.add(new Target(TYPE_FULLSCREEN,
                        new Rect(0, 0, secondarySplitRawBounds.left, h),
                        new Rect(l, t, secondarySplitRawBounds.left, t + ih),
                        new Rect(l, t, l + iw, t + ih),
                        new Rect(0, 0, w, h)));
            }
@@ -178,7 +180,7 @@ public class DragAndDropPolicy {
        } else {
            // Otherwise only show the fullscreen target
            mTargets.add(new Target(TYPE_FULLSCREEN,
                    new Rect(0, 0, w, h),
                    new Rect(l, t, l + iw, t + ih),
                    new Rect(l, t, l + iw, t + ih),
                    new Rect(0, 0, w, h)));
        }
@@ -210,6 +212,7 @@ public class DragAndDropPolicy {
        final boolean isShortcut = description.hasMimeType(MIMETYPE_APPLICATION_SHORTCUT);
        final Intent dragData = mSession.dragData;

        boolean deferAppLaunchUntilSplit = false;
        if (target.type == TYPE_FULLSCREEN) {
            if (mSplitScreen != null && mSplitScreen.isDividerVisible()) {
                // If in split, remove split and launch fullscreen
@@ -226,9 +229,11 @@ public class DragAndDropPolicy {
                // Not in split, enter split now
                mStarter.enterSplitScreen(mSession.runningTaskId,
                        target.type == TYPE_SPLIT_LEFT || target.type == TYPE_SPLIT_TOP);
                deferAppLaunchUntilSplit = true;
            }
        }

        final Runnable startAppRunnable = () -> {
            Bundle opts = dragData.hasExtra(EXTRA_ACTIVITY_OPTIONS)
                    ? dragData.getBundleExtra(EXTRA_ACTIVITY_OPTIONS)
                    : null;
@@ -241,6 +246,24 @@ public class DragAndDropPolicy {
            } else {
                mStarter.startIntent(dragData.getParcelableExtra(EXTRA_PENDING_INTENT), opts);
            }
        };
        if (deferAppLaunchUntilSplit) {
            // TODO(b/169894807): The enterSplitScreen() call above will trigger the current task
            // into split, and we should wait for home and other tasks to be moved to
            // split-secondary before trying to launch the new secondary task.  This can be removed
            // once we have app-pairs.
            mSplitScreen.registerInSplitScreenListener(new Consumer<Boolean>() {
                @Override
                public void accept(Boolean inSplit) {
                    if (inSplit) {
                        startAppRunnable.run();
                        mSplitScreen.unregisterInSplitScreenListener(this);
                    }
                }
            });
        } else {
            startAppRunnable.run();
        }
    }

    /**
@@ -274,7 +297,7 @@ public class DragAndDropPolicy {
         * Updates the session data based on the current state of the system.
         */
        void update() {
            final ClipDescription description = mInitialDragData.getDescription();

            try {
                List<ActivityManager.RunningTaskInfo> tasks =
                        mIActivityTaskManager.getFilteredTasks(1,
+13 −5
Original line number Diff line number Diff line
@@ -135,17 +135,25 @@ public class DragLayout extends View {
        // visibility of the current region
        DragAndDropPolicy.Target target = mPolicy.getTargetAtLocation(
                (int) event.getX(), (int) event.getY());
        if (target != null && mCurrentTarget != target) {
        if (mCurrentTarget != target) {
            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP, "Current target: %s", target);
            Interpolator boundsInterpolator = FAST_OUT_SLOW_IN;
            if (mCurrentTarget == null) {
            if (target == null) {
                // Animating to no target
                mDropOutline.startVisibilityAnimation(false, LINEAR);
                Rect finalBounds = new Rect(mCurrentTarget.drawRegion);
                finalBounds.inset(mDisplayMargin, mDisplayMargin);
                mDropOutline.startBoundsAnimation(finalBounds, FAST_OUT_LINEAR_IN);
            } else if (mCurrentTarget == null) {
                // Animating to first target
                mDropOutline.startVisibilityAnimation(true, LINEAR);
                Rect initialBounds = new Rect(target.drawRegion);
                initialBounds.inset(mDisplayMargin, mDisplayMargin);
                mDropOutline.setRegionBounds(initialBounds);
                boundsInterpolator = LINEAR_OUT_SLOW_IN;
                mDropOutline.startBoundsAnimation(target.drawRegion, LINEAR_OUT_SLOW_IN);
            } else {
                // Bounds change
                mDropOutline.startBoundsAnimation(target.drawRegion, FAST_OUT_SLOW_IN);
            }
            mDropOutline.startBoundsAnimation(target.drawRegion, boundsInterpolator);
            mCurrentTarget = target;
        }
    }
+1 −2
Original line number Diff line number Diff line
@@ -324,8 +324,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
                    @Override
                    public void onActivityRestartAttempt(ActivityManager.RunningTaskInfo task,
                            boolean homeTaskVisible, boolean clearedTask, boolean wasVisible) {
                        if (task.configuration.windowConfiguration.getWindowingMode()
                                != WINDOWING_MODE_PINNED) {
                        if (task.getWindowingMode() != WINDOWING_MODE_PINNED) {
                            return;
                        }
                        mTouchHandler.getMotionHelper().expandLeavePip(
+1 −2
Original line number Diff line number Diff line
@@ -398,8 +398,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac

    private void onActivityRestartAttempt(ActivityManager.RunningTaskInfo task,
            boolean clearedTask) {
        if (task.configuration.windowConfiguration.getWindowingMode()
                != WINDOWING_MODE_PINNED) {
        if (task.getWindowingMode() != WINDOWING_MODE_PINNED) {
            return;
        }
        if (DEBUG) Log.d(TAG, "onPinnedActivityRestartAttempt()");
Loading