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

Commit c6eec4fd authored by Jerry Chang's avatar Jerry Chang Committed by Android (Google) Code Review
Browse files

Merge "Support to merge transition to remote handler while in split screen mode"

parents 43cb3055 f37bfeaa
Loading
Loading
Loading
Loading
+26 −16
Original line number Diff line number Diff line
@@ -70,7 +70,8 @@ class SplitScreenTransitions {
    IBinder mPendingRecent = null;

    private IBinder mAnimatingTransition = null;
    private OneShotRemoteHandler mRemoteHandler = null;
    private OneShotRemoteHandler mPendingRemoteHandler = null;
    private OneShotRemoteHandler mActiveRemoteHandler = null;

    private final Transitions.TransitionFinishCallback mRemoteFinishCB = this::onFinish;

@@ -96,10 +97,11 @@ class SplitScreenTransitions {
            @NonNull WindowContainerToken mainRoot, @NonNull WindowContainerToken sideRoot) {
        mFinishCallback = finishCallback;
        mAnimatingTransition = transition;
        if (mRemoteHandler != null) {
            mRemoteHandler.startAnimation(transition, info, startTransaction, finishTransaction,
                    mRemoteFinishCB);
            mRemoteHandler = null;
        if (mPendingRemoteHandler != null) {
            mPendingRemoteHandler.startAnimation(transition, info, startTransaction,
                    finishTransaction, mRemoteFinishCB);
            mActiveRemoteHandler = mPendingRemoteHandler;
            mPendingRemoteHandler = null;
            return;
        }
        playInternalAnimation(transition, info, startTransaction, mainRoot, sideRoot);
@@ -172,15 +174,14 @@ class SplitScreenTransitions {
    IBinder startEnterTransition(@WindowManager.TransitionType int transitType,
            @NonNull WindowContainerTransaction wct, @Nullable RemoteTransition remoteTransition,
            @NonNull Transitions.TransitionHandler handler) {
        final IBinder transition = mTransitions.startTransition(transitType, wct, handler);
        mPendingEnter = transition;

        if (remoteTransition != null) {
            // Wrapping it for ease-of-use (OneShot handles all the binder linking/death stuff)
            mRemoteHandler = new OneShotRemoteHandler(
            mPendingRemoteHandler = new OneShotRemoteHandler(
                    mTransitions.getMainExecutor(), remoteTransition);
        }
        final IBinder transition = mTransitions.startTransition(transitType, wct, handler);
        mPendingEnter = transition;
        if (mRemoteHandler != null) {
            mRemoteHandler.setTransition(transition);
            mPendingRemoteHandler.setTransition(transition);
        }
        return transition;
    }
@@ -211,9 +212,9 @@ class SplitScreenTransitions {

        if (remoteTransition != null) {
            // Wrapping it for ease-of-use (OneShot handles all the binder linking/death stuff)
            mRemoteHandler = new OneShotRemoteHandler(
            mPendingRemoteHandler = new OneShotRemoteHandler(
                    mTransitions.getMainExecutor(), remoteTransition);
            mRemoteHandler.setTransition(transition);
            mPendingRemoteHandler.setTransition(transition);
        }

        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "  splitTransition "
@@ -221,6 +222,13 @@ class SplitScreenTransitions {
        return transition;
    }

    void mergeAnimation(IBinder transition, TransitionInfo info, SurfaceControl.Transaction t,
            IBinder mergeTarget, Transitions.TransitionFinishCallback finishCallback) {
        if (mergeTarget == mAnimatingTransition && mActiveRemoteHandler != null) {
            mActiveRemoteHandler.mergeAnimation(transition, info, t, mergeTarget, finishCallback);
        }
    }

    void onFinish(WindowContainerTransaction wct, WindowContainerTransactionCallback wctCB) {
        if (!mAnimations.isEmpty()) return;
        mOnFinish.run();
@@ -241,11 +249,13 @@ class SplitScreenTransitions {
        }
        if (mAnimatingTransition == mPendingRecent) {
            // If the wct is not null while finishing recent transition, it indicates it's not
            // returning to home and hence needing the wct to reorder tasks.
            final boolean toHome = wct == null;
            mStageCoordinator.finishRecentAnimation(toHome);
            // dismissing split and thus need to reorder split task so they can be on top again.
            final boolean dismissSplit = wct == null;
            mStageCoordinator.finishRecentAnimation(dismissSplit);
            mPendingRecent = null;
        }
        mPendingRemoteHandler = null;
        mActiveRemoteHandler = null;
        mAnimatingTransition = null;
    }

+33 −17
Original line number Diff line number Diff line
@@ -166,17 +166,6 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
    @StageType
    private int mTopStageAfterFoldDismiss = STAGE_TYPE_UNDEFINED;

    private final Runnable mOnTransitionAnimationComplete = () -> {
        // If still playing, let it finish.
        if (!isSplitScreenVisible()) {
            // Update divider state after animation so that it is still around and positioned
            // properly for the animation itself.
            mSplitLayout.release();
            mSplitLayout.resetDividerPosition();
            mTopStageAfterFoldDismiss = STAGE_TYPE_UNDEFINED;
        }
    };

    private final SplitWindowManager.ParentContainerCallbacks mParentContainerCallbacks =
            new SplitWindowManager.ParentContainerCallbacks() {
                @Override
@@ -237,7 +226,7 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
        deviceStateManager.registerCallback(taskOrganizer.getExecutor(),
                new DeviceStateManager.FoldStateListener(mContext, this::onFoldedStateChanged));
        mSplitTransitions = new SplitScreenTransitions(transactionPool, transitions,
                mOnTransitionAnimationComplete, this);
                this::onTransitionAnimationComplete, this);
        mDisplayController.addDisplayWindowListener(this);
        mDisplayLayout = new DisplayLayout(displayController.getDisplayLayout(displayId));
        transitions.addHandler(this);
@@ -267,7 +256,7 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
        mRootTDAOrganizer.registerListener(displayId, this);
        mSplitLayout = splitLayout;
        mSplitTransitions = new SplitScreenTransitions(transactionPool, transitions,
                mOnTransitionAnimationComplete, this);
                this::onTransitionAnimationComplete, this);
        mMainUnfoldController = unfoldControllerProvider.get().orElse(null);
        mSideUnfoldController = unfoldControllerProvider.get().orElse(null);
        mLogger = logger;
@@ -1234,7 +1223,7 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
        final ActivityManager.RunningTaskInfo triggerTask = request.getTriggerTask();
        if (triggerTask == null) {
            // Still want to monitor everything while in split-screen, so return non-null.
            return isSplitScreenVisible() ? new WindowContainerTransaction() : null;
            return mMainStage.isActive() ? new WindowContainerTransaction() : null;
        } else if (triggerTask.displayId != mDisplayId) {
            // Skip handling task on the other display.
            return null;
@@ -1250,7 +1239,7 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
            mRecentTasks.ifPresent(recentTasks -> recentTasks.removeSplitPair(triggerTask.taskId));
        }

        if (isSplitScreenVisible()) {
        if (mMainStage.isActive()) {
            // Try to handle everything while in split-screen, so return a WCT even if it's empty.
            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "  split is active so using split"
                            + "Transition to handle request. triggerTask=%d type=%s mainChildren=%d"
@@ -1295,6 +1284,13 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
        return out;
    }

    @Override
    public void mergeAnimation(IBinder transition, TransitionInfo info,
            SurfaceControl.Transaction t, IBinder mergeTarget,
            Transitions.TransitionFinishCallback finishCallback) {
        mSplitTransitions.mergeAnimation(transition, info, t, mergeTarget, finishCallback);
    }

    @Override
    public void onTransitionMerged(@NonNull IBinder transition) {
        // Once the pending enter transition got merged, make sure to bring divider bar visible and
@@ -1375,6 +1371,17 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
        return true;
    }

    void onTransitionAnimationComplete() {
        // If still playing, let it finish.
        if (!mMainStage.isActive()) {
            // Update divider state after animation so that it is still around and positioned
            // properly for the animation itself.
            mSplitLayout.release();
            mSplitLayout.resetDividerPosition();
            mTopStageAfterFoldDismiss = STAGE_TYPE_UNDEFINED;
        }
    }

    private boolean startPendingEnterAnimation(@NonNull IBinder transition,
            @NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction t) {
        // First, verify that we actually have opened apps in both splits.
@@ -1513,8 +1520,17 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
        return true;
    }

    void finishRecentAnimation(boolean toHome) {
        if (toHome) {
    void finishRecentAnimation(boolean dismissSplit) {
        // Exclude the case that the split screen has been dismissed already.
        if (!mMainStage.isActive()) {
            // The latest split dismissing transition might be a no-op transition and thus won't
            // callback startAnimation, update split visibility here to cover this kind of no-op
            // transition case.
            setSplitsVisible(false);
            return;
        }

        if (dismissSplit) {
            final WindowContainerTransaction wct = new WindowContainerTransaction();
            prepareExitSplitScreen(STAGE_TYPE_UNDEFINED, wct);
            mSplitTransitions.startDismissTransition(null /* transition */, wct, this,