OLD | NEW |
(Empty) | |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #import "ios/chrome/browser/ui/activity_services/chrome_activity_item_source.h" |
| 6 |
| 7 #import <MobileCoreServices/MobileCoreServices.h> |
| 8 |
| 9 #include "base/logging.h" |
| 10 #import "ios/chrome/browser/ui/activity_services/activity_type_util.h" |
| 11 #import "ios/chrome/browser/ui/activity_services/appex_constants.h" |
| 12 |
| 13 #if !defined(__has_feature) || !__has_feature(objc_arc) |
| 14 #error "This file requires ARC support." |
| 15 #endif |
| 16 |
| 17 #pragma mark - UIActivityURLSource |
| 18 |
| 19 @interface UIActivityURLSource () { |
| 20 // The shared subject. |
| 21 NSString* _subject; |
| 22 // The shared url. |
| 23 NSURL* _url; |
| 24 } |
| 25 |
| 26 @end |
| 27 |
| 28 @implementation UIActivityURLSource |
| 29 |
| 30 - (instancetype)init { |
| 31 NOTREACHED(); |
| 32 return nil; |
| 33 } |
| 34 |
| 35 - (instancetype)initWithURL:(NSURL*)url subject:(NSString*)subject { |
| 36 DCHECK(subject); |
| 37 DCHECK(url); |
| 38 self = [super init]; |
| 39 if (self) { |
| 40 _subject = [subject copy]; |
| 41 _url = url; |
| 42 } |
| 43 return self; |
| 44 } |
| 45 |
| 46 #pragma mark - UIActivityItemSource |
| 47 |
| 48 - (id)activityViewController:(UIActivityViewController*)activityViewController |
| 49 itemForActivityType:(NSString*)activityType { |
| 50 return _url; |
| 51 } |
| 52 |
| 53 - (id)activityViewControllerPlaceholderItem: |
| 54 (UIActivityViewController*)activityViewController { |
| 55 return _url; |
| 56 } |
| 57 |
| 58 - (NSString*)activityViewController: |
| 59 (UIActivityViewController*)activityViewController |
| 60 subjectForActivityType:(NSString*)activityType { |
| 61 return _subject; |
| 62 } |
| 63 |
| 64 @end |
| 65 |
| 66 #pragma mark - UIActivityTextSource |
| 67 |
| 68 @interface UIActivityTextSource () { |
| 69 // The shared text. |
| 70 NSString* _text; |
| 71 } |
| 72 |
| 73 @end |
| 74 |
| 75 @implementation UIActivityTextSource |
| 76 |
| 77 - (instancetype)init { |
| 78 NOTREACHED(); |
| 79 return nil; |
| 80 } |
| 81 |
| 82 - (instancetype)initWithText:(NSString*)text { |
| 83 DCHECK(text); |
| 84 self = [super init]; |
| 85 if (self) { |
| 86 _text = [text copy]; |
| 87 } |
| 88 return self; |
| 89 } |
| 90 |
| 91 #pragma mark - UIActivityItemSource |
| 92 |
| 93 - (id)activityViewController:(UIActivityViewController*)activityViewController |
| 94 itemForActivityType:(NSString*)activityType { |
| 95 // The UIActivityTypeMail is excluded because it obtains the text through the |
| 96 // UIActivityURLSource's |...subjectForActivityType:| method. |
| 97 // The UIActivityTypeCopyToPasteboard and UIActivityTypeMessage are excluded |
| 98 // because the pasteboard and message should only contain the URL, to match |
| 99 // Safari's behavior. |
| 100 NSSet* excludedActivityTypes = [NSSet setWithArray:@[ |
| 101 UIActivityTypeCopyToPasteboard, UIActivityTypeMail, UIActivityTypeMessage |
| 102 ]]; |
| 103 if ([excludedActivityTypes containsObject:activityType]) { |
| 104 return nil; |
| 105 } |
| 106 return _text; |
| 107 } |
| 108 |
| 109 - (id)activityViewControllerPlaceholderItem: |
| 110 (UIActivityViewController*)activityViewController { |
| 111 return _text; |
| 112 } |
| 113 |
| 114 @end |
| 115 |
| 116 #pragma mark - UIActivityImageSource |
| 117 |
| 118 @interface UIActivityImageSource () { |
| 119 // The shared image. |
| 120 UIImage* _image; |
| 121 } |
| 122 |
| 123 @end |
| 124 |
| 125 @implementation UIActivityImageSource |
| 126 |
| 127 - (instancetype)init { |
| 128 NOTREACHED(); |
| 129 return nil; |
| 130 } |
| 131 |
| 132 - (instancetype)initWithImage:(UIImage*)image { |
| 133 DCHECK(image); |
| 134 self = [super init]; |
| 135 if (self) { |
| 136 _image = image; |
| 137 } |
| 138 return self; |
| 139 } |
| 140 |
| 141 #pragma mark - UIActivityItemSource |
| 142 |
| 143 - (id)activityViewController:(UIActivityViewController*)activityViewController |
| 144 itemForActivityType:(NSString*)activityType { |
| 145 return _image; |
| 146 } |
| 147 |
| 148 - (id)activityViewControllerPlaceholderItem: |
| 149 (UIActivityViewController*)activityViewController { |
| 150 return _image; |
| 151 } |
| 152 |
| 153 @end |
| 154 |
| 155 #pragma mark - UIActivityFindLoginActionSource |
| 156 |
| 157 @interface UIActivityFindLoginActionSource () { |
| 158 NSString* _subject; |
| 159 NSURL* _url; |
| 160 } |
| 161 @end |
| 162 |
| 163 @implementation UIActivityFindLoginActionSource |
| 164 |
| 165 - (instancetype)init { |
| 166 NOTREACHED(); |
| 167 return nil; |
| 168 } |
| 169 |
| 170 - (instancetype)initWithURL:(NSURL*)url subject:(NSString*)subject { |
| 171 DCHECK(url); |
| 172 DCHECK(subject); |
| 173 self = [super init]; |
| 174 if (self) { |
| 175 _url = url; |
| 176 _subject = [subject copy]; |
| 177 } |
| 178 return self; |
| 179 } |
| 180 |
| 181 #pragma mark - UIActivityItemSource |
| 182 |
| 183 - (id)activityViewControllerPlaceholderItem: |
| 184 (UIActivityViewController*)activityViewController { |
| 185 // Return the current URL as a placeholder |
| 186 return _url; |
| 187 } |
| 188 |
| 189 - (NSString*)activityViewController: |
| 190 (UIActivityViewController*)activityViewController |
| 191 subjectForActivityType:(NSString*)activityType { |
| 192 return _subject; |
| 193 } |
| 194 |
| 195 - (id)activityViewController:(UIActivityViewController*)activityViewController |
| 196 itemForActivityType:(NSString*)activityType { |
| 197 NSNumber* versionNumber = |
| 198 activity_type_util::PasswordAppExActivityVersion(activityType); |
| 199 if (!versionNumber) |
| 200 return _url; |
| 201 |
| 202 // Constructs an NSExtensionItem object from the URL being "shared". |
| 203 NSDictionary* appExItems = @{ |
| 204 activity_services::kPasswordAppExVersionNumberKey : versionNumber, |
| 205 activity_services::kPasswordAppExURLStringKey : [_url absoluteString] |
| 206 }; |
| 207 NSItemProvider* itemProvider = [[NSItemProvider alloc] |
| 208 initWithItem:appExItems |
| 209 typeIdentifier:activity_services::kUTTypeAppExtensionFindLoginAction]; |
| 210 NSExtensionItem* extensionItem = [[NSExtensionItem alloc] init]; |
| 211 [extensionItem setAttachments:@[ itemProvider ]]; |
| 212 return extensionItem; |
| 213 } |
| 214 |
| 215 - (NSString*)activityViewController: |
| 216 (UIActivityViewController*)activityViewController |
| 217 dataTypeIdentifierForActivityType:(NSString*)activityType { |
| 218 // This UTI now satisfies both the Password Management App Extension and the |
| 219 // usual NSURL for Share extensions. If the following DCHECK fails, it is |
| 220 // probably due to missing or incorrect UTImportedTypeDeclarations in |
| 221 // Info.plist. |
| 222 NSString* findLoginType = |
| 223 activity_services::kUTTypeAppExtensionFindLoginAction; |
| 224 DCHECK(UTTypeConformsTo((__bridge CFStringRef)findLoginType, kUTTypeURL)); |
| 225 DCHECK(UTTypeConformsTo((__bridge CFStringRef)findLoginType, |
| 226 (__bridge CFStringRef) |
| 227 @"org.appextension.chrome-password-action")); |
| 228 // This method may be called before or after the presentation of the |
| 229 // UIActivityViewController. When called before (i.e. user has not made a |
| 230 // selection of which AppEx to launch), |activityType| is nil. If and when |
| 231 // called after UIActivityViewController has been presented and dismissed |
| 232 // after user made a choice of which AppEx to run, this method may be called |
| 233 // with |activityType| equals to the bundle ID of the AppEx selected. |
| 234 // Default action is to return @"public.url" UTType. |
| 235 if (!activityType || |
| 236 activity_type_util::PasswordAppExActivityVersion(activityType)) { |
| 237 return findLoginType; |
| 238 } |
| 239 return (NSString*)kUTTypeURL; |
| 240 } |
| 241 |
| 242 @end |
OLD | NEW |