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

Commit d5cdea48 authored by Tony Huang's avatar Tony Huang Committed by Android (Google) Code Review
Browse files

Merge "Fix divider disappear when rotation on shell transition" into tm-dev

parents 7c722ca4 dd637175
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -218,9 +218,13 @@ public class WindowlessWindowManager implements IWindowSession {
            throw new IllegalArgumentException(
                    "Invalid window token (never added or removed already)");
        }
        removeSurface(state.mSurfaceControl);
    }

    /** Separate from {@link #remove} so that subclasses can put removal on a sync transaction. */
    protected void removeSurface(SurfaceControl sc) {
        try (SurfaceControl.Transaction t = new SurfaceControl.Transaction()) {
            t.remove(state.mSurfaceControl).apply();
            t.remove(sc).apply();
        }
    }

+24 −7
Original line number Diff line number Diff line
@@ -98,6 +98,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
    private WindowContainerToken mWinToken2;
    private int mDividePosition;
    private boolean mInitialized = false;
    private boolean mFreezeDividerWindow = false;
    private int mOrientation;
    private int mRotation;

@@ -225,11 +226,6 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
        mDividerSnapAlgorithm = getSnapAlgorithm(mContext, mRootBounds, null);
        initDividerPosition(mTempRect);

        if (mInitialized) {
            release();
            init();
        }

        return true;
    }

@@ -298,20 +294,37 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
    }

    /** Releases the surface holding the current {@link DividerView}. */
    public void release() {
    public void release(SurfaceControl.Transaction t) {
        if (!mInitialized) return;
        mInitialized = false;
        mSplitWindowManager.release();
        mSplitWindowManager.release(t);
        mDisplayImeController.removePositionProcessor(mImePositionProcessor);
        mImePositionProcessor.reset();
    }

    public void release() {
        release(null /* t */);
    }

    /** Releases and re-inflates {@link DividerView} on the root surface. */
    public void update(SurfaceControl.Transaction t) {
        if (!mInitialized) return;
        mSplitWindowManager.release(t);
        mImePositionProcessor.reset();
        mSplitWindowManager.init(this, mInsetsState);
    }

    @Override
    public void insetsChanged(InsetsState insetsState) {
        mInsetsState.set(insetsState);
        if (!mInitialized) {
            return;
        }
        if (mFreezeDividerWindow) {
            // DO NOT change its layout before transition actually run because it might cause
            // flicker.
            return;
        }
        mSplitWindowManager.onInsetsChanged(insetsState);
    }

@@ -323,6 +336,10 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
        }
    }

    public void setFreezeDividerWindow(boolean freezeDividerWindow) {
        mFreezeDividerWindow = freezeDividerWindow;
    }

    /**
     * Updates bounds with the passing position. Usually used to update recording bounds while
     * performing animation or dragging divider bar to resize the splits.
+21 −2
Original line number Diff line number Diff line
@@ -58,6 +58,9 @@ public final class SplitWindowManager extends WindowlessWindowManager {
    private SurfaceControl mLeash;
    private DividerView mDividerView;

    // Used to "pass" a transaction to WWM.remove so that view removal can be synchronized.
    private SurfaceControl.Transaction mSyncTransaction = null;

    public interface ParentContainerCallbacks {
        void attachToParentSurface(SurfaceControl.Builder b);
        void onLeashReady(SurfaceControl leash);
@@ -130,22 +133,38 @@ public final class SplitWindowManager extends WindowlessWindowManager {
     * Releases the surface control of the current {@link DividerView} and tear down the view
     * hierarchy.
     */
    void release() {
    void release(@Nullable SurfaceControl.Transaction t) {
        if (mDividerView != null) {
            mDividerView = null;
        }

        if (mViewHost != null){
            mSyncTransaction = t;
            mViewHost.release();
            mSyncTransaction = null;
            mViewHost = null;
        }

        if (mLeash != null) {
            if (t == null) {
                new SurfaceControl.Transaction().remove(mLeash).apply();
            } else {
                t.remove(mLeash);
            }
            mLeash = null;
        }
    }

    @Override
    protected void removeSurface(SurfaceControl sc) {
        // This gets called via SurfaceControlViewHost.release()
        if (mSyncTransaction != null) {
            mSyncTransaction.remove(sc);
        } else {
            super.removeSurface(sc);
        }
    }

    void setInteractive(boolean interactive) {
        if (mDividerView == null) return;
        mDividerView.setInteractive(interactive);
+18 −7
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import static android.view.WindowManager.TRANSIT_TO_BACK;
import static android.view.WindowManager.TRANSIT_TO_FRONT;
import static android.view.WindowManager.transitTypeToString;
import static android.view.WindowManagerPolicyConstants.SPLIT_DIVIDER_LAYER;
import static android.window.TransitionInfo.FLAG_IS_DISPLAY;

import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT;
@@ -1171,6 +1172,8 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
                updateUnfoldBounds();
                return;
            }

            mSplitLayout.update(null /* t */);
            onLayoutSizeChanged(mSplitLayout);
        }
    }
@@ -1198,7 +1201,6 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
        if (!ENABLE_SHELL_TRANSITIONS) return;

        final SurfaceControl.Transaction t = mTransactionPool.acquire();
        setDividerVisibility(false, t);
        mDisplayLayout.rotateTo(mContext.getResources(), toRotation);
        mSplitLayout.rotateTo(toRotation, mDisplayLayout.stableInsets());
        updateWindowBounds(mSplitLayout, wct);
@@ -1255,8 +1257,15 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
            @Nullable TransitionRequestInfo request) {
        final ActivityManager.RunningTaskInfo triggerTask = request.getTriggerTask();
        if (triggerTask == null) {
            if (mMainStage.isActive()) {
                if (request.getType() == TRANSIT_CHANGE && request.getDisplayChange() != null) {
                    mSplitLayout.setFreezeDividerWindow(true);
                }
                // Still want to monitor everything while in split-screen, so return non-null.
            return mMainStage.isActive() ? new WindowContainerTransaction() : null;
                return new WindowContainerTransaction();
            } else {
                return null;
            }
        } else if (triggerTask.displayId != mDisplayId) {
            // Skip handling task on the other display.
            return null;
@@ -1352,8 +1361,14 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
            // If we're not in split-mode, just abort so something else can handle it.
            if (!mMainStage.isActive()) return false;

            mSplitLayout.setFreezeDividerWindow(false);
            for (int iC = 0; iC < info.getChanges().size(); ++iC) {
                final TransitionInfo.Change change = info.getChanges().get(iC);
                if (change.getMode() == TRANSIT_CHANGE
                        && (change.getFlags() & FLAG_IS_DISPLAY) != 0) {
                    mSplitLayout.update(startTransaction);
                }

                final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
                if (taskInfo == null || !taskInfo.hasParentTask()) continue;
                final StageTaskListener stage = getStageOfTask(taskInfo);
@@ -1368,10 +1383,6 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
                        Log.w(TAG, "Expected onTaskVanished on " + stage + " to have been called"
                                + " with " + taskInfo.taskId + " before startAnimation().");
                    }
                } else if (info.getType() == TRANSIT_CHANGE
                        && change.getStartRotation() != change.getEndRotation()) {
                    // Show the divider after transition finished.
                    setDividerVisibility(true, finishTransaction);
                }
            }
            if (mMainStage.getChildCount() == 0 || mSideStage.getChildCount() == 0) {
+1 −1
Original line number Diff line number Diff line
@@ -61,7 +61,7 @@ public class SplitWindowManagerTests extends ShellTestCase {
    public void testInitRelease() {
        mSplitWindowManager.init(mSplitLayout, new InsetsState());
        assertThat(mSplitWindowManager.getSurfaceControl()).isNotNull();
        mSplitWindowManager.release();
        mSplitWindowManager.release(null /* t */);
        assertThat(mSplitWindowManager.getSurfaceControl()).isNull();
    }
}