Merge "Add support for sending touch events in DRT."
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index f2dab6e..16ecab7 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -342,6 +342,7 @@
* choice. Maybe make this in the buildspec later.
*/
private static final int TOUCH_SENT_INTERVAL = 50;
+ private int mCurrentTouchInterval = TOUCH_SENT_INTERVAL;
/**
* Helper class to get velocity for fling
@@ -4343,7 +4344,7 @@
// pass the touch events from UI thread to WebCore thread
if (mForwardTouchEvents && (action != MotionEvent.ACTION_MOVE
- || eventTime - mLastSentTouchTime > TOUCH_SENT_INTERVAL)) {
+ || eventTime - mLastSentTouchTime > mCurrentTouchInterval)) {
WebViewCore.TouchEventData ted = new WebViewCore.TouchEventData();
ted.mAction = action;
ted.mX = viewToContentX((int) x + mScrollX);
@@ -6634,6 +6635,16 @@
}
/**
+ * Set the time to wait between passing touches to WebCore. See also the
+ * TOUCH_SENT_INTERVAL member for further discussion.
+ *
+ * @hide This is only used by the DRT test application.
+ */
+ public void setTouchInterval(int interval) {
+ mCurrentTouchInterval = interval;
+ }
+
+ /**
* Update our cache with updatedText.
* @param updatedText The new text to put in our cache.
*/
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/CallbackProxy.java b/tests/DumpRenderTree/src/com/android/dumprendertree/CallbackProxy.java
index f33b01d..50451e7 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/CallbackProxy.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/CallbackProxy.java
@@ -16,6 +16,7 @@
package com.android.dumprendertree;
+import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.webkit.MockGeolocation;
@@ -24,7 +25,7 @@
import java.util.HashMap;
public class CallbackProxy extends Handler implements EventSender, LayoutTestController {
-
+
private EventSender mEventSender;
private LayoutTestController mLayoutTestController;
@@ -37,6 +38,15 @@
private static final int EVENT_MOUSE_DOWN = 7;
private static final int EVENT_MOUSE_MOVE = 8;
private static final int EVENT_MOUSE_UP = 9;
+ private static final int EVENT_TOUCH_START = 10;
+ private static final int EVENT_TOUCH_MOVE = 11;
+ private static final int EVENT_TOUCH_END = 12;
+ private static final int EVENT_TOUCH_CANCEL = 13;
+ private static final int EVENT_ADD_TOUCH_POINT = 14;
+ private static final int EVENT_UPDATE_TOUCH_POINT = 15;
+ private static final int EVENT_RELEASE_TOUCH_POINT = 16;
+ private static final int EVENT_CLEAR_TOUCH_POINTS = 17;
+ private static final int EVENT_CANCEL_TOUCH_POINT = 18;
private static final int LAYOUT_CLEAR_LIST = 20;
private static final int LAYOUT_DISPLAY = 21;
@@ -107,6 +117,46 @@
mEventSender.mouseUp();
break;
+ case EVENT_TOUCH_START:
+ mEventSender.touchStart();
+ break;
+
+ case EVENT_TOUCH_MOVE:
+ mEventSender.touchMove();
+ break;
+
+ case EVENT_TOUCH_END:
+ mEventSender.touchEnd();
+ break;
+
+ case EVENT_TOUCH_CANCEL:
+ mEventSender.touchCancel();
+ break;
+
+ case EVENT_ADD_TOUCH_POINT:
+ mEventSender.addTouchPoint(msg.arg1, msg.arg2);
+ break;
+
+ case EVENT_UPDATE_TOUCH_POINT:
+ Bundle args = (Bundle) msg.obj;
+ int x = args.getInt("x");
+ int y = args.getInt("y");
+ int id = args.getInt("id");
+ mEventSender.updateTouchPoint(id, x, y);
+ break;
+
+ case EVENT_RELEASE_TOUCH_POINT:
+ mEventSender.releaseTouchPoint(msg.arg1);
+ break;
+
+ case EVENT_CLEAR_TOUCH_POINTS:
+ mEventSender.clearTouchPoints();
+ break;
+
+ case EVENT_CANCEL_TOUCH_POINT:
+ mEventSender.cancelTouchPoint(msg.arg1);
+ break;
+
case LAYOUT_CLEAR_LIST:
mLayoutTestController.clearBackForwardList();
break;
@@ -252,6 +302,51 @@
public void mouseUp() {
obtainMessage(EVENT_MOUSE_UP).sendToTarget();
}
+
+ public void touchStart() {
+ obtainMessage(EVENT_TOUCH_START).sendToTarget();
+ }
+
+ public void addTouchPoint(int x, int y) {
+ obtainMessage(EVENT_ADD_TOUCH_POINT, x, y).sendToTarget();
+ }
+
+ public void updateTouchPoint(int id, int x, int y) {
+ Bundle map = new Bundle();
+ map.putInt("x", x);
+ map.putInt("y", y);
+ map.putInt("id", id);
+ obtainMessage(EVENT_UPDATE_TOUCH_POINT, map).sendToTarget();
+ }
+
+ public void setTouchModifier(String modifier, boolean enabled) {
+ // TODO(benm): Android doesn't support key modifiers on touch events yet.
+ }
+
+ public void touchMove() {
+ obtainMessage(EVENT_TOUCH_MOVE).sendToTarget();
+ }
+
+ public void releaseTouchPoint(int id) {
+ obtainMessage(EVENT_RELEASE_TOUCH_POINT, id, 0).sendToTarget();
+ }
+
+ public void touchEnd() {
+ obtainMessage(EVENT_TOUCH_END).sendToTarget();
+ }
+
+ public void touchCancel() {
+ obtainMessage(EVENT_TOUCH_CANCEL).sendToTarget();
+ }
+
+
+ public void clearTouchPoints() {
+ obtainMessage(EVENT_CLEAR_TOUCH_POINTS).sendToTarget();
+ }
+
+ public void cancelTouchPoint(int id) {
+ obtainMessage(EVENT_CANCEL_TOUCH_POINT, id, 0).sendToTarget();
+ }
// LayoutTestController Methods
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/EventSender.java b/tests/DumpRenderTree/src/com/android/dumprendertree/EventSender.java
index 82fd8d8..23cc8f5 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/EventSender.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/EventSender.java
@@ -26,4 +26,14 @@
public void keyDown (String character);
public void enableDOMUIEventLogging(int DOMNode);
public void fireKeyboardEventsToElement(int DOMNode);
+ public void touchStart();
+ public void touchMove();
+ public void touchEnd();
+ public void touchCancel();
+ public void addTouchPoint(int x, int y);
+ public void updateTouchPoint(int id, int x, int y);
+ public void setTouchModifier(String modifier, boolean enabled);
+ public void releaseTouchPoint(int id);
+ public void clearTouchPoints();
+ public void cancelTouchPoint(int id);
}
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/FileFilter.java b/tests/DumpRenderTree/src/com/android/dumprendertree/FileFilter.java
index 32219fa..452368e 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/FileFilter.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/FileFilter.java
@@ -96,6 +96,8 @@
// tests expect "LayoutTests" in their output.
"storage/domstorage/localstorage/iframe-events.html",
"storage/domstorage/sessionstorage/iframe-events.html",
+ // We do not support multi touch events.
+ "fast/events/touch/basic-multi-touch-events.html",
// below tests (failed or crashes) are filtered out temporarily due to prioritizing
"editing/selection/move-left-right.html",
};
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java b/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java
index 5763b85..e8a66c1 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java
@@ -705,6 +705,7 @@
mDumpDatabaseCallbacks = false;
mCanOpenWindows = false;
mEventSender.resetMouse();
+ mEventSender.clearTouchPoints();
mPageFinished = false;
mOneHundredPercentComplete = false;
mDumpWebKitData = false;
@@ -769,6 +770,12 @@
webview.setWebChromeClient(mChromeClient);
webview.setWebViewClient(mViewClient);
+ // Setting a touch interval of -1 effectively disables the optimisation in WebView
+ // that stops repeated touch events flooding WebCore. The Event Sender only sends a
+ // single event rather than a stream of events (like what would generally happen in
+ // a real use of touch events in a WebView) and so if the WebView drops the event,
+ // the test will fail as the test expects one callback for every touch it synthesizes.
+ webview.setTouchInterval(-1);
}
private WebView mWebView;
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/WebViewEventSender.java b/tests/DumpRenderTree/src/com/android/dumprendertree/WebViewEventSender.java
index eea6346..996eaba 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/WebViewEventSender.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/WebViewEventSender.java
@@ -16,17 +16,25 @@
package com.android.dumprendertree;
-import android.webkit.WebView;
-import android.view.KeyEvent;
+import android.os.Handler;
+import android.os.SystemClock;
import android.util.*;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.webkit.WebView;
+import java.lang.InterruptedException;
import java.util.Arrays;
+import java.util.Vector;
public class WebViewEventSender implements EventSender {
+
+ private static final String LOGTAG = "WebViewEventSender";
- WebViewEventSender(WebView webView) {
- mWebView = webView;
- }
+ WebViewEventSender(WebView webView) {
+ mWebView = webView;
+ mTouchPoints = new Vector();
+ }
public void resetMouse() {
mouseX = mouseY = 0;
@@ -186,9 +194,162 @@
}
return KeyEvent.KEYCODE_UNKNOWN;
}
-
+
+ public void touchStart() {
+ // We only support single touch so examine the first touch point only.
+ // If multi touch is enabled in the future, we need to re-examine this to send
+ // all the touch points with the event.
+ TouchPoint tp = mTouchPoints.get(0);
+
+ if (tp == null) {
+ return;
+ }
+
+ tp.setDownTime(SystemClock.uptimeMillis());
+ MotionEvent event = MotionEvent.obtain(tp.downTime(), tp.downTime(),
+ MotionEvent.ACTION_DOWN, tp.getX(), tp.getY(), 0);
+ mWebView.onTouchEvent(event);
+ }
+
+ public void touchMove() {
+ TouchPoint tp = mTouchPoints.get(0);
+
+ if (tp == null) {
+ return;
+ }
+
+ if (!tp.hasMoved()) {
+ return;
+ }
+
+ MotionEvent event = MotionEvent.obtain(tp.downTime(), SystemClock.uptimeMillis(),
+ MotionEvent.ACTION_MOVE, tp.getX(), tp.getY(), 0);
+ mWebView.onTouchEvent(event);
+
+ tp.setMoved(false);
+ }
+
+ public void touchEnd() {
+ TouchPoint tp = mTouchPoints.get(0);
+
+ if (tp == null) {
+ return;
+ }
+
+ MotionEvent event = MotionEvent.obtain(tp.downTime(), SystemClock.uptimeMillis(),
+ MotionEvent.ACTION_UP, tp.getX(), tp.getY(), 0);
+ mWebView.onTouchEvent(event);
+
+ if (tp.isReleased()) {
+ mTouchPoints.remove(0);
+ }
+ }
+
+ public void touchCancel() {
+ TouchPoint tp = mTouchPoints.get(0);
+ if (tp == null) {
+ return;
+ }
+
+ if (tp.cancelled()) {
+ MotionEvent event = MotionEvent.obtain(tp.downTime(), SystemClock.uptimeMillis(),
+ MotionEvent.ACTION_CANCEL, tp.getX(), tp.getY(), 0);
+ mWebView.onTouchEvent(event);
+ }
+ }
+
+ public void cancelTouchPoint(int id) {
+ TouchPoint tp = mTouchPoints.get(0);
+ if (tp == null) {
+ return;
+ }
+
+ tp.cancel();
+ }
+
+ public void addTouchPoint(int x, int y) {
+ mTouchPoints.add(new TouchPoint(contentsToWindowX(x), contentsToWindowY(y)));
+ if (mTouchPoints.size() > 1) {
+ Log.w(LOGTAG, "Adding more than one touch point, but multi touch is not supported!");
+ }
+ }
+
+ public void updateTouchPoint(int id, int x, int y) {
+ TouchPoint tp = mTouchPoints.get(0);
+ if (tp == null) {
+ return;
+ }
+
+ tp.update(contentsToWindowX(x), contentsToWindowY(y));
+ tp.setMoved(true);
+ }
+
+ public void setTouchModifier(String modifier, boolean enabled) {
+ // TODO(benm): This needs implementing when Android supports sending key modifiers
+ // in touch events.
+ }
+
+ public void releaseTouchPoint(int id) {
+ TouchPoint tp = mTouchPoints.get(0);
+ if (tp == null) {
+ return;
+ }
+
+ tp.release();
+ }
+
+ public void clearTouchPoints() {
+ mTouchPoints.clear();
+ }
+
+ private int contentsToWindowX(int x) {
+ return (int) (x * mWebView.getScale()) - mWebView.getScrollX();
+ }
+
+ private int contentsToWindowY(int y) {
+ return (int) (y * mWebView.getScale()) - mWebView.getScrollY();
+ }
+
private WebView mWebView = null;
private int mouseX;
private int mouseY;
+ private class TouchPoint {
+ private int mX;
+ private int mY;
+ private long mDownTime;
+ private boolean mReleased;
+ private boolean mMoved;
+ private boolean mCancelled;
+
+ public TouchPoint(int x, int y) {
+ mX = x;
+ mY = y;
+ mReleased = false;
+ mMoved = false;
+ mCancelled = false;
+ }
+
+ public void setDownTime(long downTime) { mDownTime = downTime; }
+ public long downTime() { return mDownTime; }
+ public void cancel() { mCancelled = true; }
+
+ public boolean cancelled() { return mCancelled; }
+
+ public void release() { mReleased = true; }
+ public boolean isReleased() { return mReleased; }
+
+ public void setMoved(boolean moved) { mMoved = moved; }
+ public boolean hasMoved() { return mMoved; }
+
+ public int getX() { return mX; }
+ public int getY() { return mY; }
+
+ public void update(int x, int y) {
+ mX = x;
+ mY = y;
+ }
+ };
+
+ private Vector<TouchPoint> mTouchPoints;
}