diff options
author | Dianne Hackborn <hackbod@google.com> | 2013-02-23 03:15:35 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2013-02-23 03:15:35 +0000 |
commit | bd0dc13cb870e4dc0c3dfbbeba83a9e03ab481e9 (patch) | |
tree | 280c6eb956bc3499b9d027cac432953de815566a | |
parent | 460fdd427cf7ee97dfa02f20174b6d941a09c6db (diff) | |
parent | c4aad01cbbb69c916ef323693e1fd0560b0eccba (diff) | |
download | frameworks_base-bd0dc13cb870e4dc0c3dfbbeba83a9e03ab481e9.zip frameworks_base-bd0dc13cb870e4dc0c3dfbbeba83a9e03ab481e9.tar.gz frameworks_base-bd0dc13cb870e4dc0c3dfbbeba83a9e03ab481e9.tar.bz2 |
Merge "Formalize overscan metrics."
16 files changed, 335 insertions, 162 deletions
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java index 9dc77b9..71d8fb6 100644 --- a/core/java/android/service/wallpaper/WallpaperService.java +++ b/core/java/android/service/wallpaper/WallpaperService.java @@ -153,6 +153,7 @@ public abstract class WallpaperService extends Service { int mCurWindowPrivateFlags = mWindowPrivateFlags; final Rect mVisibleInsets = new Rect(); final Rect mWinFrame = new Rect(); + final Rect mOverscanInsets = new Rect(); final Rect mContentInsets = new Rect(); final Configuration mConfiguration = new Configuration(); @@ -252,7 +253,7 @@ public abstract class WallpaperService extends Service { final BaseIWindow mWindow = new BaseIWindow() { @Override - public void resized(Rect frame, Rect contentInsets, + public void resized(Rect frame, Rect overscanInsets, Rect contentInsets, Rect visibleInsets, boolean reportDraw, Configuration newConfig) { Message msg = mCaller.obtainMessageI(MSG_WINDOW_RESIZED, reportDraw ? 1 : 0); @@ -627,7 +628,7 @@ public abstract class WallpaperService extends Service { final int relayoutResult = mSession.relayout( mWindow, mWindow.mSeq, mLayout, mWidth, mHeight, - View.VISIBLE, 0, mWinFrame, mContentInsets, + View.VISIBLE, 0, mWinFrame, mOverscanInsets, mContentInsets, mVisibleInsets, mConfiguration, mSurfaceHolder.mSurface); if (DEBUG) Log.v(TAG, "New surface: " + mSurfaceHolder.mSurface diff --git a/core/java/android/view/IWindow.aidl b/core/java/android/view/IWindow.aidl index 15bd46c..8ec07ef 100644 --- a/core/java/android/view/IWindow.aidl +++ b/core/java/android/view/IWindow.aidl @@ -45,7 +45,7 @@ oneway interface IWindow { */ void executeCommand(String command, String parameters, in ParcelFileDescriptor descriptor); - void resized(in Rect frame, in Rect contentInsets, + void resized(in Rect frame, in Rect overscanInsets, in Rect contentInsets, in Rect visibleInsets, boolean reportDraw, in Configuration newConfig); void moved(int newX, int newY); void dispatchAppVisibility(boolean visible); diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl index ff9dcce..0a8e609 100644 --- a/core/java/android/view/IWindowSession.aidl +++ b/core/java/android/view/IWindowSession.aidl @@ -63,6 +63,9 @@ interface IWindowSession { * {@link WindowManagerGlobal#RELAYOUT_DEFER_SURFACE_DESTROY}. * @param outFrame Rect in which is placed the new position/size on * screen. + * @param outOverscanInsets Rect in which is placed the offsets from + * <var>outFrame</var> in which the content of the window are inside + * of the display's overlay region. * @param outContentInsets Rect in which is placed the offsets from * <var>outFrame</var> in which the content of the window should be * placed. This can be used to modify the window layout to ensure its @@ -84,7 +87,7 @@ interface IWindowSession { */ int relayout(IWindow window, int seq, in WindowManager.LayoutParams attrs, int requestedWidth, int requestedHeight, int viewVisibility, - int flags, out Rect outFrame, + int flags, out Rect outFrame, out Rect outOverscanInsets, out Rect outContentInsets, out Rect outVisibleInsets, out Configuration outConfig, out Surface outSurface); diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java index 9008521..5d0f523 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -103,6 +103,7 @@ public class SurfaceView extends View { MyWindow mWindow; final Rect mVisibleInsets = new Rect(); final Rect mWinFrame = new Rect(); + final Rect mOverscanInsets = new Rect(); final Rect mContentInsets = new Rect(); final Configuration mConfiguration = new Configuration(); @@ -507,7 +508,7 @@ public class SurfaceView extends View { mWindow, mWindow.mSeq, mLayout, mWidth, mHeight, visible ? VISIBLE : GONE, WindowManagerGlobal.RELAYOUT_DEFER_SURFACE_DESTROY, - mWinFrame, mContentInsets, + mWinFrame, mOverscanInsets, mContentInsets, mVisibleInsets, mConfiguration, mNewSurface); if ((relayoutResult & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0) { mReportDrawNeeded = true; @@ -642,7 +643,7 @@ public class SurfaceView extends View { } @Override - public void resized(Rect frame, Rect contentInsets, + public void resized(Rect frame, Rect overscanInsets, Rect contentInsets, Rect visibleInsets, boolean reportDraw, Configuration newConfig) { SurfaceView surfaceView = mSurfaceView.get(); if (surfaceView != null) { diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index dcf51e4..ab8f934 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -5679,20 +5679,45 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if ((mViewFlags & FITS_SYSTEM_WINDOWS) == FITS_SYSTEM_WINDOWS) { mUserPaddingStart = UNDEFINED_PADDING; mUserPaddingEnd = UNDEFINED_PADDING; - if ((mViewFlags & OPTIONAL_FITS_SYSTEM_WINDOWS) == 0 - || mAttachInfo == null - || (mAttachInfo.mSystemUiVisibility & SYSTEM_UI_LAYOUT_FLAGS) == 0) { - internalSetPadding(insets.left, insets.top, insets.right, insets.bottom); - return true; - } else { - internalSetPadding(0, 0, 0, 0); - return false; + Rect localInsets = sThreadLocal.get(); + if (localInsets == null) { + localInsets = new Rect(); + sThreadLocal.set(localInsets); } + boolean res = computeFitSystemWindows(insets, localInsets); + internalSetPadding(localInsets.left, localInsets.top, + localInsets.right, localInsets.bottom); + return res; } return false; } /** + * @hide Compute the insets that should be consumed by this view and the ones + * that should propagate to those under it. + */ + protected boolean computeFitSystemWindows(Rect inoutInsets, Rect outLocalInsets) { + if ((mViewFlags & OPTIONAL_FITS_SYSTEM_WINDOWS) == 0 + || mAttachInfo == null + || ((mAttachInfo.mSystemUiVisibility & SYSTEM_UI_LAYOUT_FLAGS) == 0 + && !mAttachInfo.mOverscanRequested)) { + outLocalInsets.set(inoutInsets); + inoutInsets.set(0, 0, 0, 0); + return true; + } else { + // The application wants to take care of fitting system window for + // the content... however we still need to take care of any overscan here. + final Rect overscan = mAttachInfo.mOverscanInsets; + outLocalInsets.set(overscan); + inoutInsets.left -= overscan.left; + inoutInsets.top -= overscan.top; + inoutInsets.right -= overscan.right; + inoutInsets.bottom -= overscan.bottom; + return false; + } + } + + /** * Sets whether or not this view should account for system screen decorations * such as the status bar and inset its content; that is, controlling whether * the default implementation of {@link #fitSystemWindows(Rect)} will be @@ -17919,6 +17944,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback, /** * For windows that are full-screen but using insets to layout inside + * of the screen areas, these are the current insets to appear inside + * the overscan area of the display. + */ + final Rect mOverscanInsets = new Rect(); + + /** + * For windows that are full-screen but using insets to layout inside * of the screen decorations, these are the current insets for the * content of the window. */ @@ -18020,6 +18052,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback, boolean mHasSystemUiListeners; /** + * Set if the window has requested to extend into the overscan region + * via WindowManager.LayoutParams.FLAG_LAYOUT_IN_OVERSCAN. + */ + boolean mOverscanRequested; + + /** * Set if the visibility of any views has changed. */ boolean mViewVisibilityChanged; diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 9b6dafb..b8fae86 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -229,6 +229,7 @@ public final class ViewRootImpl implements ViewParent, boolean mIsDrawing; int mLastSystemUiVisibility; int mClientWindowLayoutFlags; + boolean mLastOverscanRequested; /** @hide */ public static final int EVENT_NOT_HANDLED = 0; @@ -262,6 +263,7 @@ public final class ViewRootImpl implements ViewParent, // These are accessed by multiple threads. final Rect mWinFrame; // frame given by window manager. + final Rect mPendingOverscanInsets = new Rect(); final Rect mPendingVisibleInsets = new Rect(); final Rect mPendingContentInsets = new Rect(); final ViewTreeObserver.InternalInsetsInfo mLastGivenInsets @@ -566,6 +568,7 @@ public final class ViewRootImpl implements ViewParent, if (mTranslator != null) { mTranslator.translateRectInScreenToAppWindow(mAttachInfo.mContentInsets); } + mPendingOverscanInsets.set(0, 0, 0, 0); mPendingContentInsets.set(mAttachInfo.mContentInsets); mPendingVisibleInsets.set(0, 0, 0, 0); if (DEBUG_LAYOUT) Log.v(TAG, "Added window " + mWindow); @@ -1255,6 +1258,9 @@ public final class ViewRootImpl implements ViewParent, mAttachInfo.mInTouchMode = !mAddedTouchMode; ensureTouchModeLocally(mAddedTouchMode); } else { + if (!mPendingOverscanInsets.equals(mAttachInfo.mOverscanInsets)) { + insetsChanged = true; + } if (!mPendingContentInsets.equals(mAttachInfo.mContentInsets)) { insetsChanged = true; } @@ -1320,15 +1326,20 @@ public final class ViewRootImpl implements ViewParent, } } - if (params != null && (host.mPrivateFlags & View.PFLAG_REQUEST_TRANSPARENT_REGIONS) != 0) { - if (!PixelFormat.formatHasAlpha(params.format)) { - params.format = PixelFormat.TRANSLUCENT; + if (params != null) { + if ((host.mPrivateFlags & View.PFLAG_REQUEST_TRANSPARENT_REGIONS) != 0) { + if (!PixelFormat.formatHasAlpha(params.format)) { + params.format = PixelFormat.TRANSLUCENT; + } } + mAttachInfo.mOverscanRequested = (params.flags + & WindowManager.LayoutParams.FLAG_LAYOUT_IN_OVERSCAN) != 0; } if (mFitSystemWindowsRequested) { mFitSystemWindowsRequested = false; mFitSystemWindowsInsets.set(mAttachInfo.mContentInsets); + mLastOverscanRequested = mAttachInfo.mOverscanRequested; host.fitSystemWindows(mFitSystemWindowsInsets); if (mLayoutRequested) { // Short-circuit catching a new layout request here, so @@ -1383,7 +1394,6 @@ public final class ViewRootImpl implements ViewParent, boolean hwInitialized = false; boolean contentInsetsChanged = false; - boolean visibleInsetsChanged; boolean hadSurface = mSurface.isValid(); try { @@ -1396,6 +1406,7 @@ public final class ViewRootImpl implements ViewParent, relayoutResult = relayoutWindow(params, viewVisibility, insetsPending); if (DEBUG_LAYOUT) Log.v(TAG, "relayout: frame=" + frame.toShortString() + + " overscan=" + mPendingOverscanInsets.toShortString() + " content=" + mPendingContentInsets.toShortString() + " visible=" + mPendingVisibleInsets.toShortString() + " surface=" + mSurface); @@ -1407,9 +1418,11 @@ public final class ViewRootImpl implements ViewParent, mPendingConfiguration.seq = 0; } + final boolean overscanInsetsChanged = !mPendingOverscanInsets.equals( + mAttachInfo.mOverscanInsets); contentInsetsChanged = !mPendingContentInsets.equals( mAttachInfo.mContentInsets); - visibleInsetsChanged = !mPendingVisibleInsets.equals( + final boolean visibleInsetsChanged = !mPendingVisibleInsets.equals( mAttachInfo.mVisibleInsets); if (contentInsetsChanged) { if (mWidth > 0 && mHeight > 0 && lp != null && @@ -1486,9 +1499,18 @@ public final class ViewRootImpl implements ViewParent, if (DEBUG_LAYOUT) Log.v(TAG, "Content insets changing to: " + mAttachInfo.mContentInsets); } + if (overscanInsetsChanged) { + mAttachInfo.mOverscanInsets.set(mPendingOverscanInsets); + if (DEBUG_LAYOUT) Log.v(TAG, "Overscan insets changing to: " + + mAttachInfo.mOverscanInsets); + // Need to relayout with content insets. + contentInsetsChanged = true; + } if (contentInsetsChanged || mLastSystemUiVisibility != - mAttachInfo.mSystemUiVisibility || mFitSystemWindowsRequested) { + mAttachInfo.mSystemUiVisibility || mFitSystemWindowsRequested + || mLastOverscanRequested != mAttachInfo.mOverscanRequested) { mLastSystemUiVisibility = mAttachInfo.mSystemUiVisibility; + mLastOverscanRequested = mAttachInfo.mOverscanRequested; mFitSystemWindowsRequested = false; mFitSystemWindowsInsets.set(mAttachInfo.mContentInsets); host.fitSystemWindows(mFitSystemWindowsInsets); @@ -2942,6 +2964,7 @@ public final class ViewRootImpl implements ViewParent, // Recycled in the fall through... SomeArgs args = (SomeArgs) msg.obj; if (mWinFrame.equals(args.arg1) + && mPendingOverscanInsets.equals(args.arg5) && mPendingContentInsets.equals(args.arg2) && mPendingVisibleInsets.equals(args.arg3) && args.arg4 == null) { @@ -2958,6 +2981,7 @@ public final class ViewRootImpl implements ViewParent, } mWinFrame.set((Rect) args.arg1); + mPendingOverscanInsets.set((Rect) args.arg5); mPendingContentInsets.set((Rect) args.arg2); mPendingVisibleInsets.set((Rect) args.arg3); @@ -4031,7 +4055,7 @@ 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, - mWinFrame, mPendingContentInsets, mPendingVisibleInsets, + mWinFrame, mPendingOverscanInsets, mPendingContentInsets, mPendingVisibleInsets, mPendingConfiguration, mSurface); //Log.d(TAG, "<<<<<< BACK FROM relayout"); if (restore) { @@ -4040,6 +4064,7 @@ public final class ViewRootImpl implements ViewParent, if (mTranslator != null) { mTranslator.translateRectInScreenToAppWinFrame(mWinFrame); + mTranslator.translateRectInScreenToAppWindow(mPendingOverscanInsets); mTranslator.translateRectInScreenToAppWindow(mPendingContentInsets); mTranslator.translateRectInScreenToAppWindow(mPendingVisibleInsets); } @@ -4245,7 +4270,7 @@ public final class ViewRootImpl implements ViewParent, mHandler.sendMessage(msg); } - public void dispatchResized(Rect frame, Rect contentInsets, + public void dispatchResized(Rect frame, Rect overscanInsets, Rect contentInsets, Rect visibleInsets, boolean reportDraw, Configuration newConfig) { if (DEBUG_LAYOUT) Log.v(TAG, "Resizing " + this + ": frame=" + frame.toShortString() + " contentInsets=" + contentInsets.toShortString() @@ -4254,6 +4279,7 @@ public final class ViewRootImpl implements ViewParent, Message msg = mHandler.obtainMessage(reportDraw ? MSG_RESIZED_REPORT : MSG_RESIZED); if (mTranslator != null) { mTranslator.translateRectInScreenToAppWindow(frame); + mTranslator.translateRectInScreenToAppWindow(overscanInsets); mTranslator.translateRectInScreenToAppWindow(contentInsets); mTranslator.translateRectInScreenToAppWindow(visibleInsets); } @@ -4263,6 +4289,7 @@ public final class ViewRootImpl implements ViewParent, args.arg2 = sameProcessCall ? new Rect(contentInsets) : contentInsets; args.arg3 = sameProcessCall ? new Rect(visibleInsets) : visibleInsets; args.arg4 = sameProcessCall && newConfig != null ? new Configuration(newConfig) : newConfig; + args.arg5 = sameProcessCall ? new Rect(overscanInsets) : overscanInsets; msg.obj = args; mHandler.sendMessage(msg); } @@ -4997,11 +5024,11 @@ public final class ViewRootImpl implements ViewParent, mWindowSession = viewAncestor.mWindowSession; } - public void resized(Rect frame, Rect contentInsets, + public void resized(Rect frame, Rect overscanInsets, Rect contentInsets, Rect visibleInsets, boolean reportDraw, Configuration newConfig) { final ViewRootImpl viewAncestor = mViewAncestor.get(); if (viewAncestor != null) { - viewAncestor.dispatchResized(frame, contentInsets, + viewAncestor.dispatchResized(frame, overscanInsets, contentInsets, visibleInsets, reportDraw, newConfig); } } diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java index 60779ce..c0044b6 100644 --- a/core/java/android/view/WindowManagerPolicy.java +++ b/core/java/android/view/WindowManagerPolicy.java @@ -154,6 +154,8 @@ public interface WindowManagerPolicy { * @param displayFrame The frame of the overall display in which this * window can appear, used for constraining the overall dimensions * of the window. + * @param overlayFrame The frame within the display that is inside + * of the overlay region. * @param contentFrame The frame within the display in which we would * like active content to appear. This will cause windows behind to * be resized to match the given content frame. @@ -165,7 +167,7 @@ public interface WindowManagerPolicy { * are visible. */ public void computeFrameLw(Rect parentFrame, Rect displayFrame, - Rect contentFrame, Rect visibleFrame); + Rect overlayFrame, Rect contentFrame, Rect visibleFrame); /** * Retrieve the current frame of the window that has been assigned by @@ -193,6 +195,15 @@ public interface WindowManagerPolicy { public Rect getDisplayFrameLw(); /** + * Retrieve the frame of the area inside the overscan region of the + * display that this window was last laid out in. Must be called with the + * window manager lock held. + * + * @return Rect The rectangle holding the display overscan frame. + */ + public Rect getOverscanFrameLw(); + + /** * Retrieve the frame of the content area that this window was last * laid out in. This is the area in which the content of the window * should be placed. It will be smaller than the display frame to diff --git a/core/java/com/android/internal/os/SomeArgs.java b/core/java/com/android/internal/os/SomeArgs.java index 88e58dc..6fb72f1 100644 --- a/core/java/com/android/internal/os/SomeArgs.java +++ b/core/java/com/android/internal/os/SomeArgs.java @@ -39,6 +39,7 @@ public final class SomeArgs { public Object arg2; public Object arg3; public Object arg4; + public Object arg5; public int argi1; public int argi2; public int argi3; @@ -85,6 +86,7 @@ public final class SomeArgs { arg2 = null; arg3 = null; arg4 = null; + arg5 = null; argi1 = 0; argi2 = 0; argi3 = 0; diff --git a/core/java/com/android/internal/view/BaseIWindow.java b/core/java/com/android/internal/view/BaseIWindow.java index b76e89d..02bd4ac 100644 --- a/core/java/com/android/internal/view/BaseIWindow.java +++ b/core/java/com/android/internal/view/BaseIWindow.java @@ -34,7 +34,7 @@ public class BaseIWindow extends IWindow.Stub { } @Override - public void resized(Rect frame, Rect contentInsets, + public void resized(Rect frame, Rect overscanInsets, Rect contentInsets, Rect visibleInsets, boolean reportDraw, Configuration newConfig) { if (reportDraw) { try { diff --git a/core/java/com/android/internal/widget/ActionBarOverlayLayout.java b/core/java/com/android/internal/widget/ActionBarOverlayLayout.java index a129496..18a696e 100644 --- a/core/java/com/android/internal/widget/ActionBarOverlayLayout.java +++ b/core/java/com/android/internal/widget/ActionBarOverlayLayout.java @@ -41,7 +41,7 @@ public class ActionBarOverlayLayout extends FrameLayout { private ActionBarView mActionView; private View mActionBarBottom; private int mLastSystemUiVisibility; - private final Rect mZeroRect = new Rect(0, 0, 0, 0); + private final Rect mLocalInsets = new Rect(); static final int[] mActionBarSizeAttr = new int [] { com.android.internal.R.attr.actionBarSize @@ -165,13 +165,8 @@ public class ActionBarOverlayLayout extends FrameLayout { // make sure its content is not being covered by system UI... though it // will still be covered by the action bar since they have requested it to // overlay. - if ((vis & SYSTEM_UI_LAYOUT_FLAGS) == 0) { - changed |= applyInsets(mContent, insets, true, true, true, true); - // The insets are now consumed. - insets.set(0, 0, 0, 0); - } else { - changed |= applyInsets(mContent, mZeroRect, true, true, true, true); - } + boolean res = computeFitSystemWindows(insets, mLocalInsets); + changed |= applyInsets(mContent, mLocalInsets, true, true, true, true); if (stable || mActionBarTop.getVisibility() == VISIBLE) { @@ -190,7 +185,7 @@ public class ActionBarOverlayLayout extends FrameLayout { if (mActionView.isSplitActionBar()) { if (stable || (mActionBarBottom != null && mActionBarBottom.getVisibility() == VISIBLE)) { - // If action bar is split, adjust buttom insets for it. + // If action bar is split, adjust bottom insets for it. insets.bottom += mActionBarHeight; } } @@ -199,7 +194,8 @@ public class ActionBarOverlayLayout extends FrameLayout { requestLayout(); } - return super.fitSystemWindows(insets); + super.fitSystemWindows(insets); + return true; } void pullChildren() { diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java index 7b4d3d0..0e545c6 100644 --- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java @@ -361,6 +361,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { static final Rect mTmpParentFrame = new Rect(); static final Rect mTmpDisplayFrame = new Rect(); + static final Rect mTmpOverscanFrame = new Rect(); static final Rect mTmpContentFrame = new Rect(); static final Rect mTmpVisibleFrame = new Rect(); static final Rect mTmpNavigationFrame = new Rect(); @@ -2493,11 +2494,12 @@ public class PhoneWindowManager implements WindowManagerPolicy { // start with the current dock rect, which will be (0,0,displayWidth,displayHeight) final Rect pf = mTmpParentFrame; final Rect df = mTmpDisplayFrame; + final Rect of = mTmpOverscanFrame; final Rect vf = mTmpVisibleFrame; - pf.left = df.left = vf.left = mDockLeft; - pf.top = df.top = vf.top = mDockTop; - pf.right = df.right = vf.right = mDockRight; - pf.bottom = df.bottom = vf.bottom = mDockBottom; + pf.left = df.left = of.left = vf.left = mDockLeft; + pf.top = df.top = of.top = vf.top = mDockTop; + pf.right = df.right = of.right = vf.right = mDockRight; + pf.bottom = df.bottom = of.bottom = vf.bottom = mDockBottom; if (isDefaultDisplay) { // For purposes of putting out fake window up to steal focus, we will @@ -2583,7 +2585,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { mStatusBarLayer = mNavigationBar.getSurfaceLayer(); // And compute the final frame. mNavigationBar.computeFrameLw(mTmpNavigationFrame, mTmpNavigationFrame, - mTmpNavigationFrame, mTmpNavigationFrame); + mTmpNavigationFrame, mTmpNavigationFrame, mTmpNavigationFrame); if (DEBUG_LAYOUT) Log.i(TAG, "mNavigationBar frame: " + mTmpNavigationFrame); } if (DEBUG_LAYOUT) Log.i(TAG, String.format("mDock rect: (%d,%d - %d,%d)", @@ -2592,10 +2594,11 @@ public class PhoneWindowManager implements WindowManagerPolicy { // decide where the status bar goes ahead of time if (mStatusBar != null) { // apply any navigation bar insets - pf.left = df.left = mUnrestrictedScreenLeft; - pf.top = df.top = mUnrestrictedScreenTop; - pf.right = df.right = mUnrestrictedScreenWidth + mUnrestrictedScreenLeft; - pf.bottom = df.bottom = mUnrestrictedScreenHeight + mUnrestrictedScreenTop; + pf.left = df.left = of.left = mUnrestrictedScreenLeft; + pf.top = df.top = of.top = mUnrestrictedScreenTop; + pf.right = df.right = of.right = mUnrestrictedScreenWidth + mUnrestrictedScreenLeft; + pf.bottom = df.bottom = of.bottom = mUnrestrictedScreenHeight + + mUnrestrictedScreenTop; vf.left = mStableLeft; vf.top = mStableTop; vf.right = mStableRight; @@ -2604,7 +2607,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { mStatusBarLayer = mStatusBar.getSurfaceLayer(); // Let the status bar determine its size. - mStatusBar.computeFrameLw(pf, df, vf, vf); + mStatusBar.computeFrameLw(pf, df, vf, vf, vf); // For layout, the status bar is always at the top with our fixed height. mStableTop = mUnrestrictedScreenTop + mStatusBarHeight; @@ -2650,8 +2653,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { return 0; } - void setAttachedWindowFrames(WindowState win, int fl, int adjust, - WindowState attached, boolean insetDecors, Rect pf, Rect df, Rect cf, Rect vf) { + void setAttachedWindowFrames(WindowState win, int fl, int adjust, WindowState attached, + boolean insetDecors, Rect pf, Rect df, Rect of, Rect cf, Rect vf) { if (win.getSurfaceLayer() > mDockLayer && attached.getSurfaceLayer() < mDockLayer) { // Here's a special case: if this attached window is a panel that is // above the dock window, and the window it is attached to is below @@ -2660,10 +2663,10 @@ public class PhoneWindowManager implements WindowManagerPolicy { // of the underlying window and the attached window is floating on top // of the whole thing. So, we ignore the attached window and explicitly // compute the frames that would be appropriate without the dock. - df.left = cf.left = vf.left = mDockLeft; - df.top = cf.top = vf.top = mDockTop; - df.right = cf.right = vf.right = mDockRight; - df.bottom = cf.bottom = vf.bottom = mDockBottom; + df.left = of.left = cf.left = vf.left = mDockLeft; + df.top = of.top = cf.top = vf.top = mDockTop; + df.right = of.right = cf.right = vf.right = mDockRight; + df.bottom = of.bottom = cf.bottom = vf.bottom = mDockBottom; } else { // The effective display frame of the attached window depends on // whether it is taking care of insetting its content. If not, @@ -2672,7 +2675,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { // the display frame and let the attached window take care of // positioning its content appropriately. if (adjust != SOFT_INPUT_ADJUST_RESIZE) { - cf.set(attached.getDisplayFrameLw()); + cf.set(attached.getOverscanFrameLw()); } else { // If the window is resizing, then we want to base the content // frame on our attached content frame to resize... however, @@ -2689,6 +2692,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { } } df.set(insetDecors ? attached.getDisplayFrameLw() : cf); + of.set(insetDecors ? attached.getOverscanFrameLw() : cf); vf.set(attached.getVisibleFrameLw()); } // The LAYOUT_IN_SCREEN flag is used to determine whether the attached @@ -2740,6 +2744,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { final Rect pf = mTmpParentFrame; final Rect df = mTmpDisplayFrame; + final Rect of = mTmpOverscanFrame; final Rect cf = mTmpContentFrame; final Rect vf = mTmpVisibleFrame; @@ -2752,31 +2757,30 @@ public class PhoneWindowManager implements WindowManagerPolicy { if (attached != null) { // If this window is attached to another, our display // frame is the same as the one we are attached to. - setAttachedWindowFrames(win, fl, adjust, attached, true, pf, df, cf, vf); + setAttachedWindowFrames(win, fl, adjust, attached, true, pf, df, of, cf, vf); } else { // Give the window full screen. - pf.left = df.left = cf.left = mOverscanScreenLeft; - pf.top = df.top = cf.top = mOverscanScreenTop; - pf.right = df.right = cf.right + pf.left = df.left = of.left = cf.left = mOverscanScreenLeft; + pf.top = df.top = of.top = cf.top = mOverscanScreenTop; + pf.right = df.right = of.right = cf.right = mOverscanScreenLeft + mOverscanScreenWidth; - pf.bottom = df.bottom = cf.bottom + pf.bottom = df.bottom = of.bottom = cf.bottom = mOverscanScreenTop + mOverscanScreenHeight; } } else if (attrs.type == TYPE_INPUT_METHOD) { - pf.left = df.left = cf.left = vf.left = mDockLeft; - pf.top = df.top = cf.top = vf.top = mDockTop; - pf.right = df.right = cf.right = vf.right = mDockRight; - pf.bottom = df.bottom = cf.bottom = vf.bottom = mDockBottom; + pf.left = df.left = of.left = cf.left = vf.left = mDockLeft; + pf.top = df.top = of.top = cf.top = vf.top = mDockTop; + pf.right = df.right = of.right = cf.right = vf.right = mDockRight; + pf.bottom = df.bottom = of.bottom = cf.bottom = vf.bottom = mDockBottom; // IM dock windows always go to the bottom of the screen. attrs.gravity = Gravity.BOTTOM; mDockLayer = win.getSurfaceLayer(); } else { - if ((fl & (FLAG_LAYOUT_IN_SCREEN | FLAG_FULLSCREEN | FLAG_LAYOUT_INSET_DECOR)) - == (FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR) - && (sysUiFl & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) { + if ((fl & (FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR)) + == (FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR)) { if (DEBUG_LAYOUT) Log.v(TAG, "layoutWindowLw(" + attrs.getTitle() - + "): IN_SCREEN, INSET_DECOR, !FULLSCREEN"); + + "): IN_SCREEN, INSET_DECOR"); // This is the case for a normal activity window: we want it // to cover all of the screen space, and it can take care of // moving its contents to account for screen decorations that @@ -2784,7 +2788,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { if (attached != null) { // If this window is attached to another, our display // frame is the same as the one we are attached to. - setAttachedWindowFrames(win, fl, adjust, attached, true, pf, df, cf, vf); + setAttachedWindowFrames(win, fl, adjust, attached, true, pf, df, of, cf, vf); } else { if (attrs.type == TYPE_STATUS_BAR_PANEL || attrs.type == TYPE_STATUS_BAR_SUB_PANEL) { @@ -2795,14 +2799,15 @@ public class PhoneWindowManager implements WindowManagerPolicy { // // However, they should still dodge the navigation bar if it exists. - pf.left = df.left = hasNavBar ? mDockLeft : mUnrestrictedScreenLeft; - pf.top = df.top = mUnrestrictedScreenTop; - pf.right = df.right = hasNavBar - ? mRestrictedScreenLeft+mRestrictedScreenWidth - : mUnrestrictedScreenLeft + mUnrestrictedScreenWidth; - pf.bottom = df.bottom = hasNavBar - ? mRestrictedScreenTop+mRestrictedScreenHeight - : mUnrestrictedScreenTop + mUnrestrictedScreenHeight; + pf.left = df.left = of.left = hasNavBar + ? mDockLeft : mUnrestrictedScreenLeft; + pf.top = df.top = of.top = mUnrestrictedScreenTop; + pf.right = df.right = of.right = hasNavBar + ? mRestrictedScreenLeft+mRestrictedScreenWidth + : mUnrestrictedScreenLeft + mUnrestrictedScreenWidth; + pf.bottom = df.bottom = of.bottom = hasNavBar + ? mRestrictedScreenTop+mRestrictedScreenHeight + : mUnrestrictedScreenTop + mUnrestrictedScreenHeight; if (DEBUG_LAYOUT) { Log.v(TAG, String.format( @@ -2814,10 +2819,11 @@ public class PhoneWindowManager implements WindowManagerPolicy { && attrs.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) { // Asking to layout into the overscan region, so give it that pure // unrestricted area. - pf.left = df.left = mOverscanScreenLeft; - pf.top = df.top = mOverscanScreenTop; - pf.right = df.right = mOverscanScreenLeft + mOverscanScreenWidth; - pf.bottom = df.bottom = mOverscanScreenTop + mOverscanScreenHeight; + pf.left = df.left = of.left = mOverscanScreenLeft; + pf.top = df.top = of.top = mOverscanScreenTop; + pf.right = df.right = of.right = mOverscanScreenLeft + mOverscanScreenWidth; + pf.bottom = df.bottom = of.bottom = mOverscanScreenTop + + mOverscanScreenHeight; } else if (mCanHideNavigationBar && (sysUiFl & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0 && attrs.type >= WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW @@ -2830,6 +2836,13 @@ public class PhoneWindowManager implements WindowManagerPolicy { pf.top = df.top = mOverscanScreenTop; pf.right = df.right = mOverscanScreenLeft + mOverscanScreenWidth; pf.bottom = df.bottom = mOverscanScreenTop + mOverscanScreenHeight; + // We need to tell the app about where the frame inside the overscan + // is, so it can inset its content by that amount -- it didn't ask + // to actually extend itself into the overscan region. + of.left = mUnrestrictedScreenLeft; + of.top = mUnrestrictedScreenTop; + of.right = mUnrestrictedScreenLeft + mUnrestrictedScreenWidth; + of.bottom = mUnrestrictedScreenTop + mUnrestrictedScreenHeight; } else { pf.left = df.left = mRestrictedOverscanScreenLeft; pf.top = df.top = mRestrictedOverscanScreenTop; @@ -2837,18 +2850,36 @@ public class PhoneWindowManager implements WindowManagerPolicy { + mRestrictedOverscanScreenWidth; pf.bottom = df.bottom = mRestrictedOverscanScreenTop + mRestrictedOverscanScreenHeight; + // We need to tell the app about where the frame inside the overscan + // is, so it can inset its content by that amount -- it didn't ask + // to actually extend itself into the overscan region. + of.left = mUnrestrictedScreenLeft; + of.top = mUnrestrictedScreenTop; + of.right = mUnrestrictedScreenLeft + mUnrestrictedScreenWidth; + of.bottom = mUnrestrictedScreenTop + mUnrestrictedScreenHeight; } - if (adjust != SOFT_INPUT_ADJUST_RESIZE) { - cf.left = mDockLeft; - cf.top = mDockTop; - cf.right = mDockRight; - cf.bottom = mDockBottom; + if ((attrs.flags&FLAG_FULLSCREEN) == 0) { + if (adjust != SOFT_INPUT_ADJUST_RESIZE) { + cf.left = mDockLeft; + cf.top = mDockTop; + cf.right = mDockRight; + cf.bottom = mDockBottom; + } else { + cf.left = mContentLeft; + cf.top = mContentTop; + cf.right = mContentRight; + cf.bottom = mContentBottom; + } } else { - cf.left = mContentLeft; - cf.top = mContentTop; - cf.right = mContentRight; - cf.bottom = mContentBottom; + // Full screen windows are always given a layout that is as if the + // status bar and other transient decors are gone. This is to avoid + // bad states when moving from a window that is not hding the + // status bar to one that is. + cf.left = mRestrictedScreenLeft; + cf.top = mRestrictedScreenTop; + cf.right = mRestrictedScreenLeft + mRestrictedScreenWidth; + cf.bottom = mRestrictedScreenTop + mRestrictedScreenHeight; } applyStableConstraints(sysUiFl, fl, cf); @@ -2870,12 +2901,13 @@ public class PhoneWindowManager implements WindowManagerPolicy { // gets everything, period. if (attrs.type == TYPE_STATUS_BAR_PANEL || attrs.type == TYPE_STATUS_BAR_SUB_PANEL) { - pf.left = df.left = cf.left = hasNavBar ? mDockLeft : mUnrestrictedScreenLeft; - pf.top = df.top = cf.top = mUnrestrictedScreenTop; - pf.right = df.right = cf.right = hasNavBar + pf.left = df.left = of.left = cf.left = hasNavBar + ? mDockLeft : mUnrestrictedScreenLeft; + pf.top = df.top = of.top = cf.top = mUnrestrictedScreenTop; + pf.right = df.right = of.right = cf.right = hasNavBar ? mRestrictedScreenLeft+mRestrictedScreenWidth : mUnrestrictedScreenLeft + mUnrestrictedScreenWidth; - pf.bottom = df.bottom = cf.bottom = hasNavBar + pf.bottom = df.bottom = of.bottom = cf.bottom = hasNavBar ? mRestrictedScreenTop+mRestrictedScreenHeight : mUnrestrictedScreenTop + mUnrestrictedScreenHeight; if (DEBUG_LAYOUT) { @@ -2886,10 +2918,12 @@ public class PhoneWindowManager implements WindowManagerPolicy { } else if (attrs.type == TYPE_NAVIGATION_BAR || attrs.type == TYPE_NAVIGATION_BAR_PANEL) { // The navigation bar has Real Ultimate Power. - pf.left = df.left = mUnrestrictedScreenLeft; - pf.top = df.top = mUnrestrictedScreenTop; - pf.right = df.right = mUnrestrictedScreenLeft + mUnrestrictedScreenWidth; - pf.bottom = df.bottom = mUnrestrictedScreenTop + mUnrestrictedScreenHeight; + pf.left = df.left = of.left = mUnrestrictedScreenLeft; + pf.top = df.top = of.top = mUnrestrictedScreenTop; + pf.right = df.right = of.right = mUnrestrictedScreenLeft + + mUnrestrictedScreenWidth; + pf.bottom = df.bottom = of.bottom = mUnrestrictedScreenTop + + mUnrestrictedScreenHeight; if (DEBUG_LAYOUT) { Log.v(TAG, String.format( "Laying out navigation bar window: (%d,%d - %d,%d)", @@ -2899,36 +2933,39 @@ public class PhoneWindowManager implements WindowManagerPolicy { || attrs.type == TYPE_BOOT_PROGRESS) && ((fl & FLAG_FULLSCREEN) != 0)) { // Fullscreen secure system overlays get what they ask for. - pf.left = df.left = mOverscanScreenLeft; - pf.top = df.top = mOverscanScreenTop; - pf.right = df.right = mOverscanScreenLeft + mOverscanScreenWidth; - pf.bottom = df.bottom = mOverscanScreenTop + mOverscanScreenHeight; + pf.left = df.left = of.left = cf.left = mOverscanScreenLeft; + pf.top = df.top = of.top = cf.top = mOverscanScreenTop; + pf.right = df.right = of.right = cf.right = mOverscanScreenLeft + + mOverscanScreenWidth; + pf.bottom = df.bottom = of.bottom = cf.bottom = mOverscanScreenTop + + mOverscanScreenHeight; } else if (attrs.type == TYPE_BOOT_PROGRESS || attrs.type == TYPE_UNIVERSE_BACKGROUND) { // Boot progress screen always covers entire display. - pf.left = df.left = cf.left = mOverscanScreenLeft; - pf.top = df.top = cf.top = mOverscanScreenTop; - pf.right = df.right = cf.right = mOverscanScreenLeft + mOverscanScreenWidth; - pf.bottom = df.bottom = cf.bottom - = mOverscanScreenTop + mOverscanScreenHeight; + pf.left = df.left = of.left = cf.left = mOverscanScreenLeft; + pf.top = df.top = of.top = cf.top = mOverscanScreenTop; + pf.right = df.right = of.right = cf.right = mOverscanScreenLeft + + mOverscanScreenWidth; + pf.bottom = df.bottom = of.bottom = cf.bottom = mOverscanScreenTop + + mOverscanScreenHeight; } else if (attrs.type == WindowManager.LayoutParams.TYPE_WALLPAPER) { // The wallpaper mostly goes into the overscan region. - pf.left = df.left = cf.left = mRestrictedOverscanScreenLeft; - pf.top = df.top = cf.top = mRestrictedOverscanScreenTop; - pf.right = df.right = cf.right + pf.left = df.left = of.left = cf.left = mRestrictedOverscanScreenLeft; + pf.top = df.top = of.top = cf.top = mRestrictedOverscanScreenTop; + pf.right = df.right = of.right = cf.right = mRestrictedOverscanScreenLeft + mRestrictedOverscanScreenWidth; - pf.bottom = df.bottom = cf.bottom + pf.bottom = df.bottom = of.bottom = cf.bottom = mRestrictedOverscanScreenTop + mRestrictedOverscanScreenHeight; } else if ((attrs.flags & FLAG_LAYOUT_IN_OVERSCAN) != 0 && attrs.type >= WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW && attrs.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) { // Asking to layout into the overscan region, so give it that pure // unrestricted area. - pf.left = df.left = cf.left = mOverscanScreenLeft; - pf.top = df.top = cf.top = mOverscanScreenTop; - pf.right = df.right = cf.right + pf.left = df.left = of.left = cf.left = mOverscanScreenLeft; + pf.top = df.top = of.top = cf.top = mOverscanScreenTop; + pf.right = df.right = of.right = cf.right = mOverscanScreenLeft + mOverscanScreenWidth; - pf.bottom = df.bottom = cf.bottom + pf.bottom = df.bottom = of.bottom = cf.bottom = mOverscanScreenTop + mOverscanScreenHeight; } else if (mCanHideNavigationBar && (sysUiFl & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0 @@ -2941,17 +2978,19 @@ public class PhoneWindowManager implements WindowManagerPolicy { // XXX This assumes that an app asking for this will also // ask for layout in only content. We can't currently figure out // what the screen would be if only laying out to hide the nav bar. - pf.left = df.left = cf.left = mUnrestrictedScreenLeft; - pf.top = df.top = cf.top = mUnrestrictedScreenTop; - pf.right = df.right = cf.right = mUnrestrictedScreenLeft + mUnrestrictedScreenWidth; - pf.bottom = df.bottom = cf.bottom - = mUnrestrictedScreenTop + mUnrestrictedScreenHeight; + pf.left = df.left = of.left = cf.left = mUnrestrictedScreenLeft; + pf.top = df.top = of.top = cf.top = mUnrestrictedScreenTop; + pf.right = df.right = of.right = cf.right = mUnrestrictedScreenLeft + + mUnrestrictedScreenWidth; + pf.bottom = df.bottom = of.bottom = cf.bottom = mUnrestrictedScreenTop + + mUnrestrictedScreenHeight; } else { - pf.left = df.left = cf.left = mRestrictedScreenLeft; - pf.top = df.top = cf.top = mRestrictedScreenTop; - pf.right = df.right = cf.right = mRestrictedScreenLeft+mRestrictedScreenWidth; - pf.bottom = df.bottom = cf.bottom - = mRestrictedScreenTop+mRestrictedScreenHeight; + pf.left = df.left = of.left = cf.left = mRestrictedScreenLeft; + pf.top = df.top = of.top = cf.top = mRestrictedScreenTop; + pf.right = df.right = of.right = cf.right = mRestrictedScreenLeft + + mRestrictedScreenWidth; + pf.bottom = df.bottom = of.bottom = cf.bottom = mRestrictedScreenTop + + mRestrictedScreenHeight; } applyStableConstraints(sysUiFl, fl, cf); @@ -2969,7 +3008,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { Log.v(TAG, "layoutWindowLw(" + attrs.getTitle() + "): attached to " + attached); // A child window should be placed inside of the same visible // frame that its parent had. - setAttachedWindowFrames(win, fl, adjust, attached, false, pf, df, cf, vf); + setAttachedWindowFrames(win, fl, adjust, attached, false, pf, df, of, cf, vf); } else { if (DEBUG_LAYOUT) Log.v(TAG, "layoutWindowLw(" + attrs.getTitle() + "): normal window"); @@ -2980,26 +3019,27 @@ public class PhoneWindowManager implements WindowManagerPolicy { // the status bar. They are protected by the STATUS_BAR_SERVICE // permission, so they have the same privileges as the status // bar itself. - pf.left = df.left = cf.left = mRestrictedScreenLeft; - pf.top = df.top = cf.top = mRestrictedScreenTop; - pf.right = df.right = cf.right = mRestrictedScreenLeft+mRestrictedScreenWidth; - pf.bottom = df.bottom = cf.bottom - = mRestrictedScreenTop+mRestrictedScreenHeight; + pf.left = df.left = of.left = cf.left = mRestrictedScreenLeft; + pf.top = df.top = of.top = cf.top = mRestrictedScreenTop; + pf.right = df.right = of.right = cf.right = mRestrictedScreenLeft + + mRestrictedScreenWidth; + pf.bottom = df.bottom = of.bottom = cf.bottom = mRestrictedScreenTop + + mRestrictedScreenHeight; } else { pf.left = mContentLeft; pf.top = mContentTop; pf.right = mContentRight; pf.bottom = mContentBottom; if (adjust != SOFT_INPUT_ADJUST_RESIZE) { - df.left = cf.left = mDockLeft; - df.top = cf.top = mDockTop; - df.right = cf.right = mDockRight; - df.bottom = cf.bottom = mDockBottom; + df.left = of.left = cf.left = mDockLeft; + df.top = of.top = cf.top = mDockTop; + df.right = of.right = cf.right = mDockRight; + df.bottom = of.bottom = cf.bottom = mDockBottom; } else { - df.left = cf.left = mContentLeft; - df.top = cf.top = mContentTop; - df.right = cf.right = mContentRight; - df.bottom = cf.bottom = mContentBottom; + df.left = of.left = cf.left = mContentLeft; + df.top = of.top = cf.top = mContentTop; + df.right = of.right = cf.right = mContentRight; + df.bottom = of.bottom = cf.bottom = mContentBottom; } if (adjust != SOFT_INPUT_ADJUST_NOTHING) { vf.left = mCurLeft; @@ -3014,8 +3054,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { } if ((fl & FLAG_LAYOUT_NO_LIMITS) != 0) { - df.left = df.top = cf.left = cf.top = vf.left = vf.top = -10000; - df.right = df.bottom = cf.right = cf.bottom = vf.right = vf.bottom = 10000; + df.left = df.top = of.left = of.top = cf.left = cf.top = vf.left = vf.top = -10000; + df.right = df.bottom = of.right = of.bottom = cf.right = cf.bottom + = vf.right = vf.bottom = 10000; } if (DEBUG_LAYOUT) Log.v(TAG, "Compute frame " + attrs.getTitle() @@ -3023,9 +3064,10 @@ public class PhoneWindowManager implements WindowManagerPolicy { + " attach=" + attached + " type=" + attrs.type + String.format(" flags=0x%08x", fl) + " pf=" + pf.toShortString() + " df=" + df.toShortString() + + " of=" + of.toShortString() + " cf=" + cf.toShortString() + " vf=" + vf.toShortString()); - win.computeFrameLw(pf, df, cf, vf); + win.computeFrameLw(pf, df, of, cf, vf); // Dock windows carve out the bottom of the screen, so normal windows // can't appear underneath them. diff --git a/services/java/com/android/server/wm/Session.java b/services/java/com/android/server/wm/Session.java index e82068c..3611f3e 100644 --- a/services/java/com/android/server/wm/Session.java +++ b/services/java/com/android/server/wm/Session.java @@ -182,13 +182,13 @@ final class Session extends IWindowSession.Stub public int relayout(IWindow window, int seq, WindowManager.LayoutParams attrs, int requestedWidth, int requestedHeight, int viewFlags, - int flags, Rect outFrame, Rect outContentInsets, + int flags, Rect outFrame, Rect outOverscanInsets, Rect outContentInsets, Rect outVisibleInsets, Configuration outConfig, Surface outSurface) { if (false) Slog.d(WindowManagerService.TAG, ">>>>>> ENTERED relayout from " + Binder.getCallingPid()); int res = mService.relayoutWindow(this, window, seq, attrs, requestedWidth, requestedHeight, viewFlags, flags, - outFrame, outContentInsets, outVisibleInsets, + outFrame, outOverscanInsets, outContentInsets, outVisibleInsets, outConfig, outSurface); if (false) Slog.d(WindowManagerService.TAG, "<<<<<< EXITING relayout to " + Binder.getCallingPid()); diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java index 6cc02a5..086da37 100644 --- a/services/java/com/android/server/wm/WindowManagerService.java +++ b/services/java/com/android/server/wm/WindowManagerService.java @@ -2640,7 +2640,7 @@ public class WindowManagerService extends IWindowManager.Stub public int relayoutWindow(Session session, IWindow client, int seq, WindowManager.LayoutParams attrs, int requestedWidth, int requestedHeight, int viewVisibility, int flags, - Rect outFrame, Rect outContentInsets, + Rect outFrame, Rect outOverscanInsets, Rect outContentInsets, Rect outVisibleInsets, Configuration outConfig, Surface outSurface) { boolean toBeDisplayed = false; boolean inTouchMode; @@ -2907,6 +2907,7 @@ public class WindowManagerService extends IWindowManager.Stub win.mAppToken.updateReportedVisibilityLocked(); } outFrame.set(win.mCompatFrame); + outOverscanInsets.set(win.mOverscanInsets); outContentInsets.set(win.mContentInsets); outVisibleInsets.set(win.mVisibleInsets); if (localLOGV) Slog.v( @@ -8127,6 +8128,8 @@ public class WindowManagerService extends IWindowManager.Stub private void updateResizingWindows(final WindowState w) { final WindowStateAnimator winAnimator = w.mWinAnimator; if (w.mHasSurface && w.mLayoutSeq == mLayoutSeq) { + w.mOverscanInsetsChanged |= + !w.mLastOverscanInsets.equals(w.mOverscanInsets); w.mContentInsetsChanged |= !w.mLastContentInsets.equals(w.mContentInsets); w.mVisibleInsetsChanged |= @@ -8154,6 +8157,7 @@ public class WindowManagerService extends IWindowManager.Stub + " configChanged=" + configChanged); } + w.mLastOverscanInsets.set(w.mOverscanInsets); w.mLastContentInsets.set(w.mContentInsets); w.mLastVisibleInsets.set(w.mVisibleInsets); makeWindowFreezingScreenIfNeededLocked(w); @@ -8690,9 +8694,11 @@ public class WindowManagerService extends IWindowManager.Stub if (DEBUG_ORIENTATION && winAnimator.mDrawState == WindowStateAnimator.DRAW_PENDING) Slog.i( TAG, "Resizing " + win + " WITH DRAW PENDING"); - win.mClient.resized(win.mFrame, win.mLastContentInsets, win.mLastVisibleInsets, + win.mClient.resized(win.mFrame, win.mLastOverscanInsets, win.mLastContentInsets, + win.mLastVisibleInsets, winAnimator.mDrawState == WindowStateAnimator.DRAW_PENDING, configChanged ? win.mConfiguration : null); + win.mOverscanInsetsChanged = false; win.mContentInsetsChanged = false; win.mVisibleInsetsChanged = false; winAnimator.mSurfaceResized = false; @@ -9656,6 +9662,18 @@ public class WindowManagerService extends IWindowManager.Stub } } + void dumpDisplayContentsLocked(PrintWriter pw, boolean dumpAll) { + pw.println("WINDOW MANAGER DISPLAY CONTENTS (dumpsys window displays)"); + if (mDisplayReady) { + DisplayContentsIterator dCIterator = new DisplayContentsIterator(); + while (dCIterator.hasNext()) { + dCIterator.next().dump(" ", pw); + } + } else { + pw.println(" NO DISPLAY"); + } + } + void dumpWindowsLocked(PrintWriter pw, boolean dumpAll, ArrayList<WindowState> windows) { pw.println("WINDOW MANAGER WINDOWS (dumpsys window windows)"); @@ -9777,15 +9795,6 @@ public class WindowManagerService extends IWindowManager.Stub } } pw.println(); - pw.println(" DisplayContents:"); - if (mDisplayReady) { - DisplayContentsIterator dCIterator = new DisplayContentsIterator(); - while (dCIterator.hasNext()) { - dCIterator.next().dump(" ", pw); - } - } else { - pw.println(" NO DISPLAY"); - } pw.print(" mCurConfiguration="); pw.println(this.mCurConfiguration); pw.print(" mCurrentFocus="); pw.println(mCurrentFocus); if (mLastFocus != mCurrentFocus) { @@ -9965,6 +9974,7 @@ public class WindowManagerService extends IWindowManager.Stub pw.println(" p[policy]: policy state"); pw.println(" a[animator]: animator state"); pw.println(" s[essions]: active sessions"); + pw.println(" d[isplays]: active display contents"); pw.println(" t[okens]: token list"); pw.println(" w[indows]: window list"); pw.println(" cmd may also be a NAME to dump windows. NAME may"); @@ -10003,6 +10013,11 @@ public class WindowManagerService extends IWindowManager.Stub dumpSessionsLocked(pw, true); } return; + } else if ("displays".equals(cmd) || "d".equals(cmd)) { + synchronized(mWindowMap) { + dumpDisplayContentsLocked(pw, true); + } + return; } else if ("tokens".equals(cmd) || "t".equals(cmd)) { synchronized(mWindowMap) { dumpTokensLocked(pw, true); @@ -10053,6 +10068,11 @@ public class WindowManagerService extends IWindowManager.Stub if (dumpAll) { pw.println("-------------------------------------------------------------------------------"); } + dumpDisplayContentsLocked(pw, dumpAll); + pw.println(); + if (dumpAll) { + pw.println("-------------------------------------------------------------------------------"); + } dumpTokensLocked(pw, dumpAll); pw.println(); if (dumpAll) { diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java index f0045b1..517c4e4 100644 --- a/services/java/com/android/server/wm/WindowState.java +++ b/services/java/com/android/server/wm/WindowState.java @@ -153,6 +153,14 @@ final class WindowState implements WindowManagerPolicy.WindowState { boolean mContentInsetsChanged; /** + * Insets that determine the area covered by the display overscan region. These are in the + * application's coordinate space (without compatibility scale applied). + */ + final Rect mOverscanInsets = new Rect(); + final Rect mLastOverscanInsets = new Rect(); + boolean mOverscanInsetsChanged; + + /** * Set to true if we are waiting for this window to receive its * given internal insets before laying out other windows based on it. */ @@ -206,6 +214,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { final Rect mContainingFrame = new Rect(); final Rect mDisplayFrame = new Rect(); + final Rect mOverscanFrame = new Rect(); final Rect mContentFrame = new Rect(); final Rect mParentFrame = new Rect(); final Rect mVisibleFrame = new Rect(); @@ -401,7 +410,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { } @Override - public void computeFrameLw(Rect pf, Rect df, Rect cf, Rect vf) { + public void computeFrameLw(Rect pf, Rect df, Rect of, Rect cf, Rect vf) { mHaveFrame = true; final Rect container = mContainingFrame; @@ -458,6 +467,9 @@ final class WindowState implements WindowManagerPolicy.WindowState { mContentChanged = true; } + final Rect overscan = mOverscanFrame; + overscan.set(of); + final Rect content = mContentFrame; content.set(cf); @@ -489,8 +501,12 @@ final class WindowState implements WindowManagerPolicy.WindowState { // Now make sure the window fits in the overall display. Gravity.applyDisplay(mAttrs.gravity, df, frame); - // Make sure the system, content and visible frames are inside of the + // Make sure the overscan, content and visible frames are inside of the // final window frame. + if (overscan.left < frame.left) overscan.left = frame.left; + if (overscan.top < frame.top) overscan.top = frame.top; + if (overscan.right > frame.right) overscan.right = frame.right; + if (overscan.bottom > frame.bottom) overscan.bottom = frame.bottom; if (content.left < frame.left) content.left = frame.left; if (content.top < frame.top) content.top = frame.top; if (content.right > frame.right) content.right = frame.right; @@ -500,6 +516,12 @@ final class WindowState implements WindowManagerPolicy.WindowState { if (visible.right > frame.right) visible.right = frame.right; if (visible.bottom > frame.bottom) visible.bottom = frame.bottom; + final Rect overscanInsets = mOverscanInsets; + overscanInsets.left = overscan.left-frame.left; + overscanInsets.top = overscan.top-frame.top; + overscanInsets.right = frame.right-overscan.right; + overscanInsets.bottom = frame.bottom-overscan.bottom; + final Rect contentInsets = mContentInsets; contentInsets.left = content.left-frame.left; contentInsets.top = content.top-frame.top; @@ -517,6 +539,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { // If there is a size compatibility scale being applied to the // window, we need to apply this to its insets so that they are // reported to the app in its coordinate space. + overscanInsets.scale(mInvGlobalScale); contentInsets.scale(mInvGlobalScale); visibleInsets.scale(mInvGlobalScale); @@ -560,6 +583,11 @@ final class WindowState implements WindowManagerPolicy.WindowState { } @Override + public Rect getOverscanFrameLw() { + return mOverscanFrame; + } + + @Override public Rect getContentFrameLw() { return mContentFrame; } @@ -1259,17 +1287,21 @@ final class WindowState implements WindowManagerPolicy.WindowState { pw.print(prefix); pw.print("Frames: containing="); mContainingFrame.printShortString(pw); pw.print(" parent="); mParentFrame.printShortString(pw); - pw.print(" display="); mDisplayFrame.printShortString(pw); + pw.println(); + pw.print(prefix); pw.print(" display="); mDisplayFrame.printShortString(pw); + pw.print(" overscan="); mOverscanFrame.printShortString(pw); pw.println(); pw.print(prefix); pw.print(" content="); mContentFrame.printShortString(pw); pw.print(" visible="); mVisibleFrame.printShortString(pw); pw.println(); - pw.print(prefix); pw.print("Cur insets: content="); - mContentInsets.printShortString(pw); + pw.print(prefix); pw.print("Cur insets: overscan="); + mOverscanInsets.printShortString(pw); + pw.print(" content="); mContentInsets.printShortString(pw); pw.print(" visible="); mVisibleInsets.printShortString(pw); pw.println(); - pw.print(prefix); pw.print("Lst insets: content="); - mLastContentInsets.printShortString(pw); + pw.print(prefix); pw.print("Lst insets: overscan="); + mLastOverscanInsets.printShortString(pw); + pw.print(" content="); mLastContentInsets.printShortString(pw); pw.print(" visible="); mLastVisibleInsets.printShortString(pw); pw.println(); } diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java index fa660e6..df576d2 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java @@ -47,7 +47,7 @@ public final class BridgeWindow implements IWindow { } @Override - public void resized(Rect arg1, Rect arg2, Rect arg3, + public void resized(Rect arg1, Rect arg1p5, Rect arg2, Rect arg3, boolean arg4, Configuration arg5) throws RemoteException { // pass for now. } diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java index 67b0a9c..f7ddbc6 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java @@ -86,7 +86,7 @@ public final class BridgeWindowSession implements IWindowSession { } @Override public int relayout(IWindow arg0, int seq, LayoutParams arg1, int arg2, int arg3, int arg4, - int arg4_5, Rect arg5, Rect arg6, Rect arg7, Configuration arg7b, + int arg4_5, Rect arg5Z, Rect arg5, Rect arg6, Rect arg7, Configuration arg7b, Surface arg8) throws RemoteException { // pass for now. return 0; |