Prevent sensor induced rotations while screen is touched
Bug: 19408285
Change-Id: Idadacc4cfb0cf41477155dc837297bacc3533ba5
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 9746142..b44eade 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -1327,6 +1327,14 @@
public void onDebug() {
// no-op
}
+ @Override
+ public void onDown() {
+ mOrientationListener.onTouchStart();
+ }
+ @Override
+ public void onUpOrCancel() {
+ mOrientationListener.onTouchEnd();
+ }
});
mImmersiveModeConfirmation = new ImmersiveModeConfirmation(mContext);
mWindowManagerFuncs.registerPointerEventListener(mSystemGestures);
diff --git a/services/core/java/com/android/server/policy/SystemGesturesPointerEventListener.java b/services/core/java/com/android/server/policy/SystemGesturesPointerEventListener.java
index cfa631f..627b328 100644
--- a/services/core/java/com/android/server/policy/SystemGesturesPointerEventListener.java
+++ b/services/core/java/com/android/server/policy/SystemGesturesPointerEventListener.java
@@ -75,6 +75,7 @@
mDebugFireable = true;
mDownPointers = 0;
captureDown(event, 0);
+ mCallbacks.onDown();
break;
case MotionEvent.ACTION_POINTER_DOWN:
captureDown(event, event.getActionIndex());
@@ -106,6 +107,7 @@
case MotionEvent.ACTION_CANCEL:
mSwipeFireable = false;
mDebugFireable = false;
+ mCallbacks.onUpOrCancel();
break;
default:
if (DEBUG) Slog.d(TAG, "Ignoring " + event);
@@ -192,6 +194,8 @@
void onSwipeFromTop();
void onSwipeFromBottom();
void onSwipeFromRight();
+ void onDown();
+ void onUpOrCancel();
void onDebug();
}
}
diff --git a/services/core/java/com/android/server/policy/WindowOrientationListener.java b/services/core/java/com/android/server/policy/WindowOrientationListener.java
index 0118127..a33ee4c 100644
--- a/services/core/java/com/android/server/policy/WindowOrientationListener.java
+++ b/services/core/java/com/android/server/policy/WindowOrientationListener.java
@@ -22,6 +22,7 @@
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Handler;
+import android.os.SystemClock;
import android.os.SystemProperties;
import android.util.Log;
import android.util.Slog;
@@ -133,6 +134,20 @@
}
}
+ public void onTouchStart() {
+ synchronized (mLock) {
+ mSensorEventListener.onTouchStartLocked();
+ }
+ }
+
+ public void onTouchEnd() {
+ long whenElapsedNanos = SystemClock.elapsedRealtimeNanos();
+
+ synchronized (mLock) {
+ mSensorEventListener.onTouchEndLocked(whenElapsedNanos);
+ }
+ }
+
/**
* Sets the current rotation.
*
@@ -269,6 +284,11 @@
private static final long PROPOSAL_MIN_TIME_SINCE_ACCELERATION_ENDED_NANOS =
500 * NANOS_PER_MS;
+ // The minimum amount of time that must have elapsed since the screen was last touched
+ // before the proposed rotation can change.
+ private static final long PROPOSAL_MIN_TIME_SINCE_TOUCH_END_NANOS =
+ 500 * NANOS_PER_MS;
+
// 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).
@@ -398,6 +418,10 @@
private long mAccelerationTimestampNanos;
private boolean mAccelerating;
+ // Timestamp when the last touch to the touch screen ended
+ private long mTouchEndedTimestampNanos = Long.MIN_VALUE;
+ private boolean mTouched;
+
// Whether we are locked into an overhead usage mode.
private boolean mOverhead;
@@ -422,6 +446,7 @@
pw.println(prefix + "mSwinging=" + mSwinging);
pw.println(prefix + "mAccelerating=" + mAccelerating);
pw.println(prefix + "mOverhead=" + mOverhead);
+ pw.println(prefix + "mTouched=" + mTouched);
}
@Override
@@ -601,6 +626,7 @@
+ ", isFlat=" + isFlat
+ ", isSwinging=" + isSwinging
+ ", isOverhead=" + mOverhead
+ + ", isTouched=" + mTouched
+ ", timeUntilSettledMS=" + remainingMS(now,
mPredictedRotationTimestampNanos + PROPOSAL_SETTLE_TIME_NANOS)
+ ", timeUntilAccelerationDelayExpiredMS=" + remainingMS(now,
@@ -608,7 +634,9 @@
+ ", timeUntilFlatDelayExpiredMS=" + remainingMS(now,
mFlatTimestampNanos + PROPOSAL_MIN_TIME_SINCE_FLAT_ENDED_NANOS)
+ ", timeUntilSwingDelayExpiredMS=" + remainingMS(now,
- mSwingTimestampNanos + PROPOSAL_MIN_TIME_SINCE_SWING_ENDED_NANOS));
+ mSwingTimestampNanos + PROPOSAL_MIN_TIME_SINCE_SWING_ENDED_NANOS)
+ + ", timeUntilTouchDelayExpiredMS=" + remainingMS(now,
+ mTouchEndedTimestampNanos + PROPOSAL_MIN_TIME_SINCE_TOUCH_END_NANOS));
}
}
@@ -710,6 +738,12 @@
return false;
}
+ // The last touch must have ended sufficiently long ago.
+ if (mTouched || now < mTouchEndedTimestampNanos
+ + PROPOSAL_MIN_TIME_SINCE_TOUCH_END_NANOS) {
+ return false;
+ }
+
// Looks good!
return true;
}
@@ -796,5 +830,14 @@
private float remainingMS(long now, long until) {
return now >= until ? 0 : (until - now) * 0.000001f;
}
+
+ private void onTouchStartLocked() {
+ mTouched = true;
+ }
+
+ private void onTouchEndLocked(long whenElapsedNanos) {
+ mTouched = false;
+ mTouchEndedTimestampNanos = whenElapsedNanos;
+ }
}
}