From 81e56d535c853d73ff537357da5b935f51cb779d Mon Sep 17 00:00:00 2001 From: Dianne Hackborn Date: Thu, 26 May 2011 00:55:58 -0700 Subject: [PATCH] Rework how we decide whether to use system or status bar. The PhoneWindowManager is now responsible for determing this, since it needs to do this before we can generate the configuration since we need to take into account the system bar size we will use. Also the Display should now report the screen height without including the system bar. Change-Id: I82dfcc5e327e4d13d82c373c6c870f557a99b757 --- core/java/android/app/ContextImpl.java | 3 -- .../content/res/CompatibilityInfo.java | 8 ++-- core/java/android/util/DisplayMetrics.java | 24 ++++++---- core/java/android/view/Display.java | 44 ++++++++++------- core/java/android/view/IWindowManager.aidl | 3 ++ .../android/view/WindowManagerPolicy.java | 6 +++ core/res/res/values-large/config.xml | 2 - core/res/res/values-sw600dp/config.xml | 2 - core/res/res/values/config.xml | 2 - core/res/res/values/dimens.xml | 6 ++- packages/SystemUI/res/values-large/config.xml | 7 --- packages/SystemUI/res/values/config.xml | 10 ++-- .../com/android/systemui/SystemUIService.java | 16 ++++++- .../statusbar/tablet/TabletStatusBar.java | 4 +- .../policy/impl/PhoneWindowManager.java | 29 ++++++++---- .../server/wm/WindowManagerService.java | 47 +++++++++++-------- 16 files changed, 129 insertions(+), 84 deletions(-) diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index 51f1e3d123070..73170bb490216 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -425,9 +425,6 @@ class ContextImpl extends Context { registerService(WINDOW_SERVICE, new ServiceFetcher() { public Object getService(ContextImpl ctx) { - RuntimeException e = new RuntimeException("foo"); - e.fillInStackTrace(); - Log.i(TAG, "Getting window manager", e); CompatibilityInfo ci = ctx.mResources.getCompatibilityInfo(); return WindowManagerImpl.getDefault(ci); }}); diff --git a/core/java/android/content/res/CompatibilityInfo.java b/core/java/android/content/res/CompatibilityInfo.java index dca53a8e2d490..8d725cd8f28b5 100644 --- a/core/java/android/content/res/CompatibilityInfo.java +++ b/core/java/android/content/res/CompatibilityInfo.java @@ -392,8 +392,8 @@ public class CompatibilityInfo implements Parcelable { // compatible with large screens, so diddle it. CompatibilityInfo.updateCompatibleScreenFrame(inoutDm, null, inoutDm); } else { - inoutDm.widthPixels = inoutDm.realWidthPixels; - inoutDm.heightPixels = inoutDm.realHeightPixels; + inoutDm.widthPixels = inoutDm.unscaledWidthPixels; + inoutDm.heightPixels = inoutDm.unscaledHeightPixels; } if (isScalingRequired()) { @@ -429,8 +429,8 @@ public class CompatibilityInfo implements Parcelable { */ public static float updateCompatibleScreenFrame(DisplayMetrics dm, Rect outRect, DisplayMetrics outDm) { - final int width = dm.realWidthPixels; - final int height = dm.realHeightPixels; + final int width = dm.unscaledWidthPixels; + final int height = dm.unscaledHeightPixels; int shortSize, longSize; if (width < height) { shortSize = width; diff --git a/core/java/android/util/DisplayMetrics.java b/core/java/android/util/DisplayMetrics.java index 8018ff901fbe9..60a4ef21c4408 100644 --- a/core/java/android/util/DisplayMetrics.java +++ b/core/java/android/util/DisplayMetrics.java @@ -105,10 +105,18 @@ public class DisplayMetrics { */ public float ydpi; - /** @hide */ - public int realWidthPixels; - /** @hide */ - public int realHeightPixels; + /** + * The reported display width prior to any compatibility mode scaling + * being applied. + * @hide + */ + public int unscaledWidthPixels; + /** + * The reported display height prior to any compatibility mode scaling + * being applied. + * @hide + */ + public int unscaledHeightPixels; public DisplayMetrics() { } @@ -121,8 +129,8 @@ public class DisplayMetrics { scaledDensity = o.scaledDensity; xdpi = o.xdpi; ydpi = o.ydpi; - realWidthPixels = o.realWidthPixels; - realHeightPixels = o.realHeightPixels; + unscaledWidthPixels = o.unscaledWidthPixels; + unscaledHeightPixels = o.unscaledHeightPixels; } public void setToDefaults() { @@ -133,8 +141,8 @@ public class DisplayMetrics { scaledDensity = density; xdpi = DENSITY_DEVICE; ydpi = DENSITY_DEVICE; - realWidthPixels = 0; - realHeightPixels = 0; + unscaledWidthPixels = 0; + unscaledHeightPixels = 0; } @Override diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java index b5d36d9ae92fe..80325463545fd 100644 --- a/core/java/android/view/Display.java +++ b/core/java/android/view/Display.java @@ -80,25 +80,37 @@ public class Display { * adjusted for you based on the current rotation of the display. */ public void getSize(Point outSize) { + getSizeInternal(outSize, true); + } + + /** + * Returns the raw size of the display, in pixels. Note that this + * should not generally be used for computing layouts, since + * a device will typically have screen decoration (such as a status bar) + * along the edges of the display that reduce the amount of application + * space available from the raw size returned here. This value is + * adjusted for you based on the current rotation of the display. + */ + private void getSizeInternal(Point outSize, boolean doCompat) { try { IWindowManager wm = getWindowManager(); if (wm != null) { wm.getDisplaySize(outSize); + if (doCompat && mCompatibilityInfo != null) { + synchronized (mTmpMetrics) { + mTmpMetrics.unscaledWidthPixels = outSize.x; + mTmpMetrics.unscaledHeightPixels = outSize.y; + mTmpMetrics.density = mDensity; + mCompatibilityInfo.applyToDisplayMetrics(mTmpMetrics); + outSize.x = mTmpMetrics.widthPixels; + outSize.y = mTmpMetrics.heightPixels; + } + } } else { // This is just for boot-strapping, initializing the // system process before the window manager is up. outSize.y = getRealHeight(); } - if (mCompatibilityInfo != null) { - synchronized (mTmpMetrics) { - mTmpMetrics.realWidthPixels = outSize.x; - mTmpMetrics.realHeightPixels = outSize.y; - mTmpMetrics.density = mDensity; - mCompatibilityInfo.applyToDisplayMetrics(mTmpMetrics); - outSize.x = mTmpMetrics.widthPixels; - outSize.y = mTmpMetrics.heightPixels; - } - } } catch (RemoteException e) { Slog.w("Display", "Unable to get display size", e); } @@ -109,7 +121,7 @@ public class Display { */ public void getRectSize(Rect outSize) { synchronized (mTmpPoint) { - getSize(mTmpPoint); + getSizeInternal(mTmpPoint, true); outSize.set(0, 0, mTmpPoint.x, mTmpPoint.y); } } @@ -137,7 +149,7 @@ public class Display { synchronized (mTmpPoint) { long now = SystemClock.uptimeMillis(); if (now > (mLastGetTime+20)) { - getSize(mTmpPoint); + getSizeInternal(mTmpPoint, true); mLastGetTime = now; } return mTmpPoint.x; @@ -152,7 +164,7 @@ public class Display { synchronized (mTmpPoint) { long now = SystemClock.uptimeMillis(); if (now > (mLastGetTime+20)) { - getSize(mTmpPoint); + getSizeInternal(mTmpPoint, true); mLastGetTime = now; } return mTmpPoint.y; @@ -218,7 +230,7 @@ public class Display { */ public void getMetrics(DisplayMetrics outMetrics) { synchronized (mTmpPoint) { - getSize(mTmpPoint); + getSizeInternal(mTmpPoint, false); outMetrics.widthPixels = mTmpPoint.x; outMetrics.heightPixels = mTmpPoint.y; } @@ -248,8 +260,8 @@ public class Display { outMetrics.xdpi = mDpiX; outMetrics.ydpi = mDpiY; - outMetrics.realWidthPixels = outMetrics.widthPixels; - outMetrics.realHeightPixels = outMetrics.heightPixels; + outMetrics.unscaledWidthPixels = outMetrics.widthPixels; + outMetrics.unscaledHeightPixels = outMetrics.heightPixels; } static IWindowManager getWindowManager() { diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl index adafb59aac3a4..bdf04ab006539 100644 --- a/core/java/android/view/IWindowManager.aidl +++ b/core/java/android/view/IWindowManager.aidl @@ -59,6 +59,9 @@ interface IWindowManager void setForcedDisplaySize(int longDimen, int shortDimen); void clearForcedDisplaySize(); + // Is device configured with a hideable status bar or a tablet system bar? + boolean canStatusBarHide(); + // These can only be called when injecting events to your own window, // or by holding the INJECT_EVENTS permission. These methods may block // until pending input events are finished being dispatched even when 'sync' is false. diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java index 086ed5a1d4a2d..beb23aa45ee30 100644 --- a/core/java/android/view/WindowManagerPolicy.java +++ b/core/java/android/view/WindowManagerPolicy.java @@ -463,6 +463,12 @@ public interface WindowManagerPolicy { */ public int getMaxWallpaperLayer(); + /** + * Return true if the policy allows the status bar to hide. Otherwise, + * it is a tablet-style system bar. + */ + public boolean canStatusBarHide(); + /** * Return the display width available after excluding any screen * decorations that can never be removed. That is, system bar or diff --git a/core/res/res/values-large/config.xml b/core/res/res/values-large/config.xml index c94256e88799d..932720089075f 100644 --- a/core/res/res/values-large/config.xml +++ b/core/res/res/values-large/config.xml @@ -23,8 +23,6 @@ 440dp - false - 2 diff --git a/core/res/res/values-sw600dp/config.xml b/core/res/res/values-sw600dp/config.xml index 49ace341622a5..d6a0cdd7d4a75 100644 --- a/core/res/res/values-sw600dp/config.xml +++ b/core/res/res/values-sw600dp/config.xml @@ -20,8 +20,6 @@ - false - 2 diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index c5fc0abb72976..5c8b9a11535bd 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -20,8 +20,6 @@ - true - diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml index 77ba33ec508d4..18876db34a006 100644 --- a/core/res/res/values/dimens.xml +++ b/core/res/res/values/dimens.xml @@ -32,8 +32,12 @@ 64dip 25dip - + + 48dip + 25dip + + 32dip 5dp diff --git a/packages/SystemUI/res/values-large/config.xml b/packages/SystemUI/res/values-large/config.xml index 299ab979d65c0..4014f8d64b94c 100644 --- a/packages/SystemUI/res/values-large/config.xml +++ b/packages/SystemUI/res/values-large/config.xml @@ -20,14 +20,7 @@ - 1 - - - com.android.systemui.statusbar.tablet.TabletStatusBar - false - diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml index 05ed0898b21f8..bb59794c830dc 100644 --- a/packages/SystemUI/res/values/config.xml +++ b/packages/SystemUI/res/values/config.xml @@ -25,16 +25,14 @@ data icon on devices --> false - - 0 - com.android.systemui.statusbar.phone.PhoneStatusBar + + com.android.systemui.statusbar.tablet.TabletStatusBar + true diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIService.java b/packages/SystemUI/src/com/android/systemui/SystemUIService.java index 870acd3c97ccf..d7a5056e78339 100644 --- a/packages/SystemUI/src/com/android/systemui/SystemUIService.java +++ b/packages/SystemUI/src/com/android/systemui/SystemUIService.java @@ -27,7 +27,10 @@ import android.content.pm.PackageManager; import android.content.res.Configuration; import android.os.Binder; import android.os.IBinder; +import android.os.RemoteException; +import android.os.ServiceManager; import android.util.Slog; +import android.view.IWindowManager; public class SystemUIService extends Service { static final String TAG = "SystemUIService"; @@ -36,7 +39,7 @@ public class SystemUIService extends Service { * The class names of the stuff to start. */ final Object[] SERVICES = new Object[] { - R.string.config_statusBarComponent, + 0, // system bar or status bar, filled in below. com.android.systemui.power.PowerUI.class, }; @@ -62,6 +65,17 @@ public class SystemUIService extends Service { @Override public void onCreate() { + // Pick status bar or system bar. + IWindowManager wm = IWindowManager.Stub.asInterface( + ServiceManager.getService(Context.WINDOW_SERVICE)); + try { + SERVICES[0] = wm.canStatusBarHide() + ? R.string.config_statusBarComponent + : R.string.config_systemBarComponent; + } catch (RemoteException e) { + Slog.w(TAG, "Failing checking whether status bar can hide", e); + } + final int N = SERVICES.length; mServices = new SystemUI[N]; for (int i=0; i height) { + shortSize = height; mLandscapeRotation = Surface.ROTATION_0; mSeascapeRotation = Surface.ROTATION_180; if (mContext.getResources().getBoolean( @@ -757,6 +757,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { mUpsideDownRotation = Surface.ROTATION_90; } } else { + shortSize = width; mPortraitRotation = Surface.ROTATION_0; mUpsideDownRotation = Surface.ROTATION_180; if (mContext.getResources().getBoolean( @@ -768,6 +769,17 @@ public class PhoneWindowManager implements WindowManagerPolicy { mSeascapeRotation = Surface.ROTATION_270; } } + + // Determine whether the status bar can hide based on the size + // of the screen. We assume sizes > 600dp are tablets where we + // will use the system bar. + int shortSizeDp = (shortSize*DisplayMetrics.DENSITY_DEVICE) + / DisplayMetrics.DENSITY_DEFAULT; + mStatusBarCanHide = shortSizeDp < 600; + mStatusBarHeight = mContext.getResources().getDimensionPixelSize( + mStatusBarCanHide + ? com.android.internal.R.dimen.status_bar_height + : com.android.internal.R.dimen.system_bar_height); } public void updateSettings() { @@ -1068,6 +1080,10 @@ public class PhoneWindowManager implements WindowManagerPolicy { return STATUS_BAR_LAYER; } + public boolean canStatusBarHide() { + return mStatusBarCanHide; + } + public int getNonDecorDisplayWidth(int rotation, int fullWidth) { return fullWidth; } @@ -1229,13 +1245,6 @@ public class PhoneWindowManager implements WindowManagerPolicy { return WindowManagerImpl.ADD_MULTIPLE_SINGLETON; } mStatusBar = win; - - // The Configuration will be stable by now, so we can load this - mStatusBarCanHide = mContext.getResources().getBoolean( - com.android.internal.R.bool.config_statusBarCanHide); - mStatusBarHeight = mContext.getResources().getDimensionPixelSize( - com.android.internal.R.dimen.status_bar_height); - break; case TYPE_STATUS_BAR_PANEL: mContext.enforceCallingOrSelfPermission( diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java index 31977e4ca3418..9c98296fb994c 100644 --- a/services/java/com/android/server/wm/WindowManagerService.java +++ b/services/java/com/android/server/wm/WindowManagerService.java @@ -408,6 +408,8 @@ public class WindowManagerService extends IWindowManager.Stub int mBaseDisplayHeight = 0; int mCurDisplayWidth = 0; int mCurDisplayHeight = 0; + int mAppDisplayWidth = 0; + int mAppDisplayHeight = 0; int mRotation = 0; int mRequestedRotation = 0; int mForcedAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; @@ -1433,8 +1435,8 @@ public class WindowManagerService extends IWindowManager.Stub int adjustWallpaperWindowsLocked() { int changed = 0; - final int dw = mCurDisplayWidth; - final int dh = mCurDisplayHeight; + final int dw = mAppDisplayWidth; + final int dh = mAppDisplayHeight; // First find top-most window that has asked to be on top of the // wallpaper; all wallpapers go behind it. @@ -1852,8 +1854,8 @@ public class WindowManagerService extends IWindowManager.Stub } boolean updateWallpaperOffsetLocked(WindowState changingTarget, boolean sync) { - final int dw = mCurDisplayWidth; - final int dh = mCurDisplayHeight; + final int dw = mAppDisplayWidth; + final int dh = mAppDisplayHeight; boolean changed = false; @@ -1893,8 +1895,8 @@ public class WindowManagerService extends IWindowManager.Stub void updateWallpaperVisibilityLocked() { final boolean visible = isWallpaperVisible(mWallpaperTarget); - final int dw = mCurDisplayWidth; - final int dh = mCurDisplayHeight; + final int dw = mAppDisplayWidth; + final int dh = mAppDisplayHeight; int curTokenIndex = mWallpaperTokens.size(); while (curTokenIndex > 0) { @@ -2701,7 +2703,7 @@ public class WindowManagerService extends IWindowManager.Stub configChanged = updateOrientationFromAppTokensLocked(false); performLayoutAndPlaceSurfacesLocked(); if (displayed && win.mIsWallpaper) { - updateWallpaperOffsetLocked(win, mCurDisplayWidth, mCurDisplayHeight, false); + updateWallpaperOffsetLocked(win, mAppDisplayWidth, mAppDisplayHeight, false); } if (win.mAppToken != null) { win.mAppToken.updateReportedVisibilityLocked(); @@ -4779,8 +4781,8 @@ public class WindowManagerService extends IWindowManager.Stub synchronized(mWindowMap) { long ident = Binder.clearCallingIdentity(); - dw = mPolicy.getNonDecorDisplayWidth(mRotation, mCurDisplayWidth); - dh = mPolicy.getNonDecorDisplayHeight(mRotation, mCurDisplayHeight); + dw = mAppDisplayWidth; + dh = mAppDisplayHeight; int aboveAppLayer = mPolicy.windowTypeToLayerLw( WindowManager.LayoutParams.TYPE_APPLICATION) * TYPE_LAYER_MULTIPLIER @@ -5555,10 +5557,10 @@ public class WindowManagerService extends IWindowManager.Stub // Override display width and height with what we are computing, // to be sure they remain consistent. - dm.widthPixels = dm.realWidthPixels = mPolicy.getNonDecorDisplayWidth( - mRotation, dw); - dm.heightPixels = dm.realHeightPixels = mPolicy.getNonDecorDisplayHeight( - mRotation, dh); + dm.widthPixels = dm.unscaledWidthPixels = mAppDisplayWidth + = mPolicy.getNonDecorDisplayWidth(mRotation, dw); + dm.heightPixels = dm.unscaledHeightPixels = mAppDisplayHeight + = mPolicy.getNonDecorDisplayHeight(mRotation, dh); mCompatibleScreenScale = CompatibilityInfo.updateCompatibleScreenFrame( dm, mCompatibleScreenFrame, null); @@ -5986,8 +5988,8 @@ public class WindowManagerService extends IWindowManager.Stub mInitialDisplayWidth = mInitialDisplayHeight; mInitialDisplayHeight = tmp; } - mBaseDisplayWidth = mCurDisplayWidth = mInitialDisplayWidth; - mBaseDisplayHeight = mCurDisplayHeight = mInitialDisplayHeight; + mBaseDisplayWidth = mCurDisplayWidth = mAppDisplayWidth = mInitialDisplayWidth; + mBaseDisplayHeight = mCurDisplayHeight = mAppDisplayHeight = mInitialDisplayHeight; mInputManager.setDisplaySize(0, mDisplay.getRawWidth(), mDisplay.getRawHeight()); mPolicy.setInitialDisplaySize(mInitialDisplayWidth, mInitialDisplayHeight); } @@ -6489,8 +6491,8 @@ public class WindowManagerService extends IWindowManager.Stub public void getDisplaySize(Point size) { synchronized(mWindowMap) { - size.x = mCurDisplayWidth; - size.y = mCurDisplayHeight; + size.x = mAppDisplayWidth; + size.y = mAppDisplayHeight; } } @@ -6622,6 +6624,10 @@ public class WindowManagerService extends IWindowManager.Stub } } + public boolean canStatusBarHide() { + return mPolicy.canStatusBarHide(); + } + // ------------------------------------------------------------- // Internals // ------------------------------------------------------------- @@ -6986,9 +6992,8 @@ public class WindowManagerService extends IWindowManager.Stub final long currentTime = SystemClock.uptimeMillis(); final int dw = mCurDisplayWidth; final int dh = mCurDisplayHeight; - - final int innerDw = mPolicy.getNonDecorDisplayWidth(mRotation, dw); - final int innerDh = mPolicy.getNonDecorDisplayHeight(mRotation, dh); + final int innerDw = mAppDisplayWidth; + final int innerDh = mAppDisplayHeight; int i; @@ -8960,6 +8965,8 @@ public class WindowManagerService extends IWindowManager.Stub pw.print(mBaseDisplayWidth); pw.print("x"); pw.print(mBaseDisplayHeight); pw.print(" cur="); pw.print(mCurDisplayWidth); pw.print("x"); pw.print(mCurDisplayHeight); + pw.print(" app="); + pw.print(mAppDisplayWidth); pw.print("x"); pw.print(mAppDisplayHeight); pw.print(" real="); pw.print(mDisplay.getRealWidth()); pw.print("x"); pw.print(mDisplay.getRealHeight()); pw.print(" raw="); pw.print(mDisplay.getRawWidth());