diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index bca9b368e1e59..73fd8ed6eb260 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -457,6 +457,9 @@ public class WebView extends AbsoluteLayout // default is not set, the UI will continue handle them. private boolean mDeferTouchProcess; + // if true, multi-touch events will be passed to webkit directly before UI + private boolean mDeferMultitouch = false; + // to avoid interfering with the current touch events, track them // separately. Currently no snapping or fling in the deferred process mode private int mDeferTouchMode = TOUCH_DONE_MODE; @@ -4943,8 +4946,9 @@ public class WebView extends AbsoluteLayout } if (DebugFlags.WEB_VIEW) { - Log.v(LOGTAG, ev + " at " + ev.getEventTime() + " mTouchMode=" - + mTouchMode); + Log.v(LOGTAG, ev + " at " + ev.getEventTime() + + " mTouchMode=" + mTouchMode + + " numPointers=" + ev.getPointerCount()); } int action = ev.getAction(); @@ -4991,16 +4995,18 @@ public class WebView extends AbsoluteLayout } } - // FIXME: we may consider to give WebKit an option to handle multi-touch - // events later. + // If the page disallows zoom, pass multi-pointer events to webkit. + if (ev.getPointerCount() > 1 + && (mZoomManager.isZoomScaleFixed() || mDeferMultitouch)) { + if (DebugFlags.WEB_VIEW) { + Log.v(LOGTAG, "passing " + ev.getPointerCount() + " points to webkit"); + } + passMultiTouchToWebKit(ev); + return true; + } + if (mZoomManager.supportsMultiTouchZoom() && ev.getPointerCount() > 1 && mTouchMode != TOUCH_DRAG_LAYER_MODE && !skipScaleGesture) { - - // if the page disallows zoom, skip multi-pointer action - if (!mZoomManager.supportsPanDuringZoom() && mZoomManager.isZoomScaleFixed()) { - return true; - } - if (!detector.isInProgress() && ev.getActionMasked() != MotionEvent.ACTION_POINTER_DOWN) { // Insert a fake pointer down event in order to start @@ -5151,8 +5157,8 @@ public class WebView extends AbsoluteLayout if (shouldForwardTouchEvent()) { TouchEventData ted = new TouchEventData(); ted.mAction = action; - ted.mX = contentX; - ted.mY = contentY; + ted.mPoints = new Point[1]; + ted.mPoints[0] = new Point(contentX, contentY); ted.mMetaState = ev.getMetaState(); ted.mReprocess = mDeferTouchProcess; mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted); @@ -5193,8 +5199,8 @@ public class WebView extends AbsoluteLayout || eventTime - mLastSentTouchTime > mCurrentTouchInterval)) { TouchEventData ted = new TouchEventData(); ted.mAction = action; - ted.mX = contentX; - ted.mY = contentY; + ted.mPoints = new Point[1]; + ted.mPoints[0] = new Point(contentX, contentY); ted.mMetaState = ev.getMetaState(); ted.mReprocess = mDeferTouchProcess; mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted); @@ -5382,8 +5388,8 @@ public class WebView extends AbsoluteLayout if (shouldForwardTouchEvent()) { TouchEventData ted = new TouchEventData(); ted.mAction = action; - ted.mX = contentX; - ted.mY = contentY; + ted.mPoints = new Point[1]; + ted.mPoints[0] = new Point(contentX, contentY); ted.mMetaState = ev.getMetaState(); ted.mReprocess = mDeferTouchProcess; mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted); @@ -5396,8 +5402,8 @@ public class WebView extends AbsoluteLayout if (inFullScreenMode() || mDeferTouchProcess) { TouchEventData ted = new TouchEventData(); ted.mAction = WebViewCore.ACTION_DOUBLETAP; - ted.mX = contentX; - ted.mY = contentY; + ted.mPoints = new Point[1]; + ted.mPoints[0] = new Point(contentX, contentY); ted.mMetaState = ev.getMetaState(); ted.mReprocess = mDeferTouchProcess; mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted); @@ -5513,14 +5519,32 @@ public class WebView extends AbsoluteLayout return true; } + private void passMultiTouchToWebKit(MotionEvent ev) { + TouchEventData ted = new TouchEventData(); + ted.mAction = ev.getAction() & MotionEvent.ACTION_MASK; + final int count = ev.getPointerCount(); + ted.mPoints = new Point[count]; + for (int c = 0; c < count; c++) { + int x = viewToContentX((int) ev.getX(c) + mScrollX); + int y = viewToContentY((int) ev.getY(c) + mScrollY); + ted.mPoints[c] = new Point(x, y); + } + ted.mMetaState = ev.getMetaState(); + ted.mReprocess = mDeferTouchProcess; + mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted); + cancelLongPress(); + mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS); + mPreventDefault = PREVENT_DEFAULT_IGNORE; + } + private void cancelWebCoreTouchEvent(int x, int y, boolean removeEvents) { if (shouldForwardTouchEvent()) { if (removeEvents) { mWebViewCore.removeMessages(EventHub.TOUCH_EVENT); } TouchEventData ted = new TouchEventData(); - ted.mX = x; - ted.mY = y; + ted.mPoints = new Point[1]; + ted.mPoints[0] = new Point(x, y); ted.mAction = MotionEvent.ACTION_CANCEL; mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted); mPreventDefault = PREVENT_DEFAULT_IGNORE; @@ -6517,8 +6541,9 @@ public class WebView extends AbsoluteLayout if (inFullScreenMode() || mDeferTouchProcess) { TouchEventData ted = new TouchEventData(); ted.mAction = WebViewCore.ACTION_LONGPRESS; - ted.mX = viewToContentX((int) mLastTouchX + mScrollX); - ted.mY = viewToContentY((int) mLastTouchY + mScrollY); + ted.mPoints = new Point[1]; + ted.mPoints[0] = new Point(viewToContentX((int) mLastTouchX + mScrollX), + viewToContentY((int) mLastTouchY + mScrollY)); // metaState for long press is tricky. Should it be the // state when the press started or when the press was // released? Or some intermediary key state? For @@ -6746,16 +6771,16 @@ public class WebView extends AbsoluteLayout TouchEventData ted = (TouchEventData) msg.obj; switch (ted.mAction) { case MotionEvent.ACTION_DOWN: - mLastDeferTouchX = contentToViewX(ted.mX) + mLastDeferTouchX = contentToViewX(ted.mPoints[0].x) - mScrollX; - mLastDeferTouchY = contentToViewY(ted.mY) + mLastDeferTouchY = contentToViewY(ted.mPoints[0].y) - mScrollY; mDeferTouchMode = TOUCH_INIT_MODE; break; case MotionEvent.ACTION_MOVE: { // no snapping in defer process - int x = contentToViewX(ted.mX) - mScrollX; - int y = contentToViewY(ted.mY) - mScrollY; + int x = contentToViewX(ted.mPoints[0].x) - mScrollX; + int y = contentToViewY(ted.mPoints[0].y) - mScrollY; if (mDeferTouchMode != TOUCH_DRAG_MODE) { mDeferTouchMode = TOUCH_DRAG_MODE; mLastDeferTouchX = x; @@ -6784,8 +6809,8 @@ public class WebView extends AbsoluteLayout break; case WebViewCore.ACTION_DOUBLETAP: // doDoubleTap() needs mLastTouchX/Y as anchor - mLastTouchX = contentToViewX(ted.mX) - mScrollX; - mLastTouchY = contentToViewY(ted.mY) - mScrollY; + mLastTouchX = contentToViewX(ted.mPoints[0].x) - mScrollX; + mLastTouchY = contentToViewY(ted.mPoints[0].y) - mScrollY; mZoomManager.handleDoubleTap(mLastTouchX, mLastTouchY); mDeferTouchMode = TOUCH_DONE_MODE; break; @@ -7493,6 +7518,17 @@ public class WebView extends AbsoluteLayout mCurrentTouchInterval = interval; } + /** + * Toggle whether multi touch events should be sent to webkit + * no matter if UI wants to handle it first. + * + * @hide This is only used by the webkit layout test. + */ + public void setDeferMultiTouch(boolean value) { + mDeferMultitouch = value; + Log.v(LOGTAG, "set mDeferMultitouch to " + value); + } + /** * Update our cache with updatedText. * @param updatedText The new text to put in our cache. diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java index 122cf6a9bd690..a0c69744c6df4 100644 --- a/core/java/android/webkit/WebViewCore.java +++ b/core/java/android/webkit/WebViewCore.java @@ -506,8 +506,8 @@ final class WebViewCore { private native void nativeTouchUp(int touchGeneration, int framePtr, int nodePtr, int x, int y); - private native boolean nativeHandleTouchEvent(int action, int x, int y, - int metaState); + private native boolean nativeHandleTouchEvent(int action, int[] x, int[] y, + int count, int metaState); private native void nativeUpdateFrameCache(); @@ -711,8 +711,7 @@ final class WebViewCore { static class TouchEventData { int mAction; - int mX; - int mY; + Point[] mPoints; int mMetaState; boolean mReprocess; } @@ -1180,12 +1179,19 @@ final class WebViewCore { case TOUCH_EVENT: { TouchEventData ted = (TouchEventData) msg.obj; + final int count = ted.mPoints.length; + int[] xArray = new int[count]; + int[] yArray = new int[count]; + for (int c = 0; c < count; c++) { + xArray[c] = ted.mPoints[c].x; + yArray[c] = ted.mPoints[c].y; + } Message.obtain( mWebView.mPrivateHandler, WebView.PREVENT_TOUCH_ID, ted.mAction, - nativeHandleTouchEvent(ted.mAction, ted.mX, - ted.mY, ted.mMetaState) ? 1 : 0, + nativeHandleTouchEvent(ted.mAction, xArray, + yArray, count, ted.mMetaState) ? 1 : 0, ted.mReprocess ? ted : null).sendToTarget(); break; } diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java b/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java index 40af8c042ea01..19815fdb74ed3 100644 --- a/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java +++ b/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java @@ -145,6 +145,10 @@ public class TestShellActivity extends Activity implements LayoutTestController // WebView::setJsFlags is noop in JSC build. mWebView.setJsFlags("--expose_gc"); + // Always send multitouch events to Webkit since the layout test + // is only for the Webkit not the browser's UI. + mWebView.setDeferMultiTouch(true); + mHandler = new AsyncHandler(); Intent intent = getIntent(); diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/WebViewEventSender.java b/tests/DumpRenderTree/src/com/android/dumprendertree/WebViewEventSender.java index 716086b797de5..383d78295f4d5 100644 --- a/tests/DumpRenderTree/src/com/android/dumprendertree/WebViewEventSender.java +++ b/tests/DumpRenderTree/src/com/android/dumprendertree/WebViewEventSender.java @@ -31,6 +31,7 @@ public class WebViewEventSender implements EventSender { WebViewEventSender(WebView webView) { mWebView = webView; + mWebView.getSettings().setBuiltInZoomControls(true); mTouchPoints = new Vector(); } @@ -170,70 +171,128 @@ public class WebViewEventSender implements EventSender { } 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) { + final int numPoints = mTouchPoints.size(); + if (numPoints == 0) { return; } - tp.setDownTime(SystemClock.uptimeMillis()); - MotionEvent event = MotionEvent.obtain(tp.downTime(), tp.downTime(), - MotionEvent.ACTION_DOWN, tp.getX(), tp.getY(), mTouchMetaState); + int[] pointerIds = new int[numPoints]; + MotionEvent.PointerCoords[] pointerCoords = new MotionEvent.PointerCoords[numPoints]; + long downTime = SystemClock.uptimeMillis(); + + for (int i = 0; i < numPoints; ++i) { + pointerIds[i] = mTouchPoints.get(i).getId(); + pointerCoords[i] = new MotionEvent.PointerCoords(); + pointerCoords[i].x = mTouchPoints.get(i).getX(); + pointerCoords[i].y = mTouchPoints.get(i).getY(); + mTouchPoints.get(i).setDownTime(downTime); + } + + MotionEvent event = MotionEvent.obtain(downTime, downTime, + MotionEvent.ACTION_DOWN, numPoints, pointerIds, pointerCoords, + mTouchMetaState, 1.0f, 1.0f, 0, 0, 0, 0); + mWebView.onTouchEvent(event); } public void touchMove() { - TouchPoint tp = mTouchPoints.get(0); - - if (tp == null) { + final int numPoints = mTouchPoints.size(); + if (numPoints == 0) { return; } - if (!tp.hasMoved()) { + int[] pointerIds = new int[numPoints]; + MotionEvent.PointerCoords[] pointerCoords = new MotionEvent.PointerCoords[numPoints]; + int numMovedPoints = 0; + for (int i = 0; i < numPoints; ++i) { + TouchPoint tp = mTouchPoints.get(i); + if (tp.hasMoved()) { + pointerIds[numMovedPoints] = mTouchPoints.get(i).getId(); + pointerCoords[i] = new MotionEvent.PointerCoords(); + pointerCoords[numMovedPoints].x = mTouchPoints.get(i).getX(); + pointerCoords[numMovedPoints].y = mTouchPoints.get(i).getY(); + ++numMovedPoints; + tp.setMoved(false); + } + } + + if (numMovedPoints == 0) { return; } - MotionEvent event = MotionEvent.obtain(tp.downTime(), SystemClock.uptimeMillis(), - MotionEvent.ACTION_MOVE, tp.getX(), tp.getY(), mTouchMetaState); + MotionEvent event = MotionEvent.obtain(mTouchPoints.get(0).downTime(), + SystemClock.uptimeMillis(), MotionEvent.ACTION_MOVE, + numMovedPoints, pointerIds, pointerCoords, + mTouchMetaState, 1.0f, 1.0f, 0, 0, 0, 0); mWebView.onTouchEvent(event); - - tp.setMoved(false); } public void touchEnd() { - TouchPoint tp = mTouchPoints.get(0); - - if (tp == null) { + final int numPoints = mTouchPoints.size(); + if (numPoints == 0) { return; } - MotionEvent event = MotionEvent.obtain(tp.downTime(), SystemClock.uptimeMillis(), - MotionEvent.ACTION_UP, tp.getX(), tp.getY(), mTouchMetaState); + int[] pointerIds = new int[numPoints]; + MotionEvent.PointerCoords[] pointerCoords = new MotionEvent.PointerCoords[numPoints]; + + for (int i = 0; i < numPoints; ++i) { + pointerIds[i] = mTouchPoints.get(i).getId(); + pointerCoords[i] = new MotionEvent.PointerCoords(); + pointerCoords[i].x = mTouchPoints.get(i).getX(); + pointerCoords[i].y = mTouchPoints.get(i).getY(); + } + + MotionEvent event = MotionEvent.obtain(mTouchPoints.get(0).downTime(), + SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, + numPoints, pointerIds, pointerCoords, + mTouchMetaState, 1.0f, 1.0f, 0, 0, 0, 0); mWebView.onTouchEvent(event); - if (tp.isReleased()) { - mTouchPoints.remove(0); + for (int i = numPoints - 1; i >= 0; --i) { // remove released points. + TouchPoint tp = mTouchPoints.get(i); + if (tp.isReleased()) { + mTouchPoints.remove(i); + } } } public void touchCancel() { - TouchPoint tp = mTouchPoints.get(0); - if (tp == null) { + final int numPoints = mTouchPoints.size(); + if (numPoints == 0) { return; } - if (tp.cancelled()) { - MotionEvent event = MotionEvent.obtain(tp.downTime(), SystemClock.uptimeMillis(), - MotionEvent.ACTION_CANCEL, tp.getX(), tp.getY(), mTouchMetaState); - mWebView.onTouchEvent(event); + int[] pointerIds = new int[numPoints]; + MotionEvent.PointerCoords[] pointerCoords = new MotionEvent.PointerCoords[numPoints]; + long cancelTime = SystemClock.uptimeMillis(); + int numCanceledPoints = 0; + + for (int i = 0; i < numPoints; ++i) { + TouchPoint tp = mTouchPoints.get(i); + if (tp.cancelled()) { + pointerIds[numCanceledPoints] = mTouchPoints.get(i).getId(); + pointerCoords[numCanceledPoints] = new MotionEvent.PointerCoords(); + pointerCoords[numCanceledPoints].x = mTouchPoints.get(i).getX(); + pointerCoords[numCanceledPoints].y = mTouchPoints.get(i).getY(); + ++numCanceledPoints; + } } + + if (numCanceledPoints == 0) { + return; + } + + MotionEvent event = MotionEvent.obtain(mTouchPoints.get(0).downTime(), + SystemClock.uptimeMillis(), MotionEvent.ACTION_CANCEL, + numCanceledPoints, pointerIds, pointerCoords, + mTouchMetaState, 1.0f, 1.0f, 0, 0, 0, 0); + + mWebView.onTouchEvent(event); } public void cancelTouchPoint(int id) { - TouchPoint tp = mTouchPoints.get(0); + TouchPoint tp = mTouchPoints.get(id); if (tp == null) { return; } @@ -242,14 +301,19 @@ public class WebViewEventSender implements EventSender { } 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!"); + final int numPoints = mTouchPoints.size(); + int id; + if (numPoints == 0) { + id = 0; + } else { + id = mTouchPoints.get(numPoints - 1).getId() + 1; } + + mTouchPoints.add(new TouchPoint(id, contentsToWindowX(x), contentsToWindowY(y))); } - public void updateTouchPoint(int id, int x, int y) { - TouchPoint tp = mTouchPoints.get(0); + public void updateTouchPoint(int i, int x, int y) { + TouchPoint tp = mTouchPoints.get(i); if (tp == null) { return; } @@ -276,7 +340,7 @@ public class WebViewEventSender implements EventSender { } public void releaseTouchPoint(int id) { - TouchPoint tp = mTouchPoints.get(0); + TouchPoint tp = mTouchPoints.get(id); if (tp == null) { return; } @@ -305,6 +369,7 @@ public class WebViewEventSender implements EventSender { private int mouseY; private class TouchPoint { + private int mId; private int mX; private int mY; private long mDownTime; @@ -312,7 +377,8 @@ public class WebViewEventSender implements EventSender { private boolean mMoved; private boolean mCancelled; - public TouchPoint(int x, int y) { + public TouchPoint(int id, int x, int y) { + mId = id; mX = x; mY = y; mReleased = false; @@ -332,6 +398,7 @@ public class WebViewEventSender implements EventSender { public void setMoved(boolean moved) { mMoved = moved; } public boolean hasMoved() { return mMoved; } + public int getId() { return mId; } public int getX() { return mX; } public int getY() { return mY; } diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/EventSenderImpl.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/EventSenderImpl.java index 93e61378b0719..8ac04360c3589 100644 --- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/EventSenderImpl.java +++ b/tests/DumpRenderTree2/src/com/android/dumprendertree2/EventSenderImpl.java @@ -58,6 +58,7 @@ public class EventSenderImpl { public static class TouchPoint { WebView mWebView; + private int mId; private int mX; private int mY; private long mDownTime; @@ -65,12 +66,17 @@ public class EventSenderImpl { private boolean mMoved = false; private boolean mCancelled = false; - public TouchPoint(WebView webView, int x, int y) { + public TouchPoint(WebView webView, int id, int x, int y) { mWebView = webView; + mId = id; mX = scaleX(x); mY = scaleY(y); } + public int getId() { + return mId; + } + public int getX() { return mX; } @@ -215,38 +221,38 @@ public class EventSenderImpl { /** TOUCH */ case MSG_ADD_TOUCH_POINT: - getTouchPoints().add(new TouchPoint(mWebView, - msg.arg1, msg.arg2)); - if (getTouchPoints().size() > 1) { - Log.w(LOG_TAG + "::MSG_ADD_TOUCH_POINT", "Added more than one touch point"); + int numPoints = getTouchPoints().size(); + int id; + if (numPoints == 0) { + id = 0; + } else { + id = getTouchPoints().get(numPoints - 1).getId() + 1; } + getTouchPoints().add(new TouchPoint(mWebView, id, + msg.arg1, msg.arg2)); break; case MSG_TOUCH_START: - /** - * FIXME: At the moment we don't support multi-touch. Hence, we only examine - * the first touch point. In future this method will need rewriting. - */ if (getTouchPoints().isEmpty()) { return; } - touchPoint = getTouchPoints().get(0); - - touchPoint.setDownTime(SystemClock.uptimeMillis()); - executeTouchEvent(touchPoint, MotionEvent.ACTION_DOWN); + for (int i = 0; i < getTouchPoints().size(); ++i) { + getTouchPoints().get(i).setDownTime(SystemClock.uptimeMillis()); + } + executeTouchEvent(MotionEvent.ACTION_DOWN); break; case MSG_UPDATE_TOUCH_POINT: bundle = (Bundle)msg.obj; - int id = bundle.getInt("id"); - if (id >= getTouchPoints().size()) { + int index = bundle.getInt("id"); + if (index >= getTouchPoints().size()) { Log.w(LOG_TAG + "::MSG_UPDATE_TOUCH_POINT", "TouchPoint out of bounds: " - + id); + + index); break; } - getTouchPoints().get(id).move(bundle.getInt("x"), bundle.getInt("y")); + getTouchPoints().get(index).move(bundle.getInt("x"), bundle.getInt("y")); break; case MSG_TOUCH_MOVE: @@ -257,13 +263,10 @@ public class EventSenderImpl { if (getTouchPoints().isEmpty()) { return; } - touchPoint = getTouchPoints().get(0); - - if (!touchPoint.hasMoved()) { - return; + executeTouchEvent(MotionEvent.ACTION_MOVE); + for (int i = 0; i < getTouchPoints().size(); ++i) { + getTouchPoints().get(i).resetHasMoved(); } - executeTouchEvent(touchPoint, MotionEvent.ACTION_MOVE); - touchPoint.resetHasMoved(); break; case MSG_CANCEL_TOUCH_POINT: @@ -284,11 +287,7 @@ public class EventSenderImpl { if (getTouchPoints().isEmpty()) { return; } - touchPoint = getTouchPoints().get(0); - - if (touchPoint.isCancelled()) { - executeTouchEvent(touchPoint, MotionEvent.ACTION_CANCEL); - } + executeTouchEvent(MotionEvent.ACTION_CANCEL); break; case MSG_RELEASE_TOUCH_POINT: @@ -309,12 +308,12 @@ public class EventSenderImpl { if (getTouchPoints().isEmpty()) { return; } - touchPoint = getTouchPoints().get(0); - - executeTouchEvent(touchPoint, MotionEvent.ACTION_UP); - if (touchPoint.isReleased()) { - getTouchPoints().remove(0); - touchPoint = null; + executeTouchEvent(MotionEvent.ACTION_UP); + // remove released points. + for (int i = getTouchPoints().size() - 1; i >= 0; --i) { + if (getTouchPoints().get(i).isReleased()) { + getTouchPoints().remove(i); + } } break; @@ -462,10 +461,48 @@ public class EventSenderImpl { return mTouchPoints; } - private void executeTouchEvent(TouchPoint touchPoint, int action) { - MotionEvent event = - MotionEvent.obtain(touchPoint.getDownTime(), SystemClock.uptimeMillis(), - action, touchPoint.getX(), touchPoint.getY(), mTouchMetaState); + private void executeTouchEvent(int action) { + int numPoints = getTouchPoints().size(); + int[] pointerIds = new int[numPoints]; + MotionEvent.PointerCoords[] pointerCoords = new MotionEvent.PointerCoords[numPoints]; + + for (int i = 0; i < numPoints; ++i) { + boolean isNeeded = false; + switch(action) { + case MotionEvent.ACTION_DOWN: + case MotionEvent.ACTION_UP: + isNeeded = true; + break; + case MotionEvent.ACTION_MOVE: + isNeeded = getTouchPoints().get(i).hasMoved(); + break; + case MotionEvent.ACTION_CANCEL: + isNeeded = getTouchPoints().get(i).isCancelled(); + break; + default: + Log.w(LOG_TAG + "::executeTouchEvent(),", "action not supported:" + action); + break; + } + + numPoints = 0; + if (isNeeded) { + pointerIds[numPoints] = getTouchPoints().get(i).getId(); + pointerCoords[numPoints] = new MotionEvent.PointerCoords(); + pointerCoords[numPoints].x = getTouchPoints().get(i).getX(); + pointerCoords[numPoints].y = getTouchPoints().get(i).getY(); + ++numPoints; + } + } + + if (numPoints == 0) { + return; + } + + MotionEvent event = MotionEvent.obtain(mTouchPoints.get(0).getDownTime(), + SystemClock.uptimeMillis(), action, + numPoints, pointerIds, pointerCoords, + mTouchMetaState, 1.0f, 1.0f, 0, 0, 0, 0); + mWebView.onTouchEvent(event); } diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestsExecutor.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestsExecutor.java index 30d255ace8918..089af0d8a5782 100644 --- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestsExecutor.java +++ b/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestsExecutor.java @@ -377,6 +377,7 @@ public class LayoutTestsExecutor extends Activity { webView.setTouchInterval(-1); webView.clearCache(true); + webView.setDeferMultiTouch(true); WebSettings webViewSettings = webView.getSettings(); webViewSettings.setAppCacheEnabled(true);