diff options
4 files changed, 183 insertions, 65 deletions
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java index 0ea461b..1d60066 100644 --- a/core/java/android/view/Display.java +++ b/core/java/android/view/Display.java @@ -200,8 +200,27 @@ public class Display { * @param outMetrics */ public void getMetrics(DisplayMetrics outMetrics) { - outMetrics.widthPixels = getWidth(); - outMetrics.heightPixels = getHeight(); + synchronized (mTmpPoint) { + getSize(mTmpPoint); + outMetrics.widthPixels = mTmpPoint.x; + outMetrics.heightPixels = mTmpPoint.y; + } + getNonSizeMetrics(outMetrics); + } + + /** + * Initialize a DisplayMetrics object from this display's data. + * + * @param outMetrics + * @hide + */ + public void getRealMetrics(DisplayMetrics outMetrics) { + outMetrics.widthPixels = getRealWidth(); + outMetrics.heightPixels = getRealHeight(); + getNonSizeMetrics(outMetrics); + } + + private void getNonSizeMetrics(DisplayMetrics outMetrics) { outMetrics.density = mDensity; outMetrics.densityDpi = (int)((mDensity*DisplayMetrics.DENSITY_DEFAULT)+.5f); outMetrics.scaledDensity= outMetrics.density; diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java index 03b3553..c7cf459 100644 --- a/core/java/android/view/WindowManagerPolicy.java +++ b/core/java/android/view/WindowManagerPolicy.java @@ -398,7 +398,7 @@ public interface WindowManagerPolicy { * display dimensions. */ public void setInitialDisplaySize(int width, int height); - + /** * Check permissions when adding a window. * @@ -826,6 +826,13 @@ public interface WindowManagerPolicy { boolean displayEnabled); /** + * Return the currently locked screen rotation, if any. Return + * Surface.ROTATION_0, Surface.ROTATION_90, Surface.ROTATION_180, or + * Surface.ROTATION_270 if locked; return -1 if not locked. + */ + public int getLockedRotationLw(); + + /** * Called when the system is mostly done booting to determine whether * the system should go into safe mode. */ diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java index bf602c6..2d68667 100755 --- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java @@ -2594,6 +2594,26 @@ public class PhoneWindowManager implements WindowManagerPolicy { } } + public int getLockedRotationLw() { + synchronized (mLock) { + if (false) { + // Not yet working. + if (mHdmiPlugged) { + return Surface.ROTATION_0; + } else if (mLidOpen == LID_OPEN) { + return mLidOpenRotation; + } else if (mDockMode == Intent.EXTRA_DOCK_STATE_CAR && mCarDockRotation >= 0) { + return mCarDockRotation; + } else if (mDockMode == Intent.EXTRA_DOCK_STATE_DESK && mDeskDockRotation >= 0) { + return mDeskDockRotation; + } else if (mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED) { + return mUserRotation; + } + } + return -1; + } + } + private int getCurrentLandscapeRotation(int lastRotation) { // if the user has locked rotation, we ignore the sensor if (mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED) { diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java index 4b9ce90..992ab3b 100644 --- a/services/java/com/android/server/wm/WindowManagerService.java +++ b/services/java/com/android/server/wm/WindowManagerService.java @@ -397,6 +397,7 @@ public class WindowManagerService extends IWindowManager.Stub int mRotation = 0; int mRequestedRotation = 0; int mForcedAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; + boolean mAltOrientation = false; int mLastRotationFlags; ArrayList<IRotationWatcher> mRotationWatchers = new ArrayList<IRotationWatcher>(); @@ -584,7 +585,6 @@ public class WindowManagerService extends IWindowManager.Stub } final Configuration mTempConfiguration = new Configuration(); - int mScreenLayout = Configuration.SCREENLAYOUT_SIZE_UNDEFINED; // The frame use to limit the size of the app running in compatibility mode. Rect mCompatibleScreenFrame = new Rect(); @@ -4757,8 +4757,8 @@ public class WindowManagerService extends IWindowManager.Stub synchronized(mWindowMap) { long ident = Binder.clearCallingIdentity(); - dw = mCurDisplayWidth; - dh = mCurDisplayHeight; + dw = mPolicy.getNonDecorDisplayWidth(mCurDisplayWidth); + dh = mPolicy.getNonDecorDisplayHeight(mCurDisplayHeight); int aboveAppLayer = mPolicy.windowTypeToLayerLw( WindowManager.LayoutParams.TYPE_APPLICATION) * TYPE_LAYER_MULTIPLIER @@ -4952,7 +4952,52 @@ public class WindowManagerService extends IWindowManager.Stub rotation = mPolicy.rotationForOrientationLw(mForcedAppOrientation, mRotation, mDisplayEnabled); if (DEBUG_ORIENTATION) Slog.v(TAG, "new rotation is set to " + rotation); + + int desiredRotation = rotation; + int lockedRotation = mPolicy.getLockedRotationLw(); + if (lockedRotation >= 0 && rotation != lockedRotation) { + // We are locked in a rotation but something is requesting + // a different rotation... we will either keep the locked + // rotation if it results in the same orientation, or have to + // switch into an emulated orientation mode. + + // First, we know that our rotation is actually going to be + // the locked rotation. + rotation = lockedRotation; + + // Now the difference between the desired and lockedRotation + // may mean that the orientation is different... if that is + // not the case, we can just make the desired rotation be the + // same as the new locked rotation. + switch (lockedRotation) { + case Surface.ROTATION_0: + if (rotation == Surface.ROTATION_180) { + desiredRotation = lockedRotation; + } + break; + case Surface.ROTATION_90: + if (rotation == Surface.ROTATION_270) { + desiredRotation = lockedRotation; + } + break; + case Surface.ROTATION_180: + if (rotation == Surface.ROTATION_0) { + desiredRotation = lockedRotation; + } + break; + case Surface.ROTATION_270: + if (rotation == Surface.ROTATION_90) { + desiredRotation = lockedRotation; + } + break; + } + } + changed = mDisplayEnabled && mRotation != rotation; + if (mAltOrientation != (rotation != desiredRotation)) { + changed = true; + mAltOrientation = rotation != desiredRotation; + } if (changed) { if (DEBUG_ORIENTATION) Slog.v(TAG, @@ -4998,6 +5043,7 @@ public class WindowManagerService extends IWindowManager.Stub Surface.setOrientation(0, rotation, animFlags); } } + for (int i=mWindows.size()-1; i>=0; i--) { WindowState w = mWindows.get(i); if (w.mSurface != null) { @@ -5438,8 +5484,32 @@ public class WindowManagerService extends IWindowManager.Stub // Use the effective "visual" dimensions based on current rotation final boolean rotated = (mRotation == Surface.ROTATION_90 || mRotation == Surface.ROTATION_270); - final int dw = rotated ? mInitialDisplayHeight : mInitialDisplayWidth; - final int dh = rotated ? mInitialDisplayWidth : mInitialDisplayHeight; + final int realdw = rotated ? mInitialDisplayHeight : mInitialDisplayWidth; + final int realdh = rotated ? mInitialDisplayWidth : mInitialDisplayHeight; + + if (mAltOrientation) { + mCurDisplayWidth = realdw; + mCurDisplayHeight = realdh; + if (realdw > realdh) { + // Turn landscape into portrait. + int maxw = (int)(realdh/1.3f); + if (maxw < realdw) { + mCurDisplayWidth = maxw; + } + } else { + // Turn portrait into landscape. + int maxh = (int)(realdw/1.3f); + if (maxh < realdh) { + mCurDisplayHeight = maxh; + } + } + } else { + mCurDisplayWidth = realdw; + mCurDisplayHeight = realdh; + } + + final int dw = mCurDisplayWidth; + final int dh = mCurDisplayHeight; int orientation = Configuration.ORIENTATION_SQUARE; if (dw < dh) { @@ -5450,69 +5520,70 @@ public class WindowManagerService extends IWindowManager.Stub config.orientation = orientation; DisplayMetrics dm = new DisplayMetrics(); - mDisplay.getMetrics(dm); - dm.realWidthPixels = mPolicy.getNonDecorDisplayWidth(dm.realWidthPixels); - dm.realHeightPixels = mPolicy.getNonDecorDisplayHeight(dm.realHeightPixels); + mDisplay.getRealMetrics(dm); + + // Override display width and height with what we are computing, + // to be sure they remain consistent. + dm.widthPixels = mPolicy.getNonDecorDisplayWidth(dw); + dm.heightPixels = mPolicy.getNonDecorDisplayHeight(dh); + mCompatibleScreenScale = CompatibilityInfo.updateCompatibleScreenFrame( dm, mCompatibleScreenFrame, null); config.screenWidthDp = (int)(dm.widthPixels / dm.density); config.screenHeightDp = (int)(dm.heightPixels / dm.density); - if (mScreenLayout == Configuration.SCREENLAYOUT_SIZE_UNDEFINED) { - // Note we only do this once because at this point we don't - // expect the screen to change in this way at runtime, and want - // to avoid all of this computation for every config change. - int longSize = dw; - int shortSize = dh; - if (longSize < shortSize) { - int tmp = longSize; - longSize = shortSize; - shortSize = tmp; - } - longSize = (int)(longSize/dm.density); - shortSize = (int)(shortSize/dm.density); - - // These semi-magic numbers define our compatibility modes for - // applications with different screens. These are guarantees to - // app developers about the space they can expect for a particular - // configuration. DO NOT CHANGE! - if (longSize < 470) { - // This is shorter than an HVGA normal density screen (which - // is 480 pixels on its long side). - mScreenLayout = Configuration.SCREENLAYOUT_SIZE_SMALL - | Configuration.SCREENLAYOUT_LONG_NO; + // Compute the screen layout size class. + int screenLayout; + int longSize = dw; + int shortSize = dh; + if (longSize < shortSize) { + int tmp = longSize; + longSize = shortSize; + shortSize = tmp; + } + longSize = (int)(longSize/dm.density); + shortSize = (int)(shortSize/dm.density); + + // These semi-magic numbers define our compatibility modes for + // applications with different screens. These are guarantees to + // app developers about the space they can expect for a particular + // configuration. DO NOT CHANGE! + if (longSize < 470) { + // This is shorter than an HVGA normal density screen (which + // is 480 pixels on its long side). + screenLayout = Configuration.SCREENLAYOUT_SIZE_SMALL + | Configuration.SCREENLAYOUT_LONG_NO; + } else { + // What size is this screen screen? + if (longSize >= 960 && shortSize >= 720) { + // 1.5xVGA or larger screens at medium density are the point + // at which we consider it to be an extra large screen. + screenLayout = Configuration.SCREENLAYOUT_SIZE_XLARGE; + } else if (longSize >= 640 && shortSize >= 480) { + // VGA or larger screens at medium density are the point + // at which we consider it to be a large screen. + screenLayout = Configuration.SCREENLAYOUT_SIZE_LARGE; } else { - // What size is this screen screen? - if (longSize >= 960 && shortSize >= 720) { - // 1.5xVGA or larger screens at medium density are the point - // at which we consider it to be an extra large screen. - mScreenLayout = Configuration.SCREENLAYOUT_SIZE_XLARGE; - } else if (longSize >= 640 && shortSize >= 480) { - // VGA or larger screens at medium density are the point - // at which we consider it to be a large screen. - mScreenLayout = Configuration.SCREENLAYOUT_SIZE_LARGE; - } else { - mScreenLayout = Configuration.SCREENLAYOUT_SIZE_NORMAL; - } - - // If this screen is wider than normal HVGA, or taller - // than FWVGA, then for old apps we want to run in size - // compatibility mode. - if (shortSize > 321 || longSize > 570) { - mScreenLayout |= Configuration.SCREENLAYOUT_COMPAT_NEEDED; - } + screenLayout = Configuration.SCREENLAYOUT_SIZE_NORMAL; + } - // Is this a long screen? - if (((longSize*3)/5) >= (shortSize-1)) { - // Anything wider than WVGA (5:3) is considering to be long. - mScreenLayout |= Configuration.SCREENLAYOUT_LONG_YES; - } else { - mScreenLayout |= Configuration.SCREENLAYOUT_LONG_NO; - } + // If this screen is wider than normal HVGA, or taller + // than FWVGA, then for old apps we want to run in size + // compatibility mode. + if (shortSize > 321 || longSize > 570) { + screenLayout |= Configuration.SCREENLAYOUT_COMPAT_NEEDED; + } + + // Is this a long screen? + if (((longSize*3)/5) >= (shortSize-1)) { + // Anything wider than WVGA (5:3) is considering to be long. + screenLayout |= Configuration.SCREENLAYOUT_LONG_YES; + } else { + screenLayout |= Configuration.SCREENLAYOUT_LONG_NO; } } - config.screenLayout = mScreenLayout; + config.screenLayout = screenLayout; // Determine whether a hard keyboard is available and enabled. boolean hardKeyboardAvailable = config.keyboard != Configuration.KEYBOARD_NOKEYS; @@ -6730,8 +6801,8 @@ public class WindowManagerService extends IWindowManager.Stub } final long currentTime = SystemClock.uptimeMillis(); - final int dw = mCurDisplayWidth = mDisplay.getRealWidth(); - final int dh = mCurDisplayHeight = mDisplay.getRealHeight(); + final int dw = mCurDisplayWidth; + final int dh = mCurDisplayHeight; final int innerDw = mPolicy.getNonDecorDisplayWidth(dw); final int innerDh = mPolicy.getNonDecorDisplayHeight(dh); @@ -8728,8 +8799,9 @@ public class WindowManagerService extends IWindowManager.Stub pw.print(" mAppsFreezingScreen="); pw.print(mAppsFreezingScreen); pw.print(" mWaitingForConfig="); pw.println(mWaitingForConfig); pw.print(" mRotation="); pw.print(mRotation); - pw.print(", mForcedAppOrientation="); pw.print(mForcedAppOrientation); - pw.print(", mRequestedRotation="); pw.println(mRequestedRotation); + pw.print(" mForcedAppOrientation="); pw.print(mForcedAppOrientation); + pw.print(" mRequestedRotation="); pw.print(mRequestedRotation); + pw.print(" mAltOrientation="); pw.println(mAltOrientation); pw.print(" mDeferredRotation="); pw.print(mDeferredRotation); pw.print(", mDeferredRotationAnimFlags="); pw.println(mDeferredRotationAnimFlags); pw.print(" mAnimationPending="); pw.print(mAnimationPending); |