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 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 |