Fix configuration calculation when task is non-fullscreen
Apparently only the navigation bar is excluded when calculating
Configuration.screenLayout. Make the calculation for non-fullscreen
tasks consistent with fullscreen tasks.
Change-Id: I027e41e49ffe95245116f3d134e0bc93af0ee450
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index 16fd909..add1b96 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -243,7 +243,8 @@
// Bounds of the Task. null for fullscreen tasks.
Rect mBounds = null;
- private final Rect mTmpRect = new Rect();
+ private final Rect mTmpStableBounds = new Rect();
+ private final Rect mTmpNonDecorBounds = new Rect();
private final Rect mTmpRect2 = new Rect();
// Last non-fullscreen bounds the task was launched in or resized to.
@@ -1353,12 +1354,7 @@
if (stack == null || StackId.persistTaskBounds(stack.mStackId)) {
mLastNonFullscreenBounds = mBounds;
}
-
- // Stable insets need to be subtracted because we also subtract it in the fullscreen
- // configuration.
- mTmpRect.set(bounds);
- subtractStableInsets(mTmpRect, insetBounds != null ? insetBounds : mTmpRect);
- mOverrideConfig = calculateOverrideConfig(mTmpRect);
+ mOverrideConfig = calculateOverrideConfig(bounds, insetBounds);
}
if (mFullscreen != oldFullscreen) {
@@ -1368,6 +1364,16 @@
return !mOverrideConfig.equals(oldConfig) ? mOverrideConfig : null;
}
+ private void subtractNonDecorInsets(Rect inOutBounds, Rect inInsetBounds) {
+ mTmpRect2.set(inInsetBounds);
+ mService.mWindowManager.subtractNonDecorInsets(mTmpRect2);
+ int leftInset = mTmpRect2.left - inInsetBounds.left;
+ int topInset = mTmpRect2.top - inInsetBounds.top;
+ int rightInset = inInsetBounds.right - mTmpRect2.right;
+ int bottomInset = inInsetBounds.bottom - mTmpRect2.bottom;
+ inOutBounds.inset(leftInset, topInset, rightInset, bottomInset);
+ }
+
private void subtractStableInsets(Rect inOutBounds, Rect inInsetBounds) {
mTmpRect2.set(inInsetBounds);
mService.mWindowManager.subtractStableInsets(mTmpRect2);
@@ -1378,23 +1384,39 @@
inOutBounds.inset(leftInset, topInset, rightInset, bottomInset);
}
- Configuration calculateOverrideConfig(Rect bounds) {
+ private Configuration calculateOverrideConfig(Rect bounds, Rect insetBounds) {
+ mTmpNonDecorBounds.set(bounds);
+ mTmpStableBounds.set(bounds);
+ subtractNonDecorInsets(
+ mTmpNonDecorBounds, insetBounds != null ? insetBounds : bounds);
+ subtractStableInsets(
+ mTmpStableBounds, insetBounds != null ? insetBounds : bounds);
+
+ // For calculating screenWidthDp, screenWidthDp, we use the stable inset screen area,
+ // i.e. the screen area without the system bars.
final Configuration serviceConfig = mService.mConfiguration;
final Configuration config = new Configuration(Configuration.EMPTY);
// TODO(multidisplay): Update Dp to that of display stack is on.
final float density = serviceConfig.densityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE;
config.screenWidthDp =
- Math.min((int)(bounds.width() / density), serviceConfig.screenWidthDp);
+ Math.min((int)(mTmpStableBounds.width() / density), serviceConfig.screenWidthDp);
config.screenHeightDp =
- Math.min((int)(bounds.height() / density), serviceConfig.screenHeightDp);
- config.smallestScreenWidthDp =
- Math.min(config.screenWidthDp, config.screenHeightDp);
+ Math.min((int)(mTmpStableBounds.height() / density), serviceConfig.screenHeightDp);
+ config.smallestScreenWidthDp = Math.min(config.screenWidthDp, config.screenHeightDp);
+
+ // TODO: Orientation?
config.orientation = (config.screenWidthDp <= config.screenHeightDp)
? Configuration.ORIENTATION_PORTRAIT
: Configuration.ORIENTATION_LANDSCAPE;
+
+ // For calculating screen layout, we need to use the non-decor inset screen area for the
+ // calculation for compatibility reasons, i.e. screen area without system bars that could
+ // never go away in Honeycomb.
+ final int compatScreenWidthDp = (int)(mTmpNonDecorBounds.width() / density);
+ final int compatScreenHeightDp = (int)(mTmpNonDecorBounds.height() / density);
final int sl = Configuration.resetScreenLayout(serviceConfig.screenLayout);
- int longSize = Math.max(config.screenWidthDp, config.screenHeightDp);
- int shortSize = Math.min(config.screenWidthDp, config.screenHeightDp);
+ final int longSize = Math.max(compatScreenHeightDp, compatScreenWidthDp);
+ final int shortSize = Math.min(compatScreenHeightDp, compatScreenWidthDp);
config.screenLayout = Configuration.reduceScreenLayout(sl, longSize, shortSize);
return config;
}
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index e88b72f..44afbcc 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -6075,9 +6075,20 @@
public void getStableInsetsLw(int displayRotation, int displayWidth, int displayHeight,
Rect outInsets) {
outInsets.setEmpty();
+
+ // Navigation bar and status bar.
+ getNonDecorInsetsLw(displayRotation, displayWidth, displayHeight, outInsets);
if (mStatusBar != null) {
outInsets.top = mStatusBarHeight;
}
+ }
+
+ @Override
+ public void getNonDecorInsetsLw(int displayRotation, int displayWidth, int displayHeight,
+ Rect outInsets) {
+ outInsets.setEmpty();
+
+ // Only navigation bar
if (mNavigationBar != null) {
if (isNavigationBarOnBottom(displayWidth, displayHeight)) {
outInsets.bottom = getNavigationBarHeight(displayRotation, mUiMode);
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 882ac57..ee95212 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -10429,6 +10429,11 @@
mPolicy.getStableInsetsLw(di.rotation, di.logicalWidth, di.logicalHeight, outInsets);
}
+ private void getNonDecorInsetsLocked(Rect outInsets) {
+ final DisplayInfo di = getDefaultDisplayInfoLocked();
+ mPolicy.getNonDecorInsetsLw(di.rotation, di.logicalWidth, di.logicalHeight, outInsets);
+ }
+
/**
* Intersects the specified {@code inOutBounds} with the display frame that excludes the stable
* inset areas.
@@ -10445,6 +10450,23 @@
}
}
+ /**
+ * Intersects the specified {@code inOutBounds} with the display frame that excludes
+ * areas that could never be removed in Honeycomb. See
+ * {@link WindowManagerPolicy#getNonDecorInsetsLw}.
+ *
+ * @param inOutBounds The inOutBounds to subtract the inset areas from.
+ */
+ public void subtractNonDecorInsets(Rect inOutBounds) {
+ synchronized (mWindowMap) {
+ getNonDecorInsetsLocked(mTmpRect2);
+ final DisplayInfo di = getDefaultDisplayInfoLocked();
+ mTmpRect.set(0, 0, di.logicalWidth, di.logicalHeight);
+ mTmpRect.inset(mTmpRect2);
+ inOutBounds.intersect(mTmpRect);
+ }
+ }
+
private MousePositionTracker mMousePositionTracker = new MousePositionTracker();
private static class MousePositionTracker implements PointerEventListener {