Merge "Updating Pause detection to use motion events directly" into ub-launcher3-master
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/FlingAndHoldTouchController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/FlingAndHoldTouchController.java
index b80830a..519939e 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/FlingAndHoldTouchController.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/FlingAndHoldTouchController.java
@@ -172,7 +172,7 @@
mMotionPauseDetector.setDisallowPause(!handlingOverviewAnim()
|| upDisplacement < mMotionPauseMinDisplacement
|| upDisplacement > mMotionPauseMaxDisplacement);
- mMotionPauseDetector.addPosition(displacement, event.getEventTime());
+ mMotionPauseDetector.addPosition(event);
return super.onDrag(displacement, event);
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
index 8628db0..799f1ad 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
@@ -317,7 +317,7 @@
// home screen elements will appear in the shelf on motion pause.
mMotionPauseDetector.setDisallowPause(mIsHomeScreenVisible
|| -displacement.y < mMotionPauseMinDisplacement);
- mMotionPauseDetector.addPosition(displacement.y, ev.getEventTime());
+ mMotionPauseDetector.addPosition(ev);
if (mIsHomeScreenVisible) {
// Cancel the shelf anim so it doesn't clobber mNonOverviewAnim.
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/AccessibilityInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/AccessibilityInputConsumer.java
index d3765c5..5ad48eb 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/AccessibilityInputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/AccessibilityInputConsumer.java
@@ -31,8 +31,8 @@
import com.android.launcher3.R;
import com.android.quickstep.InputConsumer;
import com.android.quickstep.RecentsAnimationDeviceState;
-import com.android.quickstep.util.MotionPauseDetector;
import com.android.quickstep.SystemUiProxy;
+import com.android.quickstep.util.MotionPauseDetector;
import com.android.systemui.shared.system.InputMonitorCompat;
/**
@@ -117,9 +117,7 @@
if (pointerIndex == -1) {
break;
}
-
- mMotionPauseDetector.addPosition(ev.getY(pointerIndex) - mDownY,
- ev.getEventTime());
+ mMotionPauseDetector.addPosition(ev, pointerIndex);
}
break;
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
index 3ee3c2d..8e7074d 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
@@ -59,6 +59,7 @@
import com.android.quickstep.util.ActiveGestureLog;
import com.android.quickstep.util.CachedEventDispatcher;
import com.android.quickstep.util.MotionPauseDetector;
+import com.android.quickstep.util.NavBarPosition;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.InputMonitorCompat;
@@ -77,6 +78,7 @@
public static final float QUICKSTEP_TOUCH_SLOP_RATIO = 3;
private final RecentsAnimationDeviceState mDeviceState;
+ private final NavBarPosition mNavBarPosition;
private final TaskAnimationManager mTaskAnimationManager;
private final GestureState mGestureState;
private RecentsAnimationCallbacks mActiveCallbacks;
@@ -126,13 +128,16 @@
Factory handlerFactory) {
super(base);
mDeviceState = deviceState;
+ mNavBarPosition = mDeviceState.getNavBarPosition();
mTaskAnimationManager = taskAnimationManager;
mGestureState = gestureState;
mMainThreadHandler = new Handler(Looper.getMainLooper());
mHandlerFactory = handlerFactory;
mActivityInterface = mGestureState.getActivityInterface();
- mMotionPauseDetector = new MotionPauseDetector(base);
+ mMotionPauseDetector = new MotionPauseDetector(base, false,
+ mNavBarPosition.isLeftEdge() || mNavBarPosition.isRightEdge()
+ ? MotionEvent.AXIS_X : MotionEvent.AXIS_Y);
mMotionPauseMinDisplacement = base.getResources().getDimension(
R.dimen.motion_pause_detector_min_displacement_from_app);
mOnCompleteCallback = onCompleteCallback;
@@ -172,7 +177,7 @@
if (mPassedWindowMoveSlop && mInteractionHandler != null
&& !mRecentsViewDispatcher.hasConsumer()) {
mRecentsViewDispatcher.setConsumer(mInteractionHandler.getRecentsViewDispatcher(
- mDeviceState.getNavBarPosition().getRotationMode()));
+ mNavBarPosition.getRotationMode()));
}
int edgeFlags = ev.getEdgeFlags();
ev.setEdgeFlags(edgeFlags | EDGE_NAV_BAR);
@@ -285,7 +290,7 @@
if (mDeviceState.isFullyGesturalNavMode()) {
mMotionPauseDetector.setDisallowPause(upDist < mMotionPauseMinDisplacement
|| isLikelyToStartNewTask);
- mMotionPauseDetector.addPosition(displacement, ev.getEventTime());
+ mMotionPauseDetector.addPosition(ev);
mInteractionHandler.setIsLikelyToStartNewTask(isLikelyToStartNewTask);
}
}
@@ -354,9 +359,9 @@
ViewConfiguration.get(this).getScaledMaximumFlingVelocity());
float velocityX = mVelocityTracker.getXVelocity(mActivePointerId);
float velocityY = mVelocityTracker.getYVelocity(mActivePointerId);
- float velocity = mDeviceState.getNavBarPosition().isRightEdge()
+ float velocity = mNavBarPosition.isRightEdge()
? velocityX
- : mDeviceState.getNavBarPosition().isLeftEdge()
+ : mNavBarPosition.isLeftEdge()
? -velocityX
: velocityY;
@@ -410,9 +415,9 @@
}
private float getDisplacement(MotionEvent ev) {
- if (mDeviceState.getNavBarPosition().isRightEdge()) {
+ if (mNavBarPosition.isRightEdge()) {
return ev.getX() - mDownPos.x;
- } else if (mDeviceState.getNavBarPosition().isLeftEdge()) {
+ } else if (mNavBarPosition.isLeftEdge()) {
return mDownPos.x - ev.getX();
} else {
return ev.getY() - mDownPos.y;
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/ScreenPinnedInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/ScreenPinnedInputConsumer.java
index d5ed321..b9827ff 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/ScreenPinnedInputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/ScreenPinnedInputConsumer.java
@@ -23,8 +23,8 @@
import com.android.launcher3.R;
import com.android.quickstep.GestureState;
import com.android.quickstep.InputConsumer;
-import com.android.quickstep.util.MotionPauseDetector;
import com.android.quickstep.SystemUiProxy;
+import com.android.quickstep.util.MotionPauseDetector;
/**
* An input consumer that detects swipe up and hold to exit screen pinning mode.
@@ -72,7 +72,7 @@
case MotionEvent.ACTION_MOVE:
float displacement = mTouchDownY - y;
mMotionPauseDetector.setDisallowPause(displacement < mMotionPauseMinDisplacement);
- mMotionPauseDetector.addPosition(y, ev.getEventTime());
+ mMotionPauseDetector.addPosition(ev);
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
diff --git a/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java b/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java
index 801a560..d8b10b6 100644
--- a/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java
+++ b/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java
@@ -37,8 +37,7 @@
private static final long FORCE_PAUSE_TIMEOUT = 300;
/**
- * After {@link #makePauseHarderToTrigger()}, must
- * move slowly for this long to trigger a pause.
+ * After {@link #mMakePauseHarderToTrigger}, must move slowly for this long to trigger a pause.
*/
private static final long HARDER_TRIGGER_TIMEOUT = 400;
@@ -49,13 +48,10 @@
private final Alarm mForcePauseTimeout;
private final boolean mMakePauseHarderToTrigger;
private final Context mContext;
+ private final VelocityProvider mVelocityProvider;
- private Long mPreviousTime = null;
- private Float mPreviousPosition = null;
private Float mPreviousVelocity = null;
- private Float mFirstPosition = null;
-
private OnMotionPauseListener mOnMotionPauseListener;
private boolean mIsPaused;
// Bias more for the first pause to make it feel extra responsive.
@@ -73,6 +69,13 @@
* @param makePauseHarderToTrigger Used for gestures that require a more explicit pause.
*/
public MotionPauseDetector(Context context, boolean makePauseHarderToTrigger) {
+ this(context, makePauseHarderToTrigger, MotionEvent.AXIS_Y);
+ }
+
+ /**
+ * @param makePauseHarderToTrigger Used for gestures that require a more explicit pause.
+ */
+ public MotionPauseDetector(Context context, boolean makePauseHarderToTrigger, int axis) {
mContext = context;
Resources res = context.getResources();
mSpeedVerySlow = res.getDimension(R.dimen.motion_pause_detector_speed_very_slow);
@@ -82,6 +85,7 @@
mForcePauseTimeout = new Alarm();
mForcePauseTimeout.setOnAlarmListener(alarm -> updatePaused(true /* isPaused */));
mMakePauseHarderToTrigger = makePauseHarderToTrigger;
+ mVelocityProvider = new LinearVelocityProvider(axis);
}
/**
@@ -101,28 +105,28 @@
/**
* Computes velocity and acceleration to determine whether the motion is paused.
- * @param position The x or y component of the motion being tracked.
+ * @param ev The motion being tracked.
*
* TODO: Use historical positions as well, e.g. {@link MotionEvent#getHistoricalY(int, int)}.
*/
- public void addPosition(float position, long time) {
- if (mFirstPosition == null) {
- mFirstPosition = position;
- }
+ public void addPosition(MotionEvent ev) {
+ addPosition(ev, 0);
+ }
+
+ /**
+ * Computes velocity and acceleration to determine whether the motion is paused.
+ * @param ev The motion being tracked.
+ * @param pointerIndex Index for the pointer being tracked in the motion event
+ */
+ public void addPosition(MotionEvent ev, int pointerIndex) {
mForcePauseTimeout.setAlarm(mMakePauseHarderToTrigger
? HARDER_TRIGGER_TIMEOUT
: FORCE_PAUSE_TIMEOUT);
- if (mPreviousTime != null && mPreviousPosition != null) {
- long changeInTime = Math.max(1, time - mPreviousTime);
- float changeInPosition = position - mPreviousPosition;
- float velocity = changeInPosition / changeInTime;
- if (mPreviousVelocity != null) {
- checkMotionPaused(velocity, mPreviousVelocity, time);
- }
- mPreviousVelocity = velocity;
+ Float newVelocity = mVelocityProvider.addMotionEvent(ev, pointerIndex);
+ if (newVelocity != null && mPreviousVelocity != null) {
+ checkMotionPaused(newVelocity, mPreviousVelocity, ev.getEventTime());
}
- mPreviousTime = time;
- mPreviousPosition = position;
+ mPreviousVelocity = newVelocity;
}
private void checkMotionPaused(float velocity, float prevVelocity, long time) {
@@ -178,10 +182,8 @@
}
public void clear() {
- mPreviousTime = null;
- mPreviousPosition = null;
+ mVelocityProvider.clear();
mPreviousVelocity = null;
- mFirstPosition = null;
setOnMotionPauseListener(null);
mIsPaused = mHasEverBeenPaused = false;
mSlowStartTime = 0;
@@ -195,4 +197,55 @@
public interface OnMotionPauseListener {
void onMotionPauseChanged(boolean isPaused);
}
+
+ /**
+ * Interface to abstract out velocity calculations
+ */
+ protected interface VelocityProvider {
+
+ /**
+ * Adds a new motion events, and returns the velocity at this point, or null if
+ * the velocity is not available
+ */
+ Float addMotionEvent(MotionEvent ev, int pointer);
+
+ /**
+ * Clears all stored motion event records
+ */
+ void clear();
+ }
+
+ private static class LinearVelocityProvider implements VelocityProvider {
+
+ private Long mPreviousTime = null;
+ private Float mPreviousPosition = null;
+
+ private final int mAxis;
+
+ LinearVelocityProvider(int axis) {
+ mAxis = axis;
+ }
+
+ @Override
+ public Float addMotionEvent(MotionEvent ev, int pointer) {
+ long time = ev.getEventTime();
+ float position = ev.getAxisValue(mAxis, pointer);
+ Float velocity = null;
+
+ if (mPreviousTime != null && mPreviousPosition != null) {
+ long changeInTime = Math.max(1, time - mPreviousTime);
+ float changeInPosition = position - mPreviousPosition;
+ velocity = changeInPosition / changeInTime;
+ }
+ mPreviousTime = time;
+ mPreviousPosition = position;
+ return velocity;
+ }
+
+ @Override
+ public void clear() {
+ mPreviousTime = null;
+ mPreviousPosition = null;
+ }
+ }
}