Skip to content

Commit

Permalink
Merge "Use boundsChangeTransaction to improve split-screen enter/exit…
Browse files Browse the repository at this point in the history
…" into rvc-dev
  • Loading branch information
Evan Rosky authored and Android (Google) Code Review committed Jun 1, 2020
2 parents 4c65d2c + 3613854 commit 82352f9
Show file tree
Hide file tree
Showing 9 changed files with 406 additions and 68 deletions.
6 changes: 5 additions & 1 deletion core/java/android/view/WindowlessWindowManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,11 @@ private boolean isOpaque(WindowManager.LayoutParams attrs) {

/** @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;
}
Expand Down
64 changes: 64 additions & 0 deletions core/java/android/window/WindowContainerTransaction.java
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,29 @@ public WindowContainerTransaction reorder(@NonNull WindowContainerToken child, b
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;
Expand Down Expand Up @@ -359,6 +382,41 @@ protected Change(Parcel in) {
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;
}
Expand Down Expand Up @@ -522,6 +580,12 @@ public HierarchyOp(@NonNull IBinder container, boolean toTop) {
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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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;
Expand Down Expand Up @@ -159,6 +173,7 @@ public Divider(Context context, Optional<Lazy<Recents>> recentsOptionalLazy,
mRecentsOptionalLazy = recentsOptionalLazy;
mForcedResizableController = new ForcedResizableInfoActivityController(context, this);
mTransactionPool = transactionPool;
mWindowManagerProxy = new WindowManagerProxy(mTransactionPool, mHandler);
mImePositionProcessor = new DividerImeController(mSplits, mTransactionPool, mHandler);
}

Expand Down Expand Up @@ -278,9 +293,9 @@ private void addDivider(Configuration configuration) {
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;
Expand All @@ -303,7 +318,7 @@ private void update(Configuration configuration) {
addDivider(configuration);

if (mMinimized) {
mView.setMinimizedDockStack(true, mHomeStackResizable);
mView.setMinimizedDockStack(true, mHomeStackResizable, null /* transaction */);
updateTouchable();
}
mView.setHidden(isDividerHidden);
Expand All @@ -327,11 +342,13 @@ private void updateVisibility(final boolean visible) {
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) {
Expand All @@ -344,12 +361,6 @@ private void updateVisibility(final boolean visible) {
}
}

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);
Expand Down Expand Up @@ -405,7 +416,7 @@ private void setHomeMinimized(final boolean minimized, boolean homeStackResizabl
}
}
updateTouchable();
WindowOrganizer.applyTransaction(wct);
mWindowManagerProxy.applySyncTransaction(wct);
}

void setAdjustedForIme(boolean adjustedForIme) {
Expand Down Expand Up @@ -501,7 +512,14 @@ void startEnterSplit() {
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() {
Expand Down Expand Up @@ -530,6 +548,10 @@ SplitDisplayLayout getSplitLayout() {
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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
import android.window.TaskOrganizer;
import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction;
import android.window.WindowOrganizer;

import androidx.annotation.Nullable;

Expand Down Expand Up @@ -213,7 +212,7 @@ private void updateImeAdjustState() {
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) {
Expand Down
Loading

0 comments on commit 82352f9

Please sign in to comment.