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 41b9a73c6464f5b55bf04479835fb859b68023d9..9aba0668f7f016a0aae65884983d432691567384 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 |
@@ -8,6 +8,7 @@ import android.content.Context; |
import android.content.res.Configuration; |
import android.graphics.Bitmap; |
import android.graphics.Canvas; |
+import android.graphics.PointF; |
import android.os.Build; |
import android.os.Bundle; |
import android.os.ResultReceiver; |
@@ -155,6 +156,18 @@ public class ContentViewCore implements MotionEventDelegate { |
private ContentViewGestureHandler mContentViewGestureHandler; |
private ZoomManager mZoomManager; |
+ // Currently ContentView's scrolling is handled by the native side. We keep a cached copy of the |
+ // scroll offset and content size so that we can display the scrollbar correctly. In the future, |
+ // we may switch to tile rendering and handle the scrolling in the Java level. |
+ |
+ // Cached scroll offset from the native |
+ private int mNativeScrollX; |
+ private int mNativeScrollY; |
+ |
+ // Cached content size from the native |
+ private int mContentWidth; |
+ private int mContentHeight; |
+ |
// Cached page scale factor from native |
private float mNativePageScaleFactor = 1.0f; |
private float mNativeMinimumScale = 1.0f; |
@@ -173,6 +186,9 @@ public class ContentViewCore implements MotionEventDelegate { |
private SelectionHandleController mSelectionHandleController; |
private InsertionHandleController mInsertionHandleController; |
+ // These offsets in document space with page scale normalized to 1.0. |
+ private final PointF mStartHandleNormalizedPoint = new PointF(); |
+ private final PointF mEndHandleNormalizedPoint = new PointF(); |
// Tracks whether a selection is currently active. When applied to selected text, indicates |
// whether the last selected text is still highlighted. |
@@ -374,6 +390,7 @@ public class ContentViewCore implements MotionEventDelegate { |
mZoomManager.updateMultiTouchSupport(); |
mContentViewGestureHandler = new ContentViewGestureHandler(mContext, this, mZoomManager); |
+ mNativeScrollX = mNativeScrollY = 0; |
initPopupZoomer(mContext); |
mImeAdapter = createImeAdapter(mContext); |
mKeyboardConnected = mContainerView.getResources().getConfiguration().keyboard |
@@ -547,6 +564,20 @@ public class ContentViewCore implements MotionEventDelegate { |
} |
/** |
+ * @see {@link android.webkit.WebView#getContentHeight()} |
Ted C
2012/09/18 00:21:40
the format should be:
@see android.webkit.WebView
Ramya
2012/09/21 00:06:29
Done.
|
+ */ |
+ public int getContentHeight() { |
+ return (int) (mContentHeight / mNativePageScaleFactor); |
+ } |
+ |
+ /** |
+ * @see {@link android.webkit.WebView#getContentWidth()} |
+ */ |
+ public int getContentWidth() { |
Ted C
2012/09/18 00:21:40
also, these are only used by WebView, so we don't
|
+ return (int) (mContentWidth / mNativePageScaleFactor); |
+ } |
+ |
+ /** |
* @return Whether the current WebContents has a previous navigation entry. |
*/ |
public boolean canGoBack() { |
@@ -835,6 +866,85 @@ public class ContentViewCore implements MotionEventDelegate { |
TraceEvent.end(); |
} |
+ /** |
+ * @see View#onSizeChanged(int, int, int, int) |
+ */ |
+ @SuppressWarnings("javadoc") |
+ public void onSizeChanged(int w, int h, int ow, int oh) { |
+ mPopupZoomer.hide(false); |
+ // Update the content size to make sure it is at least the View size |
+ if (mContentWidth < w) mContentWidth = w; |
+ if (mContentHeight < h) mContentHeight = h; |
+ } |
+ |
+ /** |
+ * @see View#dispatchKeyEvent(KeyEvent) |
+ */ |
+ public boolean dispatchKeyEvent(KeyEvent event) { |
Ted C
2012/09/18 00:21:40
might want to loop in Oli to make sure he's not ch
Ramya
2012/09/21 00:06:29
Done.
|
+ if (mImeAdapter != null && |
+ !mImeAdapter.isNativeImeAdapterAttached() && mNativeContentViewCore != 0) { |
+ mImeAdapter.attach(nativeGetNativeImeAdapter(mNativeContentViewCore)); |
+ } |
+ // The key handling logic is kind of confusing here. |
+ // The purpose of shouldOverrideKeyEvent() is to filter out some keys that is critical |
+ // to browser function but useless in renderer process (for example, the back button), |
+ // so the browser can still respond to these keys in a timely manner when the renderer |
+ // process is busy/blocked/busted. mImeAdapter.dispatchKeyEvent() forwards the key event |
+ // to the renderer process. If mImeAdapter is bypassed or is not interested to the event, |
+ // fall back to the default dispatcher to propagate the event to sub-views. |
+ return (!getContentViewClient().shouldOverrideKeyEvent(event) |
+ && mImeAdapter .dispatchKeyEvent(event)) |
Ted C
2012/09/20 18:20:33
remove space before .
Ramya
2012/09/21 00:06:29
Done.
|
+ || mContainerViewInternals.super_dispatchKeyEvent(event); |
+ } |
+ |
+ /** |
+ * @see View#scrollTo(int, int) |
+ */ |
+ public void scrollTo(int x, int y) { |
+ if (mNativeContentViewCore != 0) { |
Ted C
2012/09/18 00:21:40
I would do:
if (mNativeContentViewCore == 0) retur
Ramya
2012/09/21 00:06:29
Done.
|
+ int dx = x - mNativeScrollX, dy = y - mNativeScrollY; |
+ if (dx != 0 || dy != 0) { |
+ long time = System.currentTimeMillis(); |
+ nativeScrollBegin(mNativeContentViewCore, time, mNativeScrollX, mNativeScrollY); |
+ nativeScrollBy(mNativeContentViewCore, time, mNativeScrollX, mNativeScrollY, |
+ dx, dy); |
+ nativeScrollEnd(mNativeContentViewCore, time); |
+ } |
+ } |
+ } |
+ |
+ /** |
+ * @see View#computeHorizontalScrollOffset() |
+ */ |
+ @SuppressWarnings("javadoc") |
+ public int computeHorizontalScrollOffset() { |
+ return mNativeScrollX; |
+ } |
+ |
+ /** |
+ * @see View#computeHorizontalScrollRange() |
+ */ |
+ @SuppressWarnings("javadoc") |
+ public int computeHorizontalScrollRange() { |
+ return mContentWidth; |
+ } |
+ |
+ /** |
+ * @see View#computeVerticalScrollOffset() |
+ */ |
+ @SuppressWarnings("javadoc") |
+ public int computeVerticalScrollOffset() { |
+ return mNativeScrollY; |
+ } |
+ |
+ /** |
+ * @see View#computeVerticalScrollRange() |
+ */ |
+ @SuppressWarnings("javadoc") |
+ public int computeVerticalScrollRange() { |
+ return mContentHeight; |
+ } |
+ |
// End FrameLayout overrides. |
/** |
@@ -950,8 +1060,29 @@ public class ContentViewCore implements MotionEventDelegate { |
private SelectionHandleController getSelectionHandleController() { |
if (mSelectionHandleController == null) { |
- mSelectionHandleController = new SelectionHandleController(getContainerView()); |
- // TODO(olilan): add specific method implementations. |
+ mSelectionHandleController = new SelectionHandleController(getContainerView()) { |
Ted C
2012/09/18 00:21:40
is this needed by pageUp/pageDown? If not, might
Ramya
2012/09/21 00:06:29
Done.
|
+ // TODO(olilan): add specific method implementations. |
+ @Override |
+ public void selectBetweenCoordinates(int x1, int y1, int x2, int y2) { |
+ if (mNativeContentViewCore != 0 && !(x1 == x2 && y1 == y2)) { |
+ nativeSelectBetweenCoordinates(mNativeContentViewCore, x1, y1, x2, y2); |
+ } |
+ } |
+ |
+ @Override |
+ public void showHandlesAt(int x1, int y1, int dir1, int x2, int y2, int dir2) { |
+ super.showHandlesAt(x1, y1, dir1, x2, y2, dir2); |
+ mStartHandleNormalizedPoint.set( |
+ (x1 + mNativeScrollX) / mNativePageScaleFactor, |
Ted C
2012/09/18 00:21:40
+4 indent here (and below)
Ramya
2012/09/21 00:06:29
Done.
|
+ (y1 + mNativeScrollY) / mNativePageScaleFactor); |
+ mEndHandleNormalizedPoint.set( |
+ (x2 + mNativeScrollX) / mNativePageScaleFactor, |
+ (y2 + mNativeScrollY) / mNativePageScaleFactor); |
+ |
+ showSelectActionBar(); |
+ } |
+ |
+ }; |
mSelectionHandleController.hideAndDisallowAutomaticShowing(); |
} |
@@ -1035,6 +1166,36 @@ public class ContentViewCore implements MotionEventDelegate { |
return nativeCrashed(mNativeContentViewCore); |
} |
+ @SuppressWarnings("unused") |
+ @CalledByNative |
+ private void updateContentSize(int width, int height) { |
+ if (mContentWidth != width || mContentHeight != height) { |
+ mPopupZoomer.hide(true); |
+ } |
+ // Make sure the content size is at least the View size |
+ mContentWidth = Math.max(width, getWidth()); |
+ mContentHeight = Math.max(height, getHeight()); |
+ } |
+ |
+ @SuppressWarnings("unused") |
+ @CalledByNative |
+ private void updateScrollOffsetAndPageScaleFactor(int x, int y, float scale) { |
+ if (mNativeScrollX == x && mNativeScrollY == y && mNativePageScaleFactor == scale) return; |
+ |
+ mContainerViewInternals.onScrollChanged(x, y, mNativeScrollX, mNativeScrollY); |
+ |
+ // This function should be called back from native as soon |
+ // as the scroll is applied to the backbuffer. We should only |
+ // update mNativeScrollX/Y here for consistency. |
+ mNativeScrollX = x; |
+ mNativeScrollY = y; |
+ mNativePageScaleFactor = scale; |
+ |
+ mPopupZoomer.hide(true); |
+ |
+ mZoomManager.updateZoomControls(); |
+ } |
+ |
// The following methods are called by native through jni |
@SuppressWarnings("unused") |
@@ -1305,6 +1466,42 @@ public class ContentViewCore implements MotionEventDelegate { |
} |
/** |
+ * @See {@link android.webkit.WebView#pageDown(boolean) |
+ */ |
+ public boolean pageDown(boolean bottom) { |
+ if (mNativeScrollY >= mContentHeight - getHeight()) { |
+ // We seem to already be at the bottom of the page, so no scrolling will occur. |
+ return false; |
+ } |
+ |
+ if (bottom) { |
+ scrollTo(mNativeScrollX, mContentHeight - getHeight()); |
+ } else { |
+ dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_PAGE_DOWN)); |
+ dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_PAGE_DOWN)); |
+ } |
+ return true; |
+ } |
+ |
+ /** |
+ * @See {@link android.webkit.WebView#pageUp(boolean) |
Ted C
2012/09/18 00:21:40
these are both only used in WebView, so we probabl
Ramya
2012/09/21 00:06:29
Keeping it here as per the bug.
|
+ */ |
+ public boolean pageUp(boolean top) { |
+ if (mNativeScrollY == 0) { |
Ted C
2012/09/18 00:21:40
to get rid of referencing this directly, you can u
Ramya
2012/09/21 00:06:29
Done.
|
+ // We seem to already be at the top of the page, so no scrolling will occur. |
+ return false; |
+ } |
+ |
+ if (top) { |
+ scrollTo(mNativeScrollX, 0); |
Ted C
2012/09/18 00:21:40
s/mNativeScrollX/computeHorizontalScrollOffset()
Ramya
2012/09/21 00:06:29
Done.
|
+ } else { |
+ dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_PAGE_UP)); |
+ dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_PAGE_UP)); |
+ } |
+ return true; |
+ } |
+ |
+ /** |
* Callback factory method for nativeGetNavigationHistory(). |
*/ |
@CalledByNative |