Title: [170684] trunk/Source/WebKit2
Revision
170684
Author
benja...@webkit.org
Date
2014-07-01 17:49:13 -0700 (Tue, 01 Jul 2014)

Log Message

[iOS][WK2] Fix a race between the short tap and long tap highlight
https://bugs.webkit.org/show_bug.cgi?id=134530

Reviewed by Enrica Casucci.

There was a potential race of event that can theoretically cause WKContentViewInteraction
to call [WKContentView _showTapHighlight] after all interactions have been cancelled.

The race would be like this:
1) On a short tap, _singleTapRecognized: is called, a tap highlight ID is defined and
   _potentialTapInProgress is set to YES.
2) For some reason, the gesture is cancelled. The method _singleTapDidReset is called, 
   setting _potentialTapInProgress but leaving the tap highlight ID as valid.
3) The UIProcess receives the tap highlight information from the WebProcess, _didGetTapHighlightForRequest:
   has a valid ID, _potentialTapInProgress is false -> the highlight is shown right away as if a long tap
   was in progress.

The missing piece that causes this is _singleTapDidReset: must also invalidate the tap highlight ID. This is done
in the new static function cancelPotentialTapIfNecessary().

Just invalidating the ID would create another race:
1) Short tap gesture recognizer starts.
2) The long press recognizer starts before (1) is commited.
3) The long press recognizers sets up its own tap highlight ID.
4) The short tap gesture recognizer resets, erasing the tap highlight ID defined in (3).

To avoid this, the long press gesture recognizers immediately cancels any potential tap in progress.
If _singleTapDidReset: is called before (3), this does nothing. If the reset is called after (3),
_singleTapDidReset does nothing.

* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView _highlightLongPressRecognized:]):
(cancelPotentialTapIfNecessary):
(-[WKContentView _singleTapDidReset:]):

Modified Paths

Diff

Modified: trunk/Source/WebKit2/ChangeLog (170683 => 170684)


--- trunk/Source/WebKit2/ChangeLog	2014-07-02 00:47:19 UTC (rev 170683)
+++ trunk/Source/WebKit2/ChangeLog	2014-07-02 00:49:13 UTC (rev 170684)
@@ -1,3 +1,40 @@
+2014-07-01  Benjamin Poulain  <benja...@webkit.org>
+
+        [iOS][WK2] Fix a race between the short tap and long tap highlight
+        https://bugs.webkit.org/show_bug.cgi?id=134530
+
+        Reviewed by Enrica Casucci.
+
+        There was a potential race of event that can theoretically cause WKContentViewInteraction
+        to call [WKContentView _showTapHighlight] after all interactions have been cancelled.
+
+        The race would be like this:
+        1) On a short tap, _singleTapRecognized: is called, a tap highlight ID is defined and
+           _potentialTapInProgress is set to YES.
+        2) For some reason, the gesture is cancelled. The method _singleTapDidReset is called, 
+           setting _potentialTapInProgress but leaving the tap highlight ID as valid.
+        3) The UIProcess receives the tap highlight information from the WebProcess, _didGetTapHighlightForRequest:
+           has a valid ID, _potentialTapInProgress is false -> the highlight is shown right away as if a long tap
+           was in progress.
+
+        The missing piece that causes this is _singleTapDidReset: must also invalidate the tap highlight ID. This is done
+        in the new static function cancelPotentialTapIfNecessary().
+
+        Just invalidating the ID would create another race:
+        1) Short tap gesture recognizer starts.
+        2) The long press recognizer starts before (1) is commited.
+        3) The long press recognizers sets up its own tap highlight ID.
+        4) The short tap gesture recognizer resets, erasing the tap highlight ID defined in (3).
+
+        To avoid this, the long press gesture recognizers immediately cancels any potential tap in progress.
+        If _singleTapDidReset: is called before (3), this does nothing. If the reset is called after (3),
+        _singleTapDidReset does nothing.
+
+        * UIProcess/ios/WKContentViewInteraction.mm:
+        (-[WKContentView _highlightLongPressRecognized:]):
+        (cancelPotentialTapIfNecessary):
+        (-[WKContentView _singleTapDidReset:]):
+
 2014-07-01  Anders Carlsson  <ander...@apple.com>
 
         Add ABI hacks to allow WKPageRef to use WKSessionStateRef

Modified: trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm (170683 => 170684)


--- trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm	2014-07-02 00:47:19 UTC (rev 170683)
+++ trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm	2014-07-02 00:49:13 UTC (rev 170684)
@@ -877,6 +877,7 @@
 
     switch ([gestureRecognizer state]) {
     case UIGestureRecognizerStateBegan:
+        cancelPotentialTapIfNecessary(self);
         _page->tapHighlightAtPosition([gestureRecognizer startPoint], ++_latestTapHighlightID);
         _isTapHighlightIDValid = YES;
         break;
@@ -921,14 +922,20 @@
     _isTapHighlightIDValid = YES;
 }
 
+static void cancelPotentialTapIfNecessary(WKContentView* contentView)
+{
+    if (contentView->_potentialTapInProgress) {
+        contentView->_potentialTapInProgress = NO;
+        contentView->_isTapHighlightIDValid = NO;
+        [contentView _cancelInteraction];
+        contentView->_page->cancelPotentialTap();
+    }
+}
+
 - (void)_singleTapDidReset:(UITapGestureRecognizer *)gestureRecognizer
 {
     ASSERT(gestureRecognizer == _singleTapGestureRecognizer);
-    if (_potentialTapInProgress) {
-        _potentialTapInProgress = NO;
-        [self _cancelInteraction];
-        _page->cancelPotentialTap();
-    }
+    cancelPotentialTapIfNecessary(self);
 }
 
 - (void)_commitPotentialTapFailed
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to