From 9e370f2912620a4f3239cb58d2bce23a58f78cd6 Mon Sep 17 00:00:00 2001 From: Adrian Roos Date: Tue, 6 Mar 2018 18:19:45 +0100 Subject: [PATCH] Window: Provide frame size hint to ViewRootImpl Provides a better estimate to the ViewRootImpl about the likely window frame size than it can get from the configuration, which allows it to avoid unneccessary measure passes. Bug: 73813813 Test: atest PhoneWindowManagerLayoutTest Change-Id: Ia4de6509416d90eed61929ce1646904c31afdd8d --- .../service/wallpaper/WallpaperService.java | 4 +- core/java/android/view/IWindowSession.aidl | 4 +- core/java/android/view/ViewRootImpl.java | 6 +-- .../android/server/policy/PhoneWindowManager.java | 44 +++++++++++------- .../android/server/policy/WindowManagerPolicy.java | 10 ++-- .../core/java/com/android/server/wm/Session.java | 15 +++--- .../com/android/server/wm/TaskSnapshotSurface.java | 2 +- .../android/server/wm/WindowManagerService.java | 8 ++-- .../policy/PhoneWindowManagerLayoutTest.java | 53 +++++++++++++++++++++- 9 files changed, 103 insertions(+), 43 deletions(-) diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java index 8588df7f136a..a1327301da67 100644 --- a/core/java/android/service/wallpaper/WallpaperService.java +++ b/core/java/android/service/wallpaper/WallpaperService.java @@ -788,8 +788,8 @@ public abstract class WallpaperService extends Service { com.android.internal.R.style.Animation_Wallpaper; mInputChannel = new InputChannel(); if (mSession.addToDisplay(mWindow, mWindow.mSeq, mLayout, View.VISIBLE, - Display.DEFAULT_DISPLAY, mContentInsets, mStableInsets, mOutsets, - mDisplayCutout, mInputChannel) < 0) { + Display.DEFAULT_DISPLAY, mWinFrame, mContentInsets, mStableInsets, + mOutsets, mDisplayCutout, mInputChannel) < 0) { Log.w(TAG, "Failed to add window while updating wallpaper surface."); return; } diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl index d7fd3299b9e3..d8a5609a3c98 100644 --- a/core/java/android/view/IWindowSession.aidl +++ b/core/java/android/view/IWindowSession.aidl @@ -41,8 +41,8 @@ interface IWindowSession { in int viewVisibility, out Rect outContentInsets, out Rect outStableInsets, out InputChannel outInputChannel); int addToDisplay(IWindow window, int seq, in WindowManager.LayoutParams attrs, - in int viewVisibility, in int layerStackId, out Rect outContentInsets, - out Rect outStableInsets, out Rect outOutsets, + in int viewVisibility, in int layerStackId, out Rect outFrame, + out Rect outContentInsets, out Rect outStableInsets, out Rect outOutsets, out DisplayCutout.ParcelableWrapper displayCutout, out InputChannel outInputChannel); int addWithoutInputChannel(IWindow window, int seq, in WindowManager.LayoutParams attrs, in int viewVisibility, out Rect outContentInsets, out Rect outStableInsets); diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 95e4abb648b4..d908e7979cf7 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -753,7 +753,7 @@ public final class ViewRootImpl implements ViewParent, mAttachInfo.mRecomputeGlobalAttributes = true; collectViewAttributes(); res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes, - getHostVisibility(), mDisplay.getDisplayId(), + getHostVisibility(), mDisplay.getDisplayId(), mWinFrame, mAttachInfo.mContentInsets, mAttachInfo.mStableInsets, mAttachInfo.mOutsets, mAttachInfo.mDisplayCutout, mInputChannel); } catch (RemoteException e) { @@ -1711,8 +1711,8 @@ public final class ViewRootImpl implements ViewParent, desiredWindowWidth = size.x; desiredWindowHeight = size.y; } else { - desiredWindowWidth = dipToPx(config.screenWidthDp); - desiredWindowHeight = dipToPx(config.screenHeightDp); + desiredWindowWidth = mWinFrame.width(); + desiredWindowHeight = mWinFrame.height(); } // We used to use the following condition to choose 32 bits drawing caches: diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index ab0779b8fb33..8bc9830f49d5 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -4389,13 +4389,13 @@ public class PhoneWindowManager implements WindowManagerPolicy { @Override // TODO: Should probably be moved into DisplayFrames. - public boolean getInsetHintLw(WindowManager.LayoutParams attrs, Rect taskBounds, - DisplayFrames displayFrames, Rect outContentInsets, Rect outStableInsets, + public boolean getLayoutHintLw(WindowManager.LayoutParams attrs, Rect taskBounds, + DisplayFrames displayFrames, Rect outFrame, Rect outContentInsets, Rect outStableInsets, Rect outOutsets, DisplayCutout.ParcelableWrapper outDisplayCutout) { final int fl = PolicyControl.getWindowFlags(null, attrs); final int pfl = attrs.privateFlags; - final int sysuiVis = PolicyControl.getSystemUiVisibility(null, attrs); - final int systemUiVisibility = (sysuiVis | attrs.subtreeSystemUiVisibility); + final int requestedSysUiVis = PolicyControl.getSystemUiVisibility(null, attrs); + final int sysUiVis = requestedSysUiVis | getImpliedSysUiFlagsForLayout(attrs); final int displayRotation = displayFrames.mRotation; final int displayWidth = displayFrames.mDisplayWidth; final int displayHeight = displayFrames.mDisplayHeight; @@ -4416,21 +4416,20 @@ public class PhoneWindowManager implements WindowManagerPolicy { } } - final boolean layoutInScreenAndInsetDecor = - (fl & (FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR)) - == (FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR); + final boolean layoutInScreen = (fl & FLAG_LAYOUT_IN_SCREEN) != 0; + final boolean layoutInScreenAndInsetDecor = layoutInScreen && + (fl & FLAG_LAYOUT_INSET_DECOR) != 0; final boolean screenDecor = (pfl & PRIVATE_FLAG_IS_SCREEN_DECOR) != 0; if (layoutInScreenAndInsetDecor && !screenDecor) { - Rect frame; int availRight, availBottom; if (canHideNavigationBar() && - (systemUiVisibility & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0) { - frame = displayFrames.mUnrestricted; + (sysUiVis & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0) { + outFrame.set(displayFrames.mUnrestricted); availRight = displayFrames.mUnrestricted.right; availBottom = displayFrames.mUnrestricted.bottom; } else { - frame = displayFrames.mRestricted; + outFrame.set(displayFrames.mRestricted); availRight = displayFrames.mRestricted.right; availBottom = displayFrames.mRestricted.bottom; } @@ -4438,7 +4437,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { availRight - displayFrames.mStable.right, availBottom - displayFrames.mStable.bottom); - if ((systemUiVisibility & View.SYSTEM_UI_FLAG_LAYOUT_STABLE) != 0) { + if ((sysUiVis & View.SYSTEM_UI_FLAG_LAYOUT_STABLE) != 0) { if ((fl & FLAG_FULLSCREEN) != 0) { outContentInsets.set(displayFrames.mStableFullscreen.left, displayFrames.mStableFullscreen.top, @@ -4460,14 +4459,25 @@ public class PhoneWindowManager implements WindowManagerPolicy { displayWidth, displayHeight); calculateRelevantTaskInsets(taskBounds, outStableInsets, displayWidth, displayHeight); + outFrame.intersect(taskBounds); } - outDisplayCutout.set(displayFrames.mDisplayCutout.calculateRelativeTo(frame)); + outDisplayCutout.set(displayFrames.mDisplayCutout.calculateRelativeTo(outFrame)); + return mForceShowSystemBars; + } else { + if (layoutInScreen) { + outFrame.set(displayFrames.mUnrestricted); + } else { + outFrame.set(displayFrames.mStable); + } + if (taskBounds != null) { + outFrame.intersect(taskBounds); + } + + outContentInsets.setEmpty(); + outStableInsets.setEmpty(); + outDisplayCutout.set(DisplayCutout.NO_CUTOUT); return mForceShowSystemBars; } - outContentInsets.setEmpty(); - outStableInsets.setEmpty(); - outDisplayCutout.set(DisplayCutout.NO_CUTOUT); - return mForceShowSystemBars; } /** diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java index ab331a5263c8..d5c12f73cacb 100644 --- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java +++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java @@ -1145,13 +1145,14 @@ public interface WindowManagerPolicy extends WindowManagerPolicyConstants { /** - * Return the insets for the areas covered by system windows. These values are computed on the + * Return the layout hints for a newly added window. These values are computed on the * most recent layout, so they are not guaranteed to be correct. * * @param attrs The LayoutParams of the window. * @param taskBounds The bounds of the task this window is on or {@code null} if no task is * associated with the window. * @param displayFrames display frames. + * @param outFrame The frame of the window. * @param outContentInsets The areas covered by system windows, expressed as positive insets. * @param outStableInsets The areas covered by stable system windows irrespective of their * current visibility. Expressed as positive insets. @@ -1160,9 +1161,10 @@ public interface WindowManagerPolicy extends WindowManagerPolicyConstants { * @return Whether to always consume the navigation bar. * See {@link #isNavBarForcedShownLw(WindowState)}. */ - default boolean getInsetHintLw(WindowManager.LayoutParams attrs, Rect taskBounds, - DisplayFrames displayFrames, Rect outContentInsets, Rect outStableInsets, - Rect outOutsets, DisplayCutout.ParcelableWrapper outDisplayCutout) { + default boolean getLayoutHintLw(WindowManager.LayoutParams attrs, Rect taskBounds, + DisplayFrames displayFrames, Rect outFrame, Rect outContentInsets, + Rect outStableInsets, Rect outOutsets, + DisplayCutout.ParcelableWrapper outDisplayCutout) { return false; } diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java index 94b851863323..662d51d6e0e5 100644 --- a/services/core/java/com/android/server/wm/Session.java +++ b/services/core/java/com/android/server/wm/Session.java @@ -193,16 +193,16 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { int viewVisibility, Rect outContentInsets, Rect outStableInsets, InputChannel outInputChannel) { return addToDisplay(window, seq, attrs, viewVisibility, Display.DEFAULT_DISPLAY, - outContentInsets, outStableInsets, null /* outOutsets */, null /* cutout */, - outInputChannel); + new Rect() /* outFrame */, outContentInsets, outStableInsets, null /* outOutsets */, + null /* cutout */, outInputChannel); } @Override public int addToDisplay(IWindow window, int seq, WindowManager.LayoutParams attrs, - int viewVisibility, int displayId, Rect outContentInsets, Rect outStableInsets, - Rect outOutsets, DisplayCutout.ParcelableWrapper outDisplayCutout, - InputChannel outInputChannel) { - return mService.addWindow(this, window, seq, attrs, viewVisibility, displayId, + int viewVisibility, int displayId, Rect outFrame, Rect outContentInsets, + Rect outStableInsets, Rect outOutsets, + DisplayCutout.ParcelableWrapper outDisplayCutout, InputChannel outInputChannel) { + return mService.addWindow(this, window, seq, attrs, viewVisibility, displayId, outFrame, outContentInsets, outStableInsets, outOutsets, outDisplayCutout, outInputChannel); } @@ -217,7 +217,8 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { public int addToDisplayWithoutInputChannel(IWindow window, int seq, WindowManager.LayoutParams attrs, int viewVisibility, int displayId, Rect outContentInsets, Rect outStableInsets) { return mService.addWindow(this, window, seq, attrs, viewVisibility, displayId, - outContentInsets, outStableInsets, null /* outOutsets */, null /* cutout */, null); + new Rect() /* outFrame */, outContentInsets, outStableInsets, null /* outOutsets */, + null /* cutout */, null /* outInputChannel */); } @Override diff --git a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java index e4db3b075e91..a9e53a14a210 100644 --- a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java +++ b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java @@ -198,7 +198,7 @@ class TaskSnapshotSurface implements StartingSurface { } try { final int res = session.addToDisplay(window, window.mSeq, layoutParams, - View.GONE, token.getDisplayContent().getDisplayId(), tmpRect, tmpRect, + View.GONE, token.getDisplayContent().getDisplayId(), tmpFrame, tmpRect, tmpRect, tmpRect, tmpCutout, null); if (res < 0) { Slog.w(TAG, "Failed to add snapshot starting window res=" + res); diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 78c04e8e6a2c..43d978d8bff9 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -28,8 +28,6 @@ import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER import static android.content.Intent.ACTION_USER_REMOVED; import static android.content.Intent.EXTRA_USER_HANDLE; import static android.content.pm.PackageManager.PERMISSION_GRANTED; -import static android.os.Process.ROOT_UID; -import static android.os.Process.SHELL_UID; import static android.os.Process.SYSTEM_UID; import static android.os.Process.myPid; import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER; @@ -1106,7 +1104,7 @@ public class WindowManagerService extends IWindowManager.Stub } public int addWindow(Session session, IWindow client, int seq, - LayoutParams attrs, int viewVisibility, int displayId, + LayoutParams attrs, int viewVisibility, int displayId, Rect outFrame, Rect outContentInsets, Rect outStableInsets, Rect outOutsets, DisplayCutout.ParcelableWrapper outDisplayCutout, InputChannel outInputChannel) { int[] appOp = new int[1]; @@ -1447,8 +1445,8 @@ public class WindowManagerService extends IWindowManager.Stub } else { taskBounds = null; } - if (mPolicy.getInsetHintLw(win.mAttrs, taskBounds, displayFrames, outContentInsets, - outStableInsets, outOutsets, outDisplayCutout)) { + if (mPolicy.getLayoutHintLw(win.mAttrs, taskBounds, displayFrames, outFrame, + outContentInsets, outStableInsets, outOutsets, outDisplayCutout)) { res |= WindowManagerGlobal.ADD_FLAG_ALWAYS_CONSUME_NAV_BAR; } diff --git a/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerLayoutTest.java b/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerLayoutTest.java index c6800be343af..b6be3a4719d6 100644 --- a/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerLayoutTest.java +++ b/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerLayoutTest.java @@ -31,6 +31,7 @@ import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_SCREEN_DEC import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; @@ -278,22 +279,70 @@ public class PhoneWindowManagerLayoutTest extends PhoneWindowManagerTestBase { } @Test - public void insetHint_screenDecorWindow() { + public void layoutHint_screenDecorWindow() { addDisplayCutout(); mAppWindow.attrs.privateFlags |= PRIVATE_FLAG_IS_SCREEN_DECOR; mPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); + final Rect frame = new Rect(); final Rect content = new Rect(); final Rect stable = new Rect(); final Rect outsets = new Rect(); final DisplayCutout.ParcelableWrapper cutout = new DisplayCutout.ParcelableWrapper(); - mPolicy.getInsetHintLw(mAppWindow.attrs, null /* taskBounds */, mFrames, content, + mPolicy.getLayoutHintLw(mAppWindow.attrs, null /* taskBounds */, mFrames, frame, content, stable, outsets, cutout); + assertThat(frame, equalTo(mFrames.mUnrestricted)); assertThat(content, equalTo(new Rect())); assertThat(stable, equalTo(new Rect())); assertThat(outsets, equalTo(new Rect())); assertThat(cutout.get(), equalTo(DisplayCutout.NO_CUTOUT)); } + + @Test + public void layoutHint_appWindow() { + // Initialize DisplayFrames + mPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); + + final Rect outFrame = new Rect(); + final Rect outContentInsets = new Rect(); + final Rect outStableInsets = new Rect(); + final Rect outOutsets = new Rect(); + final DisplayCutout.ParcelableWrapper outDisplayCutout = + new DisplayCutout.ParcelableWrapper(); + + mPolicy.getLayoutHintLw(mAppWindow.attrs, null, mFrames, outFrame, outContentInsets, + outStableInsets, outOutsets, outDisplayCutout); + + assertThat(outFrame, is(mFrames.mUnrestricted)); + assertThat(outContentInsets, is(new Rect(0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT))); + assertThat(outStableInsets, is(new Rect(0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT))); + assertThat(outOutsets, is(new Rect())); + assertThat(outDisplayCutout, is(new DisplayCutout.ParcelableWrapper())); + } + + @Test + public void layoutHint_appWindowInTask() { + // Initialize DisplayFrames + mPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); + + final Rect taskBounds = new Rect(100, 100, 200, 200); + + final Rect outFrame = new Rect(); + final Rect outContentInsets = new Rect(); + final Rect outStableInsets = new Rect(); + final Rect outOutsets = new Rect(); + final DisplayCutout.ParcelableWrapper outDisplayCutout = + new DisplayCutout.ParcelableWrapper(); + + mPolicy.getLayoutHintLw(mAppWindow.attrs, taskBounds, mFrames, outFrame, outContentInsets, + outStableInsets, outOutsets, outDisplayCutout); + + assertThat(outFrame, is(taskBounds)); + assertThat(outContentInsets, is(new Rect())); + assertThat(outStableInsets, is(new Rect())); + assertThat(outOutsets, is(new Rect())); + assertThat(outDisplayCutout, is(new DisplayCutout.ParcelableWrapper())); + } } \ No newline at end of file -- 2.11.0