From ccaeffc03f275525c9fe66539b2d50f1076303fa Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Thu, 3 Sep 2020 00:29:30 +0800 Subject: [PATCH] Remove Session#getDisplayFrame The frame won't be changed if there is no IWindow#resized or IWindowSession#relayout. So it can be retrieved from these methods directly instead of another binder transaction. And because some parameters are usually used together for layout, the parameters are consolidated into a new ClientWindowFrames. That reduces changing the interface in the future if the frame related information needs to be changed. Also refine the resize handling in ViewRootImpl to make it easier to read. There should be no behavior change by this modification. Bug: 161781274 Test: WmTests, DialogFrameTests Change-Id: I9f711ad2023442046fa8582944320b98e7c4ecfa --- .../src/android/wm/RelayoutPerfTest.java | 19 +- .../service/wallpaper/WallpaperService.java | 69 +++---- core/java/android/view/IWindow.aidl | 9 +- core/java/android/view/IWindowSession.aidl | 12 +- core/java/android/view/View.java | 16 +- core/java/android/view/ViewDebug.java | 7 +- core/java/android/view/ViewRootImpl.java | 184 +++++++++--------- .../android/view/WindowlessWindowManager.java | 13 +- .../android/window/ClientWindowFrames.aidl | 19 ++ .../android/window/ClientWindowFrames.java | 125 ++++++++++++ .../android/internal/view/BaseIWindow.java | 11 +- .../wm/shell/common/SystemWindows.java | 22 +-- .../java/com/android/server/wm/Session.java | 16 +- .../server/wm/TaskSnapshotSurface.java | 28 ++- .../server/wm/WindowManagerService.java | 31 +-- .../com/android/server/wm/WindowState.java | 95 ++++----- .../com/android/server/wm/TestIWindow.java | 10 +- .../android/server/wm/WindowStateTests.java | 8 +- 18 files changed, 370 insertions(+), 324 deletions(-) create mode 100644 core/java/android/window/ClientWindowFrames.aidl create mode 100644 core/java/android/window/ClientWindowFrames.java diff --git a/apct-tests/perftests/windowmanager/src/android/wm/RelayoutPerfTest.java b/apct-tests/perftests/windowmanager/src/android/wm/RelayoutPerfTest.java index 269742854cb02..a701f86319698 100644 --- a/apct-tests/perftests/windowmanager/src/android/wm/RelayoutPerfTest.java +++ b/apct-tests/perftests/windowmanager/src/android/wm/RelayoutPerfTest.java @@ -21,14 +21,12 @@ import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentat import android.app.Activity; import android.content.Context; import android.graphics.Point; -import android.graphics.Rect; import android.os.RemoteException; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; import android.perftests.utils.PerfTestActivity; import android.platform.test.annotations.Presubmit; import android.util.MergedConfiguration; -import android.view.DisplayCutout; import android.view.IWindow; import android.view.IWindowSession; import android.view.InsetsSourceControl; @@ -38,6 +36,7 @@ import android.view.View; import android.view.WindowManager; import android.view.WindowManagerGlobal; import android.widget.LinearLayout; +import android.window.ClientWindowFrames; import androidx.test.filters.LargeTest; import androidx.test.rule.ActivityTestRule; @@ -125,13 +124,7 @@ public class RelayoutPerfTest extends WindowManagerPerfTestBase } private static class RelayoutRunner { - final Rect mOutFrame = new Rect(); - final Rect mOutContentInsets = new Rect(); - final Rect mOutVisibleInsets = new Rect(); - final Rect mOutStableInsets = new Rect(); - final Rect mOutBackDropFrame = new Rect(); - final DisplayCutout.ParcelableWrapper mOutDisplayCutout = - new DisplayCutout.ParcelableWrapper(DisplayCutout.NO_CUTOUT); + final ClientWindowFrames mOutFrames = new ClientWindowFrames(); final MergedConfiguration mOutMergedConfiguration = new MergedConfiguration(); final InsetsState mOutInsetsState = new InsetsState(); final InsetsSourceControl[] mOutControls = new InsetsSourceControl[0]; @@ -164,11 +157,9 @@ public class RelayoutPerfTest extends WindowManagerPerfTestBase final IWindowSession session = WindowManagerGlobal.getWindowSession(); while (state.keepRunning()) { session.relayout(mWindow, mSeq, mParams, mWidth, mHeight, - mViewVisibility.getAsInt(), mFlags, mFrameNumber, mOutFrame, - mOutContentInsets, mOutVisibleInsets, mOutStableInsets, - mOutBackDropFrame, mOutDisplayCutout, mOutMergedConfiguration, - mOutSurfaceControl, mOutInsetsState, mOutControls, mOutSurfaceSize, - mOutBlastSurfaceControl); + mViewVisibility.getAsInt(), mFlags, mFrameNumber, mOutFrames, + mOutMergedConfiguration, mOutSurfaceControl, mOutInsetsState, mOutControls, + mOutSurfaceSize, mOutBlastSurfaceControl); } } } diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java index e083417644e36..19860eb45fbfa 100644 --- a/core/java/android/service/wallpaper/WallpaperService.java +++ b/core/java/android/service/wallpaper/WallpaperService.java @@ -71,6 +71,7 @@ import android.view.ViewGroup; import android.view.WindowInsets; import android.view.WindowManager; import android.view.WindowManagerGlobal; +import android.window.ClientWindowFrames; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.os.HandlerCaller; @@ -186,17 +187,11 @@ public abstract class WallpaperService extends Service { int mCurWindowFlags = mWindowFlags; int mCurWindowPrivateFlags = mWindowPrivateFlags; Rect mPreviewSurfacePosition; - final Rect mVisibleInsets = new Rect(); - final Rect mWinFrame = new Rect(); - final Rect mContentInsets = new Rect(); - final Rect mStableInsets = new Rect(); + final ClientWindowFrames mWinFrames = new ClientWindowFrames(); final Rect mDispatchedContentInsets = new Rect(); final Rect mDispatchedStableInsets = new Rect(); final Rect mFinalSystemInsets = new Rect(); final Rect mFinalStableInsets = new Rect(); - final Rect mBackdropFrame = new Rect(); - final DisplayCutout.ParcelableWrapper mDisplayCutout = - new DisplayCutout.ParcelableWrapper(); DisplayCutout mDispatchedDisplayCutout = DisplayCutout.NO_CUTOUT; final InsetsState mInsetsState = new InsetsState(); final InsetsSourceControl[] mTempControls = new InsetsSourceControl[0]; @@ -332,11 +327,9 @@ public abstract class WallpaperService extends Service { final BaseIWindow mWindow = new BaseIWindow() { @Override - public void resized(Rect frame, Rect contentInsets, - Rect visibleInsets, Rect stableInsets, boolean reportDraw, - MergedConfiguration mergedConfiguration, Rect backDropRect, boolean forceLayout, - boolean alwaysConsumeSystemBars, int displayId, - DisplayCutout.ParcelableWrapper displayCutout) { + public void resized(ClientWindowFrames frames, boolean reportDraw, + MergedConfiguration mergedConfiguration, boolean forceLayout, + boolean alwaysConsumeSystemBars, int displayId) { Message msg = mCaller.obtainMessageI(MSG_WINDOW_RESIZED, reportDraw ? 1 : 0); mCaller.sendMessage(msg); @@ -749,10 +742,7 @@ public abstract class WallpaperService extends Service { out.print(" mCurWindowFlags="); out.println(mCurWindowFlags); out.print(prefix); out.print("mWindowPrivateFlags="); out.print(mWindowPrivateFlags); out.print(" mCurWindowPrivateFlags="); out.println(mCurWindowPrivateFlags); - out.print(prefix); out.print("mVisibleInsets="); - out.print(mVisibleInsets.toShortString()); - out.print(" mWinFrame="); out.print(mWinFrame.toShortString()); - out.print(" mContentInsets="); out.println(mContentInsets.toShortString()); + out.print(prefix); out.println("mWinFrames="); out.println(mWinFrames); out.print(prefix); out.print("mConfiguration="); out.println(mMergedConfiguration.getMergedConfiguration()); out.print(prefix); out.print("mLayout="); out.println(mLayout); @@ -890,8 +880,8 @@ public abstract class WallpaperService extends Service { InputChannel inputChannel = new InputChannel(); if (mSession.addToDisplay(mWindow, mWindow.mSeq, mLayout, View.VISIBLE, - mDisplay.getDisplayId(), mWinFrame, mContentInsets, mStableInsets, - mDisplayCutout, inputChannel, + mDisplay.getDisplayId(), mWinFrames.frame, mWinFrames.contentInsets, + mWinFrames.stableInsets, mWinFrames.displayCutout, inputChannel, mInsetsState, mTempControls) < 0) { Log.w(TAG, "Failed to add window while updating wallpaper surface."); return; @@ -914,34 +904,32 @@ public abstract class WallpaperService extends Service { final int relayoutResult = mSession.relayout( mWindow, mWindow.mSeq, mLayout, mWidth, mHeight, - View.VISIBLE, 0, -1, mWinFrame, mContentInsets, - mVisibleInsets, mStableInsets, mBackdropFrame, - mDisplayCutout, mMergedConfiguration, mSurfaceControl, + View.VISIBLE, 0, -1, mWinFrames, mMergedConfiguration, mSurfaceControl, mInsetsState, mTempControls, mSurfaceSize, mTmpSurfaceControl); if (mSurfaceControl.isValid()) { mSurfaceHolder.mSurface.copyFrom(mSurfaceControl); } if (DEBUG) Log.v(TAG, "New surface: " + mSurfaceHolder.mSurface - + ", frame=" + mWinFrame); + + ", frame=" + mWinFrames); - int w = mWinFrame.width(); - int h = mWinFrame.height(); + int w = mWinFrames.frame.width(); + int h = mWinFrames.frame.height(); if (!fixedSize) { final Rect padding = mIWallpaperEngine.mDisplayPadding; w += padding.left + padding.right; h += padding.top + padding.bottom; - mContentInsets.left += padding.left; - mContentInsets.top += padding.top; - mContentInsets.right += padding.right; - mContentInsets.bottom += padding.bottom; - mStableInsets.left += padding.left; - mStableInsets.top += padding.top; - mStableInsets.right += padding.right; - mStableInsets.bottom += padding.bottom; - mDisplayCutout.set(mDisplayCutout.get().inset(-padding.left, -padding.top, - -padding.right, -padding.bottom)); + mWinFrames.contentInsets.left += padding.left; + mWinFrames.contentInsets.top += padding.top; + mWinFrames.contentInsets.right += padding.right; + mWinFrames.contentInsets.bottom += padding.bottom; + mWinFrames.stableInsets.left += padding.left; + mWinFrames.stableInsets.top += padding.top; + mWinFrames.stableInsets.right += padding.right; + mWinFrames.stableInsets.bottom += padding.bottom; + mWinFrames.displayCutout.set(mWinFrames.displayCutout.get().inset( + -padding.left, -padding.top, -padding.right, -padding.bottom)); } else { w = myWidth; h = myHeight; @@ -960,9 +948,10 @@ public abstract class WallpaperService extends Service { Log.v(TAG, "Wallpaper size has changed: (" + mCurWidth + ", " + mCurHeight); } - insetsChanged |= !mDispatchedContentInsets.equals(mContentInsets); - insetsChanged |= !mDispatchedStableInsets.equals(mStableInsets); - insetsChanged |= !mDispatchedDisplayCutout.equals(mDisplayCutout.get()); + final DisplayCutout displayCutout = mWinFrames.displayCutout.get(); + insetsChanged |= !mDispatchedContentInsets.equals(mWinFrames.contentInsets); + insetsChanged |= !mDispatchedStableInsets.equals(mWinFrames.stableInsets); + insetsChanged |= !mDispatchedDisplayCutout.equals(displayCutout); mSurfaceHolder.setSurfaceFrameSize(w, h); mSurfaceHolder.mSurfaceLock.unlock(); @@ -1021,9 +1010,9 @@ public abstract class WallpaperService extends Service { } if (insetsChanged) { - mDispatchedContentInsets.set(mContentInsets); - mDispatchedStableInsets.set(mStableInsets); - mDispatchedDisplayCutout = mDisplayCutout.get(); + mDispatchedContentInsets.set(mWinFrames.contentInsets); + mDispatchedStableInsets.set(mWinFrames.stableInsets); + mDispatchedDisplayCutout = displayCutout; mFinalStableInsets.set(mDispatchedStableInsets); WindowInsets insets = new WindowInsets(mFinalSystemInsets, mFinalStableInsets, diff --git a/core/java/android/view/IWindow.aidl b/core/java/android/view/IWindow.aidl index e09bf9d2e80a9..94e641c62b25c 100644 --- a/core/java/android/view/IWindow.aidl +++ b/core/java/android/view/IWindow.aidl @@ -29,6 +29,7 @@ import android.view.InsetsState; import android.view.IScrollCaptureController; import android.view.KeyEvent; import android.view.MotionEvent; +import android.window.ClientWindowFrames; import com.android.internal.os.IResultReceiver; @@ -52,11 +53,9 @@ oneway interface IWindow { */ void executeCommand(String command, String parameters, in ParcelFileDescriptor descriptor); - void resized(in Rect frame, in Rect contentInsets, - in Rect visibleInsets, in Rect stableInsets, boolean reportDraw, - in MergedConfiguration newMergedConfiguration, in Rect backDropFrame, - boolean forceLayout, boolean alwaysConsumeSystemBars, int displayId, - in DisplayCutout.ParcelableWrapper displayCutout); + void resized(in ClientWindowFrames frames, boolean reportDraw, + in MergedConfiguration newMergedConfiguration, + boolean forceLayout, boolean alwaysConsumeSystemBars, int displayId); /** * Called when the window location in parent display has changed. The offset will only be a diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl index 819e89b67b387..70850d8551619 100644 --- a/core/java/android/view/IWindowSession.aidl +++ b/core/java/android/view/IWindowSession.aidl @@ -34,6 +34,7 @@ import android.view.InsetsState; import android.view.Surface; import android.view.SurfaceControl; import android.view.SurfaceControl.Transaction; +import android.window.ClientWindowFrames; import java.util.List; @@ -107,10 +108,7 @@ interface IWindowSession { */ int relayout(IWindow window, int seq, in WindowManager.LayoutParams attrs, int requestedWidth, int requestedHeight, int viewVisibility, - int flags, long frameNumber, out Rect outFrame, - out Rect outContentInsets, out Rect outVisibleInsets, out Rect outStableInsets, - out Rect outBackdropFrame, - out DisplayCutout.ParcelableWrapper displayCutout, + int flags, long frameNumber, out ClientWindowFrames outFrames, out MergedConfiguration outMergedConfiguration, out SurfaceControl outSurfaceControl, out InsetsState insetsState, out InsetsSourceControl[] activeControls, out Point outSurfaceSize, out SurfaceControl outBlastSurfaceControl); @@ -151,12 +149,6 @@ interface IWindowSession { void setInsets(IWindow window, int touchableInsets, in Rect contentInsets, in Rect visibleInsets, in Region touchableRegion); - /** - * Return the current display size in which the window is being laid out, - * accounting for screen decorations around it. - */ - void getDisplayFrame(IWindow window, out Rect outDisplayFrame); - /** * Called when the client has finished drawing the surface, if needed. * diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 89178217366f2..92a0f633aba01 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -14940,20 +14940,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * inside. In effect, this tells you the available area where content can * be placed and remain visible to users. * - *

This function requires an IPC back to the window manager to retrieve - * the requested information, so should not be used in performance critical - * code like drawing. - * * @param outRect Filled in with the visible display frame. If the view * is not attached to a window, this is simply the raw display size. */ public void getWindowVisibleDisplayFrame(Rect outRect) { if (mAttachInfo != null) { - try { - mAttachInfo.mSession.getDisplayFrame(mAttachInfo.mWindow, outRect); - } catch (RemoteException e) { - return; - } + mAttachInfo.mViewRootImpl.getDisplayFrame(outRect); // XXX This is really broken, and probably all needs to be done // in the window manager, and we need to know more about whether // we want the area behind or in front of the IME. @@ -14979,11 +14971,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, @UnsupportedAppUsage public void getWindowDisplayFrame(Rect outRect) { if (mAttachInfo != null) { - try { - mAttachInfo.mSession.getDisplayFrame(mAttachInfo.mWindow, outRect); - } catch (RemoteException e) { - return; - } + mAttachInfo.mViewRootImpl.getDisplayFrame(outRect); return; } // The view is not attached to a display so we don't have a context. diff --git a/core/java/android/view/ViewDebug.java b/core/java/android/view/ViewDebug.java index 8a5be75b6c31d..4303d705f9457 100644 --- a/core/java/android/view/ViewDebug.java +++ b/core/java/android/view/ViewDebug.java @@ -33,7 +33,6 @@ import android.os.Debug; import android.os.Handler; import android.os.Looper; import android.os.Message; -import android.os.RemoteException; import android.util.DisplayMetrics; import android.util.Log; import android.util.TypedValue; @@ -755,11 +754,7 @@ public class ViewDebug { try { Rect outRect = new Rect(); - try { - root.mAttachInfo.mSession.getDisplayFrame(root.mAttachInfo.mWindow, outRect); - } catch (RemoteException e) { - // Ignore - } + root.mAttachInfo.mViewRootImpl.getDisplayFrame(outRect); clientStream.writeInt(outRect.width()); clientStream.writeInt(outRect.height()); diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index f3a8d9754fd4e..96ed131a716a7 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -137,7 +137,6 @@ import android.view.View.MeasureSpec; import android.view.Window.OnContentApplyWindowInsetsListener; import android.view.WindowInsets.Type; import android.view.WindowInsets.Type.InsetsType; -import android.view.WindowManager.LayoutParams; import android.view.WindowManager.LayoutParams.SoftInputModeFlags; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager; @@ -160,6 +159,7 @@ import android.view.contentcapture.ContentCaptureSession; import android.view.contentcapture.MainContentCaptureSession; import android.view.inputmethod.InputMethodManager; import android.widget.Scroller; +import android.window.ClientWindowFrames; import com.android.internal.R; import com.android.internal.annotations.GuardedBy; @@ -559,8 +559,11 @@ public final class ViewRootImpl implements ViewParent, boolean mAdded; boolean mAddedTouchMode; - final Rect mTmpFrame = new Rect(); - final Rect mTmpRect = new Rect(); + /** + * It usually keeps the latest layout result from {@link IWindow#resized} or + * {@link IWindowSession#relayout}. + */ + private final ClientWindowFrames mTmpFrames = new ClientWindowFrames(); // These are accessed by multiple threads. final Rect mWinFrame; // frame given by window manager. @@ -1032,11 +1035,11 @@ public final class ViewRootImpl implements ViewParent, collectViewAttributes(); adjustLayoutParamsForCompatibility(mWindowAttributes); res = mWindowSession.addToDisplayAsUser(mWindow, mSeq, mWindowAttributes, - getHostVisibility(), mDisplay.getDisplayId(), userId, mTmpFrame, + getHostVisibility(), mDisplay.getDisplayId(), userId, mTmpFrames.frame, mAttachInfo.mContentInsets, mAttachInfo.mStableInsets, mAttachInfo.mDisplayCutout, inputChannel, mTempInsets, mTempControls); - setFrame(mTmpFrame); + setFrame(mTmpFrames.frame); } catch (RemoteException e) { mAdded = false; mView = null; @@ -1474,6 +1477,55 @@ public final class ViewRootImpl implements ViewParent, scheduleTraversals(); } + /** Handles messages {@link #MSG_RESIZED} and {@link #MSG_RESIZED_REPORT}. */ + private void handleResized(int msg, SomeArgs args) { + if (!mAdded) { + return; + } + + final ClientWindowFrames frames = (ClientWindowFrames) args.arg1; + final MergedConfiguration mergedConfiguration = (MergedConfiguration) args.arg2; + final boolean forceNextWindowRelayout = args.argi1 != 0; + final int displayId = args.argi3; + final Rect backdropFrame = frames.backdropFrame; + final DisplayCutout displayCutout = frames.displayCutout.get(); + + final boolean frameChanged = !mWinFrame.equals(frames.frame); + final boolean cutoutChanged = !mPendingDisplayCutout.get().equals(displayCutout); + final boolean backdropFrameChanged = !mPendingBackDropFrame.equals(backdropFrame); + final boolean configChanged = !mLastReportedMergedConfiguration.equals(mergedConfiguration); + final boolean displayChanged = mDisplay.getDisplayId() != displayId; + if (msg == MSG_RESIZED && !frameChanged && !cutoutChanged && !backdropFrameChanged + && !configChanged && !displayChanged && !forceNextWindowRelayout) { + return; + } + + if (configChanged) { + // If configuration changed - notify about that and, maybe, about move to display. + performConfigurationChange(mergedConfiguration, false /* force */, + displayChanged ? displayId : INVALID_DISPLAY /* same display */); + } else if (displayChanged) { + // Moved to display without config change - report last applied one. + onMovedToDisplay(displayId, mLastConfigurationFromResources); + } + + setFrame(frames.frame); + mTmpFrames.displayFrame.set(frames.displayFrame); + mPendingDisplayCutout.set(displayCutout); + mPendingBackDropFrame.set(backdropFrame); + mForceNextWindowRelayout = forceNextWindowRelayout; + mPendingAlwaysConsumeSystemBars = args.argi2 != 0; + + if (msg == MSG_RESIZED_REPORT) { + reportNextDraw(); + } + + if (mView != null && (frameChanged || cutoutChanged || configChanged)) { + forceLayout(mView); + } + requestLayout(); + } + private final DisplayListener mDisplayListener = new DisplayListener() { @Override public void onDisplayChanged(int displayId) { @@ -4919,60 +4971,13 @@ public final class ViewRootImpl implements ViewParent, case MSG_DISPATCH_GET_NEW_SURFACE: handleGetNewSurface(); break; - case MSG_RESIZED: { - // Recycled in the fall through... - SomeArgs args = (SomeArgs) msg.obj; - if (mWinFrame.equals(args.arg1) - && mPendingDisplayCutout.get().equals(args.arg9) - && mPendingBackDropFrame.equals(args.arg8) - && mLastReportedMergedConfiguration.equals(args.arg4) - && args.argi1 == 0 - && mDisplay.getDisplayId() == args.argi3) { - break; - } - } // fall through... - case MSG_RESIZED_REPORT: - if (mAdded) { - SomeArgs args = (SomeArgs) msg.obj; - - final int displayId = args.argi3; - MergedConfiguration mergedConfiguration = (MergedConfiguration) args.arg4; - final boolean displayChanged = mDisplay.getDisplayId() != displayId; - boolean configChanged = false; - - if (!mLastReportedMergedConfiguration.equals(mergedConfiguration)) { - // If configuration changed - notify about that and, maybe, - // about move to display. - performConfigurationChange(mergedConfiguration, false /* force */, - displayChanged - ? displayId : INVALID_DISPLAY /* same display */); - configChanged = true; - } else if (displayChanged) { - // Moved to display without config change - report last applied one. - onMovedToDisplay(displayId, mLastConfigurationFromResources); - } - - final boolean framesChanged = !mWinFrame.equals(args.arg1) - || !mPendingDisplayCutout.get().equals(args.arg9); - - setFrame((Rect) args.arg1); - mPendingDisplayCutout.set((DisplayCutout) args.arg9); - mPendingBackDropFrame.set((Rect) args.arg8); - mForceNextWindowRelayout = args.argi1 != 0; - mPendingAlwaysConsumeSystemBars = args.argi2 != 0; - - args.recycle(); - - if (msg.what == MSG_RESIZED_REPORT) { - reportNextDraw(); - } - - if (mView != null && (framesChanged || configChanged)) { - forceLayout(mView); - } - requestLayout(); - } + case MSG_RESIZED: + case MSG_RESIZED_REPORT: { + final SomeArgs args = (SomeArgs) msg.obj; + handleResized(msg.what, args); + args.recycle(); break; + } case MSG_INSETS_CHANGED: mInsetsController.onStateChanged((InsetsState) msg.obj); break; @@ -5007,11 +5012,11 @@ public final class ViewRootImpl implements ViewParent, final int h = mWinFrame.height(); final int l = msg.arg1; final int t = msg.arg2; - mTmpFrame.left = l; - mTmpFrame.right = l + w; - mTmpFrame.top = t; - mTmpFrame.bottom = t + h; - setFrame(mTmpFrame); + mTmpFrames.frame.left = l; + mTmpFrames.frame.right = l + w; + mTmpFrames.frame.top = t; + mTmpFrames.frame.bottom = t + h; + setFrame(mTmpFrames.frame); mPendingBackDropFrame.set(mWinFrame); maybeHandleWindowMove(mWinFrame); @@ -7418,9 +7423,10 @@ public final class ViewRootImpl implements ViewParent, (int) (mView.getMeasuredWidth() * appScale + 0.5f), (int) (mView.getMeasuredHeight() * appScale + 0.5f), viewVisibility, insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0, frameNumber, - mTmpFrame, mTmpRect, mTmpRect, mTmpRect, mPendingBackDropFrame, - mPendingDisplayCutout, mPendingMergedConfiguration, mSurfaceControl, mTempInsets, + mTmpFrames, mPendingMergedConfiguration, mSurfaceControl, mTempInsets, mTempControls, mSurfaceSize, mBlastSurfaceControl); + mPendingDisplayCutout.set(mTmpFrames.displayCutout); + mPendingBackDropFrame.set(mTmpFrames.backdropFrame); if (mSurfaceControl.isValid()) { if (!useBLAST()) { mSurface.copyFrom(mSurfaceControl); @@ -7446,9 +7452,9 @@ public final class ViewRootImpl implements ViewParent, } if (mTranslator != null) { - mTranslator.translateRectInScreenToAppWinFrame(mTmpFrame); + mTranslator.translateRectInScreenToAppWinFrame(mTmpFrames.frame); } - setFrame(mTmpFrame); + setFrame(mTmpFrames.frame); mInsetsController.onStateChanged(mTempInsets); mInsetsController.onControlsChanged(mTempControls); return relayoutResult; @@ -7459,6 +7465,14 @@ public final class ViewRootImpl implements ViewParent, mInsetsController.onFrameChanged(frame); } + /** + * Gets the current display size in which the window is being laid out, accounting for screen + * decorations around it. + */ + void getDisplayFrame(Rect outFrame) { + outFrame.set(mTmpFrames.displayFrame); + } + /** * {@inheritDoc} */ @@ -7742,11 +7756,14 @@ public final class ViewRootImpl implements ViewParent, } @UnsupportedAppUsage - private void dispatchResized(Rect frame, Rect contentInsets, - Rect visibleInsets, Rect stableInsets, boolean reportDraw, - MergedConfiguration mergedConfiguration, Rect backDropFrame, boolean forceLayout, - boolean alwaysConsumeSystemBars, int displayId, - DisplayCutout.ParcelableWrapper displayCutout) { + private void dispatchResized(ClientWindowFrames frames, boolean reportDraw, + MergedConfiguration mergedConfiguration, boolean forceLayout, + boolean alwaysConsumeSystemBars, int displayId) { + final Rect frame = frames.frame; + final Rect contentInsets = frames.contentInsets; + final Rect visibleInsets = frames.visibleInsets; + final Rect stableInsets = frames.stableInsets; + final Rect backDropFrame = frames.backdropFrame; if (DEBUG_LAYOUT) Log.v(mTag, "Resizing " + this + ": frame=" + frame.toShortString() + " contentInsets=" + contentInsets.toShortString() + " visibleInsets=" + visibleInsets.toShortString() @@ -7773,14 +7790,9 @@ public final class ViewRootImpl implements ViewParent, } SomeArgs args = SomeArgs.obtain(); final boolean sameProcessCall = (Binder.getCallingPid() == android.os.Process.myPid()); - args.arg1 = sameProcessCall ? new Rect(frame) : frame; - args.arg2 = sameProcessCall ? new Rect(contentInsets) : contentInsets; - args.arg3 = sameProcessCall ? new Rect(visibleInsets) : visibleInsets; - args.arg4 = sameProcessCall && mergedConfiguration != null + args.arg1 = sameProcessCall ? new ClientWindowFrames(frames) : frames; + args.arg2 = sameProcessCall && mergedConfiguration != null ? new MergedConfiguration(mergedConfiguration) : mergedConfiguration; - args.arg6 = sameProcessCall ? new Rect(stableInsets) : stableInsets; - args.arg8 = sameProcessCall ? new Rect(backDropFrame) : backDropFrame; - args.arg9 = displayCutout.get(); // DisplayCutout is immutable. args.argi1 = forceLayout ? 1 : 0; args.argi2 = alwaysConsumeSystemBars ? 1 : 0; args.argi3 = displayId; @@ -9074,17 +9086,13 @@ public final class ViewRootImpl implements ViewParent, } @Override - public void resized(Rect frame, Rect contentInsets, - Rect visibleInsets, Rect stableInsets, boolean reportDraw, - MergedConfiguration mergedConfiguration, Rect backDropFrame, boolean forceLayout, - boolean alwaysConsumeSystemBars, int displayId, - DisplayCutout.ParcelableWrapper displayCutout) { + public void resized(ClientWindowFrames frames, boolean reportDraw, + MergedConfiguration mergedConfiguration, boolean forceLayout, + boolean alwaysConsumeSystemBars, int displayId) { final ViewRootImpl viewAncestor = mViewAncestor.get(); if (viewAncestor != null) { - viewAncestor.dispatchResized(frame, contentInsets, - visibleInsets, stableInsets, reportDraw, mergedConfiguration, - backDropFrame, forceLayout, alwaysConsumeSystemBars, displayId, - displayCutout); + viewAncestor.dispatchResized(frames, reportDraw, mergedConfiguration, forceLayout, + alwaysConsumeSystemBars, displayId); } } diff --git a/core/java/android/view/WindowlessWindowManager.java b/core/java/android/view/WindowlessWindowManager.java index 060311ec3da88..368918d28f806 100644 --- a/core/java/android/view/WindowlessWindowManager.java +++ b/core/java/android/view/WindowlessWindowManager.java @@ -26,6 +26,7 @@ import android.os.IBinder; import android.os.RemoteException; import android.util.Log; import android.util.MergedConfiguration; +import android.window.ClientWindowFrames; import java.util.HashMap; import java.util.Objects; @@ -224,9 +225,7 @@ public class WindowlessWindowManager implements IWindowSession { @Override public int relayout(IWindow window, int seq, WindowManager.LayoutParams inAttrs, int requestedWidth, int requestedHeight, int viewFlags, int flags, long frameNumber, - Rect outFrame, Rect outContentInsets, Rect outVisibleInsets, - Rect outStableInsets, Rect outBackdropFrame, - DisplayCutout.ParcelableWrapper cutout, MergedConfiguration mergedConfiguration, + ClientWindowFrames outFrames, MergedConfiguration mergedConfiguration, SurfaceControl outSurfaceControl, InsetsState outInsetsState, InsetsSourceControl[] outActiveControls, Point outSurfaceSize, SurfaceControl outBLASTSurfaceControl) { @@ -255,7 +254,8 @@ public class WindowlessWindowManager implements IWindowSession { t.hide(sc).apply(); outSurfaceControl.release(); } - outFrame.set(0, 0, attrs.width, attrs.height); + outFrames.frame.set(0, 0, attrs.width, attrs.height); + outFrames.displayFrame.set(outFrames.frame); mergedConfiguration.setConfiguration(mConfiguration, mConfiguration); @@ -291,11 +291,6 @@ public class WindowlessWindowManager implements IWindowSession { android.graphics.Region touchableRegion) { } - @Override - public void getDisplayFrame(android.view.IWindow window, - android.graphics.Rect outDisplayFrame) { - } - @Override public void finishDrawing(android.view.IWindow window, android.view.SurfaceControl.Transaction postDrawTransaction) { diff --git a/core/java/android/window/ClientWindowFrames.aidl b/core/java/android/window/ClientWindowFrames.aidl new file mode 100644 index 0000000000000..22bbea90d35a1 --- /dev/null +++ b/core/java/android/window/ClientWindowFrames.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.window; + +parcelable ClientWindowFrames; diff --git a/core/java/android/window/ClientWindowFrames.java b/core/java/android/window/ClientWindowFrames.java new file mode 100644 index 0000000000000..0523e64f3e7a1 --- /dev/null +++ b/core/java/android/window/ClientWindowFrames.java @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.window; + +import android.annotation.NonNull; +import android.graphics.Rect; +import android.os.Parcel; +import android.os.Parcelable; +import android.view.DisplayCutout; + +/** + * The window frame container class used by client side for layout. + * @hide + */ +public class ClientWindowFrames implements Parcelable { + /** The actual window bounds. */ + public final @NonNull Rect frame; + + /** + * The container frame that is usually the same as display size. It may exclude the area of + * insets if the window layout parameter has specified fit-insets-sides. + */ + public final @NonNull Rect displayFrame; + + /** The background area while the window is resizing. */ + public final @NonNull Rect backdropFrame; + + /** The area cut from the display. */ + public final @NonNull DisplayCutout.ParcelableWrapper displayCutout; + + // TODO(b/149813814): Remove legacy insets. + public final Rect contentInsets; + public final Rect visibleInsets; + public final Rect stableInsets; + + public ClientWindowFrames() { + frame = new Rect(); + displayFrame = new Rect(); + backdropFrame = new Rect(); + displayCutout = new DisplayCutout.ParcelableWrapper(); + contentInsets = new Rect(); + visibleInsets = new Rect(); + stableInsets = new Rect(); + } + + public ClientWindowFrames(ClientWindowFrames other) { + frame = new Rect(other.frame); + displayFrame = new Rect(other.displayFrame); + backdropFrame = new Rect(other.backdropFrame); + displayCutout = new DisplayCutout.ParcelableWrapper(other.displayCutout.get()); + contentInsets = new Rect(other.contentInsets); + visibleInsets = new Rect(other.visibleInsets); + stableInsets = new Rect(other.stableInsets); + } + + private ClientWindowFrames(Parcel in) { + frame = Rect.CREATOR.createFromParcel(in); + displayFrame = Rect.CREATOR.createFromParcel(in); + backdropFrame = Rect.CREATOR.createFromParcel(in); + displayCutout = DisplayCutout.ParcelableWrapper.CREATOR.createFromParcel(in); + contentInsets = Rect.CREATOR.createFromParcel(in); + visibleInsets = Rect.CREATOR.createFromParcel(in); + stableInsets = Rect.CREATOR.createFromParcel(in); + } + + /** Needed for AIDL out parameters. */ + public void readFromParcel(Parcel in) { + frame.set(Rect.CREATOR.createFromParcel(in)); + displayFrame.set(Rect.CREATOR.createFromParcel(in)); + backdropFrame.set(Rect.CREATOR.createFromParcel(in)); + displayCutout.set(DisplayCutout.ParcelableWrapper.CREATOR.createFromParcel(in)); + contentInsets.set(Rect.CREATOR.createFromParcel(in)); + visibleInsets.set(Rect.CREATOR.createFromParcel(in)); + stableInsets.set(Rect.CREATOR.createFromParcel(in)); + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + frame.writeToParcel(dest, flags); + displayFrame.writeToParcel(dest, flags); + backdropFrame.writeToParcel(dest, flags); + displayCutout.writeToParcel(dest, flags); + contentInsets.writeToParcel(dest, flags); + visibleInsets.writeToParcel(dest, flags); + stableInsets.writeToParcel(dest, flags); + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(32); + return "ClientWindowFrames{frame=" + frame.toShortString(sb) + + " display=" + displayFrame.toShortString(sb) + + " backdrop=" + backdropFrame.toShortString(sb) + + " cutout=" + displayCutout + "}"; + } + + @Override + public int describeContents() { + return 0; + } + + public static final Creator CREATOR = new Creator() { + public ClientWindowFrames createFromParcel(Parcel in) { + return new ClientWindowFrames(in); + } + + public ClientWindowFrames[] newArray(int size) { + return new ClientWindowFrames[size]; + } + }; +} diff --git a/core/java/com/android/internal/view/BaseIWindow.java b/core/java/com/android/internal/view/BaseIWindow.java index 7f3eb45156545..d5f54a1998285 100644 --- a/core/java/com/android/internal/view/BaseIWindow.java +++ b/core/java/com/android/internal/view/BaseIWindow.java @@ -18,13 +18,11 @@ package com.android.internal.view; import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Point; -import android.graphics.Rect; import android.hardware.input.InputManager; import android.os.Bundle; import android.os.ParcelFileDescriptor; import android.os.RemoteException; import android.util.MergedConfiguration; -import android.view.DisplayCutout; import android.view.DragEvent; import android.view.IScrollCaptureController; import android.view.IWindow; @@ -33,6 +31,7 @@ import android.view.InsetsSourceControl; import android.view.InsetsState; import android.view.PointerIcon; import android.view.WindowInsets.Type.InsetsType; +import android.window.ClientWindowFrames; import com.android.internal.os.IResultReceiver; @@ -51,11 +50,9 @@ public class BaseIWindow extends IWindow.Stub { } @Override - public void resized(Rect frame, Rect contentInsets, Rect visibleInsets, - Rect stableInsets, boolean reportDraw, - MergedConfiguration mergedConfiguration, Rect backDropFrame, boolean forceLayout, - boolean alwaysConsumeSystemBars, int displayId, - DisplayCutout.ParcelableWrapper displayCutout) { + public void resized(ClientWindowFrames frames, boolean reportDraw, + MergedConfiguration mergedConfiguration, boolean forceLayout, + boolean alwaysConsumeSystemBars, int displayId) { if (reportDraw) { try { mSession.finishDrawing(this, null /* postDrawTransaction */); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java index 8abe9eeb6a9a2..b4620e27e68cb 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java @@ -22,7 +22,6 @@ import android.annotation.NonNull; import android.content.Context; import android.content.res.Configuration; import android.graphics.Point; -import android.graphics.Rect; import android.graphics.Region; import android.os.Bundle; import android.os.IBinder; @@ -32,7 +31,6 @@ import android.util.MergedConfiguration; import android.util.Slog; import android.util.SparseArray; import android.view.Display; -import android.view.DisplayCutout; import android.view.DragEvent; import android.view.IScrollCaptureController; import android.view.IWindow; @@ -47,6 +45,7 @@ import android.view.View; import android.view.ViewGroup; import android.view.WindowManager; import android.view.WindowlessWindowManager; +import android.window.ClientWindowFrames; import com.android.internal.os.IResultReceiver; @@ -274,22 +273,20 @@ public class SystemWindows { @Override public int relayout(IWindow window, int seq, WindowManager.LayoutParams attrs, int requestedWidth, int requestedHeight, int viewVisibility, int flags, - long frameNumber, Rect outFrame, Rect outOverscanInsets, Rect outContentInsets, - Rect outVisibleInsets, Rect outStableInsets, - DisplayCutout.ParcelableWrapper cutout, MergedConfiguration mergedConfiguration, + long frameNumber, ClientWindowFrames outFrames, + MergedConfiguration mergedConfiguration, SurfaceControl outSurfaceControl, InsetsState outInsetsState, InsetsSourceControl[] outActiveControls, Point outSurfaceSize, SurfaceControl outBLASTSurfaceControl) { int res = super.relayout(window, seq, attrs, requestedWidth, requestedHeight, - viewVisibility, flags, frameNumber, outFrame, outOverscanInsets, - outContentInsets, outVisibleInsets, outStableInsets, - cutout, mergedConfiguration, outSurfaceControl, outInsetsState, + viewVisibility, flags, frameNumber, outFrames, + mergedConfiguration, outSurfaceControl, outInsetsState, outActiveControls, outSurfaceSize, outBLASTSurfaceControl); if (res != 0) { return res; } DisplayLayout dl = mDisplayController.getDisplayLayout(mDisplayId); - outStableInsets.set(dl.stableInsets()); + outFrames.stableInsets.set(dl.stableInsets()); return 0; } @@ -314,10 +311,9 @@ public class SystemWindows { ContainerWindow() {} @Override - public void resized(Rect frame, Rect contentInsets, Rect visibleInsets, Rect stableInsets, - boolean reportDraw, MergedConfiguration newMergedConfiguration, Rect backDropFrame, - boolean forceLayout, boolean alwaysConsumeSystemBars, int displayId, - DisplayCutout.ParcelableWrapper displayCutout) {} + public void resized(ClientWindowFrames frames, boolean reportDraw, + MergedConfiguration newMergedConfiguration, boolean forceLayout, + boolean alwaysConsumeSystemBars, int displayId) {} @Override public void locationInParentDisplayChanged(Point offset) {} diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java index 3b32a9d762580..3d6d7b72671b5 100644 --- a/services/core/java/com/android/server/wm/Session.java +++ b/services/core/java/com/android/server/wm/Session.java @@ -56,6 +56,7 @@ import android.view.InsetsState; import android.view.SurfaceControl; import android.view.SurfaceSession; import android.view.WindowManager; +import android.window.ClientWindowFrames; import com.android.internal.os.logging.MetricsLoggerWrapper; import com.android.internal.protolog.common.ProtoLog; @@ -201,9 +202,7 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { @Override public int relayout(IWindow window, int seq, WindowManager.LayoutParams attrs, int requestedWidth, int requestedHeight, int viewFlags, int flags, long frameNumber, - Rect outFrame, Rect outContentInsets, Rect outVisibleInsets, - Rect outStableInsets, Rect outBackdropFrame, - DisplayCutout.ParcelableWrapper cutout, MergedConfiguration mergedConfiguration, + ClientWindowFrames outFrames, MergedConfiguration mergedConfiguration, SurfaceControl outSurfaceControl, InsetsState outInsetsState, InsetsSourceControl[] outActiveControls, Point outSurfaceSize, SurfaceControl outBLASTSurfaceControl) { @@ -212,10 +211,8 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, mRelayoutTag); int res = mService.relayoutWindow(this, window, seq, attrs, requestedWidth, requestedHeight, viewFlags, flags, frameNumber, - outFrame, outContentInsets, outVisibleInsets, - outStableInsets, outBackdropFrame, cutout, - mergedConfiguration, outSurfaceControl, outInsetsState, outActiveControls, - outSurfaceSize, outBLASTSurfaceControl); + outFrames, mergedConfiguration, outSurfaceControl, outInsetsState, + outActiveControls, outSurfaceSize, outBLASTSurfaceControl); Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); if (false) Slog.d(TAG_WM, "<<<<<< EXITING relayout to " + Binder.getCallingPid()); @@ -239,11 +236,6 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { visibleInsets, touchableArea); } - @Override - public void getDisplayFrame(IWindow window, Rect outDisplayFrame) { - mService.getWindowDisplayFrame(this, window, outDisplayFrame); - } - @Override public void finishDrawing(IWindow window, @Nullable SurfaceControl.Transaction postDrawTransaction) { diff --git a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java index e9ada6be7e7b4..100f1bff12a7d 100644 --- a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java +++ b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java @@ -67,7 +67,6 @@ import android.os.RemoteException; import android.os.SystemClock; import android.util.MergedConfiguration; import android.util.Slog; -import android.view.DisplayCutout; import android.view.IWindowSession; import android.view.InsetsSourceControl; import android.view.InsetsState; @@ -79,6 +78,7 @@ import android.view.ViewGroup.LayoutParams; import android.view.ViewRootImpl; import android.view.WindowManager; import android.view.WindowManagerGlobal; +import android.window.ClientWindowFrames; import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; @@ -159,12 +159,8 @@ class TaskSnapshotSurface implements StartingSurface { final IWindowSession session = WindowManagerGlobal.getWindowSession(); window.setSession(session); final SurfaceControl surfaceControl = new SurfaceControl(); - final Rect tmpRect = new Rect(); - final DisplayCutout.ParcelableWrapper tmpCutout = new DisplayCutout.ParcelableWrapper(); - final Rect tmpFrame = new Rect(); + final ClientWindowFrames tmpFrames = new ClientWindowFrames(); final Rect taskBounds; - final Rect tmpContentInsets = new Rect(); - final Rect tmpStableInsets = new Rect(); final InsetsState mTmpInsetsState = new InsetsState(); final InsetsSourceControl[] mTempControls = new InsetsSourceControl[0]; final MergedConfiguration tmpMergedConfiguration = new MergedConfiguration(); @@ -254,8 +250,9 @@ class TaskSnapshotSurface implements StartingSurface { } try { final int res = session.addToDisplay(window, window.mSeq, layoutParams, - View.GONE, activity.getDisplayContent().getDisplayId(), tmpFrame, tmpRect, - tmpRect, tmpCutout, null, mTmpInsetsState, mTempControls); + View.GONE, activity.getDisplayContent().getDisplayId(), tmpFrames.frame, + tmpFrames.contentInsets, tmpFrames.stableInsets, tmpFrames.displayCutout, + null /* outInputChannel */, mTmpInsetsState, mTempControls); if (res < 0) { Slog.w(TAG, "Failed to add snapshot starting window res=" + res); return null; @@ -270,15 +267,14 @@ class TaskSnapshotSurface implements StartingSurface { window.setOuter(snapshotSurface); try { session.relayout(window, window.mSeq, layoutParams, -1, -1, View.VISIBLE, 0, -1, - tmpFrame, tmpContentInsets, tmpRect, tmpStableInsets, tmpRect, - tmpCutout, tmpMergedConfiguration, surfaceControl, mTmpInsetsState, + tmpFrames, tmpMergedConfiguration, surfaceControl, mTmpInsetsState, mTempControls, sTmpSurfaceSize, sTmpSurfaceControl); } catch (RemoteException e) { // Local call. } - final Rect systemBarInsets = getSystemBarInsets(tmpFrame, insetsState); - snapshotSurface.setFrames(tmpFrame, systemBarInsets); + final Rect systemBarInsets = getSystemBarInsets(tmpFrames.frame, insetsState); + snapshotSurface.setFrames(tmpFrames.frame, systemBarInsets); snapshotSurface.drawSnapshot(); return snapshotSurface; } @@ -528,11 +524,9 @@ class TaskSnapshotSurface implements StartingSurface { } @Override - public void resized(Rect frame, Rect contentInsets, Rect visibleInsets, - Rect stableInsets, boolean reportDraw, - MergedConfiguration mergedConfiguration, Rect backDropFrame, boolean forceLayout, - boolean alwaysConsumeSystemBars, int displayId, - DisplayCutout.ParcelableWrapper displayCutout) { + public void resized(ClientWindowFrames frames, boolean reportDraw, + MergedConfiguration mergedConfiguration, boolean forceLayout, + boolean alwaysConsumeSystemBars, int displayId) { if (mergedConfiguration != null && mOuter != null && mOuter.mOrientationOnCreation != mergedConfiguration.getMergedConfiguration().orientation) { diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 017747f03ca0a..8083091002bea 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -258,6 +258,7 @@ import android.view.WindowManager.RemoveContentMode; import android.view.WindowManager.TransitionType; import android.view.WindowManagerGlobal; import android.view.WindowManagerPolicyConstants.PointerEventListener; +import android.window.ClientWindowFrames; import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; @@ -2065,21 +2066,6 @@ public class WindowManagerService extends IWindowManager.Stub } } - public void getWindowDisplayFrame(Session session, IWindow client, - Rect outDisplayFrame) { - synchronized (mGlobalLock) { - WindowState win = windowForClientLocked(session, client, false); - if (win == null) { - outDisplayFrame.setEmpty(); - return; - } - outDisplayFrame.set(win.getDisplayFrame()); - if (win.inSizeCompatMode()) { - outDisplayFrame.scale(win.mInvGlobalScale); - } - } - } - public void onRectangleOnScreenRequested(IBinder token, Rect rectangle) { synchronized (mGlobalLock) { if (mAccessibilityController != null) { @@ -2115,9 +2101,7 @@ public class WindowManagerService extends IWindowManager.Stub public int relayoutWindow(Session session, IWindow client, int seq, LayoutParams attrs, int requestedWidth, int requestedHeight, int viewVisibility, int flags, - long frameNumber, Rect outFrame, Rect outContentInsets, - Rect outVisibleInsets, Rect outStableInsets, Rect outBackdropFrame, - DisplayCutout.ParcelableWrapper outCutout, MergedConfiguration mergedConfiguration, + long frameNumber, ClientWindowFrames outFrames, MergedConfiguration mergedConfiguration, SurfaceControl outSurfaceControl, InsetsState outInsetsState, InsetsSourceControl[] outActiveControls, Point outSurfaceSize, SurfaceControl outBLASTSurfaceControl) { @@ -2419,18 +2403,14 @@ public class WindowManagerService extends IWindowManager.Stub // The last inset values represent the last client state win.updateLastInsetValues(); - win.getCompatFrame(outFrame); - win.getInsetsForRelayout(outContentInsets, outVisibleInsets, - outStableInsets); - outCutout.set(win.getWmDisplayCutout().getDisplayCutout()); - outBackdropFrame.set(win.getBackdropFrame(win.getFrame())); + win.fillClientWindowFrames(outFrames); outInsetsState.set(win.getInsetsState(), win.isClientLocal()); if (DEBUG) { Slog.v(TAG_WM, "Relayout given client " + client.asBinder() + ", requestedWidth=" + requestedWidth + ", requestedHeight=" + requestedHeight + ", viewVisibility=" + viewVisibility - + "\nRelayout returning frame=" + outFrame + + "\nRelayout returning frame=" + outFrames.frame + ", surface=" + outSurfaceControl); } @@ -2440,8 +2420,7 @@ public class WindowManagerService extends IWindowManager.Stub result |= mInTouchMode ? WindowManagerGlobal.RELAYOUT_RES_IN_TOUCH_MODE : 0; if (DEBUG_LAYOUT) { - Slog.v(TAG_WM, - "Relayout complete " + win + ": outFrame=" + outFrame.toShortString()); + Slog.v(TAG_WM, "Relayout complete " + win + ": outFrames=" + outFrames); } win.mInRelayout = false; diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 84a9c750d2d36..721f002a1b410 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -209,7 +209,6 @@ import android.util.Slog; import android.util.TimeUtils; import android.util.proto.ProtoOutputStream; import android.view.Display; -import android.view.DisplayCutout; import android.view.DisplayInfo; import android.view.Gravity; import android.view.IApplicationToken; @@ -233,6 +232,7 @@ import android.view.WindowManager; import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.view.animation.Interpolator; +import android.window.ClientWindowFrames; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.policy.KeyInterceptionInfo; @@ -387,15 +387,6 @@ class WindowState extends WindowContainer implements WindowManagerP private final Configuration mTempConfiguration = new Configuration(); - /** - * The last content insets returned to the client in relayout. We use - * these in the bounds animation to ensure we only observe inset changes - * at the same time that a client resizes it's surface so that we may use - * the geometryAppliesWithResize synchronization mechanism to keep - * the contents in place. - */ - final Rect mLastRelayoutContentInsets = new Rect(); - /** * Set to true if we are waiting for this window to receive its * given internal insets before laying out other windows based on it. @@ -437,6 +428,8 @@ class WindowState extends WindowContainer implements WindowManagerP private final WindowFrames mWindowFrames = new WindowFrames(); + private final ClientWindowFrames mClientWindowFrames = new ClientWindowFrames(); + /** The frames used to compute a temporal layout appearance. */ private WindowFrames mSimulatedWindowFrames; @@ -1299,7 +1292,10 @@ class WindowState extends WindowContainer implements WindowManagerP return mWindowFrames.mRelFrame; } - /** Retrieves the frame of the display that this window was last laid out in. */ + /** + * Gets the frame that excludes the area of side insets according to the layout parameter from + * {@link WindowManager.LayoutParams#setFitInsetsSides}. + */ Rect getDisplayFrame() { return mWindowFrames.mDisplayFrame; } @@ -3585,6 +3581,39 @@ class WindowState extends WindowContainer implements WindowManagerP return wpc != null && wpc.registeredForDisplayConfigChanges(); } + void fillClientWindowFrames(ClientWindowFrames outFrames) { + outFrames.frame.set(mWindowFrames.mCompatFrame); + outFrames.displayFrame.set(mWindowFrames.mDisplayFrame); + if (mInvGlobalScale != 1.0f && inSizeCompatMode()) { + 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); + } + outFrames.displayCutout.set(mWindowFrames.mDisplayCutout.getDisplayCutout()); + + // TODO(b/149813814): Remove legacy insets. + outFrames.contentInsets.set(mWindowFrames.mLastContentInsets); + outFrames.visibleInsets.set(mWindowFrames.mLastVisibleInsets); + outFrames.stableInsets.set(mWindowFrames.mLastStableInsets); + } + void reportResized() { // If the activity is scheduled to relaunch, skip sending the resized to ViewRootImpl now // since it will be destroyed anyway. This also prevents the client from receiving @@ -3616,23 +3645,18 @@ class WindowState extends WindowContainer implements WindowManagerP mWinAnimator.mSurfaceResized = false; mWindowFrames.resetInsetsChanged(); - final Rect frame = mWindowFrames.mCompatFrame; - final Rect contentInsets = mWindowFrames.mLastContentInsets; - final Rect visibleInsets = mWindowFrames.mLastVisibleInsets; - final Rect stableInsets = mWindowFrames.mLastStableInsets; final MergedConfiguration mergedConfiguration = mLastReportedConfiguration; final boolean reportDraw = mWinAnimator.mDrawState == DRAW_PENDING || useBLASTSync() || !mRedrawForSyncReported; final boolean forceRelayout = reportOrientation || isDragResizeChanged() || !mRedrawForSyncReported; final int displayId = getDisplayId(); - final DisplayCutout displayCutout = getWmDisplayCutout().getDisplayCutout(); + fillClientWindowFrames(mClientWindowFrames); mRedrawForSyncReported = true; try { - mClient.resized(frame, contentInsets, visibleInsets, stableInsets, reportDraw, - mergedConfiguration, getBackdropFrame(frame), forceRelayout, + mClient.resized(mClientWindowFrames, reportDraw, mergedConfiguration, forceRelayout, getDisplayContent().getDisplayPolicy().areSystemBarsForcedShownLw(this), - displayId, new DisplayCutout.ParcelableWrapper(displayCutout)); + displayId); if (mWmService.mAccessibilityController != null) { mWmService.mAccessibilityController.onSomeWindowResizedOrMovedLocked(displayId); @@ -3738,27 +3762,6 @@ class WindowState extends WindowContainer implements WindowManagerP return (mAttrs.insetsFlags.behavior & BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE) != 0; } - Rect getBackdropFrame(Rect frame) { - // 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. - boolean resizing = isDragResizing() || isDragResizeChanged(); - if (getWindowConfiguration().useWindowFrameForBackdrop() || !resizing) { - // 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. - mTmpRect.set(frame); - mTmpRect.offsetTo(0, 0); - return mTmpRect; - } - final DisplayInfo displayInfo = getDisplayInfo(); - mTmpRect.set(0, 0, displayInfo.logicalWidth, displayInfo.logicalHeight); - return mTmpRect; - } - private int getRootTaskId() { final Task stack = getRootTask(); if (stack == null) { @@ -5670,18 +5673,6 @@ class WindowState extends WindowContainer implements WindowManagerP } } - /** - * Copy the inset values over so they can be sent back to the client when a relayout occurs. - */ - void getInsetsForRelayout(Rect outContentInsets, Rect outVisibleInsets, - Rect outStableInsets) { - outContentInsets.set(mWindowFrames.mContentInsets); - outVisibleInsets.set(mWindowFrames.mVisibleInsets); - outStableInsets.set(mWindowFrames.mStableInsets); - - mLastRelayoutContentInsets.set(mWindowFrames.mContentInsets); - } - void getContentInsets(Rect outContentInsets) { outContentInsets.set(mWindowFrames.mContentInsets); } diff --git a/services/tests/wmtests/src/com/android/server/wm/TestIWindow.java b/services/tests/wmtests/src/com/android/server/wm/TestIWindow.java index e39b4bcd2eb0c..d37f3f402c300 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TestIWindow.java +++ b/services/tests/wmtests/src/com/android/server/wm/TestIWindow.java @@ -17,17 +17,16 @@ package com.android.server.wm; import android.graphics.Point; -import android.graphics.Rect; import android.os.Bundle; import android.os.ParcelFileDescriptor; import android.os.RemoteException; import android.util.MergedConfiguration; -import android.view.DisplayCutout; import android.view.DragEvent; import android.view.IScrollCaptureController; import android.view.IWindow; import android.view.InsetsSourceControl; import android.view.InsetsState; +import android.window.ClientWindowFrames; import com.android.internal.os.IResultReceiver; @@ -38,10 +37,9 @@ public class TestIWindow extends IWindow.Stub { } @Override - public void resized(Rect frame, Rect contentInsets, Rect visibleInsets, - Rect stableInsets, boolean reportDraw, MergedConfiguration mergedConfig, - Rect backDropFrame, boolean forceLayout, boolean alwaysConsumeSystemBars, int displayId, - DisplayCutout.ParcelableWrapper displayCutout) throws RemoteException { + public void resized(ClientWindowFrames frames, boolean reportDraw, + MergedConfiguration mergedConfig, boolean forceLayout, boolean alwaysConsumeSystemBars, + int displayId) throws RemoteException { } @Override diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java index 3106ca26c8a17..c18043fcc4b99 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java @@ -581,12 +581,10 @@ public class WindowStateTests extends WindowTestsBase { mWm.mResizingWindows.remove(win); spyOn(win.mClient); try { - doThrow(new RemoteException("test")).when(win.mClient).resized(any() /* frame */, - any() /* contentInsets */, any() /* visibleInsets */, any() /* stableInsets */, + doThrow(new RemoteException("test")).when(win.mClient).resized(any() /* frames */, anyBoolean() /* reportDraw */, any() /* mergedConfig */, - any() /* backDropFrame */, anyBoolean() /* forceLayout */, - anyBoolean() /* alwaysConsumeSystemBars */, anyInt() /* displayId */, - any() /* displayCutout */); + anyBoolean() /* forceLayout */, anyBoolean() /* alwaysConsumeSystemBars */, + anyInt() /* displayId */); } catch (RemoteException ignored) { } win.reportResized();