Double tap to expand PiP.
- Also fix issue with dismiss scrim not clearing when quickly swiping in
the dismiss area and back, due to an incorrect check (menu state NONE
!= menu is not visible).
Bug: 62078042
Test: com.android.systemui.pip.phone.PipTouchStateTest
Test: Double tap PiP to expand it
Change-Id: I96d9ba169feadf0ea8315152fb3a5b2cfb69a2f0
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchState.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchState.java
index 686b3bb..b9369d3 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchState.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchState.java
@@ -17,11 +17,15 @@
package com.android.systemui.pip.phone;
import android.graphics.PointF;
+import android.os.Handler;
+import android.os.SystemClock;
import android.util.Log;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.ViewConfiguration;
+import com.android.internal.annotations.VisibleForTesting;
+
import java.io.PrintWriter;
/**
@@ -31,9 +35,17 @@
private static final String TAG = "PipTouchHandler";
private static final boolean DEBUG = false;
- private ViewConfiguration mViewConfig;
+ @VisibleForTesting
+ static final long DOUBLE_TAP_TIMEOUT = 200;
+
+ private final Handler mHandler;
+ private final ViewConfiguration mViewConfig;
+ private final Runnable mDoubleTapTimeoutCallback;
private VelocityTracker mVelocityTracker;
+ private long mDownTouchTime = 0;
+ private long mLastDownTouchTime = 0;
+ private long mUpTouchTime = 0;
private final PointF mDownTouch = new PointF();
private final PointF mDownDelta = new PointF();
private final PointF mLastTouch = new PointF();
@@ -41,13 +53,22 @@
private final PointF mVelocity = new PointF();
private boolean mAllowTouches = true;
private boolean mIsUserInteracting = false;
+ // Set to true only if the multiple taps occur within the double tap timeout
+ private boolean mIsDoubleTap = false;
+ // Set to true only if a gesture
+ private boolean mIsWaitingForDoubleTap = false;
private boolean mIsDragging = false;
+ // The previous gesture was a drag
+ private boolean mPreviouslyDragging = false;
private boolean mStartedDragging = false;
private boolean mAllowDraggingOffscreen = false;
private int mActivePointerId;
- public PipTouchState(ViewConfiguration viewConfig) {
+ public PipTouchState(ViewConfiguration viewConfig, Handler handler,
+ Runnable doubleTapTimeoutCallback) {
mViewConfig = viewConfig;
+ mHandler = handler;
+ mDoubleTapTimeoutCallback = doubleTapTimeoutCallback;
}
/**
@@ -81,6 +102,14 @@
mDownTouch.set(mLastTouch);
mAllowDraggingOffscreen = true;
mIsUserInteracting = true;
+ mDownTouchTime = ev.getEventTime();
+ mIsDoubleTap = !mPreviouslyDragging &&
+ (mDownTouchTime - mLastDownTouchTime) < DOUBLE_TAP_TIMEOUT;
+ mIsWaitingForDoubleTap = false;
+ mLastDownTouchTime = mDownTouchTime;
+ if (mDoubleTapTimeoutCallback != null) {
+ mHandler.removeCallbacks(mDoubleTapTimeoutCallback);
+ }
break;
}
case MotionEvent.ACTION_MOVE: {
@@ -155,7 +184,11 @@
break;
}
+ mUpTouchTime = ev.getEventTime();
mLastTouch.set(ev.getX(pointerIndex), ev.getY(pointerIndex));
+ mPreviouslyDragging = mIsDragging;
+ mIsWaitingForDoubleTap = !mIsDoubleTap && !mIsDragging &&
+ (mUpTouchTime - mDownTouchTime) < DOUBLE_TAP_TIMEOUT;
// Fall through to clean up
}
@@ -251,6 +284,39 @@
return mAllowDraggingOffscreen;
}
+ /**
+ * @return whether this gesture is a double-tap.
+ */
+ public boolean isDoubleTap() {
+ return mIsDoubleTap;
+ }
+
+ /**
+ * @return whether this gesture will potentially lead to a following double-tap.
+ */
+ public boolean isWaitingForDoubleTap() {
+ return mIsWaitingForDoubleTap;
+ }
+
+ /**
+ * Schedules the callback to run if the next double tap does not occur. Only runs if
+ * isWaitingForDoubleTap() is true.
+ */
+ public void scheduleDoubleTapTimeoutCallback() {
+ if (mIsWaitingForDoubleTap) {
+ long delay = getDoubleTapTimeoutCallbackDelay();
+ mHandler.removeCallbacks(mDoubleTapTimeoutCallback);
+ mHandler.postDelayed(mDoubleTapTimeoutCallback, delay);
+ }
+ }
+
+ @VisibleForTesting long getDoubleTapTimeoutCallbackDelay() {
+ if (mIsWaitingForDoubleTap) {
+ return Math.max(0, DOUBLE_TAP_TIMEOUT - (mUpTouchTime - mDownTouchTime));
+ }
+ return -1;
+ }
+
private void initOrResetVelocityTracker() {
if (mVelocityTracker == null) {
mVelocityTracker = VelocityTracker.obtain();