Loading api/current.xml +55 −0 Original line number Diff line number Diff line Loading @@ -46755,6 +46755,17 @@ visibility="public" > </field> <field name="SCREEN_ORIENTATION_FULL_SENSOR" type="int" transient="false" volatile="false" value="10" static="true" final="true" deprecated="not deprecated" visibility="public" > </field> <field name="SCREEN_ORIENTATION_LANDSCAPE" type="int" transient="false" Loading Loading @@ -46788,6 +46799,28 @@ visibility="public" > </field> <field name="SCREEN_ORIENTATION_REVERSE_LANDSCAPE" type="int" transient="false" volatile="false" value="8" static="true" final="true" deprecated="not deprecated" visibility="public" > </field> <field name="SCREEN_ORIENTATION_REVERSE_PORTRAIT" type="int" transient="false" volatile="false" value="9" static="true" final="true" deprecated="not deprecated" visibility="public" > </field> <field name="SCREEN_ORIENTATION_SENSOR" type="int" transient="false" Loading @@ -46799,6 +46832,28 @@ visibility="public" > </field> <field name="SCREEN_ORIENTATION_SENSOR_LANDSCAPE" type="int" transient="false" volatile="false" value="6" static="true" final="true" deprecated="not deprecated" visibility="public" > </field> <field name="SCREEN_ORIENTATION_SENSOR_PORTRAIT" type="int" transient="false" volatile="false" value="7" static="true" final="true" deprecated="not deprecated" visibility="public" > </field> <field name="SCREEN_ORIENTATION_UNSPECIFIED" type="int" transient="false" core/java/android/content/pm/ActivityInfo.java +38 −2 Original line number Diff line number Diff line Loading @@ -194,10 +194,41 @@ public class ActivityInfo extends ComponentInfo public static final int SCREEN_ORIENTATION_SENSOR = 4; /** * Constant corresponding to <code>sensor</code> in * Constant corresponding to <code>nosensor</code> in * the {@link android.R.attr#screenOrientation} attribute. */ public static final int SCREEN_ORIENTATION_NOSENSOR = 5; /** * Constant corresponding to <code>sensorLandscape</code> in * the {@link android.R.attr#screenOrientation} attribute. */ public static final int SCREEN_ORIENTATION_SENSOR_LANDSCAPE = 6; /** * Constant corresponding to <code>sensorPortrait</code> in * the {@link android.R.attr#screenOrientation} attribute. */ public static final int SCREEN_ORIENTATION_SENSOR_PORTRAIT = 7; /** * Constant corresponding to <code>reverseLandscape</code> in * the {@link android.R.attr#screenOrientation} attribute. */ public static final int SCREEN_ORIENTATION_REVERSE_LANDSCAPE = 8; /** * Constant corresponding to <code>reversePortrait</code> in * the {@link android.R.attr#screenOrientation} attribute. */ public static final int SCREEN_ORIENTATION_REVERSE_PORTRAIT = 9; /** * Constant corresponding to <code>fullSensor</code> in * the {@link android.R.attr#screenOrientation} attribute. */ public static final int SCREEN_ORIENTATION_FULL_SENSOR = 10; /** * The preferred screen orientation this activity would like to run in. * From the {@link android.R.attr#screenOrientation} attribute, one of Loading @@ -207,7 +238,12 @@ public class ActivityInfo extends ComponentInfo * {@link #SCREEN_ORIENTATION_USER}, * {@link #SCREEN_ORIENTATION_BEHIND}, * {@link #SCREEN_ORIENTATION_SENSOR}, * {@link #SCREEN_ORIENTATION_NOSENSOR}. * {@link #SCREEN_ORIENTATION_NOSENSOR}, * {@link #SCREEN_ORIENTATION_SENSOR_LANDSCAPE}, * {@link #SCREEN_ORIENTATION_SENSOR_PORTRAIT}, * {@link #SCREEN_ORIENTATION_REVERSE_LANDSCAPE}, * {@link #SCREEN_ORIENTATION_REVERSE_PORTRAIT}, * {@link #SCREEN_ORIENTATION_FULL_SENSOR}. */ public int screenOrientation = SCREEN_ORIENTATION_UNSPECIFIED; Loading core/java/android/view/WindowOrientationListener.java +49 −10 Original line number Diff line number Diff line Loading @@ -28,6 +28,11 @@ import android.util.Log; * A special helper class used by the WindowManager * for receiving notifications from the SensorManager when * the orientation of the device has changed. * * NOTE: If changing anything here, please run the API demo * "App/Activity/Screen Orientation" to ensure that all orientation * modes still work correctly. * * @hide */ public abstract class WindowOrientationListener { Loading Loading @@ -103,6 +108,10 @@ public abstract class WindowOrientationListener { } } public void setAllow180Rotation(boolean allowed) { mSensorEventListener.setAllow180Rotation(allowed); } public int getCurrentRotation(int lastRotation) { if (mEnabled) { return mSensorEventListener.getCurrentRotation(lastRotation); Loading Loading @@ -151,19 +160,20 @@ public abstract class WindowOrientationListener { private static final int ROTATION_0 = 0; private static final int ROTATION_90 = 1; private static final int ROTATION_270 = 2; private static final int ROTATION_180 = 3; // Mapping our internal aliases into actual Surface rotation values private static final int[] INTERNAL_TO_SURFACE_ROTATION = new int[] { Surface.ROTATION_0, Surface.ROTATION_90, Surface.ROTATION_270}; Surface.ROTATION_0, Surface.ROTATION_90, Surface.ROTATION_270, Surface.ROTATION_180}; // Mapping Surface rotation values to internal aliases. // We have no constant for Surface.ROTATION_180. That should never happen, but if it // does, we'll arbitrarily choose a mapping. private static final int[] SURFACE_TO_INTERNAL_ROTATION = new int[] { ROTATION_0, ROTATION_90, ROTATION_90, ROTATION_270}; ROTATION_0, ROTATION_90, ROTATION_180, ROTATION_270}; // Threshold ranges of orientation angle to transition into other orientation states. // The first list is for transitions from ROTATION_0, the next for ROTATION_90, etc. // The first list is for transitions from ROTATION_0, ROTATION_90, ROTATION_270, // and then ROTATION_180. // ROTATE_TO defines the orientation each threshold range transitions to, and must be kept // in sync with this. // We generally transition about the halfway point between two states with a swing of 30 Loading @@ -172,13 +182,32 @@ public abstract class WindowOrientationListener { {{60, 180}, {180, 300}}, {{0, 30}, {195, 315}, {315, 360}}, {{0, 45}, {45, 165}, {330, 360}}, }; // Handle situation where we are currently doing 180 rotation // but that is no longer allowed. {{0, 45}, {45, 135}, {135, 225}, {225, 315}, {315, 360}}, }; // See THRESHOLDS private static final int[][] ROTATE_TO = new int[][] { {ROTATION_90, ROTATION_270}, {ROTATION_0, ROTATION_270, ROTATION_0}, {ROTATION_0, ROTATION_90, ROTATION_0}, {ROTATION_0, ROTATION_90, ROTATION_0, ROTATION_270, ROTATION_0}, }; // Thresholds that allow all 4 orientations. private static final int[][][] THRESHOLDS_WITH_180 = new int[][][] { {{60, 165}, {165, 195}, {195, 300}}, {{0, 30}, {165, 195}, {195, 315}, {315, 360}}, {{0, 45}, {45, 165}, {165, 195}, {330, 360}}, {{0, 45}, {45, 135}, {225, 315}, {315, 360}}, }; // See THRESHOLDS_WITH_180 private static final int[][] ROTATE_TO_WITH_180 = new int[][] { {ROTATION_90, ROTATION_180, ROTATION_270}, {ROTATION_0, ROTATION_180, ROTATION_90, ROTATION_0}, {ROTATION_0, ROTATION_270, ROTATION_180, ROTATION_0}, {ROTATION_0, ROTATION_90, ROTATION_270, ROTATION_0}, }; // Maximum absolute tilt angle at which to consider orientation data. Beyond this (i.e. Loading @@ -188,7 +217,7 @@ public abstract class WindowOrientationListener { // Additional limits on tilt angle to transition to each new orientation. We ignore all // data with tilt beyond MAX_TILT, but we can set stricter limits on transitions to a // particular orientation here. private static final int[] MAX_TRANSITION_TILT = new int[] {MAX_TILT, 65, 65}; private static final int[] MAX_TRANSITION_TILT = new int[] {MAX_TILT, 65, 65, 40}; // Between this tilt angle and MAX_TILT, we'll allow orientation changes, but we'll filter // with a higher time constant, making us less sensitive to change. This primarily helps Loading Loading @@ -228,6 +257,8 @@ public abstract class WindowOrientationListener { private static final float ACCELERATING_LOWPASS_ALPHA = computeLowpassAlpha(ACCELERATING_TIME_CONSTANT_MS); private boolean mAllow180Rotation = false; private WindowOrientationListener mOrientationListener; private int mRotation = ROTATION_0; // Current orientation state private float mTiltAngle = 0; // low-pass filtered Loading @@ -249,6 +280,10 @@ public abstract class WindowOrientationListener { return (float) SAMPLING_PERIOD_MS / (timeConstantMs + SAMPLING_PERIOD_MS); } void setAllow180Rotation(boolean allowed) { mAllow180Rotation = allowed; } int getCurrentRotation(int lastRotation) { if (mTiltDistrust > 0) { // we really don't know the current orientation, so trust what's currently displayed Loading @@ -259,7 +294,9 @@ public abstract class WindowOrientationListener { private void calculateNewRotation(float orientation, float tiltAngle) { if (localLOGV) Log.i(TAG, orientation + ", " + tiltAngle + ", " + mRotation); int thresholdRanges[][] = THRESHOLDS[mRotation]; final boolean allow180Rotation = mAllow180Rotation; int thresholdRanges[][] = allow180Rotation ? THRESHOLDS_WITH_180[mRotation] : THRESHOLDS[mRotation]; int row = -1; for (int i = 0; i < thresholdRanges.length; i++) { if (orientation >= thresholdRanges[i][0] && orientation < thresholdRanges[i][1]) { Loading @@ -269,13 +306,15 @@ public abstract class WindowOrientationListener { } if (row == -1) return; // no matching transition int rotation = ROTATE_TO[mRotation][row]; int rotation = allow180Rotation ? ROTATE_TO_WITH_180[mRotation][row] : ROTATE_TO[mRotation][row]; if (tiltAngle > MAX_TRANSITION_TILT[rotation]) { // tilted too far flat to go to this rotation return; } if (localLOGV) Log.i(TAG, " new rotation = " + rotation); if (localLOGV) Log.i(TAG, "orientation " + orientation + " gives new rotation = " + rotation); mRotation = rotation; mOrientationListener.onOrientationChanged(INTERNAL_TO_SURFACE_ROTATION[mRotation]); } Loading core/res/res/values/attrs_manifest.xml +20 −2 Original line number Diff line number Diff line Loading @@ -495,10 +495,10 @@ orientation will changed based on how the user rotates the device --> <enum name="unspecified" value="-1" /> <!-- Would like to have the screen in a landscape orientation: that is, with the display wider than it is tall. --> is, with the display wider than it is tall, ignoring sensor data. --> <enum name="landscape" value="0" /> <!-- Would like to have the screen in a portrait orientation: that is, with the display taller than it is wide. --> is, with the display taller than it is wide, ignoring sensor data. --> <enum name="portrait" value="1" /> <!-- Use the user's current preferred orientation of the handset. --> <enum name="user" value="2" /> Loading @@ -511,6 +511,24 @@ <!-- Always ignore orientation determined by orientation sensor: the display will not rotate when the user moves the device. --> <enum name="nosensor" value="5" /> <!-- Would like to have the screen in landscape orientation, but can use the sensor to change which direction the screen is facing. --> <enum name="sensorLandscape" value="6" /> <!-- Would like to have the screen in portrait orientation, but can use the sensor to change which direction the screen is facing. --> <enum name="sensorPortait" value="7" /> <!-- Would like to have the screen in landscape orientation, turned in the opposite direction from normal landscape. --> <enum name="reverseLandscape" value="8" /> <!-- Would like to have the screen in portrait orientation, turned in the opposite direction from normal portrait. --> <enum name="reversePortait" value="9" /> <!-- Orientation is determined by a physical orientation sensor: the display will rotate based on how the user moves the device. This allows any of the 4 possible rotations, regardless of what the device will normally do (for example some devices won't normally use 180 degree rotation). --> <enum name="fullSensor" value="10" /> </attr> <!-- Specify one or more configuration changes that the activity will Loading policy/src/com/android/internal/policy/impl/PhoneWindowManager.java +60 −22 Original line number Diff line number Diff line Loading @@ -288,7 +288,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { int mLandscapeRotation = -1; // default landscape rotation int mSeascapeRotation = -1; // "other" landscape rotation, 180 degrees from mLandscapeRotation int mPortraitRotation = -1; int mPortraitRotation = -1; // default portrait rotation int mUpsideDownRotation = -1; // "other" portrait rotation // Nothing to see here, move along... int mFancyRotationAnimation; Loading Loading @@ -353,26 +354,25 @@ public class PhoneWindowManager implements WindowManagerPolicy { boolean useSensorForOrientationLp(int appOrientation) { // The app says use the sensor. if (appOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR) { if (appOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR || appOrientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR || appOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE || appOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT) { return true; } // The user preference says we can rotate, and the app is willing to rotate. // Note we include SCREEN_ORIENTATION_LANDSCAPE since we can use the sensor to choose // between the two possible landscape rotations. if (mAccelerometerDefault != 0 && (appOrientation == ActivityInfo.SCREEN_ORIENTATION_USER || appOrientation == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED || appOrientation == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE)) { || appOrientation == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED)) { return true; } // We're in a dock that has a rotation affinity, an the app is willing to rotate. // We're in a dock that has a rotation affinity, and the app is willing to rotate. if ((mCarDockEnablesAccelerometer && mDockMode == Intent.EXTRA_DOCK_STATE_CAR) || (mDeskDockEnablesAccelerometer && mDockMode == Intent.EXTRA_DOCK_STATE_DESK)) { // Note we override the nosensor flag here. if (appOrientation == ActivityInfo.SCREEN_ORIENTATION_USER || appOrientation == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED || appOrientation == ActivityInfo.SCREEN_ORIENTATION_NOSENSOR || appOrientation == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) { || appOrientation == ActivityInfo.SCREEN_ORIENTATION_NOSENSOR) { return true; } } Loading @@ -386,7 +386,10 @@ public class PhoneWindowManager implements WindowManagerPolicy { * screen is switched off. */ boolean needSensorRunningLp() { if (mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR) { if (mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR || mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR || mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT || mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE) { // If the application has explicitly requested to follow the // orientation, then we need to turn the sensor or. return true; Loading Loading @@ -2060,21 +2063,42 @@ public class PhoneWindowManager implements WindowManagerPolicy { if (d.getWidth() > d.getHeight()) { mPortraitRotation = Surface.ROTATION_90; mLandscapeRotation = Surface.ROTATION_0; mUpsideDownRotation = Surface.ROTATION_270; mSeascapeRotation = Surface.ROTATION_180; } else { mPortraitRotation = Surface.ROTATION_0; mLandscapeRotation = Surface.ROTATION_90; mUpsideDownRotation = Surface.ROTATION_180; mSeascapeRotation = Surface.ROTATION_270; } } synchronized (mLock) { if (orientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) { switch (orientation) { case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT: //always return portrait if orientation set to portrait return mPortraitRotation; } else if (orientation == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) { case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE: //always return landscape if orientation set to landscape return mLandscapeRotation; case ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT: //always return portrait if orientation set to portrait return mUpsideDownRotation; case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE: //always return seascape if orientation set to reverse landscape return mSeascapeRotation; case ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE: //return either landscape rotation based on the sensor mOrientationListener.setAllow180Rotation(false); return getCurrentLandscapeRotation(lastRotation); case ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT: mOrientationListener.setAllow180Rotation(true); return getCurrentPortraitRotation(lastRotation); } mOrientationListener.setAllow180Rotation( orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR); // case for nosensor meaning ignore sensor and consider only lid // or orientation sensor disabled //or case.unspecified Loading @@ -2094,18 +2118,15 @@ public class PhoneWindowManager implements WindowManagerPolicy { } private int getCurrentLandscapeRotation(int lastRotation) { // landscape-only apps can take either landscape rotation if (useSensorForOrientationLp(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE)) { int sensorRotation = mOrientationListener.getCurrentRotation(lastRotation); if (isLandscapeOrSeascape(sensorRotation)) { return sensorRotation; } } // try to preserve the old rotation if it was landscape if (isLandscapeOrSeascape(lastRotation)) { return lastRotation; } // default to one of the two landscape rotations // default to one of the primary landscape rotation return mLandscapeRotation; } Loading @@ -2113,6 +2134,23 @@ public class PhoneWindowManager implements WindowManagerPolicy { return sensorRotation == mLandscapeRotation || sensorRotation == mSeascapeRotation; } private int getCurrentPortraitRotation(int lastRotation) { int sensorRotation = mOrientationListener.getCurrentRotation(lastRotation); if (isAnyPortrait(sensorRotation)) { return sensorRotation; } // try to preserve the old rotation if it was portrait if (isAnyPortrait(lastRotation)) { return lastRotation; } // default to one of the primary portrait rotations return mPortraitRotation; } private boolean isAnyPortrait(int sensorRotation) { return sensorRotation == mPortraitRotation || sensorRotation == mUpsideDownRotation; } public boolean detectSafeMode() { try { int menuState = mWindowManager.getKeycodeState(KeyEvent.KEYCODE_MENU); Loading Loading
api/current.xml +55 −0 Original line number Diff line number Diff line Loading @@ -46755,6 +46755,17 @@ visibility="public" > </field> <field name="SCREEN_ORIENTATION_FULL_SENSOR" type="int" transient="false" volatile="false" value="10" static="true" final="true" deprecated="not deprecated" visibility="public" > </field> <field name="SCREEN_ORIENTATION_LANDSCAPE" type="int" transient="false" Loading Loading @@ -46788,6 +46799,28 @@ visibility="public" > </field> <field name="SCREEN_ORIENTATION_REVERSE_LANDSCAPE" type="int" transient="false" volatile="false" value="8" static="true" final="true" deprecated="not deprecated" visibility="public" > </field> <field name="SCREEN_ORIENTATION_REVERSE_PORTRAIT" type="int" transient="false" volatile="false" value="9" static="true" final="true" deprecated="not deprecated" visibility="public" > </field> <field name="SCREEN_ORIENTATION_SENSOR" type="int" transient="false" Loading @@ -46799,6 +46832,28 @@ visibility="public" > </field> <field name="SCREEN_ORIENTATION_SENSOR_LANDSCAPE" type="int" transient="false" volatile="false" value="6" static="true" final="true" deprecated="not deprecated" visibility="public" > </field> <field name="SCREEN_ORIENTATION_SENSOR_PORTRAIT" type="int" transient="false" volatile="false" value="7" static="true" final="true" deprecated="not deprecated" visibility="public" > </field> <field name="SCREEN_ORIENTATION_UNSPECIFIED" type="int" transient="false"
core/java/android/content/pm/ActivityInfo.java +38 −2 Original line number Diff line number Diff line Loading @@ -194,10 +194,41 @@ public class ActivityInfo extends ComponentInfo public static final int SCREEN_ORIENTATION_SENSOR = 4; /** * Constant corresponding to <code>sensor</code> in * Constant corresponding to <code>nosensor</code> in * the {@link android.R.attr#screenOrientation} attribute. */ public static final int SCREEN_ORIENTATION_NOSENSOR = 5; /** * Constant corresponding to <code>sensorLandscape</code> in * the {@link android.R.attr#screenOrientation} attribute. */ public static final int SCREEN_ORIENTATION_SENSOR_LANDSCAPE = 6; /** * Constant corresponding to <code>sensorPortrait</code> in * the {@link android.R.attr#screenOrientation} attribute. */ public static final int SCREEN_ORIENTATION_SENSOR_PORTRAIT = 7; /** * Constant corresponding to <code>reverseLandscape</code> in * the {@link android.R.attr#screenOrientation} attribute. */ public static final int SCREEN_ORIENTATION_REVERSE_LANDSCAPE = 8; /** * Constant corresponding to <code>reversePortrait</code> in * the {@link android.R.attr#screenOrientation} attribute. */ public static final int SCREEN_ORIENTATION_REVERSE_PORTRAIT = 9; /** * Constant corresponding to <code>fullSensor</code> in * the {@link android.R.attr#screenOrientation} attribute. */ public static final int SCREEN_ORIENTATION_FULL_SENSOR = 10; /** * The preferred screen orientation this activity would like to run in. * From the {@link android.R.attr#screenOrientation} attribute, one of Loading @@ -207,7 +238,12 @@ public class ActivityInfo extends ComponentInfo * {@link #SCREEN_ORIENTATION_USER}, * {@link #SCREEN_ORIENTATION_BEHIND}, * {@link #SCREEN_ORIENTATION_SENSOR}, * {@link #SCREEN_ORIENTATION_NOSENSOR}. * {@link #SCREEN_ORIENTATION_NOSENSOR}, * {@link #SCREEN_ORIENTATION_SENSOR_LANDSCAPE}, * {@link #SCREEN_ORIENTATION_SENSOR_PORTRAIT}, * {@link #SCREEN_ORIENTATION_REVERSE_LANDSCAPE}, * {@link #SCREEN_ORIENTATION_REVERSE_PORTRAIT}, * {@link #SCREEN_ORIENTATION_FULL_SENSOR}. */ public int screenOrientation = SCREEN_ORIENTATION_UNSPECIFIED; Loading
core/java/android/view/WindowOrientationListener.java +49 −10 Original line number Diff line number Diff line Loading @@ -28,6 +28,11 @@ import android.util.Log; * A special helper class used by the WindowManager * for receiving notifications from the SensorManager when * the orientation of the device has changed. * * NOTE: If changing anything here, please run the API demo * "App/Activity/Screen Orientation" to ensure that all orientation * modes still work correctly. * * @hide */ public abstract class WindowOrientationListener { Loading Loading @@ -103,6 +108,10 @@ public abstract class WindowOrientationListener { } } public void setAllow180Rotation(boolean allowed) { mSensorEventListener.setAllow180Rotation(allowed); } public int getCurrentRotation(int lastRotation) { if (mEnabled) { return mSensorEventListener.getCurrentRotation(lastRotation); Loading Loading @@ -151,19 +160,20 @@ public abstract class WindowOrientationListener { private static final int ROTATION_0 = 0; private static final int ROTATION_90 = 1; private static final int ROTATION_270 = 2; private static final int ROTATION_180 = 3; // Mapping our internal aliases into actual Surface rotation values private static final int[] INTERNAL_TO_SURFACE_ROTATION = new int[] { Surface.ROTATION_0, Surface.ROTATION_90, Surface.ROTATION_270}; Surface.ROTATION_0, Surface.ROTATION_90, Surface.ROTATION_270, Surface.ROTATION_180}; // Mapping Surface rotation values to internal aliases. // We have no constant for Surface.ROTATION_180. That should never happen, but if it // does, we'll arbitrarily choose a mapping. private static final int[] SURFACE_TO_INTERNAL_ROTATION = new int[] { ROTATION_0, ROTATION_90, ROTATION_90, ROTATION_270}; ROTATION_0, ROTATION_90, ROTATION_180, ROTATION_270}; // Threshold ranges of orientation angle to transition into other orientation states. // The first list is for transitions from ROTATION_0, the next for ROTATION_90, etc. // The first list is for transitions from ROTATION_0, ROTATION_90, ROTATION_270, // and then ROTATION_180. // ROTATE_TO defines the orientation each threshold range transitions to, and must be kept // in sync with this. // We generally transition about the halfway point between two states with a swing of 30 Loading @@ -172,13 +182,32 @@ public abstract class WindowOrientationListener { {{60, 180}, {180, 300}}, {{0, 30}, {195, 315}, {315, 360}}, {{0, 45}, {45, 165}, {330, 360}}, }; // Handle situation where we are currently doing 180 rotation // but that is no longer allowed. {{0, 45}, {45, 135}, {135, 225}, {225, 315}, {315, 360}}, }; // See THRESHOLDS private static final int[][] ROTATE_TO = new int[][] { {ROTATION_90, ROTATION_270}, {ROTATION_0, ROTATION_270, ROTATION_0}, {ROTATION_0, ROTATION_90, ROTATION_0}, {ROTATION_0, ROTATION_90, ROTATION_0, ROTATION_270, ROTATION_0}, }; // Thresholds that allow all 4 orientations. private static final int[][][] THRESHOLDS_WITH_180 = new int[][][] { {{60, 165}, {165, 195}, {195, 300}}, {{0, 30}, {165, 195}, {195, 315}, {315, 360}}, {{0, 45}, {45, 165}, {165, 195}, {330, 360}}, {{0, 45}, {45, 135}, {225, 315}, {315, 360}}, }; // See THRESHOLDS_WITH_180 private static final int[][] ROTATE_TO_WITH_180 = new int[][] { {ROTATION_90, ROTATION_180, ROTATION_270}, {ROTATION_0, ROTATION_180, ROTATION_90, ROTATION_0}, {ROTATION_0, ROTATION_270, ROTATION_180, ROTATION_0}, {ROTATION_0, ROTATION_90, ROTATION_270, ROTATION_0}, }; // Maximum absolute tilt angle at which to consider orientation data. Beyond this (i.e. Loading @@ -188,7 +217,7 @@ public abstract class WindowOrientationListener { // Additional limits on tilt angle to transition to each new orientation. We ignore all // data with tilt beyond MAX_TILT, but we can set stricter limits on transitions to a // particular orientation here. private static final int[] MAX_TRANSITION_TILT = new int[] {MAX_TILT, 65, 65}; private static final int[] MAX_TRANSITION_TILT = new int[] {MAX_TILT, 65, 65, 40}; // Between this tilt angle and MAX_TILT, we'll allow orientation changes, but we'll filter // with a higher time constant, making us less sensitive to change. This primarily helps Loading Loading @@ -228,6 +257,8 @@ public abstract class WindowOrientationListener { private static final float ACCELERATING_LOWPASS_ALPHA = computeLowpassAlpha(ACCELERATING_TIME_CONSTANT_MS); private boolean mAllow180Rotation = false; private WindowOrientationListener mOrientationListener; private int mRotation = ROTATION_0; // Current orientation state private float mTiltAngle = 0; // low-pass filtered Loading @@ -249,6 +280,10 @@ public abstract class WindowOrientationListener { return (float) SAMPLING_PERIOD_MS / (timeConstantMs + SAMPLING_PERIOD_MS); } void setAllow180Rotation(boolean allowed) { mAllow180Rotation = allowed; } int getCurrentRotation(int lastRotation) { if (mTiltDistrust > 0) { // we really don't know the current orientation, so trust what's currently displayed Loading @@ -259,7 +294,9 @@ public abstract class WindowOrientationListener { private void calculateNewRotation(float orientation, float tiltAngle) { if (localLOGV) Log.i(TAG, orientation + ", " + tiltAngle + ", " + mRotation); int thresholdRanges[][] = THRESHOLDS[mRotation]; final boolean allow180Rotation = mAllow180Rotation; int thresholdRanges[][] = allow180Rotation ? THRESHOLDS_WITH_180[mRotation] : THRESHOLDS[mRotation]; int row = -1; for (int i = 0; i < thresholdRanges.length; i++) { if (orientation >= thresholdRanges[i][0] && orientation < thresholdRanges[i][1]) { Loading @@ -269,13 +306,15 @@ public abstract class WindowOrientationListener { } if (row == -1) return; // no matching transition int rotation = ROTATE_TO[mRotation][row]; int rotation = allow180Rotation ? ROTATE_TO_WITH_180[mRotation][row] : ROTATE_TO[mRotation][row]; if (tiltAngle > MAX_TRANSITION_TILT[rotation]) { // tilted too far flat to go to this rotation return; } if (localLOGV) Log.i(TAG, " new rotation = " + rotation); if (localLOGV) Log.i(TAG, "orientation " + orientation + " gives new rotation = " + rotation); mRotation = rotation; mOrientationListener.onOrientationChanged(INTERNAL_TO_SURFACE_ROTATION[mRotation]); } Loading
core/res/res/values/attrs_manifest.xml +20 −2 Original line number Diff line number Diff line Loading @@ -495,10 +495,10 @@ orientation will changed based on how the user rotates the device --> <enum name="unspecified" value="-1" /> <!-- Would like to have the screen in a landscape orientation: that is, with the display wider than it is tall. --> is, with the display wider than it is tall, ignoring sensor data. --> <enum name="landscape" value="0" /> <!-- Would like to have the screen in a portrait orientation: that is, with the display taller than it is wide. --> is, with the display taller than it is wide, ignoring sensor data. --> <enum name="portrait" value="1" /> <!-- Use the user's current preferred orientation of the handset. --> <enum name="user" value="2" /> Loading @@ -511,6 +511,24 @@ <!-- Always ignore orientation determined by orientation sensor: the display will not rotate when the user moves the device. --> <enum name="nosensor" value="5" /> <!-- Would like to have the screen in landscape orientation, but can use the sensor to change which direction the screen is facing. --> <enum name="sensorLandscape" value="6" /> <!-- Would like to have the screen in portrait orientation, but can use the sensor to change which direction the screen is facing. --> <enum name="sensorPortait" value="7" /> <!-- Would like to have the screen in landscape orientation, turned in the opposite direction from normal landscape. --> <enum name="reverseLandscape" value="8" /> <!-- Would like to have the screen in portrait orientation, turned in the opposite direction from normal portrait. --> <enum name="reversePortait" value="9" /> <!-- Orientation is determined by a physical orientation sensor: the display will rotate based on how the user moves the device. This allows any of the 4 possible rotations, regardless of what the device will normally do (for example some devices won't normally use 180 degree rotation). --> <enum name="fullSensor" value="10" /> </attr> <!-- Specify one or more configuration changes that the activity will Loading
policy/src/com/android/internal/policy/impl/PhoneWindowManager.java +60 −22 Original line number Diff line number Diff line Loading @@ -288,7 +288,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { int mLandscapeRotation = -1; // default landscape rotation int mSeascapeRotation = -1; // "other" landscape rotation, 180 degrees from mLandscapeRotation int mPortraitRotation = -1; int mPortraitRotation = -1; // default portrait rotation int mUpsideDownRotation = -1; // "other" portrait rotation // Nothing to see here, move along... int mFancyRotationAnimation; Loading Loading @@ -353,26 +354,25 @@ public class PhoneWindowManager implements WindowManagerPolicy { boolean useSensorForOrientationLp(int appOrientation) { // The app says use the sensor. if (appOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR) { if (appOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR || appOrientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR || appOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE || appOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT) { return true; } // The user preference says we can rotate, and the app is willing to rotate. // Note we include SCREEN_ORIENTATION_LANDSCAPE since we can use the sensor to choose // between the two possible landscape rotations. if (mAccelerometerDefault != 0 && (appOrientation == ActivityInfo.SCREEN_ORIENTATION_USER || appOrientation == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED || appOrientation == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE)) { || appOrientation == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED)) { return true; } // We're in a dock that has a rotation affinity, an the app is willing to rotate. // We're in a dock that has a rotation affinity, and the app is willing to rotate. if ((mCarDockEnablesAccelerometer && mDockMode == Intent.EXTRA_DOCK_STATE_CAR) || (mDeskDockEnablesAccelerometer && mDockMode == Intent.EXTRA_DOCK_STATE_DESK)) { // Note we override the nosensor flag here. if (appOrientation == ActivityInfo.SCREEN_ORIENTATION_USER || appOrientation == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED || appOrientation == ActivityInfo.SCREEN_ORIENTATION_NOSENSOR || appOrientation == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) { || appOrientation == ActivityInfo.SCREEN_ORIENTATION_NOSENSOR) { return true; } } Loading @@ -386,7 +386,10 @@ public class PhoneWindowManager implements WindowManagerPolicy { * screen is switched off. */ boolean needSensorRunningLp() { if (mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR) { if (mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR || mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR || mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT || mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE) { // If the application has explicitly requested to follow the // orientation, then we need to turn the sensor or. return true; Loading Loading @@ -2060,21 +2063,42 @@ public class PhoneWindowManager implements WindowManagerPolicy { if (d.getWidth() > d.getHeight()) { mPortraitRotation = Surface.ROTATION_90; mLandscapeRotation = Surface.ROTATION_0; mUpsideDownRotation = Surface.ROTATION_270; mSeascapeRotation = Surface.ROTATION_180; } else { mPortraitRotation = Surface.ROTATION_0; mLandscapeRotation = Surface.ROTATION_90; mUpsideDownRotation = Surface.ROTATION_180; mSeascapeRotation = Surface.ROTATION_270; } } synchronized (mLock) { if (orientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) { switch (orientation) { case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT: //always return portrait if orientation set to portrait return mPortraitRotation; } else if (orientation == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) { case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE: //always return landscape if orientation set to landscape return mLandscapeRotation; case ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT: //always return portrait if orientation set to portrait return mUpsideDownRotation; case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE: //always return seascape if orientation set to reverse landscape return mSeascapeRotation; case ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE: //return either landscape rotation based on the sensor mOrientationListener.setAllow180Rotation(false); return getCurrentLandscapeRotation(lastRotation); case ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT: mOrientationListener.setAllow180Rotation(true); return getCurrentPortraitRotation(lastRotation); } mOrientationListener.setAllow180Rotation( orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR); // case for nosensor meaning ignore sensor and consider only lid // or orientation sensor disabled //or case.unspecified Loading @@ -2094,18 +2118,15 @@ public class PhoneWindowManager implements WindowManagerPolicy { } private int getCurrentLandscapeRotation(int lastRotation) { // landscape-only apps can take either landscape rotation if (useSensorForOrientationLp(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE)) { int sensorRotation = mOrientationListener.getCurrentRotation(lastRotation); if (isLandscapeOrSeascape(sensorRotation)) { return sensorRotation; } } // try to preserve the old rotation if it was landscape if (isLandscapeOrSeascape(lastRotation)) { return lastRotation; } // default to one of the two landscape rotations // default to one of the primary landscape rotation return mLandscapeRotation; } Loading @@ -2113,6 +2134,23 @@ public class PhoneWindowManager implements WindowManagerPolicy { return sensorRotation == mLandscapeRotation || sensorRotation == mSeascapeRotation; } private int getCurrentPortraitRotation(int lastRotation) { int sensorRotation = mOrientationListener.getCurrentRotation(lastRotation); if (isAnyPortrait(sensorRotation)) { return sensorRotation; } // try to preserve the old rotation if it was portrait if (isAnyPortrait(lastRotation)) { return lastRotation; } // default to one of the primary portrait rotations return mPortraitRotation; } private boolean isAnyPortrait(int sensorRotation) { return sensorRotation == mPortraitRotation || sensorRotation == mUpsideDownRotation; } public boolean detectSafeMode() { try { int menuState = mWindowManager.getKeycodeState(KeyEvent.KEYCODE_MENU); Loading