Changeset 215573 in webkit
- Timestamp:
- Apr 20, 2017 12:59:46 PM (7 years ago)
- Location:
- trunk
- Files:
-
- 4 added
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebKit2/ChangeLog
r215569 r215573 1 2017-04-20 Wenson Hsieh <wenson_hsieh@apple.com> 2 3 [WK2] -[WKContentView doAfterPositionInformationUpdate:atPosition:] should be robust against synchronous reentrancy 4 https://bugs.webkit.org/show_bug.cgi?id=170922 5 <rdar://problem/31634990> 6 7 Reviewed by Tim Horton. 8 9 Refactors part of the asynchronous position information mechanism introduced in 10 <https://trac.webkit.org/changeset/215171>, and introduces infrastructure for unit testing UI-side position 11 information requests. 12 13 _invokeAndRemovePendingHandlersValidForCurrentPositionInformation is a helper method on WKContentView 14 responsible for invoking queued position information handlers after receiving a position information response 15 from the web process. Previously, this method would iterate over the list of pending callbacks and invoke all 16 callbacks whose requests are satisfied by the incoming position information update, saving the indices of these 17 handled callbacks in the process. At the end, it would then remove callbacks at these indices from the array of 18 pending callbacks. This is problematic when a synchronous position update (via 19 ensurePositionInformationIsUpToDate:) is triggered from within one of these callbacks, since 20 _invokeAndRemovePendingHandlersValidForCurrentPositionInformation will be called from within itself, and then we 21 will attempt to remove a callback at the same index twice. 22 23 To fix this, we change the array of pending position information handlers to be an array of optionals instead. 24 When invoking and removing pending handlers after a position information response arrives, we now mark callbacks 25 as handled by setting them to std::nullopt. Then, when the top-level invocation to 26 _invokeAndRemovePendingHandlersValidForCurrentPositionInformation is finished, we remove all marked handlers 27 from the pending vector. 28 29 Covered by 6 new unit tests: 30 - PositionInformationTests.FindDraggableLinkAtPosition 31 - PositionInformationTests.RequestDraggableLinkAtPosition 32 - PositionInformationTests.FindDraggableLinkAtDifferentPositionWithinRequestBlock 33 - PositionInformationTests.FindDraggableLinkAtSamePositionWithinRequestBlock 34 - PositionInformationTests.RequestDraggableLinkAtSamePositionWithinRequestBlock 35 - PositionInformationTests.RequestDraggableLinkAtDifferentPositionWithinRequestBlock 36 37 * UIProcess/API/Cocoa/WKWebView.mm: 38 (-[WKWebView draggableElementAtPosition:]): 39 (-[WKWebView requestDraggableElementAtPosition:completionBlock:]): 40 41 Uses WKContentView's position information request helpers to search for draggable elements on the page. There 42 are both synchronous and asynchronous versions of this, both of which retrieve a _WKDraggableElementInfo. 43 44 * UIProcess/API/Cocoa/WKWebViewPrivate.h: 45 * UIProcess/API/Cocoa/_WKDraggableElementInfo.h: Added. 46 * UIProcess/API/Cocoa/_WKDraggableElementInfo.mm: Added. 47 48 Exposes what elements are draggable at a given position as SPI (only for use in testing code, at the moment). 49 50 (-[_WKDraggableElementInfo initWithInteractionInformationAtPosition:]): 51 (-[_WKDraggableElementInfo copyWithZone:]): 52 * UIProcess/API/Cocoa/_WKDraggableElementInfoInternal.h: Added. 53 * UIProcess/ios/WKContentViewInteraction.h: 54 * UIProcess/ios/WKContentViewInteraction.mm: 55 (-[WKContentView currentPositionInformation]): 56 (-[WKContentView doAfterPositionInformationUpdate:forRequest:]): 57 (-[WKContentView _invokeAndRemovePendingHandlersValidForCurrentPositionInformation]): 58 * WebKit2.xcodeproj/project.pbxproj: 59 1 60 2017-04-20 Anders Carlsson <andersca@apple.com> 2 61 -
trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm
r215512 r215573 37 37 #import "FullscreenClient.h" 38 38 #import "IconLoadingDelegate.h" 39 #import "InteractionInformationAtPosition.h" 40 #import "InteractionInformationRequest.h" 39 41 #import "LegacySessionStateCoding.h" 40 42 #import "Logging.h" … … 84 86 #import "WebViewImpl.h" 85 87 #import "_WKDiagnosticLoggingDelegate.h" 88 #import "_WKDraggableElementInfoInternal.h" 86 89 #import "_WKFindDelegate.h" 87 90 #import "_WKFrameHandleInternal.h" … … 5089 5092 5090 5093 #if PLATFORM(IOS) 5094 - (_WKDraggableElementInfo *)draggableElementAtPosition:(CGPoint)position 5095 { 5096 [_contentView ensurePositionInformationIsUpToDate:WebKit::InteractionInformationRequest(WebCore::roundedIntPoint(position))]; 5097 return [_WKDraggableElementInfo infoWithInteractionInformationAtPosition:[_contentView currentPositionInformation]]; 5098 } 5099 5100 - (void)requestDraggableElementAtPosition:(CGPoint)position completionBlock:(void (^)(_WKDraggableElementInfo *))block 5101 { 5102 [_contentView doAfterPositionInformationUpdate:[capturedBlock = makeBlockPtr(block)] (WebKit::InteractionInformationAtPosition information) { 5103 capturedBlock([_WKDraggableElementInfo infoWithInteractionInformationAtPosition:information]); 5104 } forRequest:WebKit::InteractionInformationRequest(WebCore::roundedIntPoint(position))]; 5105 } 5091 5106 5092 5107 - (CGRect)_contentVisibleRect -
trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebViewPrivate.h
r215502 r215573 68 68 69 69 @class WKBrowsingContextHandle; 70 @class _WKDraggableElementInfo; 70 71 @class _WKFrameHandle; 71 72 @class _WKHitTestResult; … … 336 337 - (NSArray *)_simulatedItemsForSession:(id)session WK_API_AVAILABLE(ios(WK_IOS_TBA)); 337 338 - (void)_simulatePrepareForDataInteractionSession:(id)session completion:(dispatch_block_t)completion WK_API_AVAILABLE(ios(WK_IOS_TBA)); 339 340 - (_WKDraggableElementInfo *)draggableElementAtPosition:(CGPoint)position; 341 - (void)requestDraggableElementAtPosition:(CGPoint)position completionBlock:(void (^)(_WKDraggableElementInfo *))block; 338 342 339 343 #endif // TARGET_OS_IPHONE -
trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.h
r215502 r215573 88 88 89 89 typedef BlockPtr<void(WebKit::InteractionInformationAtPosition)> InteractionInformationCallback; 90 typedef std::pair<WebKit::InteractionInformationRequest, InteractionInformationCallback> InteractionInformationRequestAndCallback; 90 91 91 92 namespace WebKit { … … 175 176 176 177 std::optional<WebKit::InteractionInformationRequest> _outstandingPositionInformationRequest; 177 Vector<std::pair<WebKit::InteractionInformationRequest, InteractionInformationCallback>> _pendingPositionInformationHandlers; 178 179 uint64_t _positionInformationCallbackDepth; 180 Vector<std::optional<InteractionInformationRequestAndCallback>> _pendingPositionInformationHandlers; 178 181 179 182 std::unique_ptr<WebKit::InputViewUpdateDeferrer> _inputViewUpdateDeferrer; … … 288 291 - (void)_accessibilityRetrieveRectsAtSelectionOffset:(NSInteger)offset withText:(NSString *)text; 289 292 293 @property (nonatomic, readonly) WebKit::InteractionInformationAtPosition currentPositionInformation; 294 - (void)doAfterPositionInformationUpdate:(void (^)(WebKit::InteractionInformationAtPosition))action forRequest:(WebKit::InteractionInformationRequest)request; 295 - (void)ensurePositionInformationIsUpToDate:(WebKit::InteractionInformationRequest)request; 296 290 297 #if ENABLE(DATA_INTERACTION) 291 298 - (void)_didPerformDataInteractionControllerOperation; -
trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm
r215484 r215573 58 58 #import "WebProcessProxy.h" 59 59 #import "_WKActivatedElementInfoInternal.h" 60 #import "_WKDraggableElementInfoInternal.h" 60 61 #import "_WKElementAction.h" 61 62 #import "_WKFocusedElementInfo.h" … … 1307 1308 } 1308 1309 1310 - (InteractionInformationAtPosition)currentPositionInformation 1311 { 1312 return _positionInformation; 1313 } 1314 1309 1315 - (void)doAfterPositionInformationUpdate:(void (^)(InteractionInformationAtPosition))action forRequest:(InteractionInformationRequest)request 1310 1316 { … … 1315 1321 } 1316 1322 1317 _pendingPositionInformationHandlers.append( { request, action });1323 _pendingPositionInformationHandlers.append(InteractionInformationRequestAndCallback(request, action)); 1318 1324 1319 1325 if (![self _hasValidOutstandingPositionInformationRequest:request]) … … 1362 1368 ASSERT(_hasValidPositionInformation); 1363 1369 1364 Vector<size_t> indicesOfHandledRequests; 1370 ++_positionInformationCallbackDepth; 1371 auto updatedPositionInformation = _positionInformation; 1372 1365 1373 for (size_t index = 0; index < _pendingPositionInformationHandlers.size(); ++index) { 1366 auto &requestAndHandler = _pendingPositionInformationHandlers[index];1367 if (! [self _currentPositionInformationIsValidForRequest:requestAndHandler.first])1374 auto requestAndHandler = _pendingPositionInformationHandlers[index]; 1375 if (!requestAndHandler) 1368 1376 continue; 1369 1377 1370 if (requestAndHandler.second) 1371 requestAndHandler.second(_positionInformation); 1372 1373 indicesOfHandledRequests.append(index); 1374 } 1375 1376 while (indicesOfHandledRequests.size()) 1377 _pendingPositionInformationHandlers.remove(indicesOfHandledRequests.takeLast()); 1378 if (![self _currentPositionInformationIsValidForRequest:requestAndHandler->first]) 1379 continue; 1380 1381 _pendingPositionInformationHandlers[index] = std::nullopt; 1382 1383 if (requestAndHandler->second) 1384 requestAndHandler->second(updatedPositionInformation); 1385 } 1386 1387 if (--_positionInformationCallbackDepth) 1388 return; 1389 1390 for (int index = _pendingPositionInformationHandlers.size() - 1; index >= 0; --index) { 1391 if (!_pendingPositionInformationHandlers[index]) 1392 _pendingPositionInformationHandlers.remove(index); 1393 } 1378 1394 } 1379 1395 -
trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj
r215521 r215573 2011 2011 F44DFEB21E9E752F0038D196 /* WebIconUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = F44DFEB01E9E752F0038D196 /* WebIconUtilities.h */; }; 2012 2012 F44DFEB31E9E752F0038D196 /* WebIconUtilities.mm in Sources */ = {isa = PBXBuildFile; fileRef = F44DFEB11E9E752F0038D196 /* WebIconUtilities.mm */; }; 2013 F4E8CB911EA6AB5B00E31198 /* _WKDraggableElementInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = F4E8CB8E1EA6AB5B00E31198 /* _WKDraggableElementInfo.h */; settings = {ATTRIBUTES = (Private, ); }; }; 2014 F4E8CB921EA6AB5B00E31198 /* _WKDraggableElementInfo.mm in Sources */ = {isa = PBXBuildFile; fileRef = F4E8CB8F1EA6AB5B00E31198 /* _WKDraggableElementInfo.mm */; }; 2015 F4E8CB931EA6AB5B00E31198 /* _WKDraggableElementInfoInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = F4E8CB901EA6AB5B00E31198 /* _WKDraggableElementInfoInternal.h */; }; 2013 2016 F6113E25126CE1820057D0A7 /* APIUserContentURLPattern.h in Headers */ = {isa = PBXBuildFile; fileRef = F6113E24126CE1820057D0A7 /* APIUserContentURLPattern.h */; }; 2014 2017 F6113E28126CE19B0057D0A7 /* WKUserContentURLPattern.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F6113E26126CE19B0057D0A7 /* WKUserContentURLPattern.cpp */; }; … … 4346 4349 F44DFEB01E9E752F0038D196 /* WebIconUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebIconUtilities.h; path = ios/WebIconUtilities.h; sourceTree = "<group>"; }; 4347 4350 F44DFEB11E9E752F0038D196 /* WebIconUtilities.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = WebIconUtilities.mm; path = ios/WebIconUtilities.mm; sourceTree = "<group>"; }; 4351 F4E8CB8E1EA6AB5B00E31198 /* _WKDraggableElementInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _WKDraggableElementInfo.h; sourceTree = "<group>"; }; 4352 F4E8CB8F1EA6AB5B00E31198 /* _WKDraggableElementInfo.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = _WKDraggableElementInfo.mm; sourceTree = "<group>"; }; 4353 F4E8CB901EA6AB5B00E31198 /* _WKDraggableElementInfoInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _WKDraggableElementInfoInternal.h; sourceTree = "<group>"; }; 4348 4354 F6113E24126CE1820057D0A7 /* APIUserContentURLPattern.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = APIUserContentURLPattern.h; sourceTree = "<group>"; }; 4349 4355 F6113E26126CE19B0057D0A7 /* WKUserContentURLPattern.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WKUserContentURLPattern.cpp; sourceTree = "<group>"; }; … … 5529 5535 A1A4FE6018DD54A400B5EA8A /* _WKDownloadDelegate.h */, 5530 5536 A1A4FE5918DCE9FA00B5EA8A /* _WKDownloadInternal.h */, 5537 F4E8CB8E1EA6AB5B00E31198 /* _WKDraggableElementInfo.h */, 5538 F4E8CB8F1EA6AB5B00E31198 /* _WKDraggableElementInfo.mm */, 5539 F4E8CB901EA6AB5B00E31198 /* _WKDraggableElementInfoInternal.h */, 5531 5540 379A873818BBFE0F00588AF2 /* _WKElementAction.h */, 5532 5541 379A873718BBFE0F00588AF2 /* _WKElementAction.mm */, … … 8055 8064 sourceTree = "<group>"; 8056 8065 }; 8066 F4D7BCCA1EA494FA00C421D3 /* Recovered References */ = { 8067 isa = PBXGroup; 8068 children = ( 8069 C58CDF281887548B00871536 /* InteractionInformationAtPosition.h */, 8070 ); 8071 name = "Recovered References"; 8072 sourceTree = "<group>"; 8073 }; 8057 8074 F638955A133BF57D008941D5 /* mac */ = { 8058 8075 isa = PBXGroup; … … 8212 8229 2D8786241BDB58FF00D02ABB /* APIUserStyleSheet.h in Headers */, 8213 8230 C5E1AFED16B21017006CC1F2 /* APIWebArchive.h in Headers */, 8231 F4E8CB931EA6AB5B00E31198 /* _WKDraggableElementInfoInternal.h in Headers */, 8214 8232 C5E1AFEF16B21029006CC1F2 /* APIWebArchiveResource.h in Headers */, 8215 8233 1AE286841C7F93860069AC4F /* APIWebsiteDataRecord.h in Headers */, … … 8884 8902 1A4D664C18A3030E00D82E21 /* WKFrameInfo.h in Headers */, 8885 8903 2DF9EEE81A78245500B6CFBE /* WKFrameInfoInternal.h in Headers */, 8904 F4E8CB911EA6AB5B00E31198 /* _WKDraggableElementInfo.h in Headers */, 8886 8905 1A6FA21E1BD0435B00AAA650 /* WKFrameInfoPrivate.h in Headers */, 8887 8906 2D3A65E71A7C3AA700CAC637 /* WKFrameInfoRef.h in Headers */, … … 10525 10544 93A253F51C92413200F9F68D /* WKPreviewActionItemIdentifiers.mm in Sources */, 10526 10545 9395E68C1BF2C35200F49BCE /* WKPreviewElementInfo.mm in Sources */, 10546 F4E8CB921EA6AB5B00E31198 /* _WKDraggableElementInfo.mm in Sources */, 10527 10547 0FCB4E6718BBE3D9000FCFC9 /* WKPrintingView.mm in Sources */, 10528 10548 BCBAACEC145225E30053F82F /* WKProcessGroup.mm in Sources */, -
trunk/Tools/ChangeLog
r215556 r215573 1 2017-04-20 Wenson Hsieh <wenson_hsieh@apple.com> 2 3 [WK2] -[WKContentView doAfterPositionInformationUpdate:atPosition:] should be robust against synchronous reentrancy 4 https://bugs.webkit.org/show_bug.cgi?id=170922 5 <rdar://problem/31634990> 6 7 Reviewed by Tim Horton. 8 9 Adds six new unit tests for retrieving interaction information at a given position in the UI process. See 10 WebKit2 ChangeLog for more details. 11 12 * TestWebKitAPI/Tests/ios/PositionInformationTests.mm: 13 (-[_WKDraggableElementInfo expectToBeLink:image:atPoint:]): 14 (TestWebKitAPI::TEST): 15 (TestWebKitAPI::expectCGPointsToBeEqual): Deleted. 16 1 17 2017-04-20 Xan Lopez <xlopez@igalia.com> 2 18 -
trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
r215536 r215573 599 599 F4D4F3B61E4E2BCB00BB2767 /* DataInteractionSimulator.mm in Sources */ = {isa = PBXBuildFile; fileRef = F4D4F3B41E4E2BCB00BB2767 /* DataInteractionSimulator.mm */; }; 600 600 F4D4F3B91E4E36E400BB2767 /* DataInteractionTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = F4D4F3B71E4E36E400BB2767 /* DataInteractionTests.mm */; }; 601 F4D7BCD81EA5789800C421D3 /* PositionInformationTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = F4D7BCD61EA574DD00C421D3 /* PositionInformationTests.mm */; }; 601 602 F4DEF6ED1E9B4DB60048EF61 /* image-in-link-and-input.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F4DEF6EC1E9B4D950048EF61 /* image-in-link-and-input.html */; }; 602 603 F4F137921D9B683E002BEC57 /* large-video-test-now-playing.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F4F137911D9B6832002BEC57 /* large-video-test-now-playing.html */; }; … … 1484 1485 F4D4F3B51E4E2BCB00BB2767 /* DataInteractionSimulator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DataInteractionSimulator.h; sourceTree = "<group>"; }; 1485 1486 F4D4F3B71E4E36E400BB2767 /* DataInteractionTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DataInteractionTests.mm; sourceTree = "<group>"; }; 1487 F4D7BCD61EA574DD00C421D3 /* PositionInformationTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = PositionInformationTests.mm; sourceTree = "<group>"; }; 1486 1488 F4DEF6EC1E9B4D950048EF61 /* image-in-link-and-input.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "image-in-link-and-input.html"; sourceTree = "<group>"; }; 1487 1489 F4F137911D9B6832002BEC57 /* large-video-test-now-playing.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "large-video-test-now-playing.html"; sourceTree = "<group>"; }; … … 1814 1816 F4D4F3B71E4E36E400BB2767 /* DataInteractionTests.mm */, 1815 1817 7560917719259C59009EF06E /* MemoryCacheAddImageToCacheIOS.mm */, 1818 F4D7BCD61EA574DD00C421D3 /* PositionInformationTests.mm */, 1816 1819 ); 1817 1820 path = ios; … … 2919 2922 7CCE7EAF1A411A3800447C4C /* PlatformUtilities.cpp in Sources */, 2920 2923 0F139E781A423A6B00F590F5 /* PlatformUtilitiesCocoa.mm in Sources */, 2924 F4D7BCD81EA5789800C421D3 /* PositionInformationTests.mm in Sources */, 2921 2925 7CCE7EA61A411A0F00447C4C /* PlatformUtilitiesMac.mm in Sources */, 2922 2926 7CCE7EA71A411A1300447C4C /* PlatformWebViewMac.mm in Sources */,
Note: See TracChangeset
for help on using the changeset viewer.