diff options
| author | 2022-06-15 20:38:00 +0800 | |
|---|---|---|
| committer | 2022-07-06 07:15:33 +0000 | |
| commit | ac5d2862d9c99c47b763780a6f5e025ce0336a5d (patch) | |
| tree | 6a891992642f164cf063ac78bdfc27221d6eb797 | |
| parent | cf3b16d69b5f769a2bb45cc860ddbce79cdef9d0 (diff) | |
Remove using of setResizing in split screen
We use setResizing to draw app bottom background for reducing flicker
while split decor screen fade-in. But this cause another flicker after
resizing finished. Use split decor to draw a fill up background to
reduce flicker mentioned at first and remove using of setResizing.
Do some temp rect optimization in this CL too.
Fix: 235451160
Fix: 237040271
Fix: 238045271
Test: manual
Test: pass existing tests
Change-Id: I6b70f35d47ced78eaacc9ecd9ae1ebf3a11dbc1f
5 files changed, 101 insertions, 30 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java index 5ebe384d84b7..8bc16bcc9d9d 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java @@ -206,12 +206,12 @@ public class DividerView extends FrameLayout implements View.OnTouchListener { mSplitLayout = layout; mSplitWindowManager = splitWindowManager; mViewHost = viewHost; - mDividerBounds.set(layout.getDividerBounds()); + layout.getDividerBounds(mDividerBounds); onInsetsChanged(insetsState, false /* animate */); } void onInsetsChanged(InsetsState insetsState, boolean animate) { - mTempRect.set(mSplitLayout.getDividerBounds()); + mSplitLayout.getDividerBounds(mTempRect); final InsetsSource taskBarInsetsSource = insetsState.getSource(InsetsState.ITYPE_EXTRA_NAVIGATION_BAR); // Only insets the divider bar with task bar when it's expanded so that the rounded corners diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java index 484294ab295b..6fb021ea5e2f 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java @@ -56,6 +56,7 @@ import com.android.wm.shell.common.SurfaceUtils; public class SplitDecorManager extends WindowlessWindowManager { private static final String TAG = SplitDecorManager.class.getSimpleName(); private static final String RESIZING_BACKGROUND_SURFACE_NAME = "ResizingBackground"; + private static final String GAP_BACKGROUND_SURFACE_NAME = "GapBackground"; private static final long FADE_DURATION = 133; private final IconProvider mIconProvider; @@ -67,6 +68,7 @@ public class SplitDecorManager extends WindowlessWindowManager { private SurfaceControl mHostLeash; private SurfaceControl mIconLeash; private SurfaceControl mBackgroundLeash; + private SurfaceControl mGapBackgroundLeash; private boolean mShown; private boolean mIsResizing; @@ -141,6 +143,10 @@ public class SplitDecorManager extends WindowlessWindowManager { t.remove(mBackgroundLeash); mBackgroundLeash = null; } + if (mGapBackgroundLeash != null) { + t.remove(mGapBackgroundLeash); + mGapBackgroundLeash = null; + } mHostLeash = null; mIcon = null; mResizingIconView = null; @@ -150,7 +156,7 @@ public class SplitDecorManager extends WindowlessWindowManager { /** Showing resizing hint. */ public void onResizing(ActivityManager.RunningTaskInfo resizingTask, Rect newBounds, - SurfaceControl.Transaction t) { + Rect sideBounds, SurfaceControl.Transaction t) { if (mResizingIconView == null) { return; } @@ -176,6 +182,19 @@ public class SplitDecorManager extends WindowlessWindowManager { .setLayer(mBackgroundLeash, Integer.MAX_VALUE - 1); } + if (mGapBackgroundLeash == null) { + final boolean isLandscape = newBounds.height() == sideBounds.height(); + final int left = isLandscape ? mBounds.width() : 0; + final int top = isLandscape ? 0 : mBounds.height(); + mGapBackgroundLeash = SurfaceUtils.makeColorLayer(mHostLeash, + GAP_BACKGROUND_SURFACE_NAME, mSurfaceSession); + // Fill up another side bounds area. + t.setColor(mGapBackgroundLeash, getResizingBackgroundColor(resizingTask)) + .setLayer(mGapBackgroundLeash, Integer.MAX_VALUE - 2) + .setPosition(mGapBackgroundLeash, left, top) + .setWindowCrop(mGapBackgroundLeash, sideBounds.width(), sideBounds.height()); + } + if (mIcon == null && resizingTask.topActivityInfo != null) { mIcon = mIconProvider.getIcon(resizingTask.topActivityInfo); mResizingIconView.setImageDrawable(mIcon); @@ -225,6 +244,7 @@ public class SplitDecorManager extends WindowlessWindowManager { } if (mShown) { startFadeAnimation(false /* show */, true /* isResized */); + mShown = false; } else { // Decor surface is hidden so release it directly. releaseDecor(t); @@ -249,7 +269,9 @@ public class SplitDecorManager extends WindowlessWindowManager { @Override public void onAnimationStart(@NonNull Animator animation) { if (show) { - animT.show(mBackgroundLeash).show(mIconLeash).apply(); + animT.show(mBackgroundLeash).show(mIconLeash).show(mGapBackgroundLeash).apply(); + } else { + animT.hide(mGapBackgroundLeash).apply(); } } @@ -280,6 +302,11 @@ public class SplitDecorManager extends WindowlessWindowManager { mBackgroundLeash = null; } + if (mGapBackgroundLeash != null) { + t.remove(mGapBackgroundLeash); + mGapBackgroundLeash = null; + } + if (mIcon != null) { mResizingIconView.setVisibility(View.GONE); mResizingIconView.setImageDrawable(null); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java index c962de67a93b..5801d43aaefd 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java @@ -200,6 +200,44 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange return outBounds; } + /** Gets bounds of the primary split with screen based coordinate on the param Rect. */ + public void getBounds1(Rect rect) { + rect.set(mBounds1); + } + + /** Gets bounds of the primary split with parent based coordinate on the param Rect. */ + public void getRefBounds1(Rect rect) { + getBounds1(rect); + rect.offset(-mRootBounds.left, -mRootBounds.top); + } + + /** Gets bounds of the secondary split with screen based coordinate on the param Rect. */ + public void getBounds2(Rect rect) { + rect.set(mBounds2); + } + + /** Gets bounds of the secondary split with parent based coordinate on the param Rect. */ + public void getRefBounds2(Rect rect) { + getBounds2(rect); + rect.offset(-mRootBounds.left, -mRootBounds.top); + } + + /** Gets root bounds of the whole split layout on the param Rect. */ + public void getRootBounds(Rect rect) { + rect.set(mRootBounds); + } + + /** Gets bounds of divider window with screen based coordinate on the param Rect. */ + public void getDividerBounds(Rect rect) { + rect.set(mDividerBounds); + } + + /** Gets bounds of divider window with parent based coordinate on the param Rect. */ + public void getRefDividerBounds(Rect rect) { + getDividerBounds(rect); + rect.offset(-mRootBounds.left, -mRootBounds.top); + } + /** Returns leash of the current divider bar. */ @Nullable public SurfaceControl getDividerLeash() { @@ -560,8 +598,8 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange t.setPosition(leash, distX, distY); t.setWindowCrop(leash, width, height); } else { - final int offsetX = width - start.width(); - final int offsetY = height - start.height(); + final int offsetX = width - tempStart.width(); + final int offsetY = height - tempStart.height(); t.setPosition(leash, distX + offsetX, distY + offsetY); mTempRect.set(0, 0, width, height); mTempRect.offsetTo(-offsetX, -offsetY); @@ -610,15 +648,15 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange boolean applyResizingOffset) { final SurfaceControl dividerLeash = getDividerLeash(); if (dividerLeash != null) { - mTempRect.set(getRefDividerBounds()); + getRefDividerBounds(mTempRect); t.setPosition(dividerLeash, mTempRect.left, mTempRect.top); // Resets layer of divider bar to make sure it is always on top. t.setLayer(dividerLeash, Integer.MAX_VALUE); } - mTempRect.set(getRefBounds1()); + getRefBounds1(mTempRect); t.setPosition(leash1, mTempRect.left, mTempRect.top) .setWindowCrop(leash1, mTempRect.width(), mTempRect.height()); - mTempRect.set(getRefBounds2()); + getRefBounds2(mTempRect); t.setPosition(leash2, mTempRect.left, mTempRect.top) .setWindowCrop(leash2, mTempRect.width(), mTempRect.height()); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java index 4e7b20e3ae84..70b31061204b 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java @@ -171,6 +171,9 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, private final ShellExecutor mMainExecutor; private final Optional<RecentTasksController> mRecentTasks; + private final Rect mTempRect1 = new Rect(); + private final Rect mTempRect2 = new Rect(); + /** * A single-top root task which the split divider attached to. */ @@ -749,7 +752,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, wct.reorder(mRootTaskInfo.token, false /* onTop */); mTaskOrganizer.applyTransaction(wct); mSyncQueue.runInSync(t -> { - setResizingSplits(false /* resizing */); t.setWindowCrop(mMainStage.mRootLeash, null) .setWindowCrop(mSideStage.mRootLeash, null); setDividerVisibility(false, t); @@ -1148,12 +1150,11 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, mDividerFadeInAnimator.cancel(); return; } + mSplitLayout.getRefDividerBounds(mTempRect1); transaction.show(dividerLeash); transaction.setAlpha(dividerLeash, 0); transaction.setLayer(dividerLeash, Integer.MAX_VALUE); - transaction.setPosition(dividerLeash, - mSplitLayout.getRefDividerBounds().left, - mSplitLayout.getRefDividerBounds().top); + transaction.setPosition(dividerLeash, mTempRect1.left, mTempRect1.top); transaction.apply(); } @@ -1212,7 +1213,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, return; } - setResizingSplits(false /* resizing */); final int dismissTop = mainStageToTop ? STAGE_TYPE_MAIN : STAGE_TYPE_SIDE; final WindowContainerTransaction wct = new WindowContainerTransaction(); prepareExitSplitScreen(dismissTop, wct); @@ -1243,10 +1243,11 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, public void onLayoutSizeChanging(SplitLayout layout) { final SurfaceControl.Transaction t = mTransactionPool.acquire(); t.setFrameTimelineVsync(Choreographer.getInstance().getVsyncId()); - setResizingSplits(true /* resizing */); updateSurfaceBounds(layout, t, true /* applyResizingOffset */); - mMainStage.onResizing(getMainStageBounds(), t); - mSideStage.onResizing(getSideStageBounds(), t); + getMainStageBounds(mTempRect1); + getSideStageBounds(mTempRect2); + mMainStage.onResizing(mTempRect1, mTempRect2, t); + mSideStage.onResizing(mTempRect2, mTempRect1, t); t.apply(); mTransactionPool.release(t); } @@ -1258,7 +1259,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, sendOnBoundsChanged(); mSyncQueue.queue(wct); mSyncQueue.runInSync(t -> { - setResizingSplits(false /* resizing */); updateSurfaceBounds(layout, t, false /* applyResizingOffset */); mMainStage.onResized(t); mSideStage.onResized(t); @@ -1293,16 +1293,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, applyResizingOffset); } - void setResizingSplits(boolean resizing) { - if (resizing == mResizingSplits) return; - try { - ActivityTaskManager.getService().setSplitScreenResizing(resizing); - mResizingSplits = resizing; - } catch (RemoteException e) { - Slog.w(TAG, "Error calling setSplitScreenResizing", e); - } - } - @Override public int getSplitItemPosition(WindowContainerToken token) { if (token == null) { @@ -1386,6 +1376,22 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, ? mSplitLayout.getBounds2() : mSplitLayout.getBounds1(); } + private void getSideStageBounds(Rect rect) { + if (mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT) { + mSplitLayout.getBounds1(rect); + } else { + mSplitLayout.getBounds2(rect); + } + } + + private void getMainStageBounds(Rect rect) { + if (mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT) { + mSplitLayout.getBounds2(rect); + } else { + mSplitLayout.getBounds1(rect); + } + } + /** * Get the stage that should contain this `taskInfo`. The stage doesn't necessarily contain * this task (yet) so this can also be used to identify which stage to put a task into. diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java index 23eec96a5d8f..e08af0ccf386 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java @@ -285,9 +285,9 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener { } } - void onResizing(Rect newBounds, SurfaceControl.Transaction t) { + void onResizing(Rect newBounds, Rect sideBounds, SurfaceControl.Transaction t) { if (mSplitDecorManager != null && mRootTaskInfo != null) { - mSplitDecorManager.onResizing(mRootTaskInfo, newBounds, t); + mSplitDecorManager.onResizing(mRootTaskInfo, newBounds, sideBounds, t); } } |