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

Commit 82352f9d authored by Evan Rosky's avatar Evan Rosky Committed by Android (Google) Code Review
Browse files

Merge "Use boundsChangeTransaction to improve split-screen enter/exit" into rvc-dev

parents 4c65d2cb 3613854d
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -209,7 +209,11 @@ public class WindowlessWindowManager implements IWindowSession {

    /** @hide */
    protected SurfaceControl getSurfaceControl(View rootView) {
        final State s = mStateForWindow.get(rootView.getViewRootImpl().mWindow.asBinder());
        final ViewRootImpl root = rootView.getViewRootImpl();
        if (root == null) {
            return null;
        }
        final State s = mStateForWindow.get(root.mWindow.asBinder());
        if (s == null) {
            return null;
        }
+64 −0
Original line number Diff line number Diff line
@@ -264,6 +264,29 @@ public final class WindowContainerTransaction implements Parcelable {
        return this;
    }

    /**
     * Merges another WCT into this one.
     * @param transfer When true, this will transfer everything from other potentially leaving
     *                 other in an unusable state. When false, other is left alone, but
     *                 SurfaceFlinger Transactions will not be merged.
     * @hide
     */
    public void merge(WindowContainerTransaction other, boolean transfer) {
        for (int i = 0, n = other.mChanges.size(); i < n; ++i) {
            final IBinder key = other.mChanges.keyAt(i);
            Change existing = mChanges.get(key);
            if (existing == null) {
                existing = new Change();
                mChanges.put(key, existing);
            }
            existing.merge(other.mChanges.valueAt(i), transfer);
        }
        for (int i = 0, n = other.mHierarchyOps.size(); i < n; ++i) {
            mHierarchyOps.add(transfer ? other.mHierarchyOps.get(i)
                    : new HierarchyOp(other.mHierarchyOps.get(i)));
        }
    }

    /** @hide */
    public Map<IBinder, Change> getChanges() {
        return mChanges;
@@ -359,6 +382,41 @@ public final class WindowContainerTransaction implements Parcelable {
            mActivityWindowingMode = in.readInt();
        }

        /**
         * @param transfer When true, this will transfer other into this leaving other in an
         *                 undefined state. Use this if you don't intend to use other. When false,
         *                 SurfaceFlinger Transactions will not merge.
         */
        public void merge(Change other, boolean transfer) {
            mConfiguration.setTo(other.mConfiguration, other.mConfigSetMask, other.mWindowSetMask);
            mConfigSetMask |= other.mConfigSetMask;
            mWindowSetMask |= other.mWindowSetMask;
            if ((other.mChangeMask & CHANGE_FOCUSABLE) != 0) {
                mFocusable = other.mFocusable;
            }
            if (transfer && (other.mChangeMask & CHANGE_BOUNDS_TRANSACTION) != 0) {
                mBoundsChangeTransaction = other.mBoundsChangeTransaction;
                other.mBoundsChangeTransaction = null;
            }
            if ((other.mChangeMask & CHANGE_PIP_CALLBACK) != 0) {
                mPinnedBounds = transfer ? other.mPinnedBounds : new Rect(other.mPinnedBounds);
            }
            if ((other.mChangeMask & CHANGE_HIDDEN) != 0) {
                mHidden = other.mHidden;
            }
            mChangeMask |= other.mChangeMask;
            if (other.mActivityWindowingMode >= 0) {
                mActivityWindowingMode = other.mActivityWindowingMode;
            }
            if (other.mWindowingMode >= 0) {
                mWindowingMode = other.mWindowingMode;
            }
            if (other.mBoundsChangeSurfaceBounds != null) {
                mBoundsChangeSurfaceBounds = transfer ? other.mBoundsChangeSurfaceBounds
                        : new Rect(other.mBoundsChangeSurfaceBounds);
            }
        }

        public int getWindowingMode() {
            return mWindowingMode;
        }
@@ -522,6 +580,12 @@ public final class WindowContainerTransaction implements Parcelable {
            mToTop = toTop;
        }

        public HierarchyOp(@NonNull HierarchyOp copy) {
            mContainer = copy.mContainer;
            mReparent = copy.mReparent;
            mToTop = copy.mToTop;
        }

        protected HierarchyOp(Parcel in) {
            mContainer = in.readStrongBinder();
            mReparent = in.readStrongBinder();
+38 −16
Original line number Diff line number Diff line
@@ -99,16 +99,19 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks,
    private Handler mHandler;
    private KeyguardStateController mKeyguardStateController;

    private WindowManagerProxy mWindowManagerProxy;

    private final ArrayList<WeakReference<Consumer<Boolean>>> mDockedStackExistsListeners =
            new ArrayList<>();

    private SplitScreenTaskOrganizer mSplits = new SplitScreenTaskOrganizer(this);

    private DisplayChangeController.OnDisplayChangingListener mRotationController =
            (display, fromRotation, toRotation, t) -> {
                if (!mSplits.isSplitScreenSupported()) {
            (display, fromRotation, toRotation, wct) -> {
                if (!mSplits.isSplitScreenSupported() || mWindowManagerProxy == null) {
                    return;
                }
                WindowContainerTransaction t = new WindowContainerTransaction();
                DisplayLayout displayLayout =
                        new DisplayLayout(mDisplayController.getDisplayLayout(display));
                SplitDisplayLayout sdl = new SplitDisplayLayout(mContext, displayLayout, mSplits);
@@ -127,6 +130,17 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks,
                if (isSplitActive()) {
                    WindowManagerProxy.applyHomeTasksMinimized(sdl, mSplits.mSecondary.token, t);
                }
                if (mWindowManagerProxy.queueSyncTransactionIfWaiting(t)) {
                    // Because sync transactions are serialized, its possible for an "older"
                    // bounds-change to get applied after a screen rotation. In that case, we
                    // want to actually defer on that rather than apply immediately. Of course,
                    // this means that the bounds may not change until after the rotation so
                    // the user might see some artifacts. This should be rare.
                    Slog.w(TAG, "Screen rotated while other operations were pending, this may"
                            + " result in some graphical artifacts.");
                } else {
                    wct.merge(t, true /* transfer */);
                }
            };

    private final DividerImeController mImePositionProcessor;
@@ -159,6 +173,7 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks,
        mRecentsOptionalLazy = recentsOptionalLazy;
        mForcedResizableController = new ForcedResizableInfoActivityController(context, this);
        mTransactionPool = transactionPool;
        mWindowManagerProxy = new WindowManagerProxy(mTransactionPool, mHandler);
        mImePositionProcessor = new DividerImeController(mSplits, mTransactionPool, mHandler);
    }

@@ -278,9 +293,9 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks,
                LayoutInflater.from(dctx).inflate(R.layout.docked_stack_divider, null);
        DisplayLayout displayLayout = mDisplayController.getDisplayLayout(mContext.getDisplayId());
        mView.injectDependencies(mWindowManager, mDividerState, this, mSplits, mSplitLayout,
                mImePositionProcessor);
                mImePositionProcessor, mWindowManagerProxy);
        mView.setVisibility(mVisible ? View.VISIBLE : View.INVISIBLE);
        mView.setMinimizedDockStack(mMinimized, mHomeStackResizable);
        mView.setMinimizedDockStack(mMinimized, mHomeStackResizable, null /* transaction */);
        final int size = dctx.getResources().getDimensionPixelSize(
                com.android.internal.R.dimen.docked_stack_divider_thickness);
        final boolean landscape = configuration.orientation == ORIENTATION_LANDSCAPE;
@@ -303,7 +318,7 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks,
        addDivider(configuration);

        if (mMinimized) {
            mView.setMinimizedDockStack(true, mHomeStackResizable);
            mView.setMinimizedDockStack(true, mHomeStackResizable, null /* transaction */);
            updateTouchable();
        }
        mView.setHidden(isDividerHidden);
@@ -327,11 +342,13 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks,
            if (visible) {
                mView.enterSplitMode(mHomeStackResizable);
                // Update state because animations won't finish.
                mView.setMinimizedDockStack(mMinimized, mHomeStackResizable);
                mWindowManagerProxy.runInSync(
                        t -> mView.setMinimizedDockStack(mMinimized, mHomeStackResizable, t));

            } else {
                mView.exitSplitMode();
                // un-minimize so that next entry triggers minimize anim.
                mView.setMinimizedDockStack(false /* minimized */, mHomeStackResizable);
                mWindowManagerProxy.runInSync(
                        t -> mView.setMinimizedDockStack(false, mHomeStackResizable, t));
            }
            // Notify existence listeners
            synchronized (mDockedStackExistsListeners) {
@@ -344,12 +361,6 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks,
        }
    }

    void onSplitDismissed() {
        updateVisibility(false /* visible */);
        mMinimized = false;
        removeDivider();
    }

    /** Switch to minimized state if appropriate */
    public void setMinimized(final boolean minimized) {
        if (DEBUG) Slog.d(TAG, "posting ext setMinimized " + minimized + " vis:" + mVisible);
@@ -405,7 +416,7 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks,
            }
        }
        updateTouchable();
        WindowOrganizer.applyTransaction(wct);
        mWindowManagerProxy.applySyncTransaction(wct);
    }

    void setAdjustedForIme(boolean adjustedForIme) {
@@ -501,7 +512,14 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks,
        update(mDisplayController.getDisplayContext(
                mContext.getDisplayId()).getResources().getConfiguration());
        // Set resizable directly here because applyEnterSplit already resizes home stack.
        mHomeStackResizable = WindowManagerProxy.applyEnterSplit(mSplits, mSplitLayout);
        mHomeStackResizable = mWindowManagerProxy.applyEnterSplit(mSplits, mSplitLayout);
    }

    void startDismissSplit() {
        mWindowManagerProxy.applyDismissSplit(mSplits, mSplitLayout, true /* dismissOrMaximize */);
        updateVisibility(false /* visible */);
        mMinimized = false;
        removeDivider();
    }

    void ensureMinimizedSplit() {
@@ -530,6 +548,10 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks,
        return mSplitLayout;
    }

    WindowManagerProxy getWmProxy() {
        return mWindowManagerProxy;
    }

    /** @return the container token for the secondary split root task. */
    public WindowContainerToken getSecondaryRoot() {
        if (mSplits == null || mSplits.mSecondary == null) {
+1 −2
Original line number Diff line number Diff line
@@ -29,7 +29,6 @@ import android.view.SurfaceControl;
import android.window.TaskOrganizer;
import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction;
import android.window.WindowOrganizer;

import androidx.annotation.Nullable;

@@ -213,7 +212,7 @@ class DividerImeController implements DisplayImeController.ImePositionProcessor
                    SCREEN_WIDTH_DP_UNDEFINED, SCREEN_HEIGHT_DP_UNDEFINED);
        }

        WindowOrganizer.applyTransaction(wct);
        mSplits.mDivider.getWmProxy().applySyncTransaction(wct);

        // Update all the adjusted-for-ime states
        if (!mPaused) {
+39 −32
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ import android.view.VelocityTracker;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewConfiguration;
import android.view.ViewRootImpl;
import android.view.ViewTreeObserver.InternalInsetsInfo;
import android.view.ViewTreeObserver.OnComputeInternalInsetsListener;
import android.view.WindowManager;
@@ -138,7 +139,7 @@ public class DividerView extends FrameLayout implements OnTouchListener,
    private final Rect mOtherInsetRect = new Rect();
    private final Rect mLastResizeRect = new Rect();
    private final Rect mTmpRect = new Rect();
    private final WindowManagerProxy mWindowManagerProxy = WindowManagerProxy.getInstance();
    private WindowManagerProxy mWindowManagerProxy;
    private DividerWindowManager mWindowManager;
    private VelocityTracker mVelocityTracker;
    private FlingAnimationUtils mFlingAnimationUtils;
@@ -360,13 +361,14 @@ public class DividerView extends FrameLayout implements OnTouchListener,

    public void injectDependencies(DividerWindowManager windowManager, DividerState dividerState,
            DividerCallbacks callback, SplitScreenTaskOrganizer tiles, SplitDisplayLayout sdl,
            DividerImeController imeController) {
            DividerImeController imeController, WindowManagerProxy wmProxy) {
        mWindowManager = windowManager;
        mState = dividerState;
        mCallback = callback;
        mTiles = tiles;
        mSplitLayout = sdl;
        mImeController = imeController;
        mWindowManagerProxy = wmProxy;

        if (mState.mRatioPositionBeforeMinimized == 0) {
            // Set the middle target as the initial state
@@ -376,10 +378,6 @@ public class DividerView extends FrameLayout implements OnTouchListener,
        }
    }

    public WindowManagerProxy getWindowManagerProxy() {
        return mWindowManagerProxy;
    }

    public Rect getNonMinimizedSplitScreenSecondaryBounds() {
        mOtherTaskRect.set(mSplitLayout.mSecondary);
        return mOtherTaskRect;
@@ -519,7 +517,8 @@ public class DividerView extends FrameLayout implements OnTouchListener,
                if (mMoving && mDockSide != WindowManager.DOCKED_INVALID) {
                    SnapTarget snapTarget = getSnapAlgorithm().calculateSnapTarget(
                            mStartPosition, 0 /* velocity */, false /* hardDismiss */);
                    resizeStackSurfaces(calculatePosition(x, y), mStartPosition, snapTarget);
                    resizeStackSurfaces(calculatePosition(x, y), mStartPosition, snapTarget,
                            null /* transaction */);
                }
                break;
            case MotionEvent.ACTION_UP:
@@ -608,7 +607,7 @@ public class DividerView extends FrameLayout implements OnTouchListener,
                taskPositionSameAtEnd && animation.getAnimatedFraction() == 1f
                        ? TASK_POSITION_SAME
                        : snapTarget.taskPosition,
                snapTarget));
                snapTarget, null /* transaction */));
        Consumer<Boolean> endAction = cancelled -> {
            if (DEBUG) Slog.d(TAG, "End Fling " + cancelled + " min:" + mIsInMinimizeInteraction);
            final boolean wasMinimizeInteraction = mIsInMinimizeInteraction;
@@ -716,7 +715,7 @@ public class DividerView extends FrameLayout implements OnTouchListener,
            dismissOrMaximize = mDockSide == WindowManager.DOCKED_RIGHT
                    || mDockSide == WindowManager.DOCKED_BOTTOM;
        }
        mWindowManagerProxy.dismissOrMaximizeDocked(mTiles, dismissOrMaximize);
        mWindowManagerProxy.dismissOrMaximizeDocked(mTiles, mSplitLayout, dismissOrMaximize);
        Transaction t = mTiles.getTransaction();
        setResizeDimLayer(t, true /* primary */, 0f);
        setResizeDimLayer(t, false /* primary */, 0f);
@@ -806,7 +805,8 @@ public class DividerView extends FrameLayout implements OnTouchListener,
        mWindowManager.setTouchRegion(touchRegion);
    }

    public void setMinimizedDockStack(boolean minimized, boolean isHomeStackResizable) {
    void setMinimizedDockStack(boolean minimized, boolean isHomeStackResizable,
            Transaction t) {
        mHomeStackResizable = isHomeStackResizable;
        updateDockSide();
        if (!minimized) {
@@ -840,9 +840,10 @@ public class DividerView extends FrameLayout implements OnTouchListener,
                    // Relayout to recalculate the divider shadow when minimizing
                    requestLayout();
                    mIsInMinimizeInteraction = true;
                    resizeStackSurfaces(mSplitLayout.getMinimizedSnapAlgorithm().getMiddleTarget());
                    resizeStackSurfaces(
                            mSplitLayout.getMinimizedSnapAlgorithm().getMiddleTarget(), t);
                } else {
                    resizeStackSurfaces(mSnapTargetBeforeMinimized);
                    resizeStackSurfaces(mSnapTargetBeforeMinimized, t);
                    mIsInMinimizeInteraction = false;
                }
            }
@@ -873,10 +874,11 @@ public class DividerView extends FrameLayout implements OnTouchListener,
     * assigned to it.
     */
    private SurfaceControl getWindowSurfaceControl() {
        if (getViewRootImpl() == null) {
        final ViewRootImpl root = getViewRootImpl();
        if (root == null) {
            return null;
        }
        SurfaceControl out = getViewRootImpl().getSurfaceControl();
        SurfaceControl out = root.getSurfaceControl();
        if (out != null && out.isValid()) {
            return out;
        }
@@ -885,7 +887,6 @@ public class DividerView extends FrameLayout implements OnTouchListener,

    void exitSplitMode() {
        // Reset tile bounds
        post(() -> {
        final SurfaceControl sc = getWindowSurfaceControl();
        if (sc == null) {
            return;
@@ -893,7 +894,6 @@ public class DividerView extends FrameLayout implements OnTouchListener,
        Transaction t = mTiles.getTransaction();
        t.hide(sc).apply();
        mTiles.releaseTransaction(t);
        });
        int midPos = mSplitLayout.getSnapAlgorithm().getMiddleTarget().position;
        WindowManagerProxy.applyResizeSplits(midPos, mSplitLayout);
    }
@@ -1049,8 +1049,8 @@ public class DividerView extends FrameLayout implements OnTouchListener,
                mDividerSize);
    }

    private void resizeStackSurfaces(SnapTarget taskSnapTarget) {
        resizeStackSurfaces(taskSnapTarget.position, taskSnapTarget.position, taskSnapTarget);
    private void resizeStackSurfaces(SnapTarget taskSnapTarget, Transaction t) {
        resizeStackSurfaces(taskSnapTarget.position, taskSnapTarget.position, taskSnapTarget, t);
    }

    void resizeSplitSurfaces(Transaction t, Rect dockedRect, Rect otherRect) {
@@ -1105,7 +1105,8 @@ public class DividerView extends FrameLayout implements OnTouchListener,
        }
    }

    void resizeStackSurfaces(int position, int taskPosition, SnapTarget taskSnapTarget) {
    void resizeStackSurfaces(int position, int taskPosition, SnapTarget taskSnapTarget,
            Transaction transaction) {
        if (mRemoved) {
            // This divider view has been removed so shouldn't have any additional influence.
            return;
@@ -1123,7 +1124,8 @@ public class DividerView extends FrameLayout implements OnTouchListener,
            mBackground.invalidate();
        }

        Transaction t = mTiles.getTransaction();
        final boolean ownTransaction = transaction == null;
        final Transaction t = ownTransaction ? mTiles.getTransaction() : transaction;
        mLastResizeRect.set(mDockedRect);
        if (mHomeStackResizable && mIsInMinimizeInteraction) {
            calculateBoundsForPosition(mSnapTargetBeforeMinimized.position, mDockSide,
@@ -1138,8 +1140,10 @@ public class DividerView extends FrameLayout implements OnTouchListener,
            }
            resizeSplitSurfaces(t, mDockedRect, mDockedTaskRect, mOtherRect,
                    mOtherTaskRect);
            if (ownTransaction) {
                t.apply();
                mTiles.releaseTransaction(t);
            }
            return;
        }

@@ -1201,9 +1205,11 @@ public class DividerView extends FrameLayout implements OnTouchListener,
        SnapTarget closestDismissTarget = getSnapAlgorithm().getClosestDismissTarget(position);
        float dimFraction = getDimFraction(position, closestDismissTarget);
        setResizeDimLayer(t, isDismissTargetPrimary(closestDismissTarget), dimFraction);
        if (ownTransaction) {
            t.apply();
            mTiles.releaseTransaction(t);
        }
    }

    private void applyExitAnimationParallax(Rect taskRect, int position) {
        if (mDockSide == WindowManager.DOCKED_TOP) {
@@ -1383,7 +1389,8 @@ public class DividerView extends FrameLayout implements OnTouchListener,

        resizeStackSurfaces(calculatePositionForInsetBounds(),
                mSplitLayout.getSnapAlgorithm().getMiddleTarget().position,
                mSplitLayout.getSnapAlgorithm().getMiddleTarget());
                mSplitLayout.getSnapAlgorithm().getMiddleTarget(),
                null /* transaction */);
    }

    void onRecentsDrawn() {
Loading