diff options
author | John Reck <jreck@google.com> | 2011-08-25 18:25:09 -0700 |
---|---|---|
committer | John Reck <jreck@google.com> | 2011-08-26 15:17:55 -0700 |
commit | 335f4547530b58d60003b844139ba25de9486124 (patch) | |
tree | 9ff4b57a313a679f23322c3741828dfb2981071c | |
parent | cf56f1e7ad7586831faa5bacb537f71cdb227e61 (diff) | |
download | frameworks_base-335f4547530b58d60003b844139ba25de9486124.zip frameworks_base-335f4547530b58d60003b844139ba25de9486124.tar.gz frameworks_base-335f4547530b58d60003b844139ba25de9486124.tar.bz2 |
Better touch rects
Bug: 5164486
Get the focus rings from webkit instead of the navcache
and draw them in Java.
Change-Id: Ib44d3f6972b3cdbca4d2f0a3034f53d9ae5bb2a8
-rw-r--r-- | core/java/android/webkit/WebView.java | 140 | ||||
-rw-r--r-- | core/java/android/webkit/WebViewCore.java | 19 |
2 files changed, 98 insertions, 61 deletions
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index 5d776fd..d579900 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. @@ -3991,7 +3994,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, @@ -4003,7 +4006,8 @@ public class WebView extends AbsoluteLayout nativeRecordButtons(hasFocus() && hasWindowFocus(), mTouchMode == TOUCH_SHORTPRESS_START_MODE || mTrackballDown || mGotCenterDown, false); - drawCoreAndCursorRing(canvas, mBackgroundColor, mDrawCursorRing); + drawCoreAndCursorRing(canvas, mBackgroundColor, + mDrawCursorRing && drawRings); } /** @@ -4067,7 +4071,15 @@ 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); + boolean drawNativeRings = !drawJavaRings; + if (USE_WEBKIT_RINGS) { + drawNativeRings = !drawJavaRings && !isInTouchMode(); + } + drawContent(canvas, drawNativeRings); canvas.restoreToCount(saveCount); if (AUTO_REDRAW_HACK && mAutoRedraw) { @@ -4080,16 +4092,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 +4130,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 +5802,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 +5826,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 +5925,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 @@ -6483,8 +6504,8 @@ public class WebView extends AbsoluteLayout 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 +7157,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 +8060,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 +8383,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 +8422,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() { diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java index 400cdbd..127355f 100644 --- a/core/java/android/webkit/WebViewCore.java +++ b/core/java/android/webkit/WebViewCore.java @@ -801,6 +801,8 @@ public final class WebViewCore { int mX; int mY; int mSlop; + int mNativeLayer; + Rect mNativeLayerRect; } static class AutoFillData { @@ -1015,7 +1017,6 @@ public final class WebViewCore { static final int REMOVE_PACKAGE_NAME = 186; static final int GET_TOUCH_HIGHLIGHT_RECTS = 187; - static final int REMOVE_TOUCH_HIGHLIGHT_RECTS = 188; // accessibility support static final int MODIFY_SELECTION = 190; @@ -1576,6 +1577,10 @@ public final class WebViewCore { case GET_TOUCH_HIGHLIGHT_RECTS: TouchHighlightData d = (TouchHighlightData) msg.obj; + if (d.mNativeLayer != 0) { + nativeScrollLayer(d.mNativeLayer, + d.mNativeLayerRect); + } ArrayList<Rect> rects = nativeGetTouchHighlightRects (d.mX, d.mY, d.mSlop); mWebView.mPrivateHandler.obtainMessage( @@ -1583,12 +1588,6 @@ public final class WebViewCore { .sendToTarget(); break; - case REMOVE_TOUCH_HIGHLIGHT_RECTS: - mWebView.mPrivateHandler.obtainMessage( - WebView.SET_TOUCH_HIGHLIGHT_RECTS, null) - .sendToTarget(); - break; - case USE_MOCK_DEVICE_ORIENTATION: useMockDeviceOrientation(); break; @@ -2228,9 +2227,9 @@ public final class WebViewCore { } // remove the touch highlight when moving to a new page - if (getSettings().supportTouchOnly()) { - mEventHub.sendMessage(Message.obtain(null, - EventHub.REMOVE_TOUCH_HIGHLIGHT_RECTS)); + if (WebView.USE_WEBKIT_RINGS || getSettings().supportTouchOnly()) { + mWebView.mPrivateHandler.sendEmptyMessage( + WebView.SET_TOUCH_HIGHLIGHT_RECTS); } // reset the scroll position, the restored offset and scales |