Skip to content

Commit 1f903c3

Browse files
author
Dianne Hackborn
committed
Fix issue #5283365: Rotating the device to portrait mode, hides the keyboard partly
PhoneWindowManager now takes full responsibility for deciding where the navigation bar goes. This gets rid of a bunch of race conditions with determining layout while the nav bar is moving itself at the same time the window manager is computing a new configuration. Note that this breaks the "nav bar on left" option. The current nav bar code could also be cleaned up some more to completely drive its behavior based on onSizeChanged() happening during relayout. Change-Id: I1651d74c3464ba0d588aab3049e099c78420146a
1 parent 4e2134b commit 1f903c3

File tree

4 files changed

+60
-79
lines changed

4 files changed

+60
-79
lines changed

core/java/android/view/WindowManagerPolicy.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -478,30 +478,30 @@ public void init(Context context, IWindowManager windowManager,
478478
* decorations that can never be removed. That is, system bar or
479479
* button bar.
480480
*/
481-
public int getNonDecorDisplayWidth(int rotation, int fullWidth);
481+
public int getNonDecorDisplayWidth(int fullWidth, int fullHeight, int rotation);
482482

483483
/**
484484
* Return the display height available after excluding any screen
485485
* decorations that can never be removed. That is, system bar or
486486
* button bar.
487487
*/
488-
public int getNonDecorDisplayHeight(int rotation, int fullHeight);
488+
public int getNonDecorDisplayHeight(int fullWidth, int fullHeight, int rotation);
489489

490490
/**
491491
* Return the available screen width that we should report for the
492492
* configuration. This must be no larger than
493493
* {@link #getNonDecorDisplayWidth(int, int)}; it may be smaller than
494494
* that to account for more transient decoration like a status bar.
495495
*/
496-
public int getConfigDisplayWidth(int rotation, int fullWidth);
496+
public int getConfigDisplayWidth(int fullWidth, int fullHeight, int rotation);
497497

498498
/**
499499
* Return the available screen height that we should report for the
500500
* configuration. This must be no larger than
501501
* {@link #getNonDecorDisplayHeight(int, int)}; it may be smaller than
502502
* that to account for more transient decoration like a status bar.
503503
*/
504-
public int getConfigDisplayHeight(int rotation, int fullHeight);
504+
public int getConfigDisplayHeight(int fullWidth, int fullHeight, int rotation);
505505

506506
/**
507507
* Return whether the given window should forcibly hide everything
@@ -671,8 +671,10 @@ public int prepareAddWindowLw(WindowState win,
671671
*
672672
* @param displayWidth The current full width of the screen.
673673
* @param displayHeight The current full height of the screen.
674+
* @param displayRotation The current rotation being applied to the base
675+
* window.
674676
*/
675-
public void beginLayoutLw(int displayWidth, int displayHeight);
677+
public void beginLayoutLw(int displayWidth, int displayHeight, int displayRotation);
676678

677679
/**
678680
* Called for each window attached to the window manager as layout is

packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java

Lines changed: 1 addition & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -469,20 +469,10 @@ private void repositionNavigationBar() {
469469
}
470470

471471
private WindowManager.LayoutParams getNavigationBarLayoutParams() {
472-
final int rotation = mDisplay.getRotation();
473-
final boolean sideways =
474-
(rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270);
475-
476-
final Resources res = mContext.getResources();
477-
final int size = res.getDimensionPixelSize(R.dimen.navigation_bar_size);
478-
479472
WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
480-
sideways ? size : ViewGroup.LayoutParams.MATCH_PARENT,
481-
sideways ? ViewGroup.LayoutParams.MATCH_PARENT : size,
473+
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT,
482474
WindowManager.LayoutParams.TYPE_NAVIGATION_BAR,
483475
0
484-
| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
485-
| WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
486476
| WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
487477
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
488478
| WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
@@ -494,21 +484,6 @@ private WindowManager.LayoutParams getNavigationBarLayoutParams() {
494484
}
495485

496486
lp.setTitle("NavigationBar");
497-
switch (rotation) {
498-
case Surface.ROTATION_90:
499-
// device has been turned 90deg counter-clockwise
500-
lp.gravity = Gravity.RIGHT | Gravity.FILL_VERTICAL;
501-
break;
502-
case Surface.ROTATION_270:
503-
// device has been turned 90deg clockwise
504-
lp.gravity = (NavigationBarView.NAVBAR_ALWAYS_AT_RIGHT ? Gravity.RIGHT
505-
: Gravity.LEFT)
506-
| Gravity.FILL_VERTICAL;
507-
break;
508-
default:
509-
lp.gravity = Gravity.BOTTOM | Gravity.FILL_HORIZONTAL;
510-
break;
511-
}
512487
lp.windowAnimations = 0;
513488

514489
return lp;

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

Lines changed: 37 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,7 @@ public void handleMotion(MotionEvent event, InputQueue.FinishedCallback finished
345345
static final Rect mTmpDisplayFrame = new Rect();
346346
static final Rect mTmpContentFrame = new Rect();
347347
static final Rect mTmpVisibleFrame = new Rect();
348+
static final Rect mTmpNavigationFrame = new Rect();
348349

349350
WindowState mTopFullscreenOpaqueWindowState;
350351
WindowState mTopAppWindowState;
@@ -1125,27 +1126,27 @@ public boolean canStatusBarHide() {
11251126
return mStatusBarCanHide;
11261127
}
11271128

1128-
public int getNonDecorDisplayWidth(int rotation, int fullWidth) {
1129+
public int getNonDecorDisplayWidth(int fullWidth, int fullHeight, int rotation) {
11291130
// Assumes that the navigation bar appears on the side of the display in landscape.
1130-
final boolean horizontal
1131-
= (rotation == Surface.ROTATION_270 || rotation == Surface.ROTATION_90);
1132-
return fullWidth - (horizontal ? mNavigationBarWidth : 0);
1131+
if (fullWidth > fullHeight) {
1132+
return fullWidth - mNavigationBarWidth;
1133+
}
1134+
return fullWidth;
11331135
}
11341136

1135-
public int getNonDecorDisplayHeight(int rotation, int fullHeight) {
1136-
final boolean horizontal
1137-
= (rotation == Surface.ROTATION_270 || rotation == Surface.ROTATION_90);
1137+
public int getNonDecorDisplayHeight(int fullWidth, int fullHeight, int rotation) {
1138+
// Assumes the navigation bar appears on the bottom of the display in portrait.
11381139
return fullHeight
11391140
- (mStatusBarCanHide ? 0 : mStatusBarHeight)
1140-
- (horizontal ? 0 : mNavigationBarHeight);
1141+
- ((fullWidth > fullHeight) ? 0 : mNavigationBarHeight);
11411142
}
11421143

1143-
public int getConfigDisplayWidth(int rotation, int fullWidth) {
1144-
return getNonDecorDisplayWidth(rotation, fullWidth);
1144+
public int getConfigDisplayWidth(int fullWidth, int fullHeight, int rotation) {
1145+
return getNonDecorDisplayWidth(fullWidth, fullHeight, rotation);
11451146
}
11461147

1147-
public int getConfigDisplayHeight(int rotation, int fullHeight) {
1148-
return getNonDecorDisplayHeight(rotation, fullHeight);
1148+
public int getConfigDisplayHeight(int fullWidth, int fullHeight, int rotation) {
1149+
return getNonDecorDisplayHeight(fullWidth, fullHeight, rotation);
11491150
}
11501151

11511152
public boolean doesForceHide(WindowState win, WindowManager.LayoutParams attrs) {
@@ -1687,7 +1688,7 @@ public void getContentInsetHintLw(WindowManager.LayoutParams attrs, Rect content
16871688
}
16881689

16891690
/** {@inheritDoc} */
1690-
public void beginLayoutLw(int displayWidth, int displayHeight) {
1691+
public void beginLayoutLw(int displayWidth, int displayHeight, int displayRotation) {
16911692
mUnrestrictedScreenLeft = mUnrestrictedScreenTop = 0;
16921693
mUnrestrictedScreenWidth = displayWidth;
16931694
mUnrestrictedScreenHeight = displayHeight;
@@ -1713,30 +1714,31 @@ public void beginLayoutLw(int displayWidth, int displayHeight) {
17131714
if (mStatusBar != null) {
17141715
Rect navr = null;
17151716
if (mNavigationBar != null) {
1716-
mNavigationBar.computeFrameLw(pf, df, vf, vf);
1717-
if (mNavigationBar.isVisibleLw()) {
1718-
navr = mNavigationBar.getFrameLw();
1719-
1720-
if (navr.top == 0) {
1721-
// Navigation bar is vertical
1722-
if (mDockLeft == navr.left) {
1723-
mDockLeft = navr.right;
1724-
} else if (mDockRight == navr.right) {
1725-
mDockRight = navr.left;
1726-
}
1727-
} else {
1728-
// Navigation bar horizontal, at bottom
1729-
if (mDockBottom == navr.bottom) {
1730-
mDockBottom = navr.top;
1731-
}
1717+
// Force the navigation bar to its appropriate place and
1718+
// size. We need to do this directly, instead of relying on
1719+
// it to bubble up from the nav bar, because this needs to
1720+
// change atomically with screen rotations.
1721+
if (displayWidth < displayHeight) {
1722+
// Portrait screen; nav bar goes on bottom.
1723+
mTmpNavigationFrame.set(0, displayHeight-mNavigationBarHeight,
1724+
displayWidth, displayHeight);
1725+
if (mNavigationBar.isVisibleLw()) {
1726+
mDockBottom = mTmpNavigationFrame.top;
1727+
}
1728+
} else {
1729+
// Landscape screen; nav bar goes to the right.
1730+
mTmpNavigationFrame.set(displayWidth-mNavigationBarWidth, 0,
1731+
displayWidth, displayHeight);
1732+
if (mNavigationBar.isVisibleLw()) {
1733+
mDockRight = mTmpNavigationFrame.left;
17321734
}
17331735
}
1736+
mNavigationBar.computeFrameLw(mTmpNavigationFrame, mTmpNavigationFrame,
1737+
mTmpNavigationFrame, mTmpNavigationFrame);
1738+
if (DEBUG_LAYOUT) Log.i(TAG, "mNavigationBar frame: " + mTmpNavigationFrame);
17341739
}
1735-
if (DEBUG_LAYOUT) {
1736-
Log.i(TAG, "mNavigationBar frame: " + navr);
1737-
Log.i(TAG, String.format("mDock rect: (%d,%d - %d,%d)",
1738-
mDockLeft, mDockTop, mDockRight, mDockBottom));
1739-
}
1740+
if (DEBUG_LAYOUT) Log.i(TAG, String.format("mDock rect: (%d,%d - %d,%d)",
1741+
mDockLeft, mDockTop, mDockRight, mDockBottom));
17401742

17411743
// apply navigation bar insets
17421744
pf.left = df.left = vf.left = mDockLeft;
@@ -1862,7 +1864,7 @@ void setAttachedWindowFrames(WindowState win, int fl, int adjust,
18621864
public void layoutWindowLw(WindowState win, WindowManager.LayoutParams attrs,
18631865
WindowState attached) {
18641866
// we've already done the status bar
1865-
if (win == mStatusBar) {
1867+
if (win == mStatusBar || win == mNavigationBar) {
18661868
return;
18671869
}
18681870

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

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5701,8 +5701,8 @@ Configuration computeNewConfigurationLocked() {
57015701
return config;
57025702
}
57035703

5704-
private int reduceConfigWidthSize(int curSize, int rotation, float density, int dw) {
5705-
int size = (int)(mPolicy.getConfigDisplayWidth(rotation, dw) / density);
5704+
private int reduceConfigWidthSize(int curSize, int rotation, float density, int dw, int dh) {
5705+
int size = (int)(mPolicy.getConfigDisplayWidth(dw, dh, rotation) / density);
57065706
if (size < curSize) {
57075707
curSize = size;
57085708
}
@@ -5722,17 +5722,17 @@ private int computeSmallestWidth(boolean rotated, int dw, int dh, float density)
57225722
unrotDw = dw;
57235723
unrotDh = dh;
57245724
}
5725-
int sw = reduceConfigWidthSize(unrotDw, Surface.ROTATION_0, density, unrotDw);
5726-
sw = reduceConfigWidthSize(sw, Surface.ROTATION_90, density, unrotDh);
5727-
sw = reduceConfigWidthSize(sw, Surface.ROTATION_180, density, unrotDw);
5728-
sw = reduceConfigWidthSize(sw, Surface.ROTATION_270, density, unrotDh);
5725+
int sw = reduceConfigWidthSize(unrotDw, Surface.ROTATION_0, density, unrotDw, unrotDh);
5726+
sw = reduceConfigWidthSize(sw, Surface.ROTATION_90, density, unrotDw, unrotDh);
5727+
sw = reduceConfigWidthSize(sw, Surface.ROTATION_180, density, unrotDw, unrotDh);
5728+
sw = reduceConfigWidthSize(sw, Surface.ROTATION_270, density, unrotDw, unrotDh);
57295729
return sw;
57305730
}
57315731

57325732
private int reduceCompatConfigWidthSize(int curSize, int rotation, DisplayMetrics dm,
57335733
int dw, int dh) {
5734-
dm.noncompatWidthPixels = mPolicy.getNonDecorDisplayWidth(rotation, dw);
5735-
dm.noncompatHeightPixels = mPolicy.getNonDecorDisplayHeight(rotation, dh);
5734+
dm.noncompatWidthPixels = mPolicy.getNonDecorDisplayWidth(dw, dh, rotation);
5735+
dm.noncompatHeightPixels = mPolicy.getNonDecorDisplayHeight(dw, dh, rotation);
57365736
float scale = CompatibilityInfo.computeCompatibleScaling(dm, null);
57375737
int size = (int)(((dm.noncompatWidthPixels / scale) / dm.density) + .5f);
57385738
if (curSize == 0 || size < curSize) {
@@ -5809,15 +5809,17 @@ boolean computeNewConfigurationLocked(Configuration config) {
58095809

58105810
// Update application display metrics.
58115811
final DisplayMetrics dm = mDisplayMetrics;
5812-
mAppDisplayWidth = mPolicy.getNonDecorDisplayWidth(mRotation, dw);
5813-
mAppDisplayHeight = mPolicy.getNonDecorDisplayHeight(mRotation, dh);
5812+
mAppDisplayWidth = mPolicy.getNonDecorDisplayWidth(dw, dh, mRotation);
5813+
mAppDisplayHeight = mPolicy.getNonDecorDisplayHeight(dw, dh, mRotation);
58145814
mDisplay.getMetricsWithSize(dm, mAppDisplayWidth, mAppDisplayHeight);
58155815

58165816
mCompatibleScreenScale = CompatibilityInfo.computeCompatibleScaling(dm,
58175817
mCompatDisplayMetrics);
58185818

5819-
config.screenWidthDp = (int)(mPolicy.getConfigDisplayWidth(mRotation, dw) / dm.density);
5820-
config.screenHeightDp = (int)(mPolicy.getConfigDisplayHeight(mRotation, dh) / dm.density);
5819+
config.screenWidthDp = (int)(mPolicy.getConfigDisplayWidth(dw, dh, mRotation)
5820+
/ dm.density);
5821+
config.screenHeightDp = (int)(mPolicy.getConfigDisplayHeight(dw, dh, mRotation)
5822+
/ dm.density);
58215823
config.smallestScreenWidthDp = computeSmallestWidth(rotated, dw, dh, dm.density);
58225824

58235825
config.compatScreenWidthDp = (int)(config.screenWidthDp / mCompatibleScreenScale);
@@ -7151,7 +7153,7 @@ private final int performLayoutLockedInner(boolean initial, boolean updateInputW
71517153
if (DEBUG_LAYOUT) Slog.v(TAG, "performLayout: needed="
71527154
+ mLayoutNeeded + " dw=" + dw + " dh=" + dh);
71537155

7154-
mPolicy.beginLayoutLw(dw, dh);
7156+
mPolicy.beginLayoutLw(dw, dh, mRotation);
71557157

71567158
int seq = mLayoutSeq+1;
71577159
if (seq < 0) seq = 0;

0 commit comments

Comments
 (0)