From 0ec1328f85a08a610868856c688ebb8196c79c17 Mon Sep 17 00:00:00 2001 From: Filip Gruszczynski Date: Thu, 25 Jun 2015 11:26:01 -0700 Subject: [PATCH] Calculate outset hint when adding window. Outsets aren't dynamic so they are a great candidate for a hint when the window is added through the window manager. Thanks to this during first view hierarchy measure or wallpaper window layout they are immediately available and don't require multiple measure/layout passes. Bug: 21593814 Change-Id: I573c15ffbbe4fcd8a6ed9c5e4fcd6cfbbcd7434f --- .../service/wallpaper/WallpaperService.java | 2 +- core/java/android/view/IWindowSession.aidl | 2 +- core/java/android/view/ViewRootImpl.java | 4 +- .../android/view/WindowManagerPolicy.java | 6 ++- .../policy/impl/PhoneWindowManager.java | 38 ++++++++++++++----- .../java/com/android/server/wm/Session.java | 8 ++-- .../server/wm/WindowManagerService.java | 6 ++- 7 files changed, 45 insertions(+), 21 deletions(-) diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java index 5420cadf54202..5791d6344bf27 100644 --- a/core/java/android/service/wallpaper/WallpaperService.java +++ b/core/java/android/service/wallpaper/WallpaperService.java @@ -652,7 +652,7 @@ 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, + Display.DEFAULT_DISPLAY, mContentInsets, mStableInsets, mOutsets, 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 ed609856277a4..f1a5404fc96d6 100644 --- a/core/java/android/view/IWindowSession.aidl +++ b/core/java/android/view/IWindowSession.aidl @@ -40,7 +40,7 @@ interface IWindowSession { 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 InputChannel outInputChannel); + out Rect outStableInsets, out Rect outOutsets, out InputChannel outInputChannel); int addWithoutInputChannel(IWindow window, int seq, in WindowManager.LayoutParams attrs, in int viewVisibility, out Rect outContentInsets, out Rect outStableInsets); int addToDisplayWithoutInputChannel(IWindow window, int seq, in WindowManager.LayoutParams attrs, diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index a182ef1fb2515..8f7570e157f60 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -526,7 +526,8 @@ public final class ViewRootImpl implements ViewParent, collectViewAttributes(); res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes, getHostVisibility(), mDisplay.getDisplayId(), - mAttachInfo.mContentInsets, mAttachInfo.mStableInsets, mInputChannel); + mAttachInfo.mContentInsets, mAttachInfo.mStableInsets, + mAttachInfo.mOutsets, mInputChannel); } catch (RemoteException e) { mAdded = false; mView = null; @@ -1538,6 +1539,7 @@ public final class ViewRootImpl implements ViewParent, + " content=" + mPendingContentInsets.toShortString() + " visible=" + mPendingVisibleInsets.toShortString() + " visible=" + mPendingStableInsets.toShortString() + + " outsets=" + mPendingOutsets.toShortString() + " surface=" + mSurface); if (mPendingConfiguration.seq != 0) { diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java index 71cb8899cb115..7061ebd01d7e3 100644 --- a/core/java/android/view/WindowManagerPolicy.java +++ b/core/java/android/view/WindowManagerPolicy.java @@ -877,13 +877,15 @@ public interface WindowManagerPolicy { * be correct. * * @param attrs The LayoutParams of the window. + * @param rotation Rotation of the display. * @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. + * @param outOutsets The areas that are not real display, but we would like to treat as such. * */ - public void getInsetHintLw(WindowManager.LayoutParams attrs, Rect outContentInsets, - Rect outStableInsets); + public void getInsetHintLw(WindowManager.LayoutParams attrs, int rotation, + Rect outContentInsets, Rect outStableInsets, Rect outOutsets); /** * Called when layout of the windows is finished. After this function has diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java index f1e8ec4809d5b..2ad70cb668751 100644 --- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java @@ -519,6 +519,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { Display mDisplay; + private int mDisplayRotation; + int mLandscapeRotation = 0; // default landscape rotation int mSeascapeRotation = 0; // "other" landscape rotation, 180 degrees from mLandscapeRotation int mPortraitRotation = 0; // default portrait rotation @@ -3219,12 +3221,28 @@ public class PhoneWindowManager implements WindowManagerPolicy { } @Override - public void getInsetHintLw(WindowManager.LayoutParams attrs, Rect outContentInsets, - Rect outStableInsets) { + public void getInsetHintLw(WindowManager.LayoutParams attrs, int displayRotation, + Rect outContentInsets, Rect outStableInsets, Rect outOutsets) { final int fl = PolicyControl.getWindowFlags(null, attrs); final int sysuiVis = PolicyControl.getSystemUiVisibility(null, attrs); final int systemUiVisibility = (sysuiVis | attrs.subtreeSystemUiVisibility); + final boolean useOutsets = outOutsets != null && shouldUseOutsets(attrs, fl); + if (useOutsets) { + int outset = ScreenShapeHelper.getWindowOutsetBottomPx(mContext.getResources()); + if (outset > 0) { + if (displayRotation == Surface.ROTATION_0) { + outOutsets.bottom += outset; + } else if (displayRotation == Surface.ROTATION_90) { + outOutsets.right += outset; + } else if (displayRotation == Surface.ROTATION_180) { + outOutsets.top += outset; + } else if (displayRotation == Surface.ROTATION_270) { + outOutsets.left += outset; + } + } + } + if ((fl & (FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR)) == (FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR)) { int availRight, availBottom; @@ -3264,10 +3282,16 @@ public class PhoneWindowManager implements WindowManagerPolicy { outStableInsets.setEmpty(); } + private boolean shouldUseOutsets(WindowManager.LayoutParams attrs, int fl) { + return attrs.type == TYPE_WALLPAPER || (fl & (WindowManager.LayoutParams.FLAG_FULLSCREEN + | WindowManager.LayoutParams.FLAG_LAYOUT_IN_OVERSCAN)) != 0; + } + /** {@inheritDoc} */ @Override public void beginLayoutLw(boolean isDefaultDisplay, int displayWidth, int displayHeight, int displayRotation) { + mDisplayRotation = displayRotation; final int overscanLeft, overscanTop, overscanRight, overscanBottom; if (isDefaultDisplay) { switch (displayRotation) { @@ -4035,19 +4059,13 @@ public class PhoneWindowManager implements WindowManagerPolicy { // need to provide information to the clients that want to pretend that you can draw there. // We only want to apply outsets to certain types of windows. For example, we never want to // apply the outsets to floating dialogs, because they wouldn't make sense there. - final boolean useOutsets = attrs.type == TYPE_WALLPAPER - || (fl & (WindowManager.LayoutParams.FLAG_FULLSCREEN - | WindowManager.LayoutParams.FLAG_LAYOUT_IN_OVERSCAN)) != 0; + final boolean useOutsets = shouldUseOutsets(attrs, fl); if (isDefaultDisplay && useOutsets) { osf = mTmpOutsetFrame; osf.set(cf.left, cf.top, cf.right, cf.bottom); int outset = ScreenShapeHelper.getWindowOutsetBottomPx(mContext.getResources()); if (outset > 0) { - int rotation = Surface.ROTATION_0; - try { - rotation = mWindowManager.getRotation(); - } catch (RemoteException e) { - } + int rotation = mDisplayRotation; if (rotation == Surface.ROTATION_0) { osf.bottom += outset; } else if (rotation == Surface.ROTATION_90) { diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java index 40e6d5843313d..cdfcea49d47f6 100644 --- a/services/core/java/com/android/server/wm/Session.java +++ b/services/core/java/com/android/server/wm/Session.java @@ -158,15 +158,15 @@ final class Session extends IWindowSession.Stub int viewVisibility, Rect outContentInsets, Rect outStableInsets, InputChannel outInputChannel) { return addToDisplay(window, seq, attrs, viewVisibility, Display.DEFAULT_DISPLAY, - outContentInsets, outStableInsets, outInputChannel); + outContentInsets, outStableInsets, null /* outOutsets */, outInputChannel); } @Override public int addToDisplay(IWindow window, int seq, WindowManager.LayoutParams attrs, int viewVisibility, int displayId, Rect outContentInsets, Rect outStableInsets, - InputChannel outInputChannel) { + Rect outOutsets, InputChannel outInputChannel) { return mService.addWindow(this, window, seq, attrs, viewVisibility, displayId, - outContentInsets, outStableInsets, outInputChannel); + outContentInsets, outStableInsets, outOutsets, outInputChannel); } @Override @@ -180,7 +180,7 @@ final class Session extends IWindowSession.Stub 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); + outContentInsets, outStableInsets, null /* outOutsets */, null); } public void remove(IWindow window) { diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index b75622b6ec956..6dd9ef6d5a32a 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -2277,7 +2277,8 @@ public class WindowManagerService extends IWindowManager.Stub public int addWindow(Session session, IWindow client, int seq, WindowManager.LayoutParams attrs, int viewVisibility, int displayId, - Rect outContentInsets, Rect outStableInsets, InputChannel outInputChannel) { + Rect outContentInsets, Rect outStableInsets, Rect outOutsets, + InputChannel outInputChannel) { int[] appOp = new int[1]; int res = mPolicy.checkAddPermission(attrs, appOp); if (res != WindowManagerGlobal.ADD_OKAY) { @@ -2515,7 +2516,8 @@ public class WindowManagerService extends IWindowManager.Stub winAnimator.mEnteringAnimation = true; if (displayContent.isDefaultDisplay) { - mPolicy.getInsetHintLw(win.mAttrs, outContentInsets, outStableInsets); + mPolicy.getInsetHintLw(win.mAttrs, mRotation, outContentInsets, outStableInsets, + outOutsets); } else { outContentInsets.setEmpty(); outStableInsets.setEmpty();