diff options
Diffstat (limited to 'core/java/android/webkit/WebView.java')
-rw-r--r-- | core/java/android/webkit/WebView.java | 159 |
1 files changed, 104 insertions, 55 deletions
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index 5d776fd..4748522 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -43,6 +43,7 @@ import android.graphics.Point; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.Region; +import android.graphics.RegionIterator; import android.graphics.Shader; import android.graphics.drawable.Drawable; import android.net.Proxy; @@ -605,8 +606,9 @@ public class WebView extends AbsoluteLayout // know to handle Shift and arrows natively first private boolean mAccessibilityScriptInjected; + static final boolean USE_WEBKIT_RINGS = true; // the color used to highlight the touch rectangles - private static final int mHightlightColor = 0x33000000; + private static final int mHightlightColor = 0x6633b5e5; // the round corner for the highlight path private static final float TOUCH_HIGHLIGHT_ARC = 5.0f; // the region indicating where the user touched on the screen @@ -619,6 +621,7 @@ public class WebView extends AbsoluteLayout private Paint mTouchCrossHairColor; private int mTouchHighlightX; private int mTouchHighlightY; + private long mTouchHighlightRequested; // Basically this proxy is used to tell the Video to update layer tree at // SetBaseLayer time and to pause when WebView paused. @@ -3451,6 +3454,7 @@ public class WebView extends AbsoluteLayout } abortAnimation(); mPrivateHandler.removeMessages(RESUME_WEBCORE_PRIORITY); + nativeSetIsScrolling(false); if (!mBlockWebkitViewMessages) { WebViewCore.resumePriority(); if (!mSelectingText) { @@ -3991,7 +3995,7 @@ public class WebView extends AbsoluteLayout return super.drawChild(canvas, child, drawingTime); } - private void drawContent(Canvas canvas) { + private void drawContent(Canvas canvas, boolean drawRings) { // Update the buttons in the picture, so when we draw the picture // to the screen, they are in the correct state. // Tell the native side if user is a) touching the screen, @@ -4000,10 +4004,14 @@ public class WebView extends AbsoluteLayout // state. // If mNativeClass is 0, we should not reach here, so we do not // need to check it again. - nativeRecordButtons(hasFocus() && hasWindowFocus(), - mTouchMode == TOUCH_SHORTPRESS_START_MODE - || mTrackballDown || mGotCenterDown, false); - drawCoreAndCursorRing(canvas, mBackgroundColor, mDrawCursorRing); + if (mDrawCursorRing && drawRings) { + // Only update if we are actually going to use the result + nativeRecordButtons(hasFocus() && hasWindowFocus(), + mTouchMode == TOUCH_SHORTPRESS_START_MODE + || mTrackballDown || mGotCenterDown, false); + } + drawCoreAndCursorRing(canvas, mBackgroundColor, + mDrawCursorRing && drawRings); } /** @@ -4067,7 +4075,16 @@ public class WebView extends AbsoluteLayout if (mTitleBar != null) { canvas.translate(0, getTitleHeight()); } - drawContent(canvas); + boolean drawJavaRings = !mTouchHighlightRegion.isEmpty() + && (mTouchMode == TOUCH_INIT_MODE + || mTouchMode == TOUCH_SHORTPRESS_START_MODE + || mTouchMode == TOUCH_SHORTPRESS_MODE + || mTouchMode == TOUCH_DONE_MODE); + boolean drawNativeRings = !drawJavaRings; + if (USE_WEBKIT_RINGS) { + drawNativeRings = !drawJavaRings && !isInTouchMode(); + } + drawContent(canvas, drawNativeRings); canvas.restoreToCount(saveCount); if (AUTO_REDRAW_HACK && mAutoRedraw) { @@ -4080,16 +4097,22 @@ public class WebView extends AbsoluteLayout } // paint the highlight in the end - if (!mTouchHighlightRegion.isEmpty()) { - if (mTouchHightlightPaint == null) { - mTouchHightlightPaint = new Paint(); - mTouchHightlightPaint.setColor(mHightlightColor); - mTouchHightlightPaint.setAntiAlias(true); - mTouchHightlightPaint.setPathEffect(new CornerPathEffect( - TOUCH_HIGHLIGHT_ARC)); + if (drawJavaRings) { + long delay = System.currentTimeMillis() - mTouchHighlightRequested; + if (delay < ViewConfiguration.getTapTimeout()) { + Rect r = mTouchHighlightRegion.getBounds(); + postInvalidateDelayed(delay, r.left, r.top, r.right, r.bottom); + } else { + if (mTouchHightlightPaint == null) { + mTouchHightlightPaint = new Paint(); + mTouchHightlightPaint.setColor(mHightlightColor); + } + RegionIterator iter = new RegionIterator(mTouchHighlightRegion); + Rect r = new Rect(); + while (iter.next(r)) { + canvas.drawRect(r, mTouchHightlightPaint); + } } - canvas.drawPath(mTouchHighlightRegion.getBoundaryPath(), - mTouchHightlightPaint); } if (DEBUG_TOUCH_HIGHLIGHT) { if (getSettings().getNavDump()) { @@ -4112,11 +4135,10 @@ public class WebView extends AbsoluteLayout } } - private void removeTouchHighlight(boolean removePendingMessage) { - if (removePendingMessage) { - mWebViewCore.removeMessages(EventHub.GET_TOUCH_HIGHLIGHT_RECTS); - } - mWebViewCore.sendMessage(EventHub.REMOVE_TOUCH_HIGHLIGHT_RECTS); + private void removeTouchHighlight() { + mWebViewCore.removeMessages(EventHub.GET_TOUCH_HIGHLIGHT_RECTS); + mPrivateHandler.removeMessages(SET_TOUCH_HIGHLIGHT_RECTS); + setTouchHighlightRects(null); } @Override @@ -5785,8 +5807,8 @@ public class WebView extends AbsoluteLayout mPrivateHandler.removeMessages(RESUME_WEBCORE_PRIORITY); } else if (mPrivateHandler.hasMessages(RELEASE_SINGLE_TAP)) { mPrivateHandler.removeMessages(RELEASE_SINGLE_TAP); - if (getSettings().supportTouchOnly()) { - removeTouchHighlight(true); + if (USE_WEBKIT_RINGS || getSettings().supportTouchOnly()) { + removeTouchHighlight(); } if (deltaX * deltaX + deltaY * deltaY < mDoubleTapSlopSquare) { mTouchMode = TOUCH_DOUBLE_TAP_MODE; @@ -5809,15 +5831,19 @@ public class WebView extends AbsoluteLayout mWebViewCore.sendMessage( EventHub.UPDATE_FRAME_CACHE_IF_LOADING); } - if (getSettings().supportTouchOnly()) { + if (USE_WEBKIT_RINGS || getSettings().supportTouchOnly()) { TouchHighlightData data = new TouchHighlightData(); data.mX = contentX; data.mY = contentY; + data.mNativeLayerRect = new Rect(); + data.mNativeLayer = nativeScrollableLayer( + contentX, contentY, data.mNativeLayerRect, null); data.mSlop = viewToContentDimension(mNavSlop); + mTouchHighlightRegion.setEmpty(); if (!mBlockWebkitViewMessages) { - mWebViewCore.sendMessageDelayed( - EventHub.GET_TOUCH_HIGHLIGHT_RECTS, data, - ViewConfiguration.getTapTimeout()); + mTouchHighlightRequested = System.currentTimeMillis(); + mWebViewCore.sendMessageAtFrontOfQueue( + EventHub.GET_TOUCH_HIGHLIGHT_RECTS, data); } if (DEBUG_TOUCH_HIGHLIGHT) { if (getSettings().getNavDump()) { @@ -5904,8 +5930,8 @@ public class WebView extends AbsoluteLayout if (mTouchMode == TOUCH_DOUBLE_TAP_MODE) { mTouchMode = TOUCH_INIT_MODE; } - if (getSettings().supportTouchOnly()) { - removeTouchHighlight(true); + if (USE_WEBKIT_RINGS || getSettings().supportTouchOnly()) { + removeTouchHighlight(); } } // pass the touch events from UI thread to WebCore thread @@ -6382,6 +6408,8 @@ public class WebView extends AbsoluteLayout WebViewCore.reducePriority(); // to get better performance, pause updating the picture WebViewCore.pauseUpdatePicture(mWebViewCore); + nativeSetIsScrolling(true); + if (!mDragFromTextInput) { nativeHideCursor(); } @@ -6478,13 +6506,14 @@ public class WebView extends AbsoluteLayout || mTouchMode == TOUCH_DRAG_LAYER_MODE) && !mSelectingText) { WebViewCore.resumePriority(); WebViewCore.resumeUpdatePicture(mWebViewCore); + nativeSetIsScrolling(false); } mPrivateHandler.removeMessages(SWITCH_TO_SHORTPRESS); mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS); mPrivateHandler.removeMessages(DRAG_HELD_MOTIONLESS); mPrivateHandler.removeMessages(AWAKEN_SCROLL_BARS); - if (getSettings().supportTouchOnly()) { - removeTouchHighlight(true); + if (USE_WEBKIT_RINGS || getSettings().supportTouchOnly()) { + removeTouchHighlight(); } mHeldMotionless = MOTIONLESS_TRUE; mTouchMode = TOUCH_DONE_MODE; @@ -7136,8 +7165,20 @@ public class WebView extends AbsoluteLayout int contentX = viewToContentX(mLastTouchX + mScrollX); int contentY = viewToContentY(mLastTouchY + mScrollY); int slop = viewToContentDimension(mNavSlop); + if (USE_WEBKIT_RINGS && !mTouchHighlightRegion.isEmpty()) { + // set mTouchHighlightRequested to 0 to cause an immediate + // drawing of the touch rings + mTouchHighlightRequested = 0; + invalidate(mTouchHighlightRegion.getBounds()); + mPrivateHandler.postDelayed(new Runnable() { + @Override + public void run() { + removeTouchHighlight(); + } + }, ViewConfiguration.getPressedStateDuration()); + } if (getSettings().supportTouchOnly()) { - removeTouchHighlight(false); + removeTouchHighlight(); WebViewCore.TouchUpData touchUpData = new WebViewCore.TouchUpData(); // use "0" as generation id to inform WebKit to use the same x/y as // it used when processing GET_TOUCH_HIGHLIGHT_RECTS @@ -8027,8 +8068,8 @@ public class WebView extends AbsoluteLayout break; } case SWITCH_TO_LONGPRESS: { - if (getSettings().supportTouchOnly()) { - removeTouchHighlight(false); + if (USE_WEBKIT_RINGS || getSettings().supportTouchOnly()) { + removeTouchHighlight(); } if (inFullScreenMode() || mDeferTouchProcess) { TouchEventData ted = new TouchEventData(); @@ -8350,26 +8391,9 @@ public class WebView extends AbsoluteLayout break; case SET_TOUCH_HIGHLIGHT_RECTS: - invalidate(mTouchHighlightRegion.getBounds()); - mTouchHighlightRegion.setEmpty(); - if (msg.obj != null) { - ArrayList<Rect> rects = (ArrayList<Rect>) msg.obj; - for (Rect rect : rects) { - Rect viewRect = contentToViewRect(rect); - // some sites, like stories in nytimes.com, set - // mouse event handler in the top div. It is not - // user friendly to highlight the div if it covers - // more than half of the screen. - if (viewRect.width() < getWidth() >> 1 - || viewRect.height() < getHeight() >> 1) { - mTouchHighlightRegion.union(viewRect); - invalidate(viewRect); - } else { - Log.w(LOGTAG, "Skip the huge selection rect:" - + viewRect); - } - } - } + @SuppressWarnings("unchecked") + ArrayList<Rect> rects = (ArrayList<Rect>) msg.obj; + setTouchHighlightRects(rects); break; case SAVE_WEBARCHIVE_FINISHED: @@ -8406,6 +8430,28 @@ public class WebView extends AbsoluteLayout } } + private void setTouchHighlightRects(ArrayList<Rect> rects) { + invalidate(mTouchHighlightRegion.getBounds()); + mTouchHighlightRegion.setEmpty(); + if (rects != null) { + for (Rect rect : rects) { + Rect viewRect = contentToViewRect(rect); + // some sites, like stories in nytimes.com, set + // mouse event handler in the top div. It is not + // user friendly to highlight the div if it covers + // more than half of the screen. + if (viewRect.width() < getWidth() >> 1 + || viewRect.height() < getHeight() >> 1) { + mTouchHighlightRegion.union(viewRect); + } else { + Log.w(LOGTAG, "Skip the huge selection rect:" + + viewRect); + } + } + invalidate(mTouchHighlightRegion.getBounds()); + } + } + /** @hide Called by JNI when pages are swapped (only occurs with hardware * acceleration) */ protected void pageSwapCallback() { @@ -9078,7 +9124,9 @@ public class WebView extends AbsoluteLayout /** @hide send content invalidate */ protected void contentInvalidateAll() { - mWebViewCore.sendMessage(EventHub.CONTENT_INVALIDATE_ALL); + if (mWebViewCore != null && !mBlockWebkitViewMessages) { + mWebViewCore.sendMessage(EventHub.CONTENT_INVALIDATE_ALL); + } } /** @hide call pageSwapCallback upon next page swap */ @@ -9277,6 +9325,7 @@ public class WebView extends AbsoluteLayout * @return True if the layer is successfully scrolled. */ private native boolean nativeScrollLayer(int layer, int newX, int newY); + private native void nativeSetIsScrolling(boolean isScrolling); private native int nativeGetBackgroundColor(); native boolean nativeSetProperty(String key, String value); native String nativeGetProperty(String key); |