Skip to content

Commit 5c58de3

Browse files
author
Dianne Hackborn
committed
Add system insets to windows.
This will be used to determine which parts of a window a completely hidden by system UI elements (status bar, nav bar, system bar) so that they can be clipped out from rendering. Change-Id: I2c6c6ac67dbdfeed82d2c089ef806fb483165bd9
1 parent 3ea8761 commit 5c58de3

File tree

13 files changed

+170
-52
lines changed

13 files changed

+170
-52
lines changed

core/java/android/service/wallpaper/WallpaperService.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ public class Engine {
154154
int mCurWindowPrivateFlags = mWindowPrivateFlags;
155155
final Rect mVisibleInsets = new Rect();
156156
final Rect mWinFrame = new Rect();
157+
final Rect mSystemInsets = new Rect();
157158
final Rect mContentInsets = new Rect();
158159
final Configuration mConfiguration = new Configuration();
159160

@@ -253,7 +254,7 @@ public void onInputEvent(InputEvent event) {
253254

254255
final BaseIWindow mWindow = new BaseIWindow() {
255256
@Override
256-
public void resized(int w, int h, Rect coveredInsets,
257+
public void resized(int w, int h, Rect systemInsets, Rect contentInsets,
257258
Rect visibleInsets, boolean reportDraw, Configuration newConfig) {
258259
Message msg = mCaller.obtainMessageI(MSG_WINDOW_RESIZED,
259260
reportDraw ? 1 : 0);
@@ -620,7 +621,7 @@ void updateSurface(boolean forceRelayout, boolean forceReport, boolean redrawNee
620621

621622
final int relayoutResult = mSession.relayout(
622623
mWindow, mWindow.mSeq, mLayout, mWidth, mHeight,
623-
View.VISIBLE, 0, mWinFrame, mContentInsets,
624+
View.VISIBLE, 0, mWinFrame, mSystemInsets, mContentInsets,
624625
mVisibleInsets, mConfiguration, mSurfaceHolder.mSurface);
625626

626627
if (DEBUG) Log.v(TAG, "New surface: " + mSurfaceHolder.mSurface

core/java/android/view/IWindow.aidl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ oneway interface IWindow {
4545
*/
4646
void executeCommand(String command, String parameters, in ParcelFileDescriptor descriptor);
4747

48-
void resized(int w, int h, in Rect coveredInsets, in Rect visibleInsets,
49-
boolean reportDraw, in Configuration newConfig);
48+
void resized(int w, int h, in Rect systemInsets, in Rect contentInsets,
49+
in Rect visibleInsets, boolean reportDraw, in Configuration newConfig);
5050
void dispatchAppVisibility(boolean visible);
5151
void dispatchGetNewSurface();
5252
void dispatchScreenState(boolean on);

core/java/android/view/IWindowSession.aidl

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ interface IWindowSession {
5858
* {@link WindowManagerImpl#RELAYOUT_DEFER_SURFACE_DESTROY}.
5959
* @param outFrame Rect in which is placed the new position/size on
6060
* screen.
61+
* @param outSystemInsets Rect in which is placed the offsets from
62+
* <var>outFrame</var> over which any core system UI elements are
63+
* currently covering the window. This is not generally used for
64+
* layout, but just to know where the window is obscured.
6165
* @param outContentInsets Rect in which is placed the offsets from
6266
* <var>outFrame</var> in which the content of the window should be
6367
* placed. This can be used to modify the window layout to ensure its
@@ -79,9 +83,9 @@ interface IWindowSession {
7983
*/
8084
int relayout(IWindow window, int seq, in WindowManager.LayoutParams attrs,
8185
int requestedWidth, int requestedHeight, int viewVisibility,
82-
int flags, out Rect outFrame, out Rect outContentInsets,
83-
out Rect outVisibleInsets, out Configuration outConfig,
84-
out Surface outSurface);
86+
int flags, out Rect outFrame, out Rect outSystemInsets,
87+
out Rect outContentInsets, out Rect outVisibleInsets,
88+
out Configuration outConfig, out Surface outSurface);
8589

8690
/**
8791
* If a call to relayout() asked to have the surface destroy deferred,

core/java/android/view/SurfaceView.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ public class SurfaceView extends View {
9898
MyWindow mWindow;
9999
final Rect mVisibleInsets = new Rect();
100100
final Rect mWinFrame = new Rect();
101+
final Rect mSystemInsets = new Rect();
101102
final Rect mContentInsets = new Rect();
102103
final Configuration mConfiguration = new Configuration();
103104

@@ -471,7 +472,7 @@ private void updateWindow(boolean force, boolean redrawNeeded) {
471472
mWindow, mWindow.mSeq, mLayout, mWidth, mHeight,
472473
visible ? VISIBLE : GONE,
473474
WindowManagerImpl.RELAYOUT_DEFER_SURFACE_DESTROY,
474-
mWinFrame, mContentInsets,
475+
mWinFrame, mSystemInsets, mContentInsets,
475476
mVisibleInsets, mConfiguration, mNewSurface);
476477
if ((relayoutResult&WindowManagerImpl.RELAYOUT_RES_FIRST_TIME) != 0) {
477478
mReportDrawNeeded = true;
@@ -605,7 +606,7 @@ public MyWindow(SurfaceView surfaceView) {
605606
mSurfaceView = new WeakReference<SurfaceView>(surfaceView);
606607
}
607608

608-
public void resized(int w, int h, Rect coveredInsets,
609+
public void resized(int w, int h, Rect systemInsets, Rect contentInsets,
609610
Rect visibleInsets, boolean reportDraw, Configuration newConfig) {
610611
SurfaceView surfaceView = mSurfaceView.get();
611612
if (surfaceView != null) {

core/java/android/view/ViewRootImpl.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,7 @@ public final class ViewRootImpl implements ViewParent,
261261

262262
final Rect mPendingVisibleInsets = new Rect();
263263
final Rect mPendingContentInsets = new Rect();
264+
final Rect mPendingSystemInsets = new Rect();
264265
final ViewTreeObserver.InternalInsetsInfo mLastGivenInsets
265266
= new ViewTreeObserver.InternalInsetsInfo();
266267

@@ -3841,7 +3842,7 @@ private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility
38413842
(int) (mView.getMeasuredWidth() * appScale + 0.5f),
38423843
(int) (mView.getMeasuredHeight() * appScale + 0.5f),
38433844
viewVisibility, insetsPending ? WindowManagerImpl.RELAYOUT_INSETS_PENDING : 0,
3844-
mWinFrame, mPendingContentInsets, mPendingVisibleInsets,
3845+
mWinFrame, mPendingSystemInsets, mPendingContentInsets, mPendingVisibleInsets,
38453846
mPendingConfiguration, mSurface);
38463847
//Log.d(TAG, "<<<<<< BACK FROM relayout");
38473848
if (restore) {
@@ -4684,11 +4685,11 @@ static class W extends IWindow.Stub {
46844685
mViewAncestor = new WeakReference<ViewRootImpl>(viewAncestor);
46854686
}
46864687

4687-
public void resized(int w, int h, Rect coveredInsets, Rect visibleInsets,
4688-
boolean reportDraw, Configuration newConfig) {
4688+
public void resized(int w, int h, Rect systemInsets, Rect contentInsets,
4689+
Rect visibleInsets, boolean reportDraw, Configuration newConfig) {
46894690
final ViewRootImpl viewAncestor = mViewAncestor.get();
46904691
if (viewAncestor != null) {
4691-
viewAncestor.dispatchResized(w, h, coveredInsets, visibleInsets, reportDraw,
4692+
viewAncestor.dispatchResized(w, h, contentInsets, visibleInsets, reportDraw,
46924693
newConfig);
46934694
}
46944695
}

core/java/android/view/WindowManagerPolicy.java

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,10 @@ public interface WindowState {
140140
* @param displayFrame The frame of the overall display in which this
141141
* window can appear, used for constraining the overall dimensions
142142
* of the window.
143+
* @param systemFrame The frame within the display that any system
144+
* elements are currently covering. These indicate which parts of
145+
* the window should be considered completely obscured by the screen
146+
* decorations.
143147
* @param contentFrame The frame within the display in which we would
144148
* like active content to appear. This will cause windows behind to
145149
* be resized to match the given content frame.
@@ -151,7 +155,7 @@ public interface WindowState {
151155
* are visible.
152156
*/
153157
public void computeFrameLw(Rect parentFrame, Rect displayFrame,
154-
Rect contentFrame, Rect visibleFrame);
158+
Rect systemFrame, Rect contentFrame, Rect visibleFrame);
155159

156160
/**
157161
* Retrieve the current frame of the window that has been assigned by
@@ -173,11 +177,19 @@ public void computeFrameLw(Rect parentFrame, Rect displayFrame,
173177
* Retrieve the frame of the display that this window was last
174178
* laid out in. Must be called with the
175179
* window manager lock held.
176-
*
180+
*
177181
* @return Rect The rectangle holding the display frame.
178182
*/
179183
public Rect getDisplayFrameLw();
180184

185+
/**
186+
* Retrieve the frame of the system elements that last covered the window.
187+
* Must be called with the window manager lock held.
188+
*
189+
* @return Rect The rectangle holding the system frame.
190+
*/
191+
public Rect getSystemFrameLw();
192+
181193
/**
182194
* Retrieve the frame of the content area that this window was last
183195
* laid out in. This is the area in which the content of the window
@@ -297,6 +309,12 @@ public void computeFrameLw(Rect parentFrame, Rect displayFrame,
297309
*/
298310
boolean isDisplayedLw();
299311

312+
/**
313+
* Return true if this window (or a window it is attached to, but not
314+
* considering its app token) is currently animating.
315+
*/
316+
public boolean isAnimatingLw();
317+
300318
/**
301319
* Is this window considered to be gone for purposes of layout?
302320
*/
@@ -305,8 +323,6 @@ public void computeFrameLw(Rect parentFrame, Rect displayFrame,
305323
/**
306324
* Returns true if this window has been shown on screen at some time in
307325
* the past. Must be called with the window manager lock held.
308-
*
309-
* @return boolean
310326
*/
311327
public boolean hasDrawnLw();
312328

core/java/com/android/internal/view/BaseIWindow.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public void setSession(IWindowSession session) {
3333
mSession = session;
3434
}
3535

36-
public void resized(int w, int h, Rect coveredInsets,
36+
public void resized(int w, int h, Rect systemInsets, Rect contentInsets,
3737
Rect visibleInsets, boolean reportDraw, Configuration newConfig) {
3838
if (reportDraw) {
3939
try {

policy/src/com/android/internal/policy/impl/PhoneWindowManager.java

Lines changed: 56 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,9 @@ public void onInputEvent(InputEvent event) {
407407
// that area of the display from all other windows.
408408
int mRestrictedScreenLeft, mRestrictedScreenTop;
409409
int mRestrictedScreenWidth, mRestrictedScreenHeight;
410+
// During layout, the current screen borders accounting for any currently
411+
// visible system UI elements.
412+
int mSystemLeft, mSystemTop, mSystemRight, mSystemBottom;
410413
// For applications requesting stable content insets, these are them.
411414
int mStableLeft, mStableTop, mStableRight, mStableBottom;
412415
// During layout, the current screen borders with all outer decoration
@@ -423,6 +426,8 @@ public void onInputEvent(InputEvent event) {
423426
int mDockLeft, mDockTop, mDockRight, mDockBottom;
424427
// During layout, the layer at which the doc window is placed.
425428
int mDockLayer;
429+
// During layout, this is the layer of the status bar.
430+
int mStatusBarLayer;
426431
int mLastSystemUiFlags;
427432
// Bits that we are in the process of clearing, so we want to prevent
428433
// them from being set by applications until everything has been updated
@@ -438,6 +443,7 @@ public void onInputEvent(InputEvent event) {
438443

439444
static final Rect mTmpParentFrame = new Rect();
440445
static final Rect mTmpDisplayFrame = new Rect();
446+
static final Rect mTmpSystemFrame = new Rect();
441447
static final Rect mTmpContentFrame = new Rect();
442448
static final Rect mTmpVisibleFrame = new Rect();
443449
static final Rect mTmpNavigationFrame = new Rect();
@@ -2168,11 +2174,12 @@ public void beginLayoutLw(int displayWidth, int displayHeight, int displayRotati
21682174
mRestrictedScreenLeft = mRestrictedScreenTop = 0;
21692175
mRestrictedScreenWidth = displayWidth;
21702176
mRestrictedScreenHeight = displayHeight;
2171-
mDockLeft = mContentLeft = mStableLeft = mCurLeft = 0;
2172-
mDockTop = mContentTop = mStableTop = mCurTop = 0;
2173-
mDockRight = mContentRight = mStableRight = mCurRight = displayWidth;
2174-
mDockBottom = mContentBottom = mStableBottom = mCurBottom = displayHeight;
2177+
mDockLeft = mContentLeft = mStableLeft = mSystemLeft = mCurLeft = 0;
2178+
mDockTop = mContentTop = mStableTop = mSystemTop = mCurTop = 0;
2179+
mDockRight = mContentRight = mStableRight = mSystemRight = mCurRight = displayWidth;
2180+
mDockBottom = mContentBottom = mStableBottom = mSystemBottom = mCurBottom = displayHeight;
21752181
mDockLayer = 0x10000000;
2182+
mStatusBarLayer = -1;
21762183

21772184
// start with the current dock rect, which will be (0,0,displayWidth,displayHeight)
21782185
final Rect pf = mTmpParentFrame;
@@ -2232,6 +2239,12 @@ public void beginLayoutLw(int displayWidth, int displayHeight, int displayRotati
22322239
// We currently want to hide the navigation UI.
22332240
mNavigationBar.hideLw(true);
22342241
}
2242+
if (navVisible && !mNavigationBar.isAnimatingLw()) {
2243+
// If the nav bar is currently requested to be visible,
2244+
// and not in the process of animating on or off, then
2245+
// we can tell the app that it is covered by it.
2246+
mSystemBottom = mTmpNavigationFrame.top;
2247+
}
22352248
} else {
22362249
// Landscape screen; nav bar goes to the right.
22372250
int left = displayWidth - mNavigationBarWidthForRotation[displayRotation];
@@ -2250,16 +2263,23 @@ public void beginLayoutLw(int displayWidth, int displayHeight, int displayRotati
22502263
// We currently want to hide the navigation UI.
22512264
mNavigationBar.hideLw(true);
22522265
}
2266+
if (navVisible && !mNavigationBar.isAnimatingLw()) {
2267+
// If the nav bar is currently requested to be visible,
2268+
// and not in the process of animating on or off, then
2269+
// we can tell the app that it is covered by it.
2270+
mSystemRight = mTmpNavigationFrame.left;
2271+
}
22532272
}
22542273
// Make sure the content and current rectangles are updated to
22552274
// account for the restrictions from the navigation bar.
22562275
mContentTop = mCurTop = mDockTop;
22572276
mContentBottom = mCurBottom = mDockBottom;
22582277
mContentLeft = mCurLeft = mDockLeft;
22592278
mContentRight = mCurRight = mDockRight;
2279+
mStatusBarLayer = mNavigationBar.getSurfaceLayer();
22602280
// And compute the final frame.
22612281
mNavigationBar.computeFrameLw(mTmpNavigationFrame, mTmpNavigationFrame,
2262-
mTmpNavigationFrame, mTmpNavigationFrame);
2282+
mTmpNavigationFrame, mTmpNavigationFrame, mTmpNavigationFrame);
22632283
if (DEBUG_LAYOUT) Log.i(TAG, "mNavigationBar frame: " + mTmpNavigationFrame);
22642284
}
22652285
if (DEBUG_LAYOUT) Log.i(TAG, String.format("mDock rect: (%d,%d - %d,%d)",
@@ -2277,8 +2297,10 @@ public void beginLayoutLw(int displayWidth, int displayHeight, int displayRotati
22772297
vf.right = mStableRight;
22782298
vf.bottom = mStableBottom;
22792299

2300+
mStatusBarLayer = mStatusBar.getSurfaceLayer();
2301+
22802302
// Let the status bar determine its size.
2281-
mStatusBar.computeFrameLw(pf, df, vf, vf);
2303+
mStatusBar.computeFrameLw(pf, df, df, vf, vf);
22822304

22832305
// For layout, the status bar is always at the top with our fixed height.
22842306
mStableTop = mUnrestrictedScreenTop + mStatusBarHeight;
@@ -2303,6 +2325,12 @@ public void beginLayoutLw(int displayWidth, int displayHeight, int displayRotati
23032325
mContentLeft, mContentTop, mContentRight, mContentBottom,
23042326
mCurLeft, mCurTop, mCurRight, mCurBottom));
23052327
}
2328+
if (mStatusBar.isVisibleLw() && !mStatusBar.isAnimatingLw()) {
2329+
// If the status bar is currently requested to be visible,
2330+
// and not in the process of animating on or off, then
2331+
// we can tell the app that it is covered by it.
2332+
mSystemTop = mUnrestrictedScreenTop + mStatusBarHeight;
2333+
}
23062334
}
23072335
}
23082336

@@ -2368,6 +2396,7 @@ public void layoutWindowLw(WindowState win, WindowManager.LayoutParams attrs,
23682396

23692397
final Rect pf = mTmpParentFrame;
23702398
final Rect df = mTmpDisplayFrame;
2399+
final Rect sf = mTmpSystemFrame;
23712400
final Rect cf = mTmpContentFrame;
23722401
final Rect vf = mTmpVisibleFrame;
23732402

@@ -2611,14 +2640,28 @@ public void layoutWindowLw(WindowState win, WindowManager.LayoutParams attrs,
26112640
df.right = df.bottom = cf.right = cf.bottom = vf.right = vf.bottom = 10000;
26122641
}
26132642

2643+
// Compute the system frame. This is easy: for things behind the
2644+
// status bar, it is any application windows; otherwise it is not set.
2645+
int parentType = attached != null ? attached.getAttrs().type : attrs.type;
2646+
if (win.getSurfaceLayer() < mStatusBarLayer
2647+
&& parentType < WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW) {
2648+
sf.left = mSystemLeft;
2649+
sf.top = mSystemTop;
2650+
sf.right = mSystemRight;
2651+
sf.bottom = mSystemBottom;
2652+
} else {
2653+
sf.left = sf.top = -10000;
2654+
sf.right = sf.bottom = 10000;
2655+
}
2656+
26142657
if (DEBUG_LAYOUT) Log.v(TAG, "Compute frame " + attrs.getTitle()
26152658
+ ": sim=#" + Integer.toHexString(sim)
26162659
+ " attach=" + attached + " type=" + attrs.type
26172660
+ String.format(" flags=0x%08x", fl)
26182661
+ " pf=" + pf.toShortString() + " df=" + df.toShortString()
26192662
+ " cf=" + cf.toShortString() + " vf=" + vf.toShortString());
26202663

2621-
win.computeFrameLw(pf, df, cf, vf);
2664+
win.computeFrameLw(pf, df, sf, cf, vf);
26222665

26232666
// Dock windows carve out the bottom of the screen, so normal windows
26242667
// can't appear underneath them.
@@ -4193,6 +4236,10 @@ public void dump(String prefix, FileDescriptor fd, PrintWriter pw, String[] args
41934236
pw.print(","); pw.print(mStableTop);
41944237
pw.print(")-("); pw.print(mStableRight);
41954238
pw.print(","); pw.print(mStableBottom); pw.println(")");
4239+
pw.print(prefix); pw.print("mSystem=("); pw.print(mSystemLeft);
4240+
pw.print(","); pw.print(mSystemTop);
4241+
pw.print(")-("); pw.print(mSystemRight);
4242+
pw.print(","); pw.print(mSystemBottom); pw.println(")");
41964243
pw.print(prefix); pw.print("mCur=("); pw.print(mCurLeft);
41974244
pw.print(","); pw.print(mCurTop);
41984245
pw.print(")-("); pw.print(mCurRight);
@@ -4205,7 +4252,8 @@ public void dump(String prefix, FileDescriptor fd, PrintWriter pw, String[] args
42054252
pw.print(","); pw.print(mDockTop);
42064253
pw.print(")-("); pw.print(mDockRight);
42074254
pw.print(","); pw.print(mDockBottom); pw.println(")");
4208-
pw.print(prefix); pw.print("mDockLayer="); pw.println(mDockLayer);
4255+
pw.print(prefix); pw.print("mDockLayer="); pw.print(mDockLayer);
4256+
pw.print(" mStatusBarLayer="); pw.println(mStatusBarLayer);
42094257
pw.print(prefix); pw.print("mTopFullscreenOpaqueWindowState=");
42104258
pw.println(mTopFullscreenOpaqueWindowState);
42114259
pw.print(prefix); pw.print("mTopIsFullscreen="); pw.print(mTopIsFullscreen);

services/java/com/android/server/wm/Session.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,13 +151,14 @@ public void remove(IWindow window) {
151151

152152
public int relayout(IWindow window, int seq, WindowManager.LayoutParams attrs,
153153
int requestedWidth, int requestedHeight, int viewFlags,
154-
int flags, Rect outFrame, Rect outContentInsets,
154+
int flags, Rect outFrame, Rect outSystemInsets, Rect outContentInsets,
155155
Rect outVisibleInsets, Configuration outConfig, Surface outSurface) {
156156
if (false) Slog.d(WindowManagerService.TAG, ">>>>>> ENTERED relayout from "
157157
+ Binder.getCallingPid());
158158
int res = mService.relayoutWindow(this, window, seq, attrs,
159159
requestedWidth, requestedHeight, viewFlags, flags,
160-
outFrame, outContentInsets, outVisibleInsets, outConfig, outSurface);
160+
outFrame, outSystemInsets, outContentInsets, outVisibleInsets,
161+
outConfig, outSurface);
161162
if (false) Slog.d(WindowManagerService.TAG, "<<<<<< EXITING relayout to "
162163
+ Binder.getCallingPid());
163164
return res;

0 commit comments

Comments
 (0)