WebItemProviderPasteboard should use -registerLoadHandlersToItemProvider: when creati...
authorwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 8 Feb 2017 01:47:31 +0000 (01:47 +0000)
committerwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 8 Feb 2017 01:47:31 +0000 (01:47 +0000)
https://bugs.webkit.org/show_bug.cgi?id=167918
<rdar://problem/30382347>

Reviewed by Tim Horton.

Adopts SPI in WebItemProviderPasteboard for object types that the platform knows how to serialize. Since we use
-createObjectOfClass: to initialize data when reading off of the pasteboard, we need to match the format that
objects conforming to UIItemProviderReading will expect. Thus, for all given objects that conform to
UIItemProviderWriting, we have them register themselves to the item provider.

We register other UTI types due to the fact that PlatformPasteboardIOS does not care about the specific
pasteboard used. This should not be necessary, however, since data written to the WebItemProviderPasteboard
should never need to be read by an actual UIPasteboard. This will be refactored in a future patch to add a
special type of WebItemProviderPasteboard-aware PlatformPasteboard.

Also fixes some reference counting issues in WebItemProviderPasteboard by changing the array of _itemProviders
to be a RetainPtr.

* platform/ios/WebItemProviderPasteboard.mm:
(-[WebItemProviderPasteboard init]):
(-[WebItemProviderPasteboard pasteboardTypes]):
(-[WebItemProviderPasteboard itemProviders]):
(-[WebItemProviderPasteboard setItemProviders:]):
(-[WebItemProviderPasteboard numberOfItems]):
(-[WebItemProviderPasteboard setItems:]):
(-[WebItemProviderPasteboard valuesForPasteboardType:inItemSet:]):
(-[WebItemProviderPasteboard itemProviderAtIndex:]):
(-[WebItemProviderPasteboard dealloc]): Deleted.

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

Source/WebCore/ChangeLog
Source/WebCore/platform/ios/WebItemProviderPasteboard.mm

index a20f2d9..0c4292c 100644 (file)
@@ -1,3 +1,35 @@
+2017-02-07  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        WebItemProviderPasteboard should use -registerLoadHandlersToItemProvider: when creating a new UIItemProvider
+        https://bugs.webkit.org/show_bug.cgi?id=167918
+        <rdar://problem/30382347>
+
+        Reviewed by Tim Horton.
+
+        Adopts SPI in WebItemProviderPasteboard for object types that the platform knows how to serialize. Since we use
+        -createObjectOfClass: to initialize data when reading off of the pasteboard, we need to match the format that
+        objects conforming to UIItemProviderReading will expect. Thus, for all given objects that conform to
+        UIItemProviderWriting, we have them register themselves to the item provider.
+
+        We register other UTI types due to the fact that PlatformPasteboardIOS does not care about the specific
+        pasteboard used. This should not be necessary, however, since data written to the WebItemProviderPasteboard
+        should never need to be read by an actual UIPasteboard. This will be refactored in a future patch to add a
+        special type of WebItemProviderPasteboard-aware PlatformPasteboard.
+
+        Also fixes some reference counting issues in WebItemProviderPasteboard by changing the array of _itemProviders
+        to be a RetainPtr.
+
+        * platform/ios/WebItemProviderPasteboard.mm:
+        (-[WebItemProviderPasteboard init]):
+        (-[WebItemProviderPasteboard pasteboardTypes]):
+        (-[WebItemProviderPasteboard itemProviders]):
+        (-[WebItemProviderPasteboard setItemProviders:]):
+        (-[WebItemProviderPasteboard numberOfItems]):
+        (-[WebItemProviderPasteboard setItems:]):
+        (-[WebItemProviderPasteboard valuesForPasteboardType:inItemSet:]):
+        (-[WebItemProviderPasteboard itemProviderAtIndex:]):
+        (-[WebItemProviderPasteboard dealloc]): Deleted.
+
 2017-02-06  Ryosuke Niwa  <rniwa@webkit.org>
 
         WebContent process repeatedly jetsams on BuzzFeed's Another Round page
index 8160120..c2cdeec 100644 (file)
@@ -34,6 +34,8 @@
 #import <MobileCoreServices/MobileCoreServices.h>
 #import <UIKit/UIColor.h>
 #import <UIKit/UIImage.h>
+#import <UIKit/UIItemProviderWriting.h>
+#import <wtf/RetainPtr.h>
 
 SOFT_LINK_FRAMEWORK(UIKit)
 SOFT_LINK_CLASS(UIKit, UIColor)
@@ -76,7 +78,9 @@ static BOOL isImageType(NSString *type)
 
 @end
 
-@implementation WebItemProviderPasteboard
+@implementation WebItemProviderPasteboard {
+    RetainPtr<NSArray> _itemProviders;
+}
 
 + (instancetype)sharedInstance
 {
@@ -91,56 +95,72 @@ static BOOL isImageType(NSString *type)
 - (instancetype)init
 {
     if (self = [super init]) {
-        _itemProviders = [[NSArray alloc] init];
+        _itemProviders = adoptNS([[NSArray alloc] init]);
         _changeCount = 0;
         _pendingOperationCount = 0;
     }
     return self;
 }
 
-- (void)dealloc
-{
-    [super dealloc];
-    [_itemProviders release];
-}
-
 - (NSArray<NSString *> *)pasteboardTypes
 {
     NSMutableSet<NSString *> *allTypes = [NSMutableSet set];
-    for (UIItemProvider *provider in _itemProviders)
+    for (UIItemProvider *provider in _itemProviders.get())
         [allTypes addObjectsFromArray:provider.registeredTypeIdentifiers];
     return allTypes.allObjects;
 }
 
+- (NSArray<UIItemProvider *> *)itemProviders
+{
+    return _itemProviders.get();
+}
+
 - (void)setItemProviders:(NSArray<UIItemProvider *> *)itemProviders
 {
     itemProviders = itemProviders ?: [NSArray array];
     if (_itemProviders == itemProviders || [_itemProviders isEqualToArray:itemProviders])
         return;
-    _itemProviders = [itemProviders copy];
+
+    _itemProviders = itemProviders;
     _changeCount++;
 }
 
 - (NSInteger)numberOfItems
 {
-    return _itemProviders.count;
+    return [_itemProviders count];
 }
 
 - (void)setItems:(NSArray *)items
 {
-    NSMutableArray *providers = [[NSMutableArray alloc] init];
+    NSMutableArray *providers = [NSMutableArray array];
     for (NSDictionary *item in items) {
         if (!item.count)
             continue;
-        UIItemProvider *itemProvider = [[getUIItemProviderClass() alloc] init];
-        for (NSString *typeIdentifier in item) {
+        RetainPtr<UIItemProvider> itemProvider = adoptNS([[getUIItemProviderClass() alloc] init]);
+        RetainPtr<NSMutableDictionary> itemRepresentationsCopy = adoptNS([item mutableCopy]);
+        // First, let the platform write all the default object types it can recognize, such as NSString and NSURL.
+        for (NSString *typeIdentifier in [itemRepresentationsCopy allKeys]) {
+            id representingObject = [itemRepresentationsCopy objectForKey:typeIdentifier];
+            if (![representingObject conformsToProtocol:@protocol(UIItemProviderWriting)])
+                continue;
+
+            id <UIItemProviderWriting> objectToWrite = (id <UIItemProviderWriting>)representingObject;
+            if (![objectToWrite.writableTypeIdentifiersForItemProvider containsObject:typeIdentifier])
+                continue;
+
+            [itemRepresentationsCopy removeObjectForKey:typeIdentifier];
+            [objectToWrite registerLoadHandlersToItemProvider:itemProvider.get()];
+        }
+
+        // Secondly, WebKit uses some custom type representations and/or type identifiers, so we need to write these as well.
+        for (NSString *typeIdentifier in itemRepresentationsCopy.get()) {
             [itemProvider registerDataRepresentationForTypeIdentifier:typeIdentifier options:nil loadHandler:^NSProgress *(UIItemProviderDataLoadCompletionBlock completionBlock)
             {
-                completionBlock(item[typeIdentifier], nil);
+                completionBlock([itemRepresentationsCopy objectForKey:typeIdentifier], nil);
                 return [NSProgress discreteProgressWithTotalUnitCount:100];
             }];
         }
-        [providers addObject:itemProvider];
+        [providers addObject:itemProvider.get()];
     }
     _changeCount++;
     _itemProviders = providers;
@@ -174,7 +194,7 @@ static BOOL isImageType(NSString *type)
         if (isColorType(pasteboardType) && [self _tryToCreateAndAppendObjectOfClass:[getUIColorClass() class] toArray:values usingProvider:provider])
             return;
 
-        if (isImageType(pasteboardType) && [self _tryToCreateAndAppendObjectOfClass:[NSString class] toArray:values usingProvider:provider])
+        if (isImageType(pasteboardType) && [self _tryToCreateAndAppendObjectOfClass:[getUIImageClass() class] toArray:values usingProvider:provider])
             return;
 
         if (isURLType(pasteboardType) && [self _tryToCreateAndAppendObjectOfClass:[NSURL class] toArray:values usingProvider:provider])
@@ -210,7 +230,7 @@ static BOOL isImageType(NSString *type)
 
 - (UIItemProvider *)itemProviderAtIndex:(NSInteger)index
 {
-    return 0 <= index && index < (NSInteger)_itemProviders.count ? _itemProviders[index] : nil;
+    return 0 <= index && index < (NSInteger)[_itemProviders count] ? [_itemProviders objectAtIndex:index] : nil;
 }
 
 - (BOOL)hasPendingOperation