Chromium Code Reviews| Index: content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java |
| diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java |
| index dcc74ce9998f071c0df9060cc8af65b406aca1b9..fc1fd9224b441ad91139b4f0a8addea3be78ae1e 100644 |
| --- a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java |
| +++ b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java |
| @@ -7,6 +7,7 @@ package org.chromium.content.browser; |
| import android.content.Context; |
| import android.content.res.Configuration; |
| import android.graphics.Canvas; |
| +import android.os.Bundle; |
| import android.util.Log; |
| import android.view.KeyEvent; |
| import android.view.MotionEvent; |
| @@ -17,14 +18,19 @@ import android.webkit.DownloadListener; |
| import org.chromium.base.CalledByNative; |
| import org.chromium.base.JNINamespace; |
| import org.chromium.base.WeakContext; |
| +import org.chromium.content.browser.ContentViewGestureHandler; |
| +import org.chromium.content.browser.TouchPoint; |
| +import org.chromium.content.browser.ZoomManager; |
| import org.chromium.content.common.TraceEvent; |
| +import org.chromium.content.browser.ContentViewGestureHandler.MotionEventDelegate; |
| + |
| /** |
| * Contains all the major functionality necessary to manage the lifecycle of a ContentView without |
| * being tied to the view system. |
| */ |
| @JNINamespace("content") |
| -public class ContentViewCore { |
| +public class ContentViewCore implements MotionEventDelegate { |
| private static final String TAG = ContentViewCore.class.getName(); |
| // The following constants match the ones in chrome/common/page_transition_types.h. |
| @@ -52,6 +58,10 @@ public class ContentViewCore { |
| // if resulting zooming will produce little visible difference. |
| private static float WEBVIEW_ZOOM_CONTROLS_EPSILON = 0.007f; |
| + // To avoid checkerboard, we clamp the fling velocity based on the maximum number of tiles |
| + // should be allowed to upload per 100ms. |
| + private static int MAX_NUM_UPLOAD_TILES = 12; |
| + |
| /** |
| * Interface that consumers of {@link ContentViewCore} must implement to allow the proper |
| * dispatching of view methods through the containing view. |
| @@ -123,6 +133,7 @@ public class ContentViewCore { |
| // Native pointer to C++ ContentView object which will be set by nativeInit() |
| private int mNativeContentViewCore = 0; |
| + private ContentViewGestureHandler mContentViewGestureHandler; |
| private ZoomManager mZoomManager; |
| // Cached page scale factor from native |
| @@ -221,7 +232,6 @@ public class ContentViewCore { |
| mPersonality = personality; |
| mContentSettings = new ContentSettings(this, mNativeContentViewCore); |
| - mContainerView.setWillNotDraw(false); |
|
aelias_OOO_until_Jul13
2012/07/19 03:43:51
Is deleting this line intentional?
Yusuf
2012/07/19 05:01:52
Yes, before removing this it was not capturing Tou
|
| mContainerView.setFocusable(true); |
| mContainerView.setFocusableInTouchMode(true); |
| if (mContainerView.getScrollBarStyle() == View.SCROLLBARS_INSIDE_OVERLAY) { |
| @@ -229,7 +239,10 @@ public class ContentViewCore { |
| mContainerView.setVerticalScrollBarEnabled(false); |
| } |
| mContainerView.setClickable(true); |
| - initGestureDetectors(context); |
| + |
| + mZoomManager = new ZoomManager(context, this); |
| + mZoomManager.updateMultiTouchSupport(); |
| + mContentViewGestureHandler = new ContentViewGestureHandler(context, this, mZoomManager); |
| Log.i(TAG, "mNativeContentView=0x"+ Integer.toHexString(mNativeContentViewCore)); |
| } |
| @@ -457,44 +470,93 @@ public class ContentViewCore { |
| if (mNativeContentViewCore != 0) nativeClearHistory(mNativeContentViewCore); |
| } |
| + // End FrameLayout overrides. |
| + |
| + |
| /** |
| - * Start pinch zoom. You must call {@link #pinchEnd} to stop. |
| + * @see View#onTouchEvent(MotionEvent) |
| */ |
| - void pinchBegin(long timeMs, int x, int y) { |
| - if (mNativeContentViewCore != 0) { |
| - // TODO(tedchoc): Pass pinch begin to native. |
| - } |
| + public boolean onTouchEvent(MotionEvent event) { |
| + return mContentViewGestureHandler.onTouchEvent(event); |
| } |
| /** |
| - * Stop pinch zoom. |
| + * @return ContentViewGestureHandler for all MotionEvent and gesture related calls. |
| */ |
| - void pinchEnd(long timeMs) { |
| + ContentViewGestureHandler getContentViewGestureHandler() { |
| + return mContentViewGestureHandler; |
| + } |
| + |
| + @Override |
| + public boolean sendTouchEvent(long timeMs, int action, TouchPoint[] pts) { |
| if (mNativeContentViewCore != 0) { |
| - // TODO(tedchoc): Pass pinch end to native. |
| + return nativeTouchEvent(mNativeContentViewCore, timeMs, action, pts); |
| } |
| + return false; |
| + } |
| + |
| + @SuppressWarnings("unused") |
| + @CalledByNative |
| + private void didSetNeedTouchEvents(boolean needTouchEvents) { |
| + mContentViewGestureHandler.didSetNeedTouchEvents(needTouchEvents); |
| } |
| - void setIgnoreSingleTap(boolean value) { |
| - mIgnoreSingleTap = value; |
| + @SuppressWarnings("unused") |
| + @CalledByNative |
| + private void confirmTouchEvent(boolean handled) { |
| + mContentViewGestureHandler.confirmTouchEvent(handled); |
| } |
| - /** |
| - * Modify the ContentView magnification level. The effect of calling this |
| - * method is exactly as after "pinch zoom". |
| - * |
| - * @param timeMs The event time in milliseconds. |
| - * @param delta The ratio of the new magnification level over the current |
| - * magnification level. |
| - * @param anchorX The magnification anchor (X) in the current view |
| - * coordinate. |
| - * @param anchorY The magnification anchor (Y) in the current view |
| - * coordinate. |
| - */ |
| - void pinchBy(long timeMs, int anchorX, int anchorY, float delta) { |
| + @Override |
| + public boolean sendGesture(int type, long timeMs, int x, int y, Bundle b) { |
| if (mNativeContentViewCore != 0) { |
| - // TODO(tedchoc): Pass pinch by to native. |
| + switch (type) { |
| + case ContentViewGestureHandler.GESTURE_SHOW_PRESSED_STATE: |
| + nativeShowPressState(mNativeContentViewCore, timeMs, x, y); |
| + return true; |
| + case ContentViewGestureHandler.GESTURE_DOUBLE_TAP: |
| + nativeDoubleTap(mNativeContentViewCore, timeMs, x, y); |
| + return true; |
| + case ContentViewGestureHandler.GESTURE_SINGLE_TAP_UP: |
| + nativeSingleTap(mNativeContentViewCore, timeMs, x, y, false); |
| + return true; |
| + case ContentViewGestureHandler.GESTURE_SINGLE_TAP_CONFIRMED: |
| + handleTapOrPress(timeMs, x, y, false, |
| + b.getBoolean(ContentViewGestureHandler.SHOW_PRESS, false)); |
| + return true; |
| + case ContentViewGestureHandler.GESTURE_LONG_PRESS: |
| + handleTapOrPress(timeMs, x, y, true, false); |
| + return true; |
| + case ContentViewGestureHandler.GESTURE_SCROLL_START: |
| + nativeScrollBegin(mNativeContentViewCore, timeMs, x, y); |
| + return true; |
| + case ContentViewGestureHandler.GESTURE_SCROLL_BY: |
| + nativeScrollBy(mNativeContentViewCore, timeMs, x, y); |
| + return true; |
| + case ContentViewGestureHandler.GESTURE_SCROLL_END: |
| + nativeScrollEnd(mNativeContentViewCore, timeMs); |
| + return true; |
| + case ContentViewGestureHandler.GESTURE_FLING_START: |
| + nativeFlingStart(mNativeContentViewCore, timeMs, x, y, |
| + clampFlingVelocityX(b.getInt(ContentViewGestureHandler.VELOCITY_X, 0)), |
| + clampFlingVelocityY(b.getInt(ContentViewGestureHandler.VELOCITY_Y, 0))); |
| + return true; |
| + case ContentViewGestureHandler.GESTURE_FLING_CANCEL: |
| + nativeFlingCancel(mNativeContentViewCore, timeMs); |
| + return true; |
| + case ContentViewGestureHandler.GESTURE_PINCH_BEGIN: |
| + nativePinchBegin(mNativeContentViewCore, timeMs, x, y); |
| + return true; |
| + case ContentViewGestureHandler.GESTURE_PINCH_BY: |
| + nativePinchBy(mNativeContentViewCore, timeMs, x, y, |
| + b.getFloat(ContentViewGestureHandler.DELTA, 0)); |
| + return true; |
| + case ContentViewGestureHandler.GESTURE_PINCH_END: |
| + nativePinchEnd(mNativeContentViewCore, timeMs); |
| + return true; |
| + } |
| } |
| + return false; |
| } |
| /** |
| @@ -531,6 +593,13 @@ public class ContentViewCore { |
| return mContentSettings; |
| } |
| + @Override |
| + public boolean didUIStealScroll(float x, float y) { |
| + //TODO(yusufo):Stubbed out for now. Upstream when computeHorizontalScrollOffset is |
| + //available. |
| + return false; |
| + } |
| + |
| private void hidePopupDialog() { |
| SelectPopupDialog.hide(this); |
| } |
| @@ -552,14 +621,22 @@ public class ContentViewCore { |
| } |
| } |
| - private void initGestureDetectors(final Context context) { |
| - try { |
| - TraceEvent.begin(); |
| - // TODO(tedchoc): Upstream the rest of the initialization. |
| - mZoomManager = new ZoomManager(context, this); |
| - mZoomManager.updateMultiTouchSupport(); |
| - } finally { |
| - TraceEvent.end(); |
| + private void handleTapOrPress( |
| + long timeMs, int x, int y, boolean isLongPress, boolean showPress) { |
| + //TODO(yusufo):Upstream the rest of the bits about handlerControllers. |
| + if (!mContainerView.isFocused()) mContainerView.requestFocus(); |
| + |
| + if (isLongPress) { |
| + if (mNativeContentViewCore != 0) { |
| + nativeLongPress(mNativeContentViewCore, timeMs, x, y, false); |
| + } |
| + } else { |
| + if (!showPress && mNativeContentViewCore != 0) { |
| + nativeShowPressState(mNativeContentViewCore, timeMs, x, y); |
| + } |
| + if (mNativeContentViewCore != 0) { |
| + nativeSingleTap(mNativeContentViewCore, timeMs, x, y, false); |
| + } |
| } |
| } |
| @@ -577,6 +654,32 @@ public class ContentViewCore { |
| } |
| } |
| + /* |
| + * To avoid checkerboard, we clamp the fling velocity based on the maximum number of tiles |
| + * allowed to be uploaded per 100ms. Calculation is limited to one direction. We assume the |
| + * tile size is 256x256. The precise distance / velocity should be calculated based on the |
| + * logic in Scroller.java. As it is almost linear for the first 100ms, we use a simple math. |
| + */ |
| + private int clampFlingVelocityX(int velocity) { |
| + int cols = MAX_NUM_UPLOAD_TILES / (int) (Math.ceil((float) getHeight() / 256) + 1); |
| + int maxVelocity = cols > 0 ? cols * 2560 : 1000; |
| + if (Math.abs(velocity) > maxVelocity) { |
| + return velocity > 0 ? maxVelocity : -maxVelocity; |
| + } else { |
| + return velocity; |
| + } |
| + } |
| + |
| + private int clampFlingVelocityY(int velocity) { |
| + int rows = MAX_NUM_UPLOAD_TILES / (int) (Math.ceil((float) getWidth() / 256) + 1); |
| + int maxVelocity = rows > 0 ? rows * 2560 : 1000; |
| + if (Math.abs(velocity) > maxVelocity) { |
| + return velocity > 0 ? maxVelocity : -maxVelocity; |
| + } else { |
| + return velocity; |
| + } |
| + } |
| + |
| /** |
| * Register the listener to be used when content can not be handled by the |
| * rendering engine, and should be downloaded instead. This will replace the |
| @@ -696,9 +799,9 @@ public class ContentViewCore { |
| int y = getHeight() / 2; |
| float delta = 1.25f; |
| - pinchBegin(timeMs, x, y); |
| - pinchBy(timeMs, x, y, delta); |
| - pinchEnd(timeMs); |
| + getContentViewGestureHandler().pinchBegin(timeMs, x, y); |
| + getContentViewGestureHandler().pinchBy(timeMs, x, y, delta); |
| + getContentViewGestureHandler().pinchEnd(timeMs); |
| return true; |
| } |
| @@ -725,14 +828,17 @@ public class ContentViewCore { |
| int y = getHeight() / 2; |
| float delta = 0.8f; |
| - pinchBegin(timeMs, x, y); |
| - pinchBy(timeMs, x, y, delta); |
| - pinchEnd(timeMs); |
| + getContentViewGestureHandler().pinchBegin(timeMs, x, y); |
| + getContentViewGestureHandler().pinchBy(timeMs, x, y, delta); |
| + getContentViewGestureHandler().pinchEnd(timeMs); |
| return true; |
| } |
| - // Invokes the graphical zoom picker widget for this ContentView. |
| + /** |
| + * Invokes the graphical zoom picker widget for this ContentView. |
| + */ |
| + @Override |
| public void invokeZoomPicker() { |
| if (mContentSettings.supportZoom()) { |
| mZoomManager.invokeZoomPicker(); |
| @@ -782,6 +888,40 @@ public class ContentViewCore { |
| // Returns true if the native side crashed so that java side can draw a sad tab. |
| private native boolean nativeCrashed(int nativeContentViewCoreImpl); |
| + private native boolean nativeTouchEvent(int nativeContentViewCoreImpl, |
| + long timeMs, int action, |
| + TouchPoint[] pts); |
| + |
| + private native void nativeScrollBegin(int nativeContentViewCoreImpl, long timeMs, int x, int y); |
| + |
| + private native void nativeScrollEnd(int nativeContentViewCoreImpl, long timeMs); |
| + |
| + private native void nativeScrollBy( |
| + int nativeContentViewCoreImpl, long timeMs, int deltaX, int deltaY); |
| + |
| + private native void nativeFlingStart( |
| + int nativeContentViewCoreImpl, long timeMs, int x, int y, int vx, int vy); |
| + |
| + private native void nativeFlingCancel(int nativeContentViewCoreImpl, long timeMs); |
| + |
| + private native void nativeSingleTap( |
| + int nativeContentViewCoreImpl, long timeMs, int x, int y, boolean linkPreviewTap); |
| + |
| + private native void nativeShowPressState( |
| + int nativeContentViewCoreImpl, long timeMs, int x, int y); |
| + |
| + private native void nativeDoubleTap(int nativeContentViewCoreImpl, long timeMs, int x, int y); |
| + |
| + private native void nativeLongPress(int nativeContentViewCoreImpl, long timeMs, int x, int y, |
| + boolean linkPreviewTap); |
| + |
| + private native void nativePinchBegin(int nativeContentViewCoreImpl, long timeMs, int x, int y); |
| + |
| + private native void nativePinchEnd(int nativeContentViewCoreImpl, long timeMs); |
| + |
| + private native void nativePinchBy(int nativeContentViewCoreImpl, long timeMs, |
| + int anchorX, int anchorY, float deltaScale); |
| + |
| private native boolean nativeCanGoBack(int nativeContentViewCoreImpl); |
| private native boolean nativeCanGoForward(int nativeContentViewCoreImpl); |