From 82c9dc951e8e19b9eab6120b6465e08c5d69beba Mon Sep 17 00:00:00 2001 From: Jorim Jaggi Date: Fri, 5 Feb 2016 15:10:33 -0800 Subject: [PATCH] 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 --- .../android/view/WindowManagerPolicy.java | 16 +++++- .../com/android/server/am/TaskRecord.java | 50 +++++++++++++------ .../server/policy/PhoneWindowManager.java | 11 ++++ .../server/wm/WindowManagerService.java | 22 ++++++++ 4 files changed, 83 insertions(+), 16 deletions(-) diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java index 609c471dfa18e..a8b7a7b8a8db8 100644 --- a/core/java/android/view/WindowManagerPolicy.java +++ b/core/java/android/view/WindowManagerPolicy.java @@ -631,7 +631,7 @@ public interface WindowManagerPolicy { /** * Return the display width available after excluding any screen - * decorations that can never be removed. That is, system bar or + * decorations that could never be removed in Honeycomb. That is, system bar or * button bar. */ public int getNonDecorDisplayWidth(int fullWidth, int fullHeight, int rotation, @@ -639,7 +639,7 @@ public interface WindowManagerPolicy { /** * Return the display height available after excluding any screen - * decorations that can never be removed. That is, system bar or + * decorations that could never be removed in Honeycomb. That is, system bar or * button bar. */ public int getNonDecorDisplayHeight(int fullWidth, int fullHeight, int rotation, @@ -1350,4 +1350,16 @@ public interface WindowManagerPolicy { */ public void getStableInsetsLw(int displayRotation, int displayWidth, int displayHeight, Rect outInsets); + + /** + * Calculates the insets for the areas that could never be removed in Honeycomb, i.e. system + * bar or button bar. See {@link #getNonDecorDisplayWidth}. + * + * @param displayRotation the current display rotation + * @param displayWidth the current display width + * @param displayHeight the current display height + * @param outInsets the insets to return + */ + public void getNonDecorInsetsLw(int displayRotation, int displayWidth, int displayHeight, + Rect outInsets); } diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java index 16fd909b329a3..add1b9642affd 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 @@ final class TaskRecord { // 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 @@ final class TaskRecord { 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 @@ final class TaskRecord { 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 @@ final class TaskRecord { 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 e88b72f7366dd..44afbcc1052a3 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 class PhoneWindowManager implements WindowManagerPolicy { 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 882ac57b124b0..ee95212c5fcf9 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 @@ public class WindowManagerService extends IWindowManager.Stub 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 @@ public class WindowManagerService extends IWindowManager.Stub } } + /** + * 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 {