From 351d589dadfffc2fd492febc754b06562132019c Mon Sep 17 00:00:00 2001 From: Tiger Huang Date: Fri, 18 Mar 2022 22:05:24 +0800 Subject: [PATCH] Let the client compute the backdrop frame on its own Since the new split-screen doesn't need the fullscreen backdrop frame. The backdrop frame will always be the window frame. The server doesn't need to send the backdrop frame to the client. The client just needs to offset the backdrop frame to (0, 0). This CL also moves the logic of calling onWindowSizeIsChanging to the handler thread because it reads some fields which should only be accessed on the handler thread. Otherwise, there might be race conditions. Bug: 161810301 Test: 1. Perform drag-resize and drag-move on a freeform app, and see if the layout is expected. 2. Move the divider in the split-screen mode, and see if there is any abnormal. Change-Id: Ie0058db0447260dd0561634179fc7721d965a9e2 --- core/java/android/view/ViewRootImpl.java | 72 ++++++++----------- .../android/window/ClientWindowFrames.java | 7 -- .../com/android/server/wm/WindowState.java | 19 ----- 3 files changed, 31 insertions(+), 67 deletions(-) diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index d15b2a457bfb1..5850715f9691f 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -401,10 +401,8 @@ public final class ViewRootImpl implements ViewParent, private static boolean sAlwaysAssignFocus; /** - * This list must only be modified by the main thread, so a lock is only needed when changing - * the list or when accessing the list from a non-main thread. + * This list must only be modified by the main thread. */ - @GuardedBy("mWindowCallbacks") final ArrayList mWindowCallbacks = new ArrayList<>(); @UnsupportedAppUsage @UiContext @@ -981,15 +979,11 @@ public final class ViewRootImpl implements ViewParent, } public void addWindowCallbacks(WindowCallbacks callback) { - synchronized (mWindowCallbacks) { - mWindowCallbacks.add(callback); - } + mWindowCallbacks.add(callback); } public void removeWindowCallbacks(WindowCallbacks callback) { - synchronized (mWindowCallbacks) { - mWindowCallbacks.remove(callback); - } + mWindowCallbacks.remove(callback); } public void reportDrawFinish() { @@ -1711,15 +1705,19 @@ public final class ViewRootImpl implements ViewParent, final boolean forceNextWindowRelayout = args.argi1 != 0; final int displayId = args.argi3; final int resizeMode = args.argi5; - final Rect backdropFrame = frames.backdropFrame; - final boolean frameChanged = !mWinFrame.equals(frames.frame); - final boolean backdropFrameChanged = !mPendingBackDropFrame.equals(backdropFrame); + final Rect frame = frames.frame; + final Rect displayFrame = frames.displayFrame; + if (mTranslator != null) { + mTranslator.translateRectInScreenToAppWindow(frame); + mTranslator.translateRectInScreenToAppWindow(displayFrame); + } + final boolean frameChanged = !mWinFrame.equals(frame); final boolean configChanged = !mLastReportedMergedConfiguration.equals(mergedConfiguration); final boolean displayChanged = mDisplay.getDisplayId() != displayId; final boolean resizeModeChanged = mResizeMode != resizeMode; - if (msg == MSG_RESIZED && !frameChanged && !backdropFrameChanged && !configChanged - && !displayChanged && !resizeModeChanged && !forceNextWindowRelayout) { + if (msg == MSG_RESIZED && !frameChanged && !configChanged && !displayChanged + && !resizeModeChanged && !forceNextWindowRelayout) { return; } @@ -1735,9 +1733,17 @@ public final class ViewRootImpl implements ViewParent, onMovedToDisplay(displayId, mLastConfigurationFromResources); } - setFrame(frames.frame); - mTmpFrames.displayFrame.set(frames.displayFrame); - mPendingBackDropFrame.set(backdropFrame); + setFrame(frame); + mTmpFrames.displayFrame.set(displayFrame); + + if (mDragResizing && mUseMTRenderer) { + boolean fullscreen = frame.equals(mPendingBackDropFrame); + for (int i = mWindowCallbacks.size() - 1; i >= 0; i--) { + mWindowCallbacks.get(i).onWindowSizeIsChanging(mPendingBackDropFrame, fullscreen, + mAttachInfo.mVisibleInsets, mAttachInfo.mStableInsets); + } + } + mForceNextWindowRelayout = forceNextWindowRelayout; mPendingAlwaysConsumeSystemBars = args.argi2 != 0; mSyncSeqId = args.argi4; @@ -5510,8 +5516,6 @@ public final class ViewRootImpl implements ViewParent, mTmpFrames.frame.top = t; mTmpFrames.frame.bottom = t + h; setFrame(mTmpFrames.frame); - - mPendingBackDropFrame.set(mWinFrame); maybeHandleWindowMove(mWinFrame); } break; @@ -8006,7 +8010,6 @@ public final class ViewRootImpl implements ViewParent, getConfiguration().windowConfiguration.getBounds()); } - mPendingBackDropFrame.set(mTmpFrames.backdropFrame); if (mSurfaceControl.isValid()) { if (!useBLAST()) { mSurface.copyFrom(mSurfaceControl); @@ -8037,6 +8040,7 @@ public final class ViewRootImpl implements ViewParent, if (mTranslator != null) { mTranslator.translateRectInScreenToAppWindow(mTmpFrames.frame); + mTranslator.translateRectInScreenToAppWindow(mTmpFrames.displayFrame); mTranslator.translateInsetsStateInScreenToAppWindow(mTempInsets); mTranslator.translateSourceControlsInScreenToAppWindow(mTempControls); } @@ -8081,6 +8085,13 @@ public final class ViewRootImpl implements ViewParent, private void setFrame(Rect frame) { mWinFrame.set(frame); + + // Surface position is now inherited from parent, and BackdropFrameRenderer uses backdrop + // frame to position content. Thus, we just keep the size of backdrop frame, and remove the + // offset to avoid double offset from display origin. + mPendingBackDropFrame.set(frame); + mPendingBackDropFrame.offsetTo(0, 0); + mInsetsController.onFrameChanged(mOverrideInsetsFrame != null ? mOverrideInsetsFrame : frame); } @@ -8472,28 +8483,7 @@ public final class ViewRootImpl implements ViewParent, private void dispatchResized(ClientWindowFrames frames, boolean reportDraw, MergedConfiguration mergedConfiguration, boolean forceLayout, boolean alwaysConsumeSystemBars, int displayId, int seqId, int resizeMode) { - final Rect frame = frames.frame; - final Rect backDropFrame = frames.backdropFrame; - if (DEBUG_LAYOUT) Log.v(mTag, "Resizing " + this + ": frame=" + frame.toShortString() - + " reportDraw=" + reportDraw - + " backDropFrame=" + backDropFrame); - - // Tell all listeners that we are resizing the window so that the chrome can get - // updated as fast as possible on a separate thread, - if (mDragResizing && mUseMTRenderer) { - boolean fullscreen = frame.equals(backDropFrame); - synchronized (mWindowCallbacks) { - for (int i = mWindowCallbacks.size() - 1; i >= 0; i--) { - mWindowCallbacks.get(i).onWindowSizeIsChanging(backDropFrame, fullscreen, - mAttachInfo.mVisibleInsets, mAttachInfo.mStableInsets); - } - } - } - Message msg = mHandler.obtainMessage(reportDraw ? MSG_RESIZED_REPORT : MSG_RESIZED); - if (mTranslator != null) { - mTranslator.translateRectInScreenToAppWindow(frame); - } SomeArgs args = SomeArgs.obtain(); final boolean sameProcessCall = (Binder.getCallingPid() == android.os.Process.myPid()); args.arg1 = sameProcessCall ? new ClientWindowFrames(frames) : frames; diff --git a/core/java/android/window/ClientWindowFrames.java b/core/java/android/window/ClientWindowFrames.java index 5b915cc22ec50..51f3fe2551ad2 100644 --- a/core/java/android/window/ClientWindowFrames.java +++ b/core/java/android/window/ClientWindowFrames.java @@ -40,9 +40,6 @@ public class ClientWindowFrames implements Parcelable { */ public final @NonNull Rect parentFrame = new Rect(); - /** The background area while the window is resizing. */ - public final @NonNull Rect backdropFrame = new Rect(); - public boolean isParentFrameClippedByDisplayCutout; public ClientWindowFrames() { @@ -52,7 +49,6 @@ public class ClientWindowFrames implements Parcelable { frame.set(other.frame); displayFrame.set(other.displayFrame); parentFrame.set(other.parentFrame); - backdropFrame.set(other.backdropFrame); isParentFrameClippedByDisplayCutout = other.isParentFrameClippedByDisplayCutout; } @@ -65,7 +61,6 @@ public class ClientWindowFrames implements Parcelable { frame.readFromParcel(in); displayFrame.readFromParcel(in); parentFrame.readFromParcel(in); - backdropFrame.readFromParcel(in); isParentFrameClippedByDisplayCutout = in.readBoolean(); } @@ -74,7 +69,6 @@ public class ClientWindowFrames implements Parcelable { frame.writeToParcel(dest, flags); displayFrame.writeToParcel(dest, flags); parentFrame.writeToParcel(dest, flags); - backdropFrame.writeToParcel(dest, flags); dest.writeBoolean(isParentFrameClippedByDisplayCutout); } @@ -84,7 +78,6 @@ public class ClientWindowFrames implements Parcelable { return "ClientWindowFrames{frame=" + frame.toShortString(sb) + " display=" + displayFrame.toShortString(sb) + " parentFrame=" + parentFrame.toShortString(sb) - + " backdrop=" + backdropFrame.toShortString(sb) + " parentClippedByDisplayCutout=" + isParentFrameClippedByDisplayCutout + "}"; } diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index f8b9453c1d624..029386658e1c5 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -3869,25 +3869,6 @@ class WindowState extends WindowContainer implements WindowManagerP outFrames.displayFrame.scale(mInvGlobalScale); } - final Rect backdropFrame = outFrames.backdropFrame; - // When the task is docked, we send fullscreen sized backdropFrame as soon as resizing - // start even if we haven't received the relayout window, so that the client requests - // the relayout sooner. When dragging stops, backdropFrame needs to stay fullscreen - // until the window to small size, otherwise the multithread renderer will shift last - // one or more frame to wrong offset. So here we send fullscreen backdrop if either - // isDragResizing() or isDragResizeChanged() is true. - final boolean resizing = isDragResizing() || isDragResizeChanged(); - if (!resizing || getWindowConfiguration().useWindowFrameForBackdrop()) { - // Surface position is now inherited from parent, and BackdropFrameRenderer uses - // backdrop frame to position content. Thus we just keep the size of backdrop frame, - // and remove the offset to avoid double offset from display origin. - backdropFrame.set(outFrames.frame); - backdropFrame.offsetTo(0, 0); - } else { - final DisplayInfo displayInfo = getDisplayInfo(); - backdropFrame.set(0, 0, displayInfo.logicalWidth, displayInfo.logicalHeight); - } - // Note: in the cases where the window is tied to an activity, we should not send a // configuration update when the window has requested to be hidden. Doing so can lead to // the client erroneously accepting a configuration that would have otherwise caused an