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

Commit 31cebbea authored by Ats Jenk's avatar Ats Jenk
Browse files

Skip bubbled tasks from merging into recents transition

We skip tasks with alwaysOnTop set to true from merging into the recents
transition.
When bubbles are collapsing, we remove the alwaysOnTop flag before the
transition starts playing.
When going from bubbles to recents, we can have the recents transition
start playing and then the bubbles collapse transition starts. In this
case we would attempt to merge the bubbles collapse transition into the
recents transition. But the bubbles transition does not support this.
Instead of checking for alwaysOnTop flag, add a check if the task is a
bubble. If it is, skip it from merging into the recents transition.

Bug: 418760100
Test: atest WMShellUnitTests:RecentsTransitionHandlerTest
Flag: com.android.wm.shell.fix_bubbles_to_recents
Change-Id: I1504f6d78397925bad02495942e54efe499c7f0f
parent 3136b5f1
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -734,7 +734,8 @@ public abstract class WMShellModule {
            Optional<RecentTasksController> recentTasksController,
            HomeTransitionObserver homeTransitionObserver,
            DisplayController displayController,
            DesksOrganizer desksOrganizer) {
            DesksOrganizer desksOrganizer,
            Optional<BubbleController> bubbleController) {
        return new RecentsTransitionHandler(
                shellInit,
                shellTaskOrganizer,
@@ -742,7 +743,8 @@ public abstract class WMShellModule {
                recentTasksController.orElse(null),
                homeTransitionObserver,
                displayController,
                desksOrganizer);
                desksOrganizer,
                bubbleController);
    }

    //
+16 −1
Original line number Diff line number Diff line
@@ -80,6 +80,7 @@ import com.android.internal.os.IResultReceiver;
import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.Flags;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.bubbles.BubbleController;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.desktopmode.multidesks.DesksOrganizer;
@@ -93,6 +94,7 @@ import com.android.wm.shell.transition.Transitions;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Supplier;

@@ -127,6 +129,7 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler,
    private @Nullable Color mBackgroundColor;
    private final DisplayController mDisplayController;
    private final DesksOrganizer mDesksOrganizer;
    private final Optional<BubbleController> mBubbleController;

    public RecentsTransitionHandler(
            @NonNull ShellInit shellInit,
@@ -135,7 +138,8 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler,
            @Nullable RecentTasksController recentTasksController,
            @NonNull HomeTransitionObserver homeTransitionObserver,
            @NonNull DisplayController displayController,
            @NonNull DesksOrganizer desksOrganizer) {
            @NonNull DesksOrganizer desksOrganizer,
            Optional<BubbleController> bubbleController) {
        mShellTaskOrganizer = shellTaskOrganizer;
        mTransitions = transitions;
        mExecutor = transitions.getMainExecutor();
@@ -143,6 +147,7 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler,
        mHomeTransitionObserver = homeTransitionObserver;
        mDisplayController = displayController;
        mDesksOrganizer = desksOrganizer;
        mBubbleController = bubbleController;
        if (recentTasksController == null) return;
        shellInit.addInitCallback(this::onInit, this);
    }
@@ -1056,6 +1061,16 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler,
            for (int i = 0; i < info.getChanges().size(); ++i) {
                final TransitionInfo.Change change = info.getChanges().get(i);
                final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
                if (Flags.fixBubblesToRecents() && taskInfo != null && mBubbleController.isPresent()
                        && mBubbleController.get().hasStableBubbleForTask(taskInfo.taskId)) {
                    ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
                            "[%d]   Canceling due to bubble task", mInstanceId);
                    // Explicitly check for bubble tasks as bubbles may have always_on_top reset
                    // when they are collapsing. Bubbles handle their own transition and can't be
                    // merged.
                    cancel("task #" + taskInfo.taskId + " is bubble");
                    return;
                }
                if (taskInfo != null
                        && taskInfo.configuration.windowConfiguration.isAlwaysOnTop()) {
                    ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
+15 −1
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import static com.android.window.flags.Flags.FLAG_ENABLE_DESKTOP_SPLITSCREEN_TRA
import static com.android.window.flags.Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND;
import static com.android.wm.shell.Flags.FLAG_ENABLE_PIP2;
import static com.android.wm.shell.Flags.FLAG_ENABLE_RECENTS_BOOKEND_TRANSITION;
import static com.android.wm.shell.Flags.FLAG_FIX_BUBBLES_TO_RECENTS;
import static com.android.wm.shell.recents.RecentsTransitionStateListener.TRANSITION_STATE_ANIMATING;
import static com.android.wm.shell.recents.RecentsTransitionStateListener.TRANSITION_STATE_NOT_RUNNING;
import static com.android.wm.shell.recents.RecentsTransitionStateListener.TRANSITION_STATE_REQUESTED;
@@ -78,6 +79,7 @@ import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.ShellTestCase;
import com.android.wm.shell.TestRunningTaskInfoBuilder;
import com.android.wm.shell.TestShellExecutor;
import com.android.wm.shell.bubbles.BubbleController;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayInsetsController;
import com.android.wm.shell.common.TaskStackListenerImpl;
@@ -146,6 +148,7 @@ public class RecentsTransitionHandlerTest extends ShellTestCase {
    @Mock private DisplayController mDisplayController;
    @Mock private Context mConnectedDisplayContext;
    @Mock private Resources mConnectedDisplayResources;
    @Mock private BubbleController mBubbleController;

    private ShellTaskOrganizer mShellTaskOrganizer;
    private RecentTasksController mRecentTasksController;
@@ -178,6 +181,7 @@ public class RecentsTransitionHandlerTest extends ShellTestCase {
        when(mConnectedDisplayResources.getDimensionPixelSize(
                R.dimen.desktop_windowing_freeform_rounded_corner_radius)
        ).thenReturn(FREEFORM_TASK_CORNER_RADIUS_ON_CD);
        when(mBubbleController.hasStableBubbleForTask(anyInt())).thenReturn(false);
        mShellInit = spy(new ShellInit(mMainExecutor));
        mShellController = spy(new ShellController(mContext, mShellInit, mShellCommandHandler,
                mDisplayInsetsController, mUserManager, mMainExecutor));
@@ -193,7 +197,7 @@ public class RecentsTransitionHandlerTest extends ShellTestCase {
        doReturn(mMainExecutor).when(mTransitions).getMainExecutor();
        mRecentsTransitionHandler = new RecentsTransitionHandler(mShellInit, mShellTaskOrganizer,
                mTransitions, mRecentTasksController, mock(HomeTransitionObserver.class),
                mDisplayController, mDesksOrganizer);
                mDisplayController, mDesksOrganizer, Optional.of(mBubbleController));
        // By default use a mock finish transaction since we are sending transitions that don't have
        // real surface controls
        mRecentsTransitionHandler.setFinishTransactionSupplier(
@@ -526,6 +530,16 @@ public class RecentsTransitionHandlerTest extends ShellTestCase {
        startTransitionAndMergeThenVerifyCanceled(mergeTransitionInfo);
    }

    @Test
    @EnableFlags(FLAG_FIX_BUBBLES_TO_RECENTS)
    public void testMerge_cancelBubbleToBack() throws Exception {
        TransitionInfo mergeTransitionInfo = new TransitionInfoBuilder(TRANSIT_TO_BACK)
                .addChange(TRANSIT_TO_BACK, new TestRunningTaskInfoBuilder().setTaskId(123).build())
                .build();
        when(mBubbleController.hasStableBubbleForTask(123)).thenReturn(true);
        startTransitionAndMergeThenVerifyCanceled(mergeTransitionInfo);
    }

    @Test
    @EnableFlags(FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
    public void testMergeAndFinish_openingTaskInDesk_setsPositionOfChild() {
+3 −1
Original line number Diff line number Diff line
@@ -127,6 +127,7 @@ import org.mockito.Answers;
import org.mockito.InOrder;

import java.util.ArrayList;
import java.util.Optional;
import java.util.function.Function;

/**
@@ -1327,7 +1328,8 @@ public class ShellTransitionTests extends ShellTestCase {
        final RecentsTransitionHandler recentsHandler =
                new RecentsTransitionHandler(shellInit, mock(ShellTaskOrganizer.class), transitions,
                        mockRecentsTaskController, mock(HomeTransitionObserver.class),
                        mock(DisplayController.class), mock(DesksOrganizer.class));
                        mock(DisplayController.class), mock(DesksOrganizer.class),
                        Optional.empty());
        recentsHandler.setFinishTransactionSupplier(
                () -> mock(SurfaceControl.Transaction.class));
        transitions.replaceDefaultHandlerForTest(mDefaultHandler);