@@ -99,6 +99,8 @@ final class WebViewInputDispatcher {
9999 private boolean mPostDoNotSendTouchEventsToWebKitUntilNextGesture ;
100100 private boolean mPostLongPressScheduled ;
101101 private boolean mPostClickScheduled ;
102+ private boolean mPostShowTapHighlightScheduled ;
103+ private boolean mPostHideTapHighlightScheduled ;
102104 private int mPostLastWebKitXOffset ;
103105 private int mPostLastWebKitYOffset ;
104106 private float mPostLastWebKitScale ;
@@ -133,6 +135,7 @@ final class WebViewInputDispatcher {
133135 private static final int LONG_PRESS_TIMEOUT =
134136 ViewConfiguration .getLongPressTimeout () + TAP_TIMEOUT ;
135137 private static final int DOUBLE_TAP_TIMEOUT = ViewConfiguration .getDoubleTapTimeout ();
138+ private static final int PRESSED_STATE_DURATION = ViewConfiguration .getPressedStateDuration ();
136139
137140 /**
138141 * Event type: Indicates a touch event type.
@@ -310,6 +313,7 @@ public boolean postPointerEvent(MotionEvent event,
310313 }
311314 unscheduleLongPressLocked ();
312315 unscheduleClickLocked ();
316+ hideTapCandidateLocked ();
313317 return false ;
314318 }
315319
@@ -349,12 +353,6 @@ private void unscheduleLongPressLocked() {
349353 }
350354 }
351355
352- public boolean shouldShowTapHighlight () {
353- synchronized (mLock ) {
354- return mPostLongPressScheduled || mPostClickScheduled ;
355- }
356- }
357-
358356 private void postLongPress () {
359357 synchronized (mLock ) {
360358 if (!mPostLongPressScheduled ) {
@@ -385,6 +383,64 @@ private void postLongPress() {
385383 }
386384 }
387385
386+ private void hideTapCandidateLocked () {
387+ unscheduleHideTapHighlightLocked ();
388+ unscheduleShowTapHighlightLocked ();
389+ mUiCallbacks .showTapHighlight (false );
390+ }
391+
392+ private void showTapCandidateLocked () {
393+ unscheduleHideTapHighlightLocked ();
394+ unscheduleShowTapHighlightLocked ();
395+ mUiCallbacks .showTapHighlight (true );
396+ scheduleHideTapHighlightLocked ();
397+ }
398+
399+ private void scheduleShowTapHighlightLocked () {
400+ unscheduleShowTapHighlightLocked ();
401+ mPostShowTapHighlightScheduled = true ;
402+ mUiHandler .sendEmptyMessageDelayed (UiHandler .MSG_SHOW_TAP_HIGHLIGHT ,
403+ TAP_TIMEOUT );
404+ }
405+
406+ private void unscheduleShowTapHighlightLocked () {
407+ if (mPostShowTapHighlightScheduled ) {
408+ mPostShowTapHighlightScheduled = false ;
409+ mUiHandler .removeMessages (UiHandler .MSG_SHOW_TAP_HIGHLIGHT );
410+ }
411+ }
412+
413+ private void scheduleHideTapHighlightLocked () {
414+ unscheduleHideTapHighlightLocked ();
415+ mPostHideTapHighlightScheduled = true ;
416+ mUiHandler .sendEmptyMessageDelayed (UiHandler .MSG_HIDE_TAP_HIGHLIGHT ,
417+ PRESSED_STATE_DURATION );
418+ }
419+
420+ private void unscheduleHideTapHighlightLocked () {
421+ if (mPostHideTapHighlightScheduled ) {
422+ mPostHideTapHighlightScheduled = false ;
423+ mUiHandler .removeMessages (UiHandler .MSG_HIDE_TAP_HIGHLIGHT );
424+ }
425+ }
426+
427+ private void postShowTapHighlight (boolean show ) {
428+ synchronized (mLock ) {
429+ if (show ) {
430+ if (!mPostShowTapHighlightScheduled ) {
431+ return ;
432+ }
433+ mPostShowTapHighlightScheduled = false ;
434+ } else {
435+ if (!mPostHideTapHighlightScheduled ) {
436+ return ;
437+ }
438+ mPostHideTapHighlightScheduled = false ;
439+ }
440+ mUiCallbacks .showTapHighlight (show );
441+ }
442+ }
443+
388444 private void scheduleClickLocked () {
389445 unscheduleClickLocked ();
390446 mPostClickScheduled = true ;
@@ -404,6 +460,7 @@ private void postClick() {
404460 return ;
405461 }
406462 mPostClickScheduled = false ;
463+ showTapCandidateLocked ();
407464
408465 MotionEvent event = mPostTouchStream .getLastEvent ();
409466 if (event == null || event .getAction () != MotionEvent .ACTION_UP ) {
@@ -442,6 +499,7 @@ private boolean isClickCandidateLocked(MotionEvent event) {
442499
443500 private void enqueueDoubleTapLocked (MotionEvent event ) {
444501 unscheduleClickLocked ();
502+ hideTapCandidateLocked ();
445503 MotionEvent eventToEnqueue = MotionEvent .obtainNoHistory (event );
446504 DispatchEvent d = obtainDispatchEventLocked (eventToEnqueue , EVENT_TYPE_DOUBLE_TAP , 0 ,
447505 mPostLastWebKitXOffset , mPostLastWebKitYOffset , mPostLastWebKitScale );
@@ -458,6 +516,7 @@ private void checkForSlopLocked(MotionEvent event) {
458516 if ((deltaX * deltaX + deltaY * deltaY ) > mTouchSlopSquared ) {
459517 unscheduleLongPressLocked ();
460518 mIsTapCandidate = false ;
519+ hideTapCandidateLocked ();
461520 }
462521 }
463522
@@ -474,14 +533,17 @@ private void updateStateTrackersLocked(DispatchEvent d, MotionEvent event) {
474533 || event .getPointerCount () > 1 ) {
475534 unscheduleLongPressLocked ();
476535 unscheduleClickLocked ();
536+ hideTapCandidateLocked ();
477537 mIsDoubleTapCandidate = false ;
478538 mIsTapCandidate = false ;
539+ hideTapCandidateLocked ();
479540 } else if (action == MotionEvent .ACTION_DOWN ) {
480541 checkForDoubleTapOnDownLocked (event );
481542 scheduleLongPressLocked ();
482543 mIsTapCandidate = true ;
483544 mInitialDownX = event .getX ();
484545 mInitialDownY = event .getY ();
546+ scheduleShowTapHighlightLocked ();
485547 } else if (action == MotionEvent .ACTION_UP ) {
486548 unscheduleLongPressLocked ();
487549 if (isClickCandidateLocked (event )) {
@@ -490,6 +552,8 @@ private void updateStateTrackersLocked(DispatchEvent d, MotionEvent event) {
490552 } else {
491553 scheduleClickLocked ();
492554 }
555+ } else {
556+ hideTapCandidateLocked ();
493557 }
494558 } else if (action == MotionEvent .ACTION_MOVE ) {
495559 checkForSlopLocked (event );
@@ -959,6 +1023,12 @@ public static interface UiCallbacks {
9591023 * through webkit or false otherwise.
9601024 */
9611025 public boolean shouldInterceptTouchEvent (MotionEvent event );
1026+
1027+ /**
1028+ * Inform's the UI that it should show the tap highlight
1029+ * @param show True if it should show the highlight, false if it should hide it
1030+ */
1031+ public void showTapHighlight (boolean show );
9621032 }
9631033
9641034 /* Implemented by {@link WebViewCore} to perform operations on the web kit thread. */
@@ -985,6 +1055,8 @@ private final class UiHandler extends Handler {
9851055 public static final int MSG_WEBKIT_TIMEOUT = 2 ;
9861056 public static final int MSG_LONG_PRESS = 3 ;
9871057 public static final int MSG_CLICK = 4 ;
1058+ public static final int MSG_SHOW_TAP_HIGHLIGHT = 5 ;
1059+ public static final int MSG_HIDE_TAP_HIGHLIGHT = 6 ;
9881060
9891061 public UiHandler (Looper looper ) {
9901062 super (looper );
@@ -1005,6 +1077,12 @@ public void handleMessage(Message msg) {
10051077 case MSG_CLICK :
10061078 postClick ();
10071079 break ;
1080+ case MSG_SHOW_TAP_HIGHLIGHT :
1081+ postShowTapHighlight (true );
1082+ break ;
1083+ case MSG_HIDE_TAP_HIGHLIGHT :
1084+ postShowTapHighlight (false );
1085+ break ;
10081086 default :
10091087 throw new IllegalStateException ("Unknown message type: " + msg .what );
10101088 }
0 commit comments