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

Commit 5e7bb081 authored by Tony Huang's avatar Tony Huang Committed by Automerger Merge Worker
Browse files

Merge "Exit split when fold only if user interacted" into udc-qpr-dev am: cf609fbb am: e07b8343

parents ddde88ac e07b8343
Loading
Loading
Loading
Loading
+44 −24
Original line number Diff line number Diff line
@@ -219,6 +219,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
    private boolean mIsDropEntering;
    private boolean mIsExiting;
    private boolean mIsRootTranslucent;
    @VisibleForTesting
    int mTopStageAfterFoldDismiss;

    private DefaultMixedHandler mMixedHandler;
    private final Toast mSplitUnsupportedToast;
@@ -1310,6 +1312,24 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
            final StageTaskListener toTop = mainStageVisible ? mMainStage : mSideStage;
            exitSplitScreen(toTop, EXIT_REASON_SCREEN_LOCKED_SHOW_ON_TOP);
        }

        // Dismiss split if the flag record any side of stages.
        if (mTopStageAfterFoldDismiss != STAGE_TYPE_UNDEFINED) {
            if (ENABLE_SHELL_TRANSITIONS) {
                // Need manually clear here due to this transition might be aborted due to keyguard
                // on top and lead to no visible change.
                clearSplitPairedInRecents(EXIT_REASON_DEVICE_FOLDED);
                final WindowContainerTransaction wct = new WindowContainerTransaction();
                prepareExitSplitScreen(mTopStageAfterFoldDismiss, wct);
                mSplitTransitions.startDismissTransition(wct, this,
                        mTopStageAfterFoldDismiss, EXIT_REASON_DEVICE_FOLDED);
            } else {
                exitSplitScreen(
                        mTopStageAfterFoldDismiss == STAGE_TYPE_MAIN ? mMainStage : mSideStage,
                        EXIT_REASON_DEVICE_FOLDED);
            }
            mTopStageAfterFoldDismiss = STAGE_TYPE_UNDEFINED;
        }
    }

    void exitSplitScreenOnHide(boolean exitSplitScreenOnHide) {
@@ -1346,15 +1366,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
        if (!mMainStage.isActive() || mIsExiting) return;

        onSplitScreenExit();
        clearSplitPairedInRecents(exitReason);

        mRecentTasks.ifPresent(recentTasks -> {
            // Notify recents if we are exiting in a way that breaks the pair, and disable further
            // updates to splits in the recents until we enter split again
            if (shouldBreakPairedTaskInRecents(exitReason) && mShouldUpdateRecents) {
                recentTasks.removeSplitPair(mMainStage.getTopVisibleChildTaskId());
                recentTasks.removeSplitPair(mSideStage.getTopVisibleChildTaskId());
            }
        });
        mShouldUpdateRecents = false;
        mIsDividerRemoteAnimating = false;
        mSplitRequest = null;
@@ -1481,6 +1494,17 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
        }
    }

    private void clearSplitPairedInRecents(@ExitReason int exitReason) {
        if (!shouldBreakPairedTaskInRecents(exitReason) || !mShouldUpdateRecents) return;

        mRecentTasks.ifPresent(recentTasks -> {
            // Notify recents if we are exiting in a way that breaks the pair, and disable further
            // updates to splits in the recents until we enter split again
            mMainStage.doForAllChildTasks(taskId -> recentTasks.removeSplitPair(taskId));
            mSideStage.doForAllChildTasks(taskId -> recentTasks.removeSplitPair(taskId));
        });
    }

    /**
     * Unlike exitSplitScreen, this takes a stagetype vs an actual stage-reference and populates
     * an existing WindowContainerTransaction (rather than applying immediately). This is intended
@@ -2208,7 +2232,11 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
        }
    }

    void updateSurfaces(SurfaceControl.Transaction transaction) {
    /**
     * Update surfaces of the split screen layout based on the current state
     * @param transaction to write the updates to
     */
    public void updateSurfaces(SurfaceControl.Transaction transaction) {
        updateSurfaceBounds(mSplitLayout, transaction, /* applyResizingOffset */ false);
        mSplitLayout.update(transaction);
    }
@@ -2227,26 +2255,18 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,

    @VisibleForTesting
    void onFoldedStateChanged(boolean folded) {
        int topStageAfterFoldDismiss = STAGE_TYPE_UNDEFINED;
        mTopStageAfterFoldDismiss = STAGE_TYPE_UNDEFINED;
        if (!folded) return;

        if (!mMainStage.isActive()) return;
        if (!isSplitActive() || !isSplitScreenVisible()) return;

        // To avoid split dismiss when user fold the device and unfold to use later, we only
        // record the flag here and try to dismiss on wakeUp callback to ensure split dismiss
        // when user interact on phone folded.
        if (mMainStage.isFocused()) {
            topStageAfterFoldDismiss = STAGE_TYPE_MAIN;
            mTopStageAfterFoldDismiss = STAGE_TYPE_MAIN;
        } else if (mSideStage.isFocused()) {
            topStageAfterFoldDismiss = STAGE_TYPE_SIDE;
        }

        if (ENABLE_SHELL_TRANSITIONS) {
            final WindowContainerTransaction wct = new WindowContainerTransaction();
            prepareExitSplitScreen(topStageAfterFoldDismiss, wct);
            mSplitTransitions.startDismissTransition(wct, this,
                    topStageAfterFoldDismiss, EXIT_REASON_DEVICE_FOLDED);
        } else {
            exitSplitScreen(
                    topStageAfterFoldDismiss == STAGE_TYPE_MAIN ? mMainStage : mSideStage,
                    EXIT_REASON_DEVICE_FOLDED);
            mTopStageAfterFoldDismiss = STAGE_TYPE_SIDE;
        }
    }

+8 −0
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ import com.android.wm.shell.windowdecor.WindowDecorViewModel;

import java.io.PrintWriter;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Predicate;

/**
@@ -347,6 +348,13 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener {
        wct.reorder(mChildrenTaskInfo.get(taskId).token, onTop /* onTop */);
    }

    void doForAllChildTasks(Consumer<Integer> consumer) {
        for (int i = mChildrenTaskInfo.size() - 1; i >= 0; i--) {
            final ActivityManager.RunningTaskInfo taskInfo = mChildrenTaskInfo.valueAt(i);
            consumer.accept(taskInfo.taskId);
        }
    }

    /** Collects all the current child tasks and prepares transaction to evict them to display. */
    void evictAllChildren(WindowContainerTransaction wct) {
        for (int i = mChildrenTaskInfo.size() - 1; i >= 0; i--) {
+3 −0
Original line number Diff line number Diff line
@@ -704,6 +704,9 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler,
        if (mPipHandler != null) {
            mPipHandler.syncPipSurfaceState(info, startTransaction, finishTransaction);
        }
        if (mSplitHandler != null && mSplitHandler.isSplitActive()) {
            mSplitHandler.updateSurfaces(startTransaction);
        }
        return mUnfoldHandler.startAnimation(
                mixed.mTransition, info, startTransaction, finishTransaction, finishCB);
    }
+0 −1
Original line number Diff line number Diff line
@@ -270,7 +270,6 @@ public class SplitTaskUnfoldAnimator implements UnfoldTaskAnimator,
    @Override
    public void prepareStartTransaction(Transaction transaction) {
        mUnfoldBackgroundController.ensureBackground(transaction);
        mSplitScreenController.get().get().updateSplitScreenSurfaces(transaction);
    }

    @Override
+9 −2
Original line number Diff line number Diff line
@@ -347,13 +347,20 @@ public class StageCoordinatorTests extends ShellTestCase {
    }

    @Test
    public void testExitSplitScreenAfterFolded() {
        when(mMainStage.isActive()).thenReturn(true);
    public void testExitSplitScreenAfterFoldedAndWakeUp() {
        when(mMainStage.isFocused()).thenReturn(true);
        when(mMainStage.getTopVisibleChildTaskId()).thenReturn(INVALID_TASK_ID);
        mSideStage.mRootTaskInfo = new TestRunningTaskInfoBuilder().setVisible(true).build();
        mMainStage.mRootTaskInfo = new TestRunningTaskInfoBuilder().setVisible(true).build();
        when(mStageCoordinator.isSplitActive()).thenReturn(true);
        when(mStageCoordinator.isSplitScreenVisible()).thenReturn(true);

        mStageCoordinator.onFoldedStateChanged(true);

        assertEquals(mStageCoordinator.mTopStageAfterFoldDismiss, STAGE_TYPE_MAIN);

        mStageCoordinator.onFinishedWakingUp();

        if (Transitions.ENABLE_SHELL_TRANSITIONS) {
            verify(mTaskOrganizer).startNewTransition(eq(TRANSIT_SPLIT_DISMISS), notNull());
        } else {