Merge "Cancelling previous touch interaction when a new touch starts" into ub-launcher3-master
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index b9f95cc..cded799 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -19,7 +19,7 @@
import static android.view.MotionEvent.ACTION_DOWN;
import static android.view.MotionEvent.ACTION_MOVE;
import static android.view.MotionEvent.ACTION_POINTER_DOWN;
-import static android.view.MotionEvent.ACTION_POINTER_UP;
+import static android.view.MotionEvent.ACTION_POINTER_INDEX_SHIFT;
import static android.view.MotionEvent.ACTION_UP;
import static com.android.systemui.shared.system.ActivityManagerWrapper
@@ -52,6 +52,7 @@
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.ChoreographerCompat;
import com.android.systemui.shared.system.NavigationBarCompat.HitTarget;
+
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -299,7 +300,7 @@
mActivityHelper = activityHelper;
mActivity = activity;
mTarget = activity.getDragLayer();
- mTouchSlop = ViewConfiguration.get(mTarget.getContext()).getScaledTouchSlop();
+ mTouchSlop = ViewConfiguration.get(mActivity).getScaledTouchSlop();
mStartingInActivityBounds = startingInActivityBounds;
mQuickScrubController = mActivity.<RecentsView>getOverviewPanel()
@@ -324,12 +325,6 @@
mDownPos.set(ev.getX(), ev.getY());
} else if (!mTrackingStarted) {
switch (action) {
- case ACTION_POINTER_UP:
- case ACTION_POINTER_DOWN:
- if (!mTrackingStarted) {
- mInvalidated = true;
- }
- break;
case ACTION_CANCEL:
case ACTION_UP:
startTouchTracking(ev, true /* updateLocationOffset */);
@@ -359,15 +354,26 @@
}
// Send down touch event
- MotionEvent down = MotionEvent.obtain(ev);
+ MotionEvent down = MotionEvent.obtainNoHistory(ev);
down.setAction(ACTION_DOWN);
sendEvent(down);
- down.recycle();
mTrackingStarted = true;
+ // Send pointer down for remaining pointers.
+ int pointerCount = ev.getPointerCount();
+ for (int i = 1; i < pointerCount; i++) {
+ down.setAction(ACTION_POINTER_DOWN | (i << ACTION_POINTER_INDEX_SHIFT));
+ sendEvent(down);
+ }
+
+ down.recycle();
}
private void sendEvent(MotionEvent ev) {
+ if (!mTarget.verifyTouchDispatch(this, ev)) {
+ mInvalidated = true;
+ return;
+ }
int flags = ev.getEdgeFlags();
ev.setEdgeFlags(flags | TouchInteractionService.EDGE_NAV_BAR);
ev.offsetLocation(-mLocationOnScreen[0], -mLocationOnScreen[1]);
diff --git a/src/com/android/launcher3/views/BaseDragLayer.java b/src/com/android/launcher3/views/BaseDragLayer.java
index 1faca15..5b8df13 100644
--- a/src/com/android/launcher3/views/BaseDragLayer.java
+++ b/src/com/android/launcher3/views/BaseDragLayer.java
@@ -16,6 +16,10 @@
package com.android.launcher3.views;
+import static android.view.MotionEvent.ACTION_CANCEL;
+import static android.view.MotionEvent.ACTION_DOWN;
+import static android.view.MotionEvent.ACTION_UP;
+
import static com.android.launcher3.Utilities.SINGLE_FRAME_MS;
import android.content.Context;
@@ -79,6 +83,9 @@
protected TouchController mActiveController;
private TouchCompleteListener mTouchCompleteListener;
+ // Object controlling the current touch interaction
+ private Object mCurrentTouchOwner;
+
public BaseDragLayer(Context context, AttributeSet attrs, int alphaChannelCount) {
super(context, attrs);
mActivity = (T) ActivityContext.lookupContext(context);
@@ -94,7 +101,7 @@
public boolean onInterceptTouchEvent(MotionEvent ev) {
int action = ev.getAction();
- if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
+ if (action == ACTION_UP || action == ACTION_CANCEL) {
if (mTouchCompleteListener != null) {
mTouchCompleteListener.onTouchComplete();
}
@@ -177,7 +184,7 @@
@Override
public boolean onTouchEvent(MotionEvent ev) {
int action = ev.getAction();
- if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
+ if (action == ACTION_UP || action == ACTION_CANCEL) {
if (mTouchCompleteListener != null) {
mTouchCompleteListener.onTouchComplete();
}
@@ -192,6 +199,37 @@
}
}
+ @Override
+ public boolean dispatchTouchEvent(MotionEvent ev) {
+ return verifyTouchDispatch(this, ev) && super.dispatchTouchEvent(ev);
+ }
+
+ /**
+ * Returns true if the {@param caller} is allowed to dispatch {@param ev} on this view,
+ * false otherwise.
+ */
+ public boolean verifyTouchDispatch(Object caller, MotionEvent ev) {
+ int action = ev.getAction();
+ if (action == ACTION_DOWN) {
+ if (mCurrentTouchOwner != null) {
+ // Another touch in progress.
+ ev.setAction(ACTION_CANCEL);
+ super.dispatchTouchEvent(ev);
+ ev.setAction(action);
+ }
+ mCurrentTouchOwner = caller;
+ return true;
+ }
+ if (mCurrentTouchOwner != caller) {
+ // Someone else is controlling the touch
+ return false;
+ }
+ if (action == ACTION_UP || action == ACTION_CANCEL) {
+ mCurrentTouchOwner = null;
+ }
+ return true;
+ }
+
/**
* Determine the rect of the descendant in this DragLayer's coordinates
*