Modified: trunk/Source/WebCore/ChangeLog (216256 => 216257)
--- trunk/Source/WebCore/ChangeLog 2017-05-05 19:16:03 UTC (rev 216256)
+++ trunk/Source/WebCore/ChangeLog 2017-05-05 19:20:32 UTC (rev 216257)
@@ -1,3 +1,26 @@
+2017-05-05 Wenson Hsieh <[email protected]>
+
+ Add SPI to WebItemProviderPasteboard to synchronously load data with a given timeout
+ https://bugs.webkit.org/show_bug.cgi?id=171725
+ <rdar://problem/32014052>
+
+ Reviewed by Beth Dakin.
+
+ Adds a synchronousTimeout: argument to doAfterLoadingProvidedContentIntoFileURLs:. If a positive timeout
+ interval is specified by the client, then we will block the main thread for at most that amount of time after
+ beginning to load from the item providers.
+
+ To do this, we introduce another `dispatch_group_t` in parallel to the `fileLoadingGroup` that is entered and
+ left in the same places. However, instead of attaching a handler block, we simply perform a synchronous wait for
+ either the time limit to be reached, or the item providers to finish loading.
+
+ No new tests -- no change in behavior yet.
+
+ * platform/ios/WebItemProviderPasteboard.h:
+ * platform/ios/WebItemProviderPasteboard.mm:
+ (-[WebItemProviderPasteboard doAfterLoadingProvidedContentIntoFileURLs:]):
+ (-[WebItemProviderPasteboard doAfterLoadingProvidedContentIntoFileURLs:synchronousTimeout:]):
+
2017-05-05 Chris Dumez <[email protected]>
Clean up Attr.idl
Modified: trunk/Source/WebCore/platform/ios/WebItemProviderPasteboard.h (216256 => 216257)
--- trunk/Source/WebCore/platform/ios/WebItemProviderPasteboard.h 2017-05-05 19:16:03 UTC (rev 216256)
+++ trunk/Source/WebCore/platform/ios/WebItemProviderPasteboard.h 2017-05-05 19:20:32 UTC (rev 216257)
@@ -47,10 +47,11 @@
@end
/*! A WebItemProviderRegistrationInfoList represents a series of registration calls used to set up a
- @discussion single item provider. The order of items specified in the list (lowest indices first) is
- the order in which objects or data are registered to the item provider, and therefore indicates the
- relative fidelity of each item. Private UTI types, such as those vended through the injected editing
- bundle SPI, are considered to be higher fidelity than the other default types.
+ single item provider.
+ @discussion The order of items specified in the list (lowest indices first) is the order in which
+ objects or data are registered to the item provider, and therefore indicates the relative fidelity
+ of each item. Private UTI types, such as those vended through the injected editing bundle SPI, are
+ considered to be higher fidelity than the other default types.
*/
WEBCORE_EXPORT @interface WebItemProviderRegistrationInfoList : NSObject
@@ -88,6 +89,7 @@
// The given completion block is always dispatched on the main thread.
- (void)doAfterLoadingProvidedContentIntoFileURLs:(WebItemProviderFileLoadBlock)action;
+- (void)doAfterLoadingProvidedContentIntoFileURLs:(WebItemProviderFileLoadBlock)action synchronousTimeout:(NSTimeInterval)synchronousTimeout;
@end
Modified: trunk/Source/WebCore/platform/ios/WebItemProviderPasteboard.mm (216256 => 216257)
--- trunk/Source/WebCore/platform/ios/WebItemProviderPasteboard.mm 2017-05-05 19:16:03 UTC (rev 216256)
+++ trunk/Source/WebCore/platform/ios/WebItemProviderPasteboard.mm 2017-05-05 19:20:32 UTC (rev 216257)
@@ -422,6 +422,11 @@
- (void)doAfterLoadingProvidedContentIntoFileURLs:(WebItemProviderFileLoadBlock)action
{
+ [self doAfterLoadingProvidedContentIntoFileURLs:action synchronousTimeout:0];
+}
+
+- (void)doAfterLoadingProvidedContentIntoFileURLs:(WebItemProviderFileLoadBlock)action synchronousTimeout:(NSTimeInterval)synchronousTimeout
+{
auto changeCountBeforeLoading = _changeCount;
auto typeToFileURLMaps = adoptNS([[NSMutableArray alloc] initWithCapacity:[_itemProviders count]]);
@@ -464,6 +469,8 @@
return;
}
+ auto setFileURLsLock = adoptNS([[NSLock alloc] init]);
+ auto synchronousFileLoadingGroup = adoptOSObject(dispatch_group_create());
auto fileLoadingGroup = adoptOSObject(dispatch_group_create());
for (NSUInteger index = 0; index < [itemProvidersWithFiles count]; ++index) {
RetainPtr<UIItemProvider> itemProvider = [itemProvidersWithFiles objectAtIndex:index];
@@ -471,20 +478,19 @@
NSUInteger indexInItemProviderArray = [[indicesOfItemProvidersWithFiles objectAtIndex:index] unsignedIntegerValue];
RetainPtr<NSString> suggestedName = [itemProvider suggestedName];
dispatch_group_enter(fileLoadingGroup.get());
- [itemProvider loadFileRepresentationForTypeIdentifier:typeIdentifier.get() completionHandler:[indexInItemProviderArray, suggestedName, typeIdentifier, typeToFileURLMaps, fileLoadingGroup] (NSURL *url, NSError *error) {
+ dispatch_group_enter(synchronousFileLoadingGroup.get());
+ [itemProvider loadFileRepresentationForTypeIdentifier:typeIdentifier.get() completionHandler:[synchronousFileLoadingGroup, setFileURLsLock, indexInItemProviderArray, suggestedName, typeIdentifier, typeToFileURLMaps, fileLoadingGroup] (NSURL *url, NSError *error) {
// After executing this completion block, UIKit removes the file at the given URL. However, we need this data to persist longer for the web content process.
// To address this, we hard link the given URL to a new temporary file in the temporary directory. This follows the same flow as regular file upload, in
// WKFileUploadPanel.mm. The temporary files are cleaned up by the system at a later time.
- RetainPtr<NSURL> destinationURL = temporaryFileURLForDataInteractionContent(url.pathExtension, suggestedName.get());
- if (!destinationURL || error || ![[NSFileManager defaultManager] linkItemAtURL:url toURL:destinationURL.get() error:nil]) {
- dispatch_group_leave(fileLoadingGroup.get());
- return;
+ RetainPtr<NSURL> destinationURL = temporaryFileURLForDataInteractionContent(url.pathExtension, suggestedName.get() ?: url.lastPathComponent);
+ if (destinationURL && !error && [[NSFileManager defaultManager] linkItemAtURL:url toURL:destinationURL.get() error:nil]) {
+ [setFileURLsLock lock];
+ [typeToFileURLMaps setObject:[NSDictionary dictionaryWithObject:destinationURL.get() forKey:typeIdentifier.get()] atIndexedSubscript:indexInItemProviderArray];
+ [setFileURLsLock unlock];
}
-
- dispatch_async(dispatch_get_main_queue(), [indexInItemProviderArray, typeIdentifier, destinationURL, typeToFileURLMaps, fileLoadingGroup] {
- [typeToFileURLMaps setObject:[NSDictionary dictionaryWithObject:destinationURL.get() forKey:typeIdentifier.get()] atIndexedSubscript:indexInItemProviderArray];
- dispatch_group_leave(fileLoadingGroup.get());
- });
+ dispatch_group_leave(fileLoadingGroup.get());
+ dispatch_group_leave(synchronousFileLoadingGroup.get());
}];
}
@@ -495,6 +501,9 @@
completionBlock([retainedSelf fileURLsForDataInteraction]);
});
+
+ if (synchronousTimeout > 0)
+ dispatch_group_wait(synchronousFileLoadingGroup.get(), dispatch_time(DISPATCH_TIME_NOW, synchronousTimeout * NSEC_PER_SEC));
}
- (WebItemProviderRegistrationInfoList *)registrationInfoAtIndex:(NSUInteger)index