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 ccce565d0de81..af839d4481f75 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; @@ -560,8 +560,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. @@ -1033,11 +1036,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; @@ -1475,6 +1478,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) { @@ -4923,60 +4975,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; @@ -5011,11 +5016,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); @@ -7422,9 +7427,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); @@ -7450,9 +7456,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; @@ -7463,6 +7469,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} */ @@ -7746,11 +7760,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() @@ -7777,14 +7794,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; @@ -9078,17 +9090,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 3fd8aaf9102bf..8eb6432e0d52c 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) { @@ -2415,18 +2399,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); } @@ -2436,8 +2416,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();