Occasional deadlocks under ensurePositionInformationIsUpToDate (incoming sync message...
authortimothy_horton@apple.com <timothy_horton@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 20 Jun 2017 19:46:14 +0000 (19:46 +0000)
committertimothy_horton@apple.com <timothy_horton@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 20 Jun 2017 19:46:14 +0000 (19:46 +0000)
https://bugs.webkit.org/show_bug.cgi?id=173570
<rdar://problem/32720928>

Reviewed by Wenson Hsieh.

* UIProcess/WebPageProxy.h:
* UIProcess/ios/WebPageProxyIOS.mm:
(WebKit::WebPageProxy::getPositionInformation): Deleted.
Get rid of getPositionInformation; it only has one caller, and it's easier
to reason about the code if it's all in one place. Also, we shouldn't
add more callers...

* UIProcess/ios/WKContentViewInteraction.h:
* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView ensurePositionInformationIsUpToDate:]):
Add a return value to ensurePositionInformationIsUpToDate that indicates
whether we succeeded in that effort.

Add the flag to our waitForAndDispatchImmediately that causes the wait
to be interrupted if a sync message arrives.

(-[WKContentView gestureRecognizerShouldBegin:]):
(-[WKContentView hasSelectablePositionAtPoint:]):
(-[WKContentView pointIsNearMarkedText:]):
(-[WKContentView textInteractionGesture:shouldBeginAtPoint:]):
(-[WKContentView positionInformationForActionSheetAssistant:]):
(-[WKContentView _interactionShouldBeginFromPreviewItemController:forPosition:]):
If anything happens to interrupt our position information update, fail
in the most graceful possible way at each callsite (generally by bailing
from doing whatever action required position information).

* UIProcess/ios/WKPDFView.mm:
(-[WKPDFView positionInformationForActionSheetAssistant:]):
* UIProcess/ios/WKActionSheetAssistant.h:
* UIProcess/ios/WKActionSheetAssistant.mm:
(-[WKActionSheetAssistant synchronouslyRetrievePositionInformation]):
(-[WKActionSheetAssistant presentationRectForElementUsingClosestIndicatedRect]):
(-[WKActionSheetAssistant presentationRectForIndicatedElement]):
(-[WKActionSheetAssistant initialPresentationRectInHostViewForSheet]):
(-[WKActionSheetAssistant presentationRectInHostViewForSheet]):
(-[WKActionSheetAssistant _createSheetWithElementActions:showLinkTitle:]):
(-[WKActionSheetAssistant showImageSheet]):
(-[WKActionSheetAssistant defaultActionsForLinkSheet:]):
(-[WKActionSheetAssistant showLinkSheet]):
(-[WKActionSheetAssistant showDataDetectorsSheet]):
(-[WKActionSheetAssistant cleanupSheet]):
Instead of constantly re-querying the position information, save it aside
when presenting an action sheet, and use it to respond to all of the
subsequent questions. Also, bail from presenting the action sheet if we fail
to retrieve correct position information.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@218606 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebKit2/ChangeLog
Source/WebKit2/UIProcess/WebPageProxy.h
Source/WebKit2/UIProcess/ios/WKActionSheetAssistant.h
Source/WebKit2/UIProcess/ios/WKActionSheetAssistant.mm
Source/WebKit2/UIProcess/ios/WKContentViewInteraction.h
Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm
Source/WebKit2/UIProcess/ios/WKPDFView.mm
Source/WebKit2/UIProcess/ios/WebPageProxyIOS.mm

index 7389f58..e3d2ad8 100644 (file)
@@ -1,3 +1,57 @@
+2017-06-20  Tim Horton  <timothy_horton@apple.com>
+
+        Occasional deadlocks under ensurePositionInformationIsUpToDate (incoming sync message with waitForAndDispatchImmediately)
+        https://bugs.webkit.org/show_bug.cgi?id=173570
+        <rdar://problem/32720928>
+
+        Reviewed by Wenson Hsieh.
+
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/ios/WebPageProxyIOS.mm:
+        (WebKit::WebPageProxy::getPositionInformation): Deleted.
+        Get rid of getPositionInformation; it only has one caller, and it's easier
+        to reason about the code if it's all in one place. Also, we shouldn't
+        add more callers...
+
+        * UIProcess/ios/WKContentViewInteraction.h:
+        * UIProcess/ios/WKContentViewInteraction.mm:
+        (-[WKContentView ensurePositionInformationIsUpToDate:]):
+        Add a return value to ensurePositionInformationIsUpToDate that indicates
+        whether we succeeded in that effort.
+
+        Add the flag to our waitForAndDispatchImmediately that causes the wait
+        to be interrupted if a sync message arrives.
+
+        (-[WKContentView gestureRecognizerShouldBegin:]):
+        (-[WKContentView hasSelectablePositionAtPoint:]):
+        (-[WKContentView pointIsNearMarkedText:]):
+        (-[WKContentView textInteractionGesture:shouldBeginAtPoint:]):
+        (-[WKContentView positionInformationForActionSheetAssistant:]):
+        (-[WKContentView _interactionShouldBeginFromPreviewItemController:forPosition:]):
+        If anything happens to interrupt our position information update, fail
+        in the most graceful possible way at each callsite (generally by bailing
+        from doing whatever action required position information).
+
+        * UIProcess/ios/WKPDFView.mm:
+        (-[WKPDFView positionInformationForActionSheetAssistant:]):
+        * UIProcess/ios/WKActionSheetAssistant.h:
+        * UIProcess/ios/WKActionSheetAssistant.mm:
+        (-[WKActionSheetAssistant synchronouslyRetrievePositionInformation]):
+        (-[WKActionSheetAssistant presentationRectForElementUsingClosestIndicatedRect]):
+        (-[WKActionSheetAssistant presentationRectForIndicatedElement]):
+        (-[WKActionSheetAssistant initialPresentationRectInHostViewForSheet]):
+        (-[WKActionSheetAssistant presentationRectInHostViewForSheet]):
+        (-[WKActionSheetAssistant _createSheetWithElementActions:showLinkTitle:]):
+        (-[WKActionSheetAssistant showImageSheet]):
+        (-[WKActionSheetAssistant defaultActionsForLinkSheet:]):
+        (-[WKActionSheetAssistant showLinkSheet]):
+        (-[WKActionSheetAssistant showDataDetectorsSheet]):
+        (-[WKActionSheetAssistant cleanupSheet]):
+        Instead of constantly re-querying the position information, save it aside
+        when presenting an action sheet, and use it to respond to all of the
+        subsequent questions. Also, bail from presenting the action sheet if we fail
+        to retrieve correct position information.
+
 2017-06-20  Matt Lewis  <jlewis3@apple.com>
 
         Unreviewed, rolling out r218530.
index 84df580..3a30e84 100644 (file)
@@ -525,7 +525,6 @@ public:
     void replaceDictatedText(const String& oldText, const String& newText);
     void replaceSelectedText(const String& oldText, const String& newText);
     void didReceivePositionInformation(const InteractionInformationAtPosition&);
-    void getPositionInformation(const InteractionInformationRequest&, InteractionInformationAtPosition&);
     void requestPositionInformation(const InteractionInformationRequest&);
     void startInteractionWithElementAtPosition(const WebCore::IntPoint&);
     void stopInteraction();
index f80046c..ccf8bc0 100644 (file)
@@ -42,7 +42,7 @@ struct InteractionInformationAtPosition;
 
 @protocol WKActionSheetAssistantDelegate <NSObject>
 @required
-- (const WebKit::InteractionInformationAtPosition&)positionInformationForActionSheetAssistant:(WKActionSheetAssistant *)assistant;
+- (std::optional<WebKit::InteractionInformationAtPosition>)positionInformationForActionSheetAssistant:(WKActionSheetAssistant *)assistant;
 - (void)actionSheetAssistant:(WKActionSheetAssistant *)assistant performAction:(WebKit::SheetAction)action;
 - (void)actionSheetAssistant:(WKActionSheetAssistant *)assistant openElementAtLocation:(CGPoint)location;
 - (void)actionSheetAssistant:(WKActionSheetAssistant *)assistant shareElementWithURL:(NSURL *)url rect:(CGRect)boundingRect;
index da2636b..733228f 100644 (file)
@@ -88,6 +88,7 @@ static LSAppLink *appLinkForURL(NSURL *url)
     WeakObjCPtr<id <WKActionSheetAssistantDelegate>> _delegate;
     RetainPtr<WKActionSheet> _interactionSheet;
     RetainPtr<_WKActivatedElementInfo> _elementInfo;
+    std::optional<WebKit::InteractionInformationAtPosition> _positionInformation;
     UIView *_view;
     BOOL _needsLinkIndicator;
     BOOL _isPresentingDDUserInterface;
@@ -116,6 +117,17 @@ static LSAppLink *appLinkForURL(NSURL *url)
     [super dealloc];
 }
 
+- (BOOL)synchronouslyRetrievePositionInformation
+{
+    auto delegate = _delegate.get();
+    if (!delegate)
+        return NO;
+
+    // FIXME: This should be asynchronous, since we control the presentation of the action sheet.
+    _positionInformation = [delegate positionInformationForActionSheetAssistant:self];
+    return !!_positionInformation;
+}
+
 - (UIView *)superviewForSheet
 {
     UIView *view = [_view window];
@@ -158,15 +170,14 @@ static const CGFloat presentationElementRectPadding = 15;
 {
     UIView *view = [self superviewForSheet];
     auto delegate = _delegate.get();
-    if (!view || !delegate)
+    if (!view || !delegate || !_positionInformation)
         return CGRectZero;
 
-    auto info = [delegate positionInformationForActionSheetAssistant:self];
-    auto indicator = info.linkIndicator;
+    auto indicator = _positionInformation->linkIndicator;
     if (indicator.textRectsInBoundingRectCoordinates.isEmpty())
         return CGRectZero;
 
-    WebCore::FloatPoint touchLocation = info.request.point;
+    WebCore::FloatPoint touchLocation = _positionInformation->request.point;
     WebCore::FloatPoint linkElementLocation = indicator.textBoundingRectInRootViewCoordinates.location();
     Vector<WebCore::FloatRect> indicatedRects;
     for (auto rect : indicator.textRectsInBoundingRectCoordinates) {
@@ -188,10 +199,10 @@ static const CGFloat presentationElementRectPadding = 15;
 {
     UIView *view = [self superviewForSheet];
     auto delegate = _delegate.get();
-    if (!view || !delegate)
+    if (!view || !delegate || !_positionInformation)
         return CGRectZero;
 
-    auto elementBounds = [delegate positionInformationForActionSheetAssistant:self].bounds;
+    auto elementBounds = _positionInformation->bounds;
     return CGRectInset([view convertRect:elementBounds fromView:_view], -presentationElementRectPadding, -presentationElementRectPadding);
 }
 
@@ -199,23 +210,21 @@ static const CGFloat presentationElementRectPadding = 15;
 {
     UIView *view = [self superviewForSheet];
     auto delegate = _delegate.get();
-    if (!view || !delegate)
+    if (!view || !delegate || !_positionInformation)
         return CGRectZero;
 
-    return [self _presentationRectForSheetGivenPoint:[delegate positionInformationForActionSheetAssistant:self].request.point inHostView:view];
+    return [self _presentationRectForSheetGivenPoint:_positionInformation->request.point inHostView:view];
 }
 
 - (CGRect)presentationRectInHostViewForSheet
 {
     UIView *view = [self superviewForSheet];
     auto delegate = _delegate.get();
-    if (!view || !delegate)
+    if (!view || !delegate || !_positionInformation)
         return CGRectZero;
 
-    const auto& positionInformation = [delegate positionInformationForActionSheetAssistant:self];
-
-    CGRect boundingRect = positionInformation.bounds;
-    CGPoint fromPoint = positionInformation.request.point;
+    CGRect boundingRect = _positionInformation->bounds;
+    CGPoint fromPoint = _positionInformation->request.point;
 
     // FIXME: We must adjust our presentation point to take into account a change in document scale.
 
@@ -275,9 +284,10 @@ static const CGFloat presentationElementRectPadding = 15;
     if (!delegate)
         return;
 
-    const auto& positionInformation = [delegate positionInformationForActionSheetAssistant:self];
+    if (!_positionInformation)
+        return;
 
-    NSURL *targetURL = [NSURL URLWithString:positionInformation.url];
+    NSURL *targetURL = [NSURL URLWithString:_positionInformation->url];
     NSString *urlScheme = [targetURL scheme];
     BOOL isJavaScriptURL = [urlScheme length] && [urlScheme caseInsensitiveCompare:@"javascript"] == NSOrderedSame;
     // FIXME: We should check if Javascript is enabled in the preferences.
@@ -296,7 +306,7 @@ static const CGFloat presentationElementRectPadding = 15;
             titleIsURL = YES;
         }
     } else
-        titleString = positionInformation.title;
+        titleString = _positionInformation->title;
 
     if ([titleString length]) {
         [_interactionSheet setTitle:titleString];
@@ -333,12 +343,13 @@ static const CGFloat presentationElementRectPadding = 15;
     if (!delegate)
         return;
 
-    const auto& positionInformation = [delegate positionInformationForActionSheetAssistant:self];
+    if (![self synchronouslyRetrievePositionInformation])
+        return;
 
     void (^showImageSheetWithAlternateURLBlock)(NSURL*, NSDictionary *userInfo) = ^(NSURL *alternateURL, NSDictionary *userInfo) {
-        NSURL *targetURL = [NSURL _web_URLWithWTFString:positionInformation.url] ?: alternateURL;
-        auto elementBounds = positionInformation.bounds;
-        auto elementInfo = adoptNS([[_WKActivatedElementInfo alloc] _initWithType:_WKActivatedElementTypeImage URL:targetURL location:positionInformation.request.point title:positionInformation.title ID:positionInformation.idAttribute rect:elementBounds image:positionInformation.image.get() userInfo:userInfo]);
+        NSURL *targetURL = [NSURL _web_URLWithWTFString:_positionInformation->url] ?: alternateURL;
+        auto elementBounds = _positionInformation->bounds;
+        auto elementInfo = adoptNS([[_WKActivatedElementInfo alloc] _initWithType:_WKActivatedElementTypeImage URL:targetURL location:_positionInformation->request.point title:_positionInformation->title ID:_positionInformation->idAttribute rect:elementBounds image:_positionInformation->image.get() userInfo:userInfo]);
         if ([delegate respondsToSelector:@selector(actionSheetAssistant:showCustomSheetForElement:)] && [delegate actionSheetAssistant:self showCustomSheetForElement:elementInfo.get()])
             return;
         auto defaultActions = [self defaultActionsForImageSheet:elementInfo.get()];
@@ -363,8 +374,8 @@ static const CGFloat presentationElementRectPadding = 15;
             [self cleanupSheet];
     };
 
-    if (positionInformation.url.isEmpty() && positionInformation.image && [delegate respondsToSelector:@selector(actionSheetAssistant:getAlternateURLForImage:completion:)]) {
-        RetainPtr<UIImage> uiImage = adoptNS([[UIImage alloc] initWithCGImage:positionInformation.image->makeCGImageCopy().get()]);
+    if (_positionInformation->url.isEmpty() && _positionInformation->image && [delegate respondsToSelector:@selector(actionSheetAssistant:getAlternateURLForImage:completion:)]) {
+        RetainPtr<UIImage> uiImage = adoptNS([[UIImage alloc] initWithCGImage:_positionInformation->image->makeCGImageCopy().get()]);
 
         _hasPendingActionSheet = YES;
         RetainPtr<WKActionSheetAssistant> retainedSelf(self);
@@ -434,9 +445,10 @@ static const CGFloat presentationElementRectPadding = 15;
     if (!delegate)
         return nil;
 
-    const auto& positionInformation = [delegate positionInformationForActionSheetAssistant:self];
+    if (!_positionInformation)
+        return nil;
 
-    NSURL *targetURL = [NSURL URLWithString:positionInformation.url];
+    NSURL *targetURL = [NSURL URLWithString:_positionInformation->url];
     if (!targetURL)
         return nil;
 
@@ -495,15 +507,16 @@ static const CGFloat presentationElementRectPadding = 15;
         return;
 
     _needsLinkIndicator = YES;
-    const auto& positionInformation = [delegate positionInformationForActionSheetAssistant:self];
+    if (![self synchronouslyRetrievePositionInformation])
+        return;
 
-    NSURL *targetURL = [NSURL _web_URLWithWTFString:positionInformation.url];
+    NSURL *targetURL = [NSURL _web_URLWithWTFString:_positionInformation->url];
     if (!targetURL) {
         _needsLinkIndicator = NO;
         return;
     }
 
-    auto elementInfo = adoptNS([[_WKActivatedElementInfo alloc] _initWithType:_WKActivatedElementTypeLink URL:targetURL location:positionInformation.request.point title:positionInformation.title ID:positionInformation.idAttribute rect:positionInformation.bounds image:positionInformation.image.get()]);
+    auto elementInfo = adoptNS([[_WKActivatedElementInfo alloc] _initWithType:_WKActivatedElementTypeLink URL:targetURL location:_positionInformation->request.point title:_positionInformation->title ID:_positionInformation->idAttribute rect:_positionInformation->bounds image:_positionInformation->image.get()]);
     if ([delegate respondsToSelector:@selector(actionSheetAssistant:showCustomSheetForElement:)] && [delegate actionSheetAssistant:self showCustomSheetForElement:elementInfo.get()]) {
         _needsLinkIndicator = NO;
         return;
@@ -526,7 +539,7 @@ static const CGFloat presentationElementRectPadding = 15;
 
     _elementInfo = WTFMove(elementInfo);
 
-    if (![_interactionSheet presentSheet:[self _shouldPresentAtTouchLocationForElementRect:positionInformation.bounds] ? WKActionSheetPresentAtTouchLocation : WKActionSheetPresentAtClosestIndicatorRect])
+    if (![_interactionSheet presentSheet:[self _shouldPresentAtTouchLocationForElementRect:_positionInformation->bounds] ? WKActionSheetPresentAtTouchLocation : WKActionSheetPresentAtClosestIndicatorRect])
         [self cleanupSheet];
 }
 
@@ -537,8 +550,10 @@ static const CGFloat presentationElementRectPadding = 15;
     if (!delegate)
         return;
 
-    const WebKit::InteractionInformationAtPosition& positionInformation = [delegate positionInformationForActionSheetAssistant:self];
-    NSURL *targetURL = [NSURL _web_URLWithWTFString:positionInformation.url];
+    if (![self synchronouslyRetrievePositionInformation])
+        return;
+
+    NSURL *targetURL = [NSURL _web_URLWithWTFString:_positionInformation->url];
     if (!targetURL)
         return;
 
@@ -554,17 +569,17 @@ static const CGFloat presentationElementRectPadding = 15;
         context = [delegate dataDetectionContextForActionSheetAssistant:self];
     if ([delegate respondsToSelector:@selector(selectedTextForActionSheetAssistant:)])
         textAtSelection = [delegate selectedTextForActionSheetAssistant:self];
-    if (!positionInformation.textBefore.isEmpty() || !positionInformation.textAfter.isEmpty()) {
+    if (!_positionInformation->textBefore.isEmpty() || !_positionInformation->textAfter.isEmpty()) {
         extendedContext = adoptNS([@{
-            getkDataDetectorsLeadingText() : positionInformation.textBefore,
-            getkDataDetectorsTrailingText() : positionInformation.textAfter,
+            getkDataDetectorsLeadingText() : _positionInformation->textBefore,
+            getkDataDetectorsTrailingText() : _positionInformation->textAfter,
         } mutableCopy]);
         
         if (context)
             [extendedContext addEntriesFromDictionary:context];
         context = extendedContext.get();
     }
-    NSArray *dataDetectorsActions = [controller actionsForURL:targetURL identifier:positionInformation.dataDetectorIdentifier selectedText:textAtSelection results:positionInformation.dataDetectorResults.get() context:context];
+    NSArray *dataDetectorsActions = [controller actionsForURL:targetURL identifier:_positionInformation->dataDetectorIdentifier selectedText:textAtSelection results:_positionInformation->dataDetectorResults.get() context:context];
     if ([dataDetectorsActions count] == 0)
         return;
 
@@ -604,6 +619,7 @@ static const CGFloat presentationElementRectPadding = 15;
     [_interactionSheet setSheetDelegate:nil];
     _interactionSheet = nil;
     _elementInfo = nil;
+    _positionInformation = std::nullopt;
     _needsLinkIndicator = NO;
     _isPresentingDDUserInterface = NO;
     _hasPendingActionSheet = NO;
index 23cea7f..1134892 100644 (file)
@@ -324,7 +324,7 @@ FOR_EACH_WKCONTENTVIEW_ACTION(DECLARE_WKCONTENTVIEW_ACTION_FOR_WEB_VIEW)
 
 @property (nonatomic, readonly) WebKit::InteractionInformationAtPosition currentPositionInformation;
 - (void)doAfterPositionInformationUpdate:(void (^)(WebKit::InteractionInformationAtPosition))action forRequest:(WebKit::InteractionInformationRequest)request;
-- (void)ensurePositionInformationIsUpToDate:(WebKit::InteractionInformationRequest)request;
+- (BOOL)ensurePositionInformationIsUpToDate:(WebKit::InteractionInformationRequest)request;
 
 #if ENABLE(DATA_INTERACTION)
 - (void)_didPerformDataInteractionControllerOperation:(BOOL)handled;
index 34df602..ca31324 100644 (file)
@@ -1318,21 +1318,25 @@ static inline bool isSamePair(UIGestureRecognizer *a, UIGestureRecognizer *b, UI
         [self requestAsynchronousPositionInformationUpdate:request];
 }
 
-- (void)ensurePositionInformationIsUpToDate:(WebKit::InteractionInformationRequest)request
+- (BOOL)ensurePositionInformationIsUpToDate:(WebKit::InteractionInformationRequest)request
 {
     if ([self _currentPositionInformationIsValidForRequest:request])
-        return;
+        return YES;
+
+    auto* connection = _page->process().connection();
+    if (!connection)
+        return NO;
 
     if ([self _hasValidOutstandingPositionInformationRequest:request]) {
-        if (auto* connection = _page->process().connection()) {
-            connection->waitForAndDispatchImmediately<Messages::WebPageProxy::DidReceivePositionInformation>(_page->pageID(), Seconds::infinity());
-            return;
-        }
+        return connection->waitForAndDispatchImmediately<Messages::WebPageProxy::DidReceivePositionInformation>(_page->pageID(), Seconds::infinity(), IPC::WaitForOption::InterruptWaitingIfSyncMessageArrives);
     }
 
-    _page->getPositionInformation(request, _positionInformation);
+    _page->process().sendSync(Messages::WebPage::GetPositionInformation(request), Messages::WebPage::GetPositionInformation::Reply(_positionInformation), _page->pageID());
+
     _hasValidPositionInformation = YES;
     [self _invokeAndRemovePendingHandlersValidForCurrentPositionInformation];
+
+    return YES;
 }
 
 - (void)requestAsynchronousPositionInformationUpdate:(WebKit::InteractionInformationRequest)request
@@ -1420,7 +1424,8 @@ static inline bool isSamePair(UIGestureRecognizer *a, UIGestureRecognizer *b, UI
         if (_textSelectionAssistant) {
             // Request information about the position with sync message.
             // If the assisted node is the same, prevent the gesture.
-            [self ensurePositionInformationIsUpToDate:InteractionInformationRequest(roundedIntPoint(point))];
+            if (![self ensurePositionInformationIsUpToDate:InteractionInformationRequest(roundedIntPoint(point))])
+                return NO;
             if (_positionInformation.nodeAtPositionIsAssistedNode)
                 return NO;
         }
@@ -1458,7 +1463,8 @@ static inline bool isSamePair(UIGestureRecognizer *a, UIGestureRecognizer *b, UI
         // to gestureRecognizerShouldBegin.
         // Force a sync call if not ready yet.
         InteractionInformationRequest request(roundedIntPoint(point));
-        [self ensurePositionInformationIsUpToDate:request];
+        if (![self ensurePositionInformationIsUpToDate:request])
+            return NO;
 
         if (_textSelectionAssistant) {
             // Prevent the gesture if it is the same node.
@@ -1499,7 +1505,8 @@ static inline bool isSamePair(UIGestureRecognizer *a, UIGestureRecognizer *b, UI
         return NO;
 
     InteractionInformationRequest request(roundedIntPoint(point));
-    [self ensurePositionInformationIsUpToDate:request];
+    if (![self ensurePositionInformationIsUpToDate:request])
+        return NO;
 
 #if ENABLE(DATA_INTERACTION)
     if (_positionInformation.hasSelectionAtPosition) {
@@ -1515,7 +1522,8 @@ static inline bool isSamePair(UIGestureRecognizer *a, UIGestureRecognizer *b, UI
 - (BOOL)pointIsNearMarkedText:(CGPoint)point
 {
     InteractionInformationRequest request(roundedIntPoint(point));
-    [self ensurePositionInformationIsUpToDate:request];
+    if (![self ensurePositionInformationIsUpToDate:request])
+        return NO;
     return _positionInformation.isNearMarkedText;
 }
 
@@ -1528,7 +1536,8 @@ static inline bool isSamePair(UIGestureRecognizer *a, UIGestureRecognizer *b, UI
 - (BOOL)textInteractionGesture:(UIWKGestureType)gesture shouldBeginAtPoint:(CGPoint)point
 {
     InteractionInformationRequest request(roundedIntPoint(point));
-    [self ensurePositionInformationIsUpToDate:request];
+    if (![self ensurePositionInformationIsUpToDate:request])
+        return NO;
 
 #if ENABLE(DATA_INTERACTION)
     if (_positionInformation.hasSelectionAtPosition && gesture == UIWKGestureLoupe) {
@@ -4059,13 +4068,13 @@ static bool isAssistableInputType(InputType type)
 
 #pragma mark - Implementation of WKActionSheetAssistantDelegate.
 
-- (const WebKit::InteractionInformationAtPosition&)positionInformationForActionSheetAssistant:(WKActionSheetAssistant *)assistant
+- (std::optional<WebKit::InteractionInformationAtPosition>)positionInformationForActionSheetAssistant:(WKActionSheetAssistant *)assistant
 {
-    // FIXME: This should be more asynchronous, since we control the presentation of the action sheet.
     InteractionInformationRequest request(_positionInformation.request.point);
     request.includeSnapshot = true;
     request.includeLinkIndicator = assistant.needsLinkIndicator;
-    [self ensurePositionInformationIsUpToDate:request];
+    if (![self ensurePositionInformationIsUpToDate:request])
+        return std::nullopt;
 
     return _positionInformation;
 }
@@ -4857,7 +4866,8 @@ static BOOL positionInformationMayStartDataInteraction(const InteractionInformat
     InteractionInformationRequest request(roundedIntPoint(position));
     request.includeSnapshot = true;
     request.includeLinkIndicator = true;
-    [self ensurePositionInformationIsUpToDate:request];
+    if (![self ensurePositionInformationIsUpToDate:request])
+        return NO;
     if (!_positionInformation.isLink && !_positionInformation.isImage && !_positionInformation.isAttachment)
         return NO;
 
index d556fae..db8c7d8 100644 (file)
@@ -706,7 +706,7 @@ static NSStringCompareOptions stringCompareOptions(_WKFindOptions options)
 
 #pragma mark WKActionSheetAssistantDelegate
 
-- (const WebKit::InteractionInformationAtPosition&)positionInformationForActionSheetAssistant:(WKActionSheetAssistant *)assistant
+- (std::optional<WebKit::InteractionInformationAtPosition>)positionInformationForActionSheetAssistant:(WKActionSheetAssistant *)assistant
 {
     return _positionInformation;
 }
index 443a48b..78f6a8f 100644 (file)
@@ -638,11 +638,6 @@ void WebPageProxy::didReceivePositionInformation(const InteractionInformationAtP
     m_pageClient.positionInformationDidChange(info);
 }
 
-void WebPageProxy::getPositionInformation(const InteractionInformationRequest& request, InteractionInformationAtPosition& info)
-{
-    m_process->sendSync(Messages::WebPage::GetPositionInformation(request), Messages::WebPage::GetPositionInformation::Reply(info), m_pageID);
-}
-
 void WebPageProxy::requestPositionInformation(const InteractionInformationRequest& request)
 {
     m_process->send(Messages::WebPage::RequestPositionInformation(request), m_pageID);