Skip to content

Commit 56b53b5

Browse files
author
Dianne Hackborn
committed
Fix issue #5470311: Activity with android:configChanges defined...
...should not be restarted when rotating screen on xoom This was a side-effect of a previous fix to compute the screen layout config class based on the actual space available to the application, not the raw display size. On a device like Xoom, the system bar causes us to switch between LONG and NOTLONG depending on whether the system bar is on the short or long side of the screen. To fix this, we now compute the screen layout class the same way "smallest width" is computed: looking at all of the possible rotations and using the smallest of them all. In addition to preventing the device from toggling between long and notlong on a Xoom-like screen, this will also avoid other possible undersireable behavior like changing screen layout size when rotating. This does mean that Xoom is no longer considered a long screen even when in landscape, because it is not a long screen in portrait. Change-Id: I85f90a16294ef5a7de94d5b9231abbc6f914fe90
1 parent e7de36e commit 56b53b5

File tree

2 files changed

+97
-56
lines changed

2 files changed

+97
-56
lines changed

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1184,7 +1184,13 @@ public int getConfigDisplayWidth(int fullWidth, int fullHeight, int rotation) {
11841184
}
11851185

11861186
public int getConfigDisplayHeight(int fullWidth, int fullHeight, int rotation) {
1187-
return getNonDecorDisplayHeight(fullWidth, fullHeight, rotation);
1187+
// This is the same as getNonDecorDisplayHeight, unless the status bar
1188+
// can hide. If the status bar can hide, we don't count that as part
1189+
// of the decor; however for purposes of configurations, we do want to
1190+
// exclude it since applications can't generally use that part of the
1191+
// screen.
1192+
return getNonDecorDisplayHeight(fullWidth, fullHeight, rotation)
1193+
- (mStatusBarCanHide ? mStatusBarHeight : 0);
11881194
}
11891195

11901196
public boolean doesForceHide(WindowState win, WindowManager.LayoutParams attrs) {

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

Lines changed: 90 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -5809,7 +5809,87 @@ private int reduceConfigWidthSize(int curSize, int rotation, float density, int
58095809
return curSize;
58105810
}
58115811

5812-
private int computeSmallestWidth(boolean rotated, int dw, int dh, float density) {
5812+
private int reduceConfigLayout(int curLayout, int rotation, float density,
5813+
int dw, int dh) {
5814+
// Get the app screen size at this rotation.
5815+
int w = mPolicy.getNonDecorDisplayWidth(dw, dh, rotation);
5816+
int h = mPolicy.getNonDecorDisplayHeight(dw, dh, rotation);
5817+
5818+
// Compute the screen layout size class for this rotation.
5819+
int screenLayoutSize;
5820+
boolean screenLayoutLong;
5821+
boolean screenLayoutCompatNeeded;
5822+
int longSize = w;
5823+
int shortSize = h;
5824+
if (longSize < shortSize) {
5825+
int tmp = longSize;
5826+
longSize = shortSize;
5827+
shortSize = tmp;
5828+
}
5829+
longSize = (int)(longSize/density);
5830+
shortSize = (int)(shortSize/density);
5831+
5832+
// These semi-magic numbers define our compatibility modes for
5833+
// applications with different screens. These are guarantees to
5834+
// app developers about the space they can expect for a particular
5835+
// configuration. DO NOT CHANGE!
5836+
if (longSize < 470) {
5837+
// This is shorter than an HVGA normal density screen (which
5838+
// is 480 pixels on its long side).
5839+
screenLayoutSize = Configuration.SCREENLAYOUT_SIZE_SMALL;
5840+
screenLayoutLong = false;
5841+
screenLayoutCompatNeeded = false;
5842+
} else {
5843+
// What size is this screen screen?
5844+
if (longSize >= 960 && shortSize >= 720) {
5845+
// 1.5xVGA or larger screens at medium density are the point
5846+
// at which we consider it to be an extra large screen.
5847+
screenLayoutSize = Configuration.SCREENLAYOUT_SIZE_XLARGE;
5848+
} else if (longSize >= 640 && shortSize >= 480) {
5849+
// VGA or larger screens at medium density are the point
5850+
// at which we consider it to be a large screen.
5851+
screenLayoutSize = Configuration.SCREENLAYOUT_SIZE_LARGE;
5852+
} else {
5853+
screenLayoutSize = Configuration.SCREENLAYOUT_SIZE_NORMAL;
5854+
}
5855+
5856+
// If this screen is wider than normal HVGA, or taller
5857+
// than FWVGA, then for old apps we want to run in size
5858+
// compatibility mode.
5859+
if (shortSize > 321 || longSize > 570) {
5860+
screenLayoutCompatNeeded = true;
5861+
} else {
5862+
screenLayoutCompatNeeded = false;
5863+
}
5864+
5865+
// Is this a long screen?
5866+
if (((longSize*3)/5) >= (shortSize-1)) {
5867+
// Anything wider than WVGA (5:3) is considering to be long.
5868+
screenLayoutLong = true;
5869+
} else {
5870+
screenLayoutLong = false;
5871+
}
5872+
}
5873+
5874+
// Now reduce the last screenLayout to not be better than what we
5875+
// have found.
5876+
if (!screenLayoutLong) {
5877+
curLayout = (curLayout&~Configuration.SCREENLAYOUT_LONG_MASK)
5878+
| Configuration.SCREENLAYOUT_LONG_NO;
5879+
}
5880+
if (screenLayoutCompatNeeded) {
5881+
curLayout |= Configuration.SCREENLAYOUT_COMPAT_NEEDED;
5882+
}
5883+
int curSize = curLayout&Configuration.SCREENLAYOUT_SIZE_MASK;
5884+
if (screenLayoutSize < curSize) {
5885+
curLayout = (curLayout&~Configuration.SCREENLAYOUT_SIZE_MASK)
5886+
| screenLayoutSize;
5887+
}
5888+
return curLayout;
5889+
}
5890+
5891+
private void computeSmallestWidthAndScreenLayout(boolean rotated, int dw, int dh,
5892+
float density, Configuration outConfig) {
58135893
// We need to determine the smallest width that will occur under normal
58145894
// operation. To this, start with the base screen size and compute the
58155895
// width under the different possible rotations. We need to un-rotate
@@ -5826,7 +5906,14 @@ private int computeSmallestWidth(boolean rotated, int dw, int dh, float density)
58265906
sw = reduceConfigWidthSize(sw, Surface.ROTATION_90, density, unrotDh, unrotDw);
58275907
sw = reduceConfigWidthSize(sw, Surface.ROTATION_180, density, unrotDw, unrotDh);
58285908
sw = reduceConfigWidthSize(sw, Surface.ROTATION_270, density, unrotDh, unrotDw);
5829-
return sw;
5909+
int sl = Configuration.SCREENLAYOUT_SIZE_XLARGE
5910+
| Configuration.SCREENLAYOUT_LONG_YES;
5911+
sl = reduceConfigLayout(sl, Surface.ROTATION_0, density, unrotDw, unrotDh);
5912+
sl = reduceConfigLayout(sl, Surface.ROTATION_90, density, unrotDh, unrotDw);
5913+
sl = reduceConfigLayout(sl, Surface.ROTATION_180, density, unrotDw, unrotDh);
5914+
sl = reduceConfigLayout(sl, Surface.ROTATION_270, density, unrotDh, unrotDw);
5915+
outConfig.smallestScreenWidthDp = sw;
5916+
outConfig.screenLayout = sl;
58305917
}
58315918

58325919
private int reduceCompatConfigWidthSize(int curSize, int rotation, DisplayMetrics dm,
@@ -5924,64 +6011,12 @@ boolean computeNewConfigurationLocked(Configuration config) {
59246011
/ dm.density);
59256012
config.screenHeightDp = (int)(mPolicy.getConfigDisplayHeight(dw, dh, mRotation)
59266013
/ dm.density);
5927-
config.smallestScreenWidthDp = computeSmallestWidth(rotated, dw, dh, dm.density);
6014+
computeSmallestWidthAndScreenLayout(rotated, dw, dh, dm.density, config);
59286015

59296016
config.compatScreenWidthDp = (int)(config.screenWidthDp / mCompatibleScreenScale);
59306017
config.compatScreenHeightDp = (int)(config.screenHeightDp / mCompatibleScreenScale);
59316018
config.compatSmallestScreenWidthDp = computeCompatSmallestWidth(rotated, dm, dw, dh);
59326019

5933-
// Compute the screen layout size class.
5934-
int screenLayout;
5935-
int longSize = mAppDisplayWidth;
5936-
int shortSize = mAppDisplayHeight;
5937-
if (longSize < shortSize) {
5938-
int tmp = longSize;
5939-
longSize = shortSize;
5940-
shortSize = tmp;
5941-
}
5942-
longSize = (int)(longSize/dm.density);
5943-
shortSize = (int)(shortSize/dm.density);
5944-
5945-
// These semi-magic numbers define our compatibility modes for
5946-
// applications with different screens. These are guarantees to
5947-
// app developers about the space they can expect for a particular
5948-
// configuration. DO NOT CHANGE!
5949-
if (longSize < 470) {
5950-
// This is shorter than an HVGA normal density screen (which
5951-
// is 480 pixels on its long side).
5952-
screenLayout = Configuration.SCREENLAYOUT_SIZE_SMALL
5953-
| Configuration.SCREENLAYOUT_LONG_NO;
5954-
} else {
5955-
// What size is this screen screen?
5956-
if (longSize >= 960 && shortSize >= 720) {
5957-
// 1.5xVGA or larger screens at medium density are the point
5958-
// at which we consider it to be an extra large screen.
5959-
screenLayout = Configuration.SCREENLAYOUT_SIZE_XLARGE;
5960-
} else if (longSize >= 640 && shortSize >= 480) {
5961-
// VGA or larger screens at medium density are the point
5962-
// at which we consider it to be a large screen.
5963-
screenLayout = Configuration.SCREENLAYOUT_SIZE_LARGE;
5964-
} else {
5965-
screenLayout = Configuration.SCREENLAYOUT_SIZE_NORMAL;
5966-
}
5967-
5968-
// If this screen is wider than normal HVGA, or taller
5969-
// than FWVGA, then for old apps we want to run in size
5970-
// compatibility mode.
5971-
if (shortSize > 321 || longSize > 570) {
5972-
screenLayout |= Configuration.SCREENLAYOUT_COMPAT_NEEDED;
5973-
}
5974-
5975-
// Is this a long screen?
5976-
if (((longSize*3)/5) >= (shortSize-1)) {
5977-
// Anything wider than WVGA (5:3) is considering to be long.
5978-
screenLayout |= Configuration.SCREENLAYOUT_LONG_YES;
5979-
} else {
5980-
screenLayout |= Configuration.SCREENLAYOUT_LONG_NO;
5981-
}
5982-
}
5983-
config.screenLayout = screenLayout;
5984-
59856020
// Determine whether a hard keyboard is available and enabled.
59866021
boolean hardKeyboardAvailable = config.keyboard != Configuration.KEYBOARD_NOKEYS;
59876022
if (hardKeyboardAvailable != mHardKeyboardAvailable) {

0 commit comments

Comments
 (0)