summaryrefslogtreecommitdiffstats
path: root/remoting/android
diff options
context:
space:
mode:
Diffstat (limited to 'remoting/android')
-rw-r--r--remoting/android/java/src/org/chromium/chromoting/TapGestureDetector.java59
-rw-r--r--remoting/android/java/src/org/chromium/chromoting/TrackingInputHandler.java71
2 files changed, 100 insertions, 30 deletions
diff --git a/remoting/android/java/src/org/chromium/chromoting/TapGestureDetector.java b/remoting/android/java/src/org/chromium/chromoting/TapGestureDetector.java
index c0c2843..fa30b02 100644
--- a/remoting/android/java/src/org/chromium/chromoting/TapGestureDetector.java
+++ b/remoting/android/java/src/org/chromium/chromoting/TapGestureDetector.java
@@ -6,15 +6,16 @@ package org.chromium.chromoting;
import android.content.Context;
import android.graphics.PointF;
-import android.util.Log;
+import android.os.Handler;
+import android.os.Message;
import android.view.MotionEvent;
import android.view.ViewConfiguration;
import java.util.HashMap;
/**
- * This class detects multi-finger tap events. This is provided since the stock Android
- * gesture-detectors only detect taps made with one finger.
+ * This class detects multi-finger tap and long-press events. This is provided since the stock
+ * Android gesture-detectors only detect taps/long-presses made with one finger.
*/
public class TapGestureDetector {
/** The listener for receiving notifications of tap gestures. */
@@ -26,11 +27,21 @@ public class TapGestureDetector {
* @return True if the event is consumed.
*/
boolean onTap(int pointerCount);
+
+ /**
+ * Notified when a long-touch event occurs.
+ *
+ * @param pointerCount The number of fingers held down.
+ */
+ void onLongPress(int pointerCount);
}
/** The listener to which notifications are sent. */
private OnTapListener mListener;
+ /** Handler used for posting tasks to be executed in the future. */
+ private Handler mHandler;
+
/** The maximum number of fingers seen in the gesture. */
private int mPointerCount = 0;
@@ -46,11 +57,20 @@ public class TapGestureDetector {
*/
private int mTouchSlopSquare;
- /** Set to true whenever motion is detected in the gesture. */
- private boolean mMotionOccurred = false;
+ /** Set to true whenever motion is detected in the gesture, or a long-touch is triggered. */
+ private boolean mTapCancelled = false;
+
+ private class EventHandler extends Handler {
+ @Override
+ public void handleMessage(Message message) {
+ mListener.onLongPress(mPointerCount);
+ mTapCancelled = true;
+ }
+ }
public TapGestureDetector(Context context, OnTapListener listener) {
mListener = listener;
+ mHandler = new EventHandler();
ViewConfiguration config = ViewConfiguration.get(context);
int touchSlop = config.getScaledTouchSlop();
mTouchSlopSquare = touchSlop * touchSlop;
@@ -61,30 +81,41 @@ public class TapGestureDetector {
boolean handled = false;
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
+ reset();
+ // Cause a long-press notification to be triggered after the timeout.
+ mHandler.sendEmptyMessageDelayed(0, ViewConfiguration.getLongPressTimeout());
+ trackDownEvent(event);
+ mPointerCount = 1;
+ break;
+
case MotionEvent.ACTION_POINTER_DOWN:
trackDownEvent(event);
mPointerCount = Math.max(mPointerCount, event.getPointerCount());
break;
case MotionEvent.ACTION_MOVE:
- if (!mMotionOccurred) {
- mMotionOccurred = trackMoveEvent(event);
+ if (!mTapCancelled) {
+ if (trackMoveEvent(event)) {
+ cancelLongTouchNotification();
+ mTapCancelled = true;
+ }
}
break;
case MotionEvent.ACTION_UP:
- if (!mMotionOccurred) {
+ cancelLongTouchNotification();
+ if (!mTapCancelled) {
handled = mListener.onTap(mPointerCount);
}
- reset();
break;
case MotionEvent.ACTION_POINTER_UP:
+ cancelLongTouchNotification();
trackUpEvent(event);
break;
case MotionEvent.ACTION_CANCEL:
- reset();
+ cancelLongTouchNotification();
break;
default:
@@ -144,8 +175,14 @@ public class TapGestureDetector {
/** Cleans up any stored data for the gesture. */
private void reset() {
+ cancelLongTouchNotification();
mPointerCount = 0;
mInitialPositions.clear();
- mMotionOccurred = false;
+ mTapCancelled = false;
+ }
+
+ /** Cancels any pending long-touch notifications from the message-queue. */
+ private void cancelLongTouchNotification() {
+ mHandler.removeMessages(0);
}
}
diff --git a/remoting/android/java/src/org/chromium/chromoting/TrackingInputHandler.java b/remoting/android/java/src/org/chromium/chromoting/TrackingInputHandler.java
index 92c1dec..4bddec5 100644
--- a/remoting/android/java/src/org/chromium/chromoting/TrackingInputHandler.java
+++ b/remoting/android/java/src/org/chromium/chromoting/TrackingInputHandler.java
@@ -58,6 +58,9 @@ public class TrackingInputHandler implements TouchInputHandler {
*/
private float mSwipeThreshold;
+ /** Mouse-button currently held down, or BUTTON_UNDEFINED otherwise. */
+ private int mHeldButton = BUTTON_UNDEFINED;
+
public TrackingInputHandler(DesktopViewInterface viewer, Context context,
RenderData renderData) {
mViewer = viewer;
@@ -211,19 +214,36 @@ public class TrackingInputHandler implements TouchInputHandler {
return false;
}
+
+ /** Injects a button-up event if the button is currently held down (during a drag event). */
+ private void releaseAnyHeldButton() {
+ if (mHeldButton != BUTTON_UNDEFINED) {
+ injectButtonEvent(mHeldButton, false);
+ mHeldButton = BUTTON_UNDEFINED;
+ }
+ }
+
@Override
public boolean onTouchEvent(MotionEvent event) {
- // Avoid short-circuit logic evaluation - ensure both gesture detectors see all events so
+ // Avoid short-circuit logic evaluation - ensure all gesture detectors see all events so
// that they generate correct notifications.
boolean handled = mScroller.onTouchEvent(event);
handled |= mZoomer.onTouchEvent(event);
handled |= mTapDetector.onTouchEvent(event);
- if (event.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN) {
- mTotalMotionY = 0;
- mSwipeCompleted = false;
- }
+ switch (event.getActionMasked()) {
+ case MotionEvent.ACTION_POINTER_DOWN:
+ mTotalMotionY = 0;
+ mSwipeCompleted = false;
+ break;
+ case MotionEvent.ACTION_UP:
+ releaseAnyHeldButton();
+ break;
+
+ default:
+ break;
+ }
return handled;
}
@@ -314,27 +334,40 @@ public class TrackingInputHandler implements TouchInputHandler {
onScale(detector);
}
- /** Called when the user taps the screen with one or more fingers. */
- @Override
- public boolean onTap(int pointerCount) {
- int button;
+ /** Maps the number of fingers in a tap or long-press gesture to a mouse-button. */
+ private int mouseButtonFromPointerCount(int pointerCount) {
switch (pointerCount) {
case 1:
- button = BUTTON_LEFT;
- break;
+ return BUTTON_LEFT;
case 2:
- button = BUTTON_RIGHT;
- break;
+ return BUTTON_RIGHT;
case 3:
- button = BUTTON_MIDDLE;
- break;
+ return BUTTON_MIDDLE;
default:
- return false;
+ return BUTTON_UNDEFINED;
}
+ }
- injectButtonEvent(button, true);
- injectButtonEvent(button, false);
- return true;
+ /** Called when the user taps the screen with one or more fingers. */
+ @Override
+ public boolean onTap(int pointerCount) {
+ int button = mouseButtonFromPointerCount(pointerCount);
+ if (button == BUTTON_UNDEFINED) {
+ return false;
+ } else {
+ injectButtonEvent(button, true);
+ injectButtonEvent(button, false);
+ return true;
+ }
+ }
+
+ /** Called when a long-press is triggered for one or more fingers. */
+ @Override
+ public void onLongPress(int pointerCount) {
+ mHeldButton = mouseButtonFromPointerCount(pointerCount);
+ if (mHeldButton != BUTTON_UNDEFINED) {
+ injectButtonEvent(mHeldButton, true);
+ }
}
}
}