Add stable insets for stable system windows

Adds a new kind of inset that only accounts for stable system
windows like the system or navigation bar.

Bug: 15457292
Change-Id: I681b711f6f40a94c25b7acd3a44eb3539486afab
This commit is contained in:
Adrian Roos
2014-06-20 16:10:14 -07:00
parent f29131f701
commit fa10423fa0
14 changed files with 190 additions and 64 deletions

View File

@@ -154,6 +154,7 @@ public abstract class WallpaperService extends Service {
final Rect mWinFrame = new Rect();
final Rect mOverscanInsets = new Rect();
final Rect mContentInsets = new Rect();
final Rect mStableInsets = new Rect();
final Configuration mConfiguration = new Configuration();
final WindowManager.LayoutParams mLayout
@@ -253,7 +254,8 @@ public abstract class WallpaperService extends Service {
final BaseIWindow mWindow = new BaseIWindow() {
@Override
public void resized(Rect frame, Rect overscanInsets, Rect contentInsets,
Rect visibleInsets, boolean reportDraw, Configuration newConfig) {
Rect visibleInsets, Rect stableInsets, boolean reportDraw,
Configuration newConfig) {
Message msg = mCaller.obtainMessageI(MSG_WINDOW_RESIZED,
reportDraw ? 1 : 0);
mCaller.sendMessage(msg);
@@ -628,7 +630,7 @@ public abstract class WallpaperService extends Service {
final int relayoutResult = mSession.relayout(
mWindow, mWindow.mSeq, mLayout, mWidth, mHeight,
View.VISIBLE, 0, mWinFrame, mOverscanInsets, mContentInsets,
mVisibleInsets, mConfiguration, mSurfaceHolder.mSurface);
mVisibleInsets, mStableInsets, mConfiguration, mSurfaceHolder.mSurface);
if (DEBUG) Log.v(TAG, "New surface: " + mSurfaceHolder.mSurface
+ ", frame=" + mWinFrame);

View File

@@ -46,7 +46,8 @@ oneway interface IWindow {
void executeCommand(String command, String parameters, in ParcelFileDescriptor descriptor);
void resized(in Rect frame, in Rect overscanInsets, in Rect contentInsets,
in Rect visibleInsets, boolean reportDraw, in Configuration newConfig);
in Rect visibleInsets, in Rect stableInsets, boolean reportDraw,
in Configuration newConfig);
void moved(int newX, int newY);
void dispatchAppVisibility(boolean visible);
void dispatchGetNewSurface();

View File

@@ -89,7 +89,7 @@ interface IWindowSession {
int relayout(IWindow window, int seq, in WindowManager.LayoutParams attrs,
int requestedWidth, int requestedHeight, int viewVisibility,
int flags, out Rect outFrame, out Rect outOverscanInsets,
out Rect outContentInsets, out Rect outVisibleInsets,
out Rect outContentInsets, out Rect outVisibleInsets, out Rect outStableInsets,
out Configuration outConfig, out Surface outSurface);
/**

View File

@@ -105,6 +105,7 @@ public class SurfaceView extends View {
final Rect mWinFrame = new Rect();
final Rect mOverscanInsets = new Rect();
final Rect mContentInsets = new Rect();
final Rect mStableInsets = new Rect();
final Configuration mConfiguration = new Configuration();
static final int KEEP_SCREEN_ON_MSG = 1;
@@ -518,7 +519,7 @@ public class SurfaceView extends View {
visible ? VISIBLE : GONE,
WindowManagerGlobal.RELAYOUT_DEFER_SURFACE_DESTROY,
mWinFrame, mOverscanInsets, mContentInsets,
mVisibleInsets, mConfiguration, mNewSurface);
mVisibleInsets, mStableInsets, mConfiguration, mNewSurface);
if ((relayoutResult & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0) {
mReportDrawNeeded = true;
}
@@ -653,7 +654,8 @@ public class SurfaceView extends View {
@Override
public void resized(Rect frame, Rect overscanInsets, Rect contentInsets,
Rect visibleInsets, boolean reportDraw, Configuration newConfig) {
Rect visibleInsets, Rect stableInsets, boolean reportDraw,
Configuration newConfig) {
SurfaceView surfaceView = mSurfaceView.get();
if (surfaceView != null) {
if (DEBUG) Log.v(

View File

@@ -19804,6 +19804,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
final Rect mVisibleInsets = 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
* stable system windows.
*/
final Rect mStableInsets = new Rect();
/**
* The internal insets given by this window. This value is
* supplied by the client (through

View File

@@ -21,7 +21,6 @@ import android.animation.LayoutTransition;
import android.app.ActivityManagerNative;
import android.content.ClipDescription;
import android.content.ComponentCallbacks;
import android.content.ComponentCallbacks2;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.CompatibilityInfo;
@@ -205,7 +204,7 @@ public final class ViewRootImpl implements ViewParent,
/** Set to true while in performTraversals for detecting when die(true) is called from internal
* callbacks such as onMeasure, onPreDraw, onDraw and deferring doDie() until later. */
boolean mIsInTraversal;
boolean mFitSystemWindowsRequested;
boolean mApplyInsetsRequested;
boolean mLayoutRequested;
boolean mFirst;
boolean mReportNextDraw;
@@ -257,11 +256,13 @@ public final class ViewRootImpl implements ViewParent,
final Rect mPendingOverscanInsets = new Rect();
final Rect mPendingVisibleInsets = new Rect();
final Rect mPendingStableInsets = new Rect();
final Rect mPendingContentInsets = new Rect();
final ViewTreeObserver.InternalInsetsInfo mLastGivenInsets
= new ViewTreeObserver.InternalInsetsInfo();
final Rect mFitSystemWindowsInsets = new Rect();
final Rect mDispatchContentInsets = new Rect();
final Rect mDispatchStableInsets = new Rect();
final Configuration mLastConfiguration = new Configuration();
final Configuration mPendingConfiguration = new Configuration();
@@ -532,6 +533,7 @@ public final class ViewRootImpl implements ViewParent,
}
mPendingOverscanInsets.set(0, 0, 0, 0);
mPendingContentInsets.set(mAttachInfo.mContentInsets);
mPendingStableInsets.set(mAttachInfo.mStableInsets);
mPendingVisibleInsets.set(0, 0, 0, 0);
if (DEBUG_LAYOUT) Log.v(TAG, "Added window " + mWindow);
if (res < WindowManagerGlobal.ADD_OKAY) {
@@ -816,7 +818,7 @@ public final class ViewRootImpl implements ViewParent,
@Override
public void requestFitSystemWindows() {
checkThread();
mFitSystemWindowsRequested = true;
mApplyInsetsRequested = true;
scheduleTraversals();
}
@@ -1161,7 +1163,8 @@ public final class ViewRootImpl implements ViewParent,
}
void dispatchApplyInsets(View host) {
mFitSystemWindowsInsets.set(mAttachInfo.mContentInsets);
mDispatchContentInsets.set(mAttachInfo.mContentInsets);
mDispatchStableInsets.set(mAttachInfo.mStableInsets);
boolean isRound = false;
if ((mWindowAttributes.flags & WindowManager.LayoutParams.FLAG_LAYOUT_IN_OVERSCAN) != 0
&& mDisplay.getDisplayId() == 0) {
@@ -1171,7 +1174,8 @@ public final class ViewRootImpl implements ViewParent,
com.android.internal.R.bool.config_windowIsRound);
}
host.dispatchApplyWindowInsets(new WindowInsets(
mFitSystemWindowsInsets, isRound));
mDispatchContentInsets, null /* windowDecorInsets */,
mDispatchStableInsets, isRound));
}
private void performTraversals() {
@@ -1310,6 +1314,9 @@ public final class ViewRootImpl implements ViewParent,
if (!mPendingContentInsets.equals(mAttachInfo.mContentInsets)) {
insetsChanged = true;
}
if (!mPendingStableInsets.equals(mAttachInfo.mStableInsets)) {
insetsChanged = true;
}
if (!mPendingVisibleInsets.equals(mAttachInfo.mVisibleInsets)) {
mAttachInfo.mVisibleInsets.set(mPendingVisibleInsets);
if (DEBUG_LAYOUT) Log.v(TAG, "Visible insets changing to: "
@@ -1383,8 +1390,8 @@ public final class ViewRootImpl implements ViewParent,
& WindowManager.LayoutParams.FLAG_LAYOUT_IN_OVERSCAN) != 0;
}
if (mFitSystemWindowsRequested) {
mFitSystemWindowsRequested = false;
if (mApplyInsetsRequested) {
mApplyInsetsRequested = false;
mLastOverscanRequested = mAttachInfo.mOverscanRequested;
dispatchApplyInsets(host);
if (mLayoutRequested) {
@@ -1469,6 +1476,7 @@ public final class ViewRootImpl implements ViewParent,
+ " overscan=" + mPendingOverscanInsets.toShortString()
+ " content=" + mPendingContentInsets.toShortString()
+ " visible=" + mPendingVisibleInsets.toShortString()
+ " visible=" + mPendingStableInsets.toShortString()
+ " surface=" + mSurface);
if (mPendingConfiguration.seq != 0) {
@@ -1484,6 +1492,8 @@ public final class ViewRootImpl implements ViewParent,
mAttachInfo.mContentInsets);
final boolean visibleInsetsChanged = !mPendingVisibleInsets.equals(
mAttachInfo.mVisibleInsets);
final boolean stableInsetsChanged = !mPendingStableInsets.equals(
mAttachInfo.mStableInsets);
if (contentInsetsChanged) {
if (mWidth > 0 && mHeight > 0 && lp != null &&
((lp.systemUiVisibility|lp.subtreeSystemUiVisibility)
@@ -1558,12 +1568,19 @@ public final class ViewRootImpl implements ViewParent,
// Need to relayout with content insets.
contentInsetsChanged = true;
}
if (stableInsetsChanged) {
mAttachInfo.mStableInsets.set(mPendingStableInsets);
if (DEBUG_LAYOUT) Log.v(TAG, "Decor insets changing to: "
+ mAttachInfo.mStableInsets);
// Need to relayout with content insets.
contentInsetsChanged = true;
}
if (contentInsetsChanged || mLastSystemUiVisibility !=
mAttachInfo.mSystemUiVisibility || mFitSystemWindowsRequested
mAttachInfo.mSystemUiVisibility || mApplyInsetsRequested
|| mLastOverscanRequested != mAttachInfo.mOverscanRequested) {
mLastSystemUiVisibility = mAttachInfo.mSystemUiVisibility;
mLastOverscanRequested = mAttachInfo.mOverscanRequested;
mFitSystemWindowsRequested = false;
mApplyInsetsRequested = false;
dispatchApplyInsets(host);
}
if (visibleInsetsChanged) {
@@ -3065,6 +3082,7 @@ public final class ViewRootImpl implements ViewParent,
if (mWinFrame.equals(args.arg1)
&& mPendingOverscanInsets.equals(args.arg5)
&& mPendingContentInsets.equals(args.arg2)
&& mPendingStableInsets.equals(args.arg6)
&& mPendingVisibleInsets.equals(args.arg3)
&& args.arg4 == null) {
break;
@@ -3082,6 +3100,7 @@ public final class ViewRootImpl implements ViewParent,
mWinFrame.set((Rect) args.arg1);
mPendingOverscanInsets.set((Rect) args.arg5);
mPendingContentInsets.set((Rect) args.arg2);
mPendingStableInsets.set((Rect) args.arg6);
mPendingVisibleInsets.set((Rect) args.arg3);
args.recycle();
@@ -5167,7 +5186,7 @@ public final class ViewRootImpl implements ViewParent,
(int) (mView.getMeasuredHeight() * appScale + 0.5f),
viewVisibility, insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0,
mWinFrame, mPendingOverscanInsets, mPendingContentInsets, mPendingVisibleInsets,
mPendingConfiguration, mSurface);
mPendingStableInsets, mPendingConfiguration, mSurface);
//Log.d(TAG, "<<<<<< BACK FROM relayout");
if (restore) {
params.restore();
@@ -5178,6 +5197,7 @@ public final class ViewRootImpl implements ViewParent,
mTranslator.translateRectInScreenToAppWindow(mPendingOverscanInsets);
mTranslator.translateRectInScreenToAppWindow(mPendingContentInsets);
mTranslator.translateRectInScreenToAppWindow(mPendingVisibleInsets);
mTranslator.translateRectInScreenToAppWindow(mPendingStableInsets);
}
return relayoutResult;
}
@@ -5446,7 +5466,7 @@ public final class ViewRootImpl implements ViewParent,
}
public void dispatchResized(Rect frame, Rect overscanInsets, Rect contentInsets,
Rect visibleInsets, boolean reportDraw, Configuration newConfig) {
Rect visibleInsets, Rect stableInsets, boolean reportDraw, Configuration newConfig) {
if (DEBUG_LAYOUT) Log.v(TAG, "Resizing " + this + ": frame=" + frame.toShortString()
+ " contentInsets=" + contentInsets.toShortString()
+ " visibleInsets=" + visibleInsets.toShortString()
@@ -5465,6 +5485,7 @@ public final class ViewRootImpl implements ViewParent,
args.arg3 = sameProcessCall ? new Rect(visibleInsets) : visibleInsets;
args.arg4 = sameProcessCall && newConfig != null ? new Configuration(newConfig) : newConfig;
args.arg5 = sameProcessCall ? new Rect(overscanInsets) : overscanInsets;
args.arg6 = sameProcessCall ? new Rect(stableInsets) : stableInsets;
msg.obj = args;
mHandler.sendMessage(msg);
}
@@ -6292,11 +6313,12 @@ public final class ViewRootImpl implements ViewParent,
@Override
public void resized(Rect frame, Rect overscanInsets, Rect contentInsets,
Rect visibleInsets, boolean reportDraw, Configuration newConfig) {
Rect visibleInsets, Rect stableInsets, boolean reportDraw,
Configuration newConfig) {
final ViewRootImpl viewAncestor = mViewAncestor.get();
if (viewAncestor != null) {
viewAncestor.dispatchResized(frame, overscanInsets, contentInsets,
visibleInsets, reportDraw, newConfig);
visibleInsets, stableInsets, reportDraw, newConfig);
}
}

View File

@@ -30,13 +30,16 @@ import android.graphics.Rect;
* @see View#onApplyWindowInsets(WindowInsets)
*/
public final class WindowInsets {
private Rect mSystemWindowInsets;
private Rect mWindowDecorInsets;
private Rect mStableInsets;
private Rect mTempRect;
private boolean mIsRound;
private boolean mSystemWindowInsetsConsumed = false;
private boolean mWindowDecorInsetsConsumed = false;
private boolean mStableInsetsConsumed = false;
private static final Rect EMPTY_RECT = new Rect(0, 0, 0, 0);
@@ -49,29 +52,21 @@ public final class WindowInsets {
public static final WindowInsets CONSUMED;
static {
CONSUMED = new WindowInsets(EMPTY_RECT, EMPTY_RECT);
CONSUMED.mSystemWindowInsetsConsumed = true;
CONSUMED.mWindowDecorInsetsConsumed = true;
CONSUMED = new WindowInsets(null, null, null, false);
}
/** @hide */
public WindowInsets(Rect systemWindowInsets, Rect windowDecorInsets) {
this(systemWindowInsets, windowDecorInsets, false);
}
/** @hide */
public WindowInsets(Rect systemWindowInsets, boolean isRound) {
this(systemWindowInsets, null, isRound);
}
/** @hide */
public WindowInsets(Rect systemWindowInsets, Rect windowDecorInsets, boolean isRound) {
public WindowInsets(Rect systemWindowInsets, Rect windowDecorInsets, Rect stableInsets,
boolean isRound) {
mSystemWindowInsetsConsumed = systemWindowInsets == null;
mSystemWindowInsets = mSystemWindowInsetsConsumed ? EMPTY_RECT : systemWindowInsets;
mWindowDecorInsetsConsumed = windowDecorInsets == null;
mWindowDecorInsets = mWindowDecorInsetsConsumed ? EMPTY_RECT : windowDecorInsets;
mStableInsetsConsumed = stableInsets == null;
mStableInsets = mStableInsetsConsumed ? EMPTY_RECT : stableInsets;
mIsRound = isRound;
}
@@ -83,14 +78,16 @@ public final class WindowInsets {
public WindowInsets(WindowInsets src) {
mSystemWindowInsets = src.mSystemWindowInsets;
mWindowDecorInsets = src.mWindowDecorInsets;
mStableInsets = src.mStableInsets;
mSystemWindowInsetsConsumed = src.mSystemWindowInsetsConsumed;
mWindowDecorInsetsConsumed = src.mWindowDecorInsetsConsumed;
mStableInsetsConsumed = src.mStableInsetsConsumed;
mIsRound = src.mIsRound;
}
/** @hide */
public WindowInsets(Rect systemWindowInsets) {
this(systemWindowInsets, null);
this(systemWindowInsets, null, null, false);
}
/**
@@ -272,7 +269,7 @@ public final class WindowInsets {
* @hide Pending API
*/
public boolean isConsumed() {
return mSystemWindowInsetsConsumed && mWindowDecorInsetsConsumed;
return mSystemWindowInsetsConsumed && mWindowDecorInsetsConsumed && mStableInsetsConsumed;
}
/**
@@ -381,9 +378,57 @@ public final class WindowInsets {
return result;
}
/**
* @hide
*/
public int getStableInsetTop() {
return mStableInsets.top;
}
/**
* @hide
*/
public int getStableInsetLeft() {
return mStableInsets.left;
}
/**
* @hide
*/
public int getStableInsetRight() {
return mStableInsets.right;
}
/**
* @hide
*/
public int getStableInsetBottom() {
return mStableInsets.bottom;
}
/**
* @hide
*/
public boolean hasStableInsets() {
return mStableInsets.top != 0 || mStableInsets.left != 0 || mStableInsets.right != 0
|| mStableInsets.bottom != 0;
}
/**
* @hide
*/
public WindowInsets consumeStableInsets() {
final WindowInsets result = new WindowInsets(this);
result.mStableInsets = EMPTY_RECT;
result.mStableInsetsConsumed = true;
return result;
}
@Override
public String toString() {
return "WindowInsets{systemWindowInsets=" + mSystemWindowInsets + " windowDecorInsets=" +
mWindowDecorInsets + (isRound() ? "round}" : "}");
return "WindowInsets{systemWindowInsets=" + mSystemWindowInsets
+ " windowDecorInsets=" + mWindowDecorInsets
+ " stableInsets=" + mStableInsets +
(isRound() ? " round}" : "}");
}
}

View File

@@ -149,9 +149,11 @@ public interface WindowManagerPolicy {
* are visible.
* @param decorFrame The decor frame specified by policy specific to this window,
* to use for proper cropping during animation.
* @param stableFrame The frame around which stable system decoration is positioned.
*/
public void computeFrameLw(Rect parentFrame, Rect displayFrame,
Rect overlayFrame, Rect contentFrame, Rect visibleFrame, Rect decorFrame);
Rect overlayFrame, Rect contentFrame, Rect visibleFrame, Rect decorFrame,
Rect stableFrame);
/**
* Retrieve the current frame of the window that has been assigned by

View File

@@ -35,7 +35,7 @@ public class BaseIWindow extends IWindow.Stub {
@Override
public void resized(Rect frame, Rect overscanInsets, Rect contentInsets,
Rect visibleInsets, boolean reportDraw, Configuration newConfig) {
Rect visibleInsets, Rect stableInsets, boolean reportDraw, Configuration newConfig) {
if (reportDraw) {
try {
mSession.finishDrawing(this);

View File

@@ -2650,21 +2650,23 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
return false;
}
private void updateColorViews(WindowInsets insets) {
if (mIsFloating || !ActivityManager.isHighEndGfx()) {
// No colors on floating windows or low end devices :(
return;
private WindowInsets updateColorViews(WindowInsets insets) {
if (!mIsFloating && ActivityManager.isHighEndGfx()) {
if (insets != null) {
mLastTopInset = insets.getStableInsetTop();
mLastBottomInset = insets.getStableInsetBottom();
}
mStatusColorView = updateColorViewInt(mStatusColorView,
SYSTEM_UI_FLAG_FULLSCREEN, FLAG_TRANSLUCENT_STATUS,
mStatusBarColor, mLastTopInset, Gravity.TOP);
mNavigationColorView = updateColorViewInt(mNavigationColorView,
SYSTEM_UI_FLAG_HIDE_NAVIGATION, FLAG_TRANSLUCENT_NAVIGATION,
mNavigationBarColor, mLastBottomInset, Gravity.BOTTOM);
}
if (insets != null) {
mLastTopInset = insets.getSystemWindowInsetTop();
mLastBottomInset = insets.getSystemWindowInsetBottom();
insets = insets.consumeStableInsets();
}
mStatusColorView = updateColorViewInt(mStatusColorView,
SYSTEM_UI_FLAG_FULLSCREEN, FLAG_TRANSLUCENT_STATUS,
mStatusBarColor, mLastTopInset, Gravity.TOP);
mNavigationColorView = updateColorViewInt(mNavigationColorView,
SYSTEM_UI_FLAG_HIDE_NAVIGATION, FLAG_TRANSLUCENT_NAVIGATION,
mNavigationBarColor, mLastBottomInset, Gravity.BOTTOM);
return insets;
}
private View updateColorViewInt(View view, int systemUiHideFlag, int translucentFlag,

View File

@@ -409,6 +409,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
static final Rect mTmpContentFrame = new Rect();
static final Rect mTmpVisibleFrame = new Rect();
static final Rect mTmpDecorFrame = new Rect();
static final Rect mTmpStableFrame = new Rect();
static final Rect mTmpNavigationFrame = new Rect();
WindowState mTopFullscreenOpaqueWindowState;
@@ -2973,7 +2974,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mStatusBarLayer = mNavigationBar.getSurfaceLayer();
// And compute the final frame.
mNavigationBar.computeFrameLw(mTmpNavigationFrame, mTmpNavigationFrame,
mTmpNavigationFrame, mTmpNavigationFrame, mTmpNavigationFrame, dcf);
mTmpNavigationFrame, mTmpNavigationFrame, mTmpNavigationFrame, dcf,
mTmpNavigationFrame);
if (DEBUG_LAYOUT) Slog.i(TAG, "mNavigationBar frame: " + mTmpNavigationFrame);
if (mNavigationBarController.checkHiddenLw()) {
updateSysUiVisibility = true;
@@ -2998,7 +3000,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mStatusBarLayer = mStatusBar.getSurfaceLayer();
// Let the status bar determine its size.
mStatusBar.computeFrameLw(pf, df, vf, vf, vf, dcf);
mStatusBar.computeFrameLw(pf, df, vf, vf, vf, dcf, vf);
// For layout, the status bar is always at the top with our fixed height.
mStableTop = mUnrestrictedScreenTop + mStatusBarHeight;
@@ -3158,6 +3160,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
final Rect cf = mTmpContentFrame;
final Rect vf = mTmpVisibleFrame;
final Rect dcf = mTmpDecorFrame;
final Rect sf = mTmpStableFrame;
dcf.setEmpty();
final boolean hasNavBar = (isDefaultDisplay && mHasNavigationBar
@@ -3165,6 +3168,12 @@ public class PhoneWindowManager implements WindowManagerPolicy {
final int adjust = sim & SOFT_INPUT_MASK_ADJUST;
if (isDefaultDisplay) {
sf.set(mStableLeft, mStableTop, mStableRight, mStableBottom);
} else {
sf.set(mOverscanLeft, mOverscanTop, mOverscanRight, mOverscanBottom);
}
if (!isDefaultDisplay) {
if (attached != null) {
// If this window is attached to another, our display
@@ -3527,9 +3536,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
+ " pf=" + pf.toShortString() + " df=" + df.toShortString()
+ " of=" + of.toShortString()
+ " cf=" + cf.toShortString() + " vf=" + vf.toShortString()
+ " dcf=" + dcf.toShortString());
+ " dcf=" + dcf.toShortString()
+ " sf=" + sf.toShortString());
win.computeFrameLw(pf, df, of, cf, vf, dcf);
win.computeFrameLw(pf, df, of, cf, vf, dcf, sf);
// Dock windows carve out the bottom of the screen, so normal windows
// can't appear underneath them.

View File

@@ -189,13 +189,14 @@ 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 outOverscanInsets, Rect outContentInsets,
Rect outVisibleInsets, Configuration outConfig, Surface outSurface) {
Rect outVisibleInsets, Rect outStableInsets, 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, outOverscanInsets, outContentInsets, outVisibleInsets,
outConfig, outSurface);
outStableInsets, outConfig, outSurface);
if (false) Slog.d(WindowManagerService.TAG, "<<<<<< EXITING relayout to "
+ Binder.getCallingPid());
return res;

View File

@@ -2835,7 +2835,8 @@ public class WindowManagerService extends IWindowManager.Stub
WindowManager.LayoutParams attrs, int requestedWidth,
int requestedHeight, int viewVisibility, int flags,
Rect outFrame, Rect outOverscanInsets, Rect outContentInsets,
Rect outVisibleInsets, Configuration outConfig, Surface outSurface) {
Rect outVisibleInsets, Rect outStableInsets, Configuration outConfig,
Surface outSurface) {
boolean toBeDisplayed = false;
boolean inTouchMode;
boolean configChanged;
@@ -3112,6 +3113,7 @@ public class WindowManagerService extends IWindowManager.Stub
outOverscanInsets.set(win.mOverscanInsets);
outContentInsets.set(win.mContentInsets);
outVisibleInsets.set(win.mVisibleInsets);
outStableInsets.set(win.mStableInsets);
if (localLOGV) Slog.v(
TAG, "Relayout given client " + client.asBinder()
+ ", requestedWidth=" + requestedWidth
@@ -8878,6 +8880,8 @@ public class WindowManagerService extends IWindowManager.Stub
+ " " + w.mContentInsets.toShortString()
+ " visibleInsetsChanged=" + w.mVisibleInsetsChanged
+ " " + w.mVisibleInsets.toShortString()
+ " stableInsetsChanged=" + w.mStableInsetsChanged
+ " " + w.mStableInsets.toShortString()
+ " surfaceResized=" + winAnimator.mSurfaceResized
+ " configChanged=" + configChanged);
}
@@ -8885,6 +8889,7 @@ public class WindowManagerService extends IWindowManager.Stub
w.mLastOverscanInsets.set(w.mOverscanInsets);
w.mLastContentInsets.set(w.mContentInsets);
w.mLastVisibleInsets.set(w.mVisibleInsets);
w.mLastStableInsets.set(w.mStableInsets);
makeWindowFreezingScreenIfNeededLocked(w);
// If the orientation is changing, then we need to
// hold off on unfreezing the display until this

View File

@@ -166,6 +166,14 @@ final class WindowState implements WindowManagerPolicy.WindowState {
final Rect mLastOverscanInsets = new Rect();
boolean mOverscanInsetsChanged;
/**
* Insets that determine the area covered by the stable system windows. These are in the
* application's coordinate space (without compatibility scale applied).
*/
final Rect mStableInsets = new Rect();
final Rect mLastStableInsets = new Rect();
boolean mStableInsetsChanged;
/**
* Set to true if we are waiting for this window to receive its
* given internal insets before laying out other windows based on it.
@@ -225,6 +233,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
final Rect mParentFrame = new Rect();
final Rect mVisibleFrame = new Rect();
final Rect mDecorFrame = new Rect();
final Rect mStableFrame = new Rect();
boolean mContentChanged;
@@ -470,7 +479,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
}
@Override
public void computeFrameLw(Rect pf, Rect df, Rect of, Rect cf, Rect vf, Rect dcf) {
public void computeFrameLw(Rect pf, Rect df, Rect of, Rect cf, Rect vf, Rect dcf, Rect sf) {
mHaveFrame = true;
TaskStack stack = mAppToken != null ? getStack() : null;
@@ -537,6 +546,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
mContentFrame.set(cf);
mVisibleFrame.set(vf);
mDecorFrame.set(dcf);
mStableFrame.set(sf);
final int fw = mFrame.width();
final int fh = mFrame.height();
@@ -574,6 +584,11 @@ final class WindowState implements WindowManagerPolicy.WindowState {
Math.min(mVisibleFrame.right, mFrame.right),
Math.min(mVisibleFrame.bottom, mFrame.bottom));
mStableFrame.set(Math.max(mStableFrame.left, mFrame.left),
Math.max(mStableFrame.top, mFrame.top),
Math.min(mStableFrame.right, mFrame.right),
Math.min(mStableFrame.bottom, mFrame.bottom));
mOverscanInsets.set(Math.max(mOverscanFrame.left - mFrame.left, 0),
Math.max(mOverscanFrame.top - mFrame.top, 0),
Math.max(mFrame.right - mOverscanFrame.right, 0),
@@ -589,6 +604,11 @@ final class WindowState implements WindowManagerPolicy.WindowState {
mFrame.right - mVisibleFrame.right,
mFrame.bottom - mVisibleFrame.bottom);
mStableInsets.set(Math.max(mStableFrame.left - mFrame.left, 0),
Math.max(mStableFrame.top - mFrame.top, 0),
Math.max(mFrame.right - mStableFrame.right, 0),
Math.max(mFrame.bottom - mStableFrame.bottom, 0));
mCompatFrame.set(mFrame);
if (mEnforceSizeCompat) {
// If there is a size compatibility scale being applied to the
@@ -597,6 +617,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
mOverscanInsets.scale(mInvGlobalScale);
mContentInsets.scale(mInvGlobalScale);
mVisibleInsets.scale(mInvGlobalScale);
mStableInsets.scale(mInvGlobalScale);
// Also the scaled frame that we report to the app needs to be
// adjusted to be in its coordinate space.
@@ -618,7 +639,8 @@ final class WindowState implements WindowManagerPolicy.WindowState {
+ mRequestedHeight + ") to" + " (pw=" + pw + ", ph=" + ph
+ "): frame=" + mFrame.toShortString()
+ " ci=" + mContentInsets.toShortString()
+ " vi=" + mVisibleInsets.toShortString());
+ " vi=" + mVisibleInsets.toShortString()
+ " vi=" + mStableInsets.toShortString());
}
@Override
@@ -724,6 +746,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
mOverscanInsetsChanged |= !mLastOverscanInsets.equals(mOverscanInsets);
mContentInsetsChanged |= !mLastContentInsets.equals(mContentInsets);
mVisibleInsetsChanged |= !mLastVisibleInsets.equals(mVisibleInsets);
mStableInsetsChanged |= !mLastStableInsets.equals(mStableInsets);
return mOverscanInsetsChanged || mContentInsetsChanged || mVisibleInsetsChanged;
}
@@ -1344,6 +1367,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
final Rect overscanInsets = mLastOverscanInsets;
final Rect contentInsets = mLastContentInsets;
final Rect visibleInsets = mLastVisibleInsets;
final Rect stableInsets = mLastStableInsets;
final boolean reportDraw = mWinAnimator.mDrawState == WindowStateAnimator.DRAW_PENDING;
final Configuration newConfig = configChanged ? mConfiguration : null;
if (mClient instanceof IWindow.Stub) {
@@ -1353,15 +1377,15 @@ final class WindowState implements WindowManagerPolicy.WindowState {
public void run() {
try {
mClient.resized(frame, overscanInsets, contentInsets,
visibleInsets, reportDraw, newConfig);
visibleInsets, stableInsets, reportDraw, newConfig);
} catch (RemoteException e) {
// Not a remote call, RemoteException won't be raised.
}
}
});
} else {
mClient.resized(frame, overscanInsets, contentInsets, visibleInsets, reportDraw,
newConfig);
mClient.resized(frame, overscanInsets, contentInsets, visibleInsets, stableInsets,
reportDraw, newConfig);
}
//TODO (multidisplay): Accessibility supported only for the default display.
@@ -1373,6 +1397,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
mOverscanInsetsChanged = false;
mContentInsetsChanged = false;
mVisibleInsetsChanged = false;
mStableInsetsChanged = false;
mWinAnimator.mSurfaceResized = false;
} catch (RemoteException e) {
mOrientationChanging = false;
@@ -1522,11 +1547,13 @@ final class WindowState implements WindowManagerPolicy.WindowState {
mOverscanInsets.printShortString(pw);
pw.print(" content="); mContentInsets.printShortString(pw);
pw.print(" visible="); mVisibleInsets.printShortString(pw);
pw.print(" stable="); mStableInsets.printShortString(pw);
pw.println();
pw.print(prefix); pw.print("Lst insets: overscan=");
mLastOverscanInsets.printShortString(pw);
pw.print(" content="); mLastContentInsets.printShortString(pw);
pw.print(" visible="); mLastVisibleInsets.printShortString(pw);
pw.print(" stable="); mLastStableInsets.printShortString(pw);
pw.println();
}
pw.print(prefix); pw.print(mWinAnimator); pw.println(":");