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

Commit 71da554f authored by Tony Huang's avatar Tony Huang
Browse files

Fine turn divider transition on enter/exit split

Make divider could fade-in/out with split surface change.

Bug: 245472831
Test: manual
Test: pass existing tests
Change-Id: Ifd129ceae1db1fffc9bf4ad3b0f85279138581ef
parent 0d5627fe
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -897,7 +897,7 @@ public class PipTransition extends PipTransitionController {
                        .setWindowCrop(leash, endBounds.width(), endBounds.height());
            }
        }
        mSplitScreenOptional.get().finishEnterSplitScreen(startTransaction);
        mSplitScreenOptional.get().finishEnterSplitScreen(finishTransaction);
        startTransaction.apply();

        mPipOrganizer.onExitPipFinished(taskInfo);
+9 −2
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import static android.view.WindowManager.TRANSIT_OPEN;
import static android.view.WindowManager.TRANSIT_TO_BACK;
import static android.view.WindowManager.TRANSIT_TO_FRONT;

import static com.android.wm.shell.common.split.SplitScreenConstants.FLAG_IS_DIVIDER_BAR;
import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_MAIN;
import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_UNDEFINED;
import static com.android.wm.shell.splitscreen.SplitScreen.stageTypeToString;
@@ -155,8 +156,10 @@ class SplitScreenTransitions {
            }
            boolean isRootOrSplitSideRoot = change.getParent() == null
                    || topRoot.equals(change.getParent());
            // For enter or exit, we only want to animate the side roots but not the top-root.
            if (!isRootOrSplitSideRoot || topRoot.equals(change.getContainer())) {
            boolean isDivider = change.getFlags() == FLAG_IS_DIVIDER_BAR;
            // For enter or exit, we only want to animate side roots and the divider but not the
            // top-root.
            if (!isRootOrSplitSideRoot || topRoot.equals(change.getContainer()) || isDivider) {
                continue;
            }

@@ -165,6 +168,10 @@ class SplitScreenTransitions {
                t.setPosition(leash, change.getEndAbsBounds().left, change.getEndAbsBounds().top);
                t.setWindowCrop(leash, change.getEndAbsBounds().width(),
                        change.getEndAbsBounds().height());
            } else if (isDivider) {
                t.setPosition(leash, change.getEndAbsBounds().left, change.getEndAbsBounds().top);
                t.setLayer(leash, Integer.MAX_VALUE);
                t.show(leash);
            }
            boolean isOpening = isOpeningTransition(info);
            if (isOpening && (mode == TRANSIT_OPEN || mode == TRANSIT_TO_FRONT)) {
+28 −26
Original line number Diff line number Diff line
@@ -891,10 +891,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
            mSyncQueue.queue(wrapAsSplitRemoteAnimation(adapter), WindowManager.TRANSIT_OPEN, wct);
        }

        mSyncQueue.runInSync(t -> {
            setDividerVisibility(true, t);
        });

        setEnterInstanceId(instanceId);
    }

@@ -933,6 +929,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
            @Override
            public void onAnimationCancelled(boolean isKeyguardOccluded) {
                onRemoteAnimationFinishedOrCancelled(evictWct);
                setDividerVisibility(true, null);
                try {
                    adapter.getRunner().onAnimationCancelled(isKeyguardOccluded);
                } catch (RemoteException e) {
@@ -973,6 +970,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
                            t.setPosition(apps[i].leash, 0, 0);
                        }
                    }
                    setDividerVisibility(true, t);
                    t.apply();

                    IRemoteAnimationFinishedCallback wrapCallback =
@@ -1463,6 +1461,10 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
    void finishEnterSplitScreen(SurfaceControl.Transaction t) {
        mSplitLayout.init();
        setDividerVisibility(true, t);
        // Ensure divider surface are re-parented back into the hierarchy at the end of the
        // transition. See Transition#buildFinishTransaction for more detail.
        t.reparent(mSplitLayout.getDividerLeash(), mRootTaskLeash);

        updateSurfaceBounds(mSplitLayout, t, false /* applyResizingOffset */);
        t.show(mRootTaskLeash);
        setSplitsVisible(true);
@@ -1772,6 +1774,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
        setDividerVisibility(mainStageVisible, null);
    }

    // Set divider visibility flag and try to apply it, the param transaction is used to apply.
    // See applyDividerVisibility for more detail.
    private void setDividerVisibility(boolean visible, @Nullable SurfaceControl.Transaction t) {
        if (visible == mDividerVisible) {
            return;
@@ -1798,14 +1802,13 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
            return;
        }

        if (t != null) {
        applyDividerVisibility(t);
        } else {
            mSyncQueue.runInSync(transaction -> applyDividerVisibility(transaction));
        }
    }

    private void applyDividerVisibility(SurfaceControl.Transaction t) {
    // Apply divider visibility by current visibility flag. If param transaction is non-null, it
    // will apply by that transaction, if it is null and visible, it will run a fade-in animation,
    // otherwise hide immediately.
    private void applyDividerVisibility(@Nullable SurfaceControl.Transaction t) {
        final SurfaceControl dividerLeash = mSplitLayout.getDividerLeash();
        if (dividerLeash == null) {
            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN,
@@ -1822,7 +1825,12 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
            mDividerFadeInAnimator.cancel();
        }

        if (mDividerVisible) {
        mSplitLayout.getRefDividerBounds(mTempRect1);
        if (t != null) {
            t.setVisibility(dividerLeash, mDividerVisible);
            t.setLayer(dividerLeash, Integer.MAX_VALUE);
            t.setPosition(dividerLeash, mTempRect1.left, mTempRect1.top);
        } else if (mDividerVisible) {
            final SurfaceControl.Transaction transaction = mTransactionPool.acquire();
            mDividerFadeInAnimator = ValueAnimator.ofFloat(0f, 1f);
            mDividerFadeInAnimator.addUpdateListener(animation -> {
@@ -1862,7 +1870,10 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,

            mDividerFadeInAnimator.start();
        } else {
            t.hide(dividerLeash);
            final SurfaceControl.Transaction transaction = mTransactionPool.acquire();
            transaction.hide(dividerLeash);
            transaction.apply();
            mTransactionPool.release(transaction);
        }
    }

@@ -2446,7 +2457,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
        }

        finishEnterSplitScreen(finishT);
        addDividerBarToTransition(info, finishT, true /* show */);
        addDividerBarToTransition(info, true /* show */);
        return true;
    }

@@ -2589,7 +2600,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
        if (dismissTransition.mDismissTop == STAGE_TYPE_UNDEFINED) {
            // TODO: Have a proper remote for this. Until then, though, reset state and use the
            //       normal animation stuff (which falls back to the normal launcher remote).
            t.hide(mSplitLayout.getDividerLeash());
            setDividerVisibility(false, t);
            mSplitLayout.release(t);
            mSplitTransitions.mPendingDismiss = null;
            return false;
@@ -2607,7 +2618,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
                    });
        }

        addDividerBarToTransition(info, finishT, false /* show */);
        addDividerBarToTransition(info, false /* show */);
        return true;
    }

@@ -2648,11 +2659,11 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
        logExit(EXIT_REASON_UNKNOWN);
    }

    private void addDividerBarToTransition(@NonNull TransitionInfo info,
            @NonNull SurfaceControl.Transaction finishT, boolean show) {
    private void addDividerBarToTransition(@NonNull TransitionInfo info, boolean show) {
        final SurfaceControl leash = mSplitLayout.getDividerLeash();
        final TransitionInfo.Change barChange = new TransitionInfo.Change(null /* token */, leash);
        mSplitLayout.getRefDividerBounds(mTempRect1);
        barChange.setParent(mRootTaskInfo.token);
        barChange.setStartAbsBounds(mTempRect1);
        barChange.setEndAbsBounds(mTempRect1);
        barChange.setMode(show ? TRANSIT_TO_FRONT : TRANSIT_TO_BACK);
@@ -2660,15 +2671,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
        // Technically this should be order-0, but this is running after layer assignment
        // and it's a special case, so just add to end.
        info.addChange(barChange);

        if (show) {
            finishT.setLayer(leash, Integer.MAX_VALUE);
            finishT.setPosition(leash, mTempRect1.left, mTempRect1.top);
            finishT.show(leash);
            // Ensure divider surface are re-parented back into the hierarchy at the end of the
            // transition. See Transition#buildFinishTransaction for more detail.
            finishT.reparent(leash, mRootTaskLeash);
        }
    }

    RemoteAnimationTarget getDividerBarLegacyTarget() {
+3 −0
Original line number Diff line number Diff line
@@ -113,6 +113,7 @@ public class StageCoordinatorTests extends ShellTestCase {

    private SurfaceSession mSurfaceSession = new SurfaceSession();
    private SurfaceControl mRootLeash;
    private SurfaceControl mDividerLeash;
    private ActivityManager.RunningTaskInfo mRootTask;
    private StageCoordinator mStageCoordinator;
    private Transitions mTransitions;
@@ -129,12 +130,14 @@ public class StageCoordinatorTests extends ShellTestCase {
                mTaskOrganizer, mMainStage, mSideStage, mDisplayController, mDisplayImeController,
                mDisplayInsetsController, mSplitLayout, mTransitions, mTransactionPool,
                mMainExecutor, Optional.empty()));
        mDividerLeash = new SurfaceControl.Builder(mSurfaceSession).setName("fakeDivider").build();

        when(mSplitLayout.getBounds1()).thenReturn(mBounds1);
        when(mSplitLayout.getBounds2()).thenReturn(mBounds2);
        when(mSplitLayout.getRootBounds()).thenReturn(mRootBounds);
        when(mSplitLayout.isLandscape()).thenReturn(false);
        when(mSplitLayout.applyTaskChanges(any(), any(), any())).thenReturn(true);
        when(mSplitLayout.getDividerLeash()).thenReturn(mDividerLeash);

        mRootTask = new TestRunningTaskInfoBuilder().build();
        mRootLeash = new SurfaceControl.Builder(mSurfaceSession).setName("test").build();