Merge "Add support for sending touch events in DRT."

This commit is contained in:
Ben Murdoch
2010-02-03 09:15:34 -08:00
committed by Android (Google) Code Review
6 changed files with 294 additions and 8 deletions

View File

@@ -342,6 +342,7 @@ public class WebView extends AbsoluteLayout
* 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 @@ public class WebView extends AbsoluteLayout
// 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);
@@ -6633,6 +6634,16 @@ public class WebView extends AbsoluteLayout
mWebViewCore.drawContentPicture(canvas, 0, false, false);
}
/**
* 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.

View File

@@ -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 android.webkit.WebStorage;
import java.util.HashMap;
public class CallbackProxy extends Handler implements EventSender, LayoutTestController {
private EventSender mEventSender;
private LayoutTestController mLayoutTestController;
@@ -37,6 +38,15 @@ public class CallbackProxy extends Handler implements EventSender, LayoutTestCon
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 @@ public class CallbackProxy extends Handler implements EventSender, LayoutTestCon
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 class CallbackProxy extends Handler implements EventSender, LayoutTestCon
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

View File

@@ -26,4 +26,14 @@ public interface EventSender {
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);
}

View File

@@ -96,6 +96,8 @@ public class FileFilter {
// 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",
};

View File

@@ -705,6 +705,7 @@ public class TestShellActivity extends Activity implements LayoutTestController
mDumpDatabaseCallbacks = false;
mCanOpenWindows = false;
mEventSender.resetMouse();
mEventSender.clearTouchPoints();
mPageFinished = false;
mOneHundredPercentComplete = false;
mDumpWebKitData = false;
@@ -769,6 +770,12 @@ public class TestShellActivity extends Activity implements LayoutTestController
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;

View File

@@ -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 @@ public class WebViewEventSender implements EventSender {
}
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;
}