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

Commit 7183185d authored by Winson Chung's avatar Winson Chung
Browse files

Ensure that split is always notified of recents transition finishing

- In ag/31399901 we added a mixed handler callback which notifies split
  via onRecentsInSplitAnimationFinishing() when the recents transition
  is finishing along with direct information about whether the
  transition finished to home or to the app.  However, currently there
  are recents mixed transitions that actually aren't handled by recents
  (ie. they can be handled by split + remote) for which
  onRecentsInSplitAnimationStart() is still called (it still does
  things like attach the divider to the transition to be animated).

  In such cases, we should remove the bookend-transition gating logic
  from the calls added in ag/31399901 and ensure that we always notify
  split of the recents transition finish if it's not already notified
  by the recents transition handler.

  Note that this is only affected by enable_recents_bookend_transition
  because previously with the flag off the legacy call
  onRecentsInSplitAnimationFinish() would always be called in the mixed
  transition logic.
- Also add some more logs for future debugging along this path

Fixes: 393226708
Bug: 391486839
Bug: 346588978
Flag: com.android.wm.shell.enable_recents_bookend_transition
Test: atest TaplTestsTaskbarSearch#testLaunchSearchWebSuggestionInSplitscreen
Test: atest TaplTestsTaskbar#testLaunchShortcutInSplitscreen
Test: atest TaplTestsSplitscreen#testSaveAppPairMenuItemOrActionExistsOnSplitPair
Test: atest WMShellUnitTests
Change-Id: Iab2225f454d9de80bdca0f0a958596ab2d6637ff
parent 45d73de7
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -1446,6 +1446,11 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler,
                            wct.clear();

                            if (Flags.enableRecentsBookendTransition()) {
                                // Notify the mixers of the pending finish
                                for (int i = 0; i < mMixers.size(); ++i) {
                                    mMixers.get(i).handleFinishRecents(returningToApp, wct, t);
                                }

                                // In this case, we've already started the PIP transition, so we can
                                // clean up immediately
                                mPendingRunnerFinishCb = runnerFinishCb;
+16 −34
Original line number Diff line number Diff line
@@ -1669,8 +1669,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
    void prepareExitSplitScreen(@StageType int stageToTop,
            @NonNull WindowContainerTransaction wct, @ExitReason int exitReason) {
        if (!isSplitActive()) return;
        ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "prepareExitSplitScreen: stageToTop=%s",
                stageTypeToString(stageToTop));
        ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "prepareExitSplitScreen: stageToTop=%s reason=%s",
                stageTypeToString(stageToTop), exitReasonToString(exitReason));
        if (enableFlexibleSplit()) {
            mStageOrderOperator.getActiveStages().stream()
                    .filter(stage -> stage.getId() != stageToTop)
@@ -3389,12 +3389,14 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
        TransitionInfo.Change sideChild = null;
        StageTaskListener firstAppStage = null;
        StageTaskListener secondAppStage = null;
        boolean foundPausingTask = false;
        final WindowContainerTransaction evictWct = new WindowContainerTransaction();
        for (int iC = 0; iC < info.getChanges().size(); ++iC) {
            final TransitionInfo.Change change = info.getChanges().get(iC);
            final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
            if (taskInfo == null || !taskInfo.hasParentTask()) continue;
            if (mPausingTasks.contains(taskInfo.taskId)) {
                foundPausingTask = true;
                continue;
            }
            StageTaskListener stage = getStageOfTask(taskInfo);
@@ -3437,9 +3439,9 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
                            prepareExitSplitScreen(dismissTop, cancelWct, EXIT_REASON_UNKNOWN);
                            logExit(EXIT_REASON_UNKNOWN);
                        });
                Log.w(TAG, splitFailureMessage("startPendingEnterAnimation",
                        "launched 2 tasks in split, but didn't receive "
                        + "2 tasks in transition. Possibly one of them failed to launch"));
                Log.w(TAG, splitFailureMessage("startPendingEnterAnimation", "launched 2 tasks in "
                        + "split, but didn't receive 2 tasks in transition. Possibly one of them "
                        + "failed to launch (foundPausingTask=" + foundPausingTask + ")"));
                if (mRecentTasks.isPresent() && mainChild != null) {
                    mRecentTasks.get().removeSplitPair(mainChild.getTaskInfo().taskId);
                }
@@ -3794,6 +3796,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,

    /** Call this when the recents animation canceled during split-screen. */
    public void onRecentsInSplitAnimationCanceled() {
        ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "onRecentsInSplitAnimationCanceled");
        mPausingTasks.clear();
        setSplitsVisible(false);

@@ -3803,31 +3806,10 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
        mTaskOrganizer.applyTransaction(wct);
    }

    public void onRecentsInSplitAnimationFinishing(boolean returnToApp,
            @NonNull WindowContainerTransaction finishWct,
            @NonNull SurfaceControl.Transaction finishT) {
        if (!Flags.enableRecentsBookendTransition()) {
            // The non-bookend recents transition case will be handled by
            // RecentsMixedTransition wrapping the finish callback and calling
            // onRecentsInSplitAnimationFinish()
            return;
        }

        onRecentsInSplitAnimationFinishInner(returnToApp, finishWct, finishT);
    }

    /** Call this when the recents animation during split-screen finishes. */
    public void onRecentsInSplitAnimationFinish(@NonNull WindowContainerTransaction finishWct,
            @NonNull SurfaceControl.Transaction finishT) {
        if (Flags.enableRecentsBookendTransition()) {
            // The bookend recents transition case will be handled by
            // onRecentsInSplitAnimationFinishing above
            return;
        }

        // Check if the recent transition is finished by returning to the current
        // split, so we can restore the divider bar.
        boolean returnToApp = false;
    /**
     * Returns whether the given WCT is reordering any of the split tasks to top.
     */
    public boolean wctIsReorderingSplitToTop(@NonNull WindowContainerTransaction finishWct) {
        for (int i = 0; i < finishWct.getHierarchyOps().size(); ++i) {
            final WindowContainerTransaction.HierarchyOp op =
                    finishWct.getHierarchyOps().get(i);
@@ -3842,14 +3824,14 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
            }
            if (op.getType() == HIERARCHY_OP_TYPE_REORDER && op.getToTop()
                    && anyStageContainsContainer) {
                returnToApp = true;
                return true;
            }
        }
        onRecentsInSplitAnimationFinishInner(returnToApp, finishWct, finishT);
        return false;
    }

    /** Call this when the recents animation during split-screen finishes. */
    public void onRecentsInSplitAnimationFinishInner(boolean returnToApp,
    /** Called when the recents animation during split-screen finishes. */
    public void onRecentsInSplitAnimationFinishing(boolean returnToApp,
            @NonNull WindowContainerTransaction finishWct,
            @NonNull SurfaceControl.Transaction finishT) {
        ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "onRecentsInSplitAnimationFinish: returnToApp=%b",
+11 −3
Original line number Diff line number Diff line
@@ -159,9 +159,17 @@ class RecentsMixedTransition extends DefaultMixedHandler.MixedTransition {
            // If pair-to-pair switching, the post-recents clean-up isn't needed.
            wct = wct != null ? wct : new WindowContainerTransaction();
            if (mAnimType != ANIM_TYPE_PAIR_TO_PAIR) {
                // TODO(b/346588978): Only called if !enableRecentsBookendTransition(), can remove
                // once that rolls out
                mSplitHandler.onRecentsInSplitAnimationFinish(wct, finishTransaction);
                // We've dispatched to the mLeftoversHandler to handle the rest of the transition
                // and called onRecentsInSplitAnimationStart(), but if the recents handler is not
                // actually handling the transition, then onRecentsInSplitAnimationFinishing()
                // won't actually get called by the recents handler.  In such cases, we still need
                // to clean up after the changes from the start call.
                boolean splitNotifiedByRecents = mRecentsHandler == mLeftoversHandler;
                if (!splitNotifiedByRecents) {
                    mSplitHandler.onRecentsInSplitAnimationFinishing(
                            mSplitHandler.wctIsReorderingSplitToTop(wct),
                            wct, finishTransaction);
                }
            } else {
                // notify pair-to-pair recents animation finish
                mSplitHandler.onRecentsPairToPairAnimationFinish(wct);
+4 −2
Original line number Diff line number Diff line
@@ -360,7 +360,8 @@ public class SplitTransitionTests extends ShellTestCase {
            mStageCoordinator.onRecentsInSplitAnimationFinishing(false /* returnToApp */, commitWCT,
                    mock(SurfaceControl.Transaction.class));
        } else {
            mStageCoordinator.onRecentsInSplitAnimationFinish(commitWCT,
            mStageCoordinator.onRecentsInSplitAnimationFinishing(
                    mStageCoordinator.wctIsReorderingSplitToTop(commitWCT), commitWCT,
                    mock(SurfaceControl.Transaction.class));
        }
        assertFalse(mStageCoordinator.isSplitScreenVisible());
@@ -430,7 +431,8 @@ public class SplitTransitionTests extends ShellTestCase {
            mStageCoordinator.onRecentsInSplitAnimationFinishing(true /* returnToApp */, restoreWCT,
                    mock(SurfaceControl.Transaction.class));
        } else {
            mStageCoordinator.onRecentsInSplitAnimationFinish(restoreWCT,
            mStageCoordinator.onRecentsInSplitAnimationFinishing(
                    mStageCoordinator.wctIsReorderingSplitToTop(restoreWCT), restoreWCT,
                    mock(SurfaceControl.Transaction.class));
        }
        assertTrue(mStageCoordinator.isSplitScreenVisible());