summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xcore/res/res/values/config.xml37
-rwxr-xr-xcore/res/res/values/symbols.xml1
-rw-r--r--services/core/java/com/android/server/policy/WindowOrientationListener.java94
-rw-r--r--tools/orientationplot/README.txt2
-rwxr-xr-xtools/orientationplot/orientationplot.py2
5 files changed, 104 insertions, 32 deletions
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index db1ac44..e7811df 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -572,6 +572,43 @@
true here reverses that logic. -->
<bool name="config_reverseDefaultRotation">false</bool>
+ <!-- Sets the minimum and maximum tilt tolerance for each possible rotation.
+ This array consists of 4 pairs of values which specify the minimum and maximum
+ tilt angle at which the device will transition into each rotation.
+
+ The tilt angle represents the direction in which the plane of the screen is facing;
+ it is also known as the angle of elevation.
+
+ -90 degree tilt means that the screen is facing straight down
+ (the device is being held overhead upside-down)
+ 0 degree tilt means that the screen is facing outwards
+ (the device is being held vertically)
+ 90 degree tilt means that the screen is facing straight up
+ (the device is resting on a flat table)
+
+ The default tolerances are set conservatively such that the device is more
+ likely to remain in its natural orientation than rotate into a counterclockwise,
+ clockwise, or reversed posture (with an especially strong bias against the latter)
+ to prevent accidental rotation while carrying the device in hand.
+
+ These thresholds may need to be tuned when the device is intended to be
+ mounted into a dock with a particularly shallow profile wherein rotation
+ would ordinarily have been suppressed.
+
+ It is helpful to consider the desired behavior both when the device is being
+ held at a positive tilt (typical case) vs. a negative tilt (reading overhead in
+ bed) since they are quite different. In the overhead case, we typically want
+ the device to more strongly prefer to retain its current configuration (in absence
+ of a clear indication that a rotation is desired) since the user's head and neck may
+ be held at an unusual angle.
+ -->
+ <integer-array name="config_autoRotationTiltTolerance">
+ <!-- rotation: 0 (natural) --> <item>-25</item> <item>70</item>
+ <!-- rotation: 90 (rotate CCW) --> <item>-25</item> <item>65</item>
+ <!-- rotation: 180 (reverse) --> <item>-25</item> <item>60</item>
+ <!-- rotation: 270 (rotate CW) --> <item>-25</item> <item>65</item>
+ </integer-array>
+
<!-- Lid switch behavior -->
<!-- The number of degrees to rotate the display when the keyboard is open.
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index b019adb..361c0bd 100755
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1451,6 +1451,7 @@
<java-symbol type="anim" name="voice_activity_open_exit" />
<java-symbol type="anim" name="voice_activity_open_enter" />
+ <java-symbol type="array" name="config_autoRotationTiltTolerance" />
<java-symbol type="array" name="config_keyboardTapVibePattern" />
<java-symbol type="array" name="config_longPressVibePattern" />
<java-symbol type="array" name="config_safeModeDisabledVibePattern" />
diff --git a/services/core/java/com/android/server/policy/WindowOrientationListener.java b/services/core/java/com/android/server/policy/WindowOrientationListener.java
index c8fd82e..147efdd 100644
--- a/services/core/java/com/android/server/policy/WindowOrientationListener.java
+++ b/services/core/java/com/android/server/policy/WindowOrientationListener.java
@@ -24,10 +24,10 @@ import android.hardware.SensorManager;
import android.os.Handler;
import android.os.SystemClock;
import android.os.SystemProperties;
-import android.util.Log;
import android.util.Slog;
import java.io.PrintWriter;
+import java.util.Arrays;
/**
* A special helper class used by the WindowManager
@@ -40,8 +40,6 @@ import java.io.PrintWriter;
*
* You can also visualize the behavior of the WindowOrientationListener.
* Refer to frameworks/base/tools/orientationplot/README.txt for details.
- *
- * @hide
*/
public abstract class WindowOrientationListener {
private static final String TAG = "WindowOrientationListener";
@@ -90,7 +88,7 @@ public abstract class WindowOrientationListener {
? Sensor.TYPE_GRAVITY : Sensor.TYPE_ACCELEROMETER);
if (mSensor != null) {
// Create listener only if sensors do exist
- mSensorEventListener = new SensorEventListenerImpl();
+ mSensorEventListener = new SensorEventListenerImpl(context);
}
}
@@ -101,12 +99,12 @@ public abstract class WindowOrientationListener {
public void enable() {
synchronized (mLock) {
if (mSensor == null) {
- Log.w(TAG, "Cannot detect sensors. Not enabled");
+ Slog.w(TAG, "Cannot detect sensors. Not enabled");
return;
}
if (mEnabled == false) {
if (LOG) {
- Log.d(TAG, "WindowOrientationListener enabled");
+ Slog.d(TAG, "WindowOrientationListener enabled");
}
mSensorEventListener.resetLocked();
mSensorManager.registerListener(mSensorEventListener, mSensor, mRate, mHandler);
@@ -121,12 +119,12 @@ public abstract class WindowOrientationListener {
public void disable() {
synchronized (mLock) {
if (mSensor == null) {
- Log.w(TAG, "Cannot detect sensors. Invalid disable");
+ Slog.w(TAG, "Cannot detect sensors. Invalid disable");
return;
}
if (mEnabled == true) {
if (LOG) {
- Log.d(TAG, "WindowOrientationListener disabled");
+ Slog.d(TAG, "WindowOrientationListener disabled");
}
mSensorManager.unregisterListener(mSensorEventListener);
mEnabled = false;
@@ -296,7 +294,7 @@ public abstract class WindowOrientationListener {
// If the tilt angle remains greater than the specified angle for a minimum of
// the specified time, then the device is deemed to be lying flat
// (just chillin' on a table).
- private static final float FLAT_ANGLE = 75;
+ private static final float FLAT_ANGLE = 80;
private static final long FLAT_TIME_NANOS = 1000 * NANOS_PER_MS;
// If the tilt angle has increased by at least delta degrees within the specified amount
@@ -361,8 +359,24 @@ public abstract class WindowOrientationListener {
SensorManager.STANDARD_GRAVITY + ACCELERATION_TOLERANCE;
// Maximum absolute tilt angle at which to consider orientation data. Beyond this (i.e.
- // when screen is facing the sky or ground), we completely ignore orientation data.
- private static final int MAX_TILT = 75;
+ // when screen is facing the sky or ground), we completely ignore orientation data
+ // because it's too unstable.
+ private static final int MAX_TILT = 80;
+
+ // The tilt angle below which we conclude that the user is holding the device
+ // overhead reading in bed and lock into that state.
+ private static final int TILT_OVERHEAD_ENTER = -40;
+
+ // The tilt angle above which we conclude that the user would like a rotation
+ // change to occur and unlock from the overhead state.
+ private static final int TILT_OVERHEAD_EXIT = -15;
+
+ // The gap angle in degrees between adjacent orientation angles for hysteresis.
+ // This creates a "dead zone" between the current orientation and a proposed
+ // adjacent orientation. No orientation proposal is made when the orientation
+ // angle is within the gap between the current orientation and the adjacent
+ // orientation.
+ private static final int ADJACENT_ORIENTATION_ANGLE_GAP = 45;
// The tilt angle range in degrees for each orientation.
// Beyond these tilt angles, we don't even consider transitioning into the
@@ -375,28 +389,13 @@ public abstract class WindowOrientationListener {
// facing up (resting on a table).
// The ideal tilt angle is 0 (when the device is vertical) so the limits establish
// how close to vertical the device must be in order to change orientation.
- private final int[][] TILT_TOLERANCE = new int[][] {
- /* ROTATION_0 */ { -25, 70 },
+ private final int[][] mTiltToleranceConfig = new int[][] {
+ /* ROTATION_0 */ { -25, 70 }, // note: these are overridden by config.xml
/* ROTATION_90 */ { -25, 65 },
/* ROTATION_180 */ { -25, 60 },
/* ROTATION_270 */ { -25, 65 }
};
- // The tilt angle below which we conclude that the user is holding the device
- // overhead reading in bed and lock into that state.
- private final int TILT_OVERHEAD_ENTER = -40;
-
- // The tilt angle above which we conclude that the user would like a rotation
- // change to occur and unlock from the overhead state.
- private final int TILT_OVERHEAD_EXIT = -15;
-
- // The gap angle in degrees between adjacent orientation angles for hysteresis.
- // This creates a "dead zone" between the current orientation and a proposed
- // adjacent orientation. No orientation proposal is made when the orientation
- // angle is within the gap between the current orientation and the adjacent
- // orientation.
- private static final int ADJACENT_ORIENTATION_ANGLE_GAP = 45;
-
// Timestamp and value of the last accelerometer sample.
private long mLastFilteredTimestampNanos;
private float mLastFilteredX, mLastFilteredY, mLastFilteredZ;
@@ -430,11 +429,32 @@ public abstract class WindowOrientationListener {
private boolean mOverhead;
// History of observed tilt angles.
- private static final int TILT_HISTORY_SIZE = 40;
+ private static final int TILT_HISTORY_SIZE = 200;
private float[] mTiltHistory = new float[TILT_HISTORY_SIZE];
private long[] mTiltHistoryTimestampNanos = new long[TILT_HISTORY_SIZE];
private int mTiltHistoryIndex;
+ public SensorEventListenerImpl(Context context) {
+ // Load tilt tolerance configuration.
+ int[] tiltTolerance = context.getResources().getIntArray(
+ com.android.internal.R.array.config_autoRotationTiltTolerance);
+ if (tiltTolerance.length == 8) {
+ for (int i = 0; i < 4; i++) {
+ int min = tiltTolerance[i * 2];
+ int max = tiltTolerance[i * 2 + 1];
+ if (min >= -90 && min <= max && max <= 90) {
+ mTiltToleranceConfig[i][0] = min;
+ mTiltToleranceConfig[i][1] = max;
+ } else {
+ Slog.wtf(TAG, "config_autoRotationTiltTolerance contains invalid range: "
+ + "min=" + min + ", max=" + max);
+ }
+ }
+ } else {
+ Slog.wtf(TAG, "config_autoRotationTiltTolerance should have exactly 8 elements");
+ }
+ }
+
public int getProposedRotationLocked() {
return mProposedRotation;
}
@@ -451,6 +471,18 @@ public abstract class WindowOrientationListener {
pw.println(prefix + "mAccelerating=" + mAccelerating);
pw.println(prefix + "mOverhead=" + mOverhead);
pw.println(prefix + "mTouched=" + mTouched);
+ pw.print(prefix + "mTiltToleranceConfig=[");
+ for (int i = 0; i < 4; i++) {
+ if (i != 0) {
+ pw.print(", ");
+ }
+ pw.print("[");
+ pw.print(mTiltToleranceConfig[i][0]);
+ pw.print(", ");
+ pw.print(mTiltToleranceConfig[i][1]);
+ pw.print("]");
+ }
+ pw.println("]");
}
@Override
@@ -658,8 +690,8 @@ public abstract class WindowOrientationListener {
* Returns true if the tilt angle is acceptable for a given predicted rotation.
*/
private boolean isTiltAngleAcceptableLocked(int rotation, int tiltAngle) {
- return tiltAngle >= TILT_TOLERANCE[rotation][0]
- && tiltAngle <= TILT_TOLERANCE[rotation][1];
+ return tiltAngle >= mTiltToleranceConfig[rotation][0]
+ && tiltAngle <= mTiltToleranceConfig[rotation][1];
}
/**
diff --git a/tools/orientationplot/README.txt b/tools/orientationplot/README.txt
index d53f65e..958207d 100644
--- a/tools/orientationplot/README.txt
+++ b/tools/orientationplot/README.txt
@@ -9,6 +9,8 @@ PREREQUISITES
2. numpy
3. matplotlib
+eg. sudo apt-get install python-numpy python-matplotlib
+
USAGE
-----
diff --git a/tools/orientationplot/orientationplot.py b/tools/orientationplot/orientationplot.py
index 6fc3922..77ed074 100755
--- a/tools/orientationplot/orientationplot.py
+++ b/tools/orientationplot/orientationplot.py
@@ -440,7 +440,7 @@ class Plotter:
# Notice
print "Window Orientation Listener plotting tool"
print "-----------------------------------------\n"
-print "Please turn on the Window Orientation Listener logging in Development Settings."
+print "Please turn on the Window Orientation Listener logging. See README.txt."
# Start adb.
print "Starting adb logcat.\n"