diff --git a/Libraries/CameraRoll/RCTAssetsLibraryRequestHandler.m b/Libraries/CameraRoll/RCTAssetsLibraryRequestHandler.mm similarity index 94% rename from Libraries/CameraRoll/RCTAssetsLibraryRequestHandler.m rename to Libraries/CameraRoll/RCTAssetsLibraryRequestHandler.mm index a3600cb65d6..80683c6481b 100644 --- a/Libraries/CameraRoll/RCTAssetsLibraryRequestHandler.m +++ b/Libraries/CameraRoll/RCTAssetsLibraryRequestHandler.mm @@ -7,8 +7,9 @@ #import "RCTAssetsLibraryRequestHandler.h" -#import +#import #import +#import #import #import @@ -17,6 +18,12 @@ #import #import #import +#import + +#import "RCTCameraRollPlugins.h" + +@interface RCTAssetsLibraryRequestHandler() +@end @implementation RCTAssetsLibraryRequestHandler @@ -38,9 +45,9 @@ RCT_EXPORT_MODULE() - (id)sendRequest:(NSURLRequest *)request withDelegate:(id)delegate { - __block atomic_bool cancelled = ATOMIC_VAR_INIT(NO); + auto cancelled = std::make_shared>(false); void (^cancellationBlock)(void) = ^{ - atomic_store(&cancelled, YES); + cancelled->store(true); }; NSURL *requestURL = request.URL; @@ -48,15 +55,15 @@ RCT_EXPORT_MODULE() if (isPHUpload) { requestURL = [NSURL URLWithString:[@"ph" stringByAppendingString:[requestURL.absoluteString substringFromIndex:RCTNetworkingPHUploadHackScheme.length]]]; } - + if (!requestURL) { NSString *const msg = [NSString stringWithFormat:@"Cannot send request without URL"]; [delegate URLRequest:cancellationBlock didCompleteWithError:RCTErrorWithMessage(msg)]; return cancellationBlock; } - + PHFetchResult *fetchResult; - + if ([requestURL.scheme caseInsensitiveCompare:@"ph"] == NSOrderedSame) { // Fetch assets using PHAsset localIdentifier (recommended) NSString *const localIdentifier = [requestURL.absoluteString substringFromIndex:@"ph://".length]; @@ -70,7 +77,7 @@ RCT_EXPORT_MODULE() [delegate URLRequest:cancellationBlock didCompleteWithError:RCTErrorWithMessage(msg)]; return cancellationBlock; } - + if (![fetchResult firstObject]) { NSString *errorMessage = [NSString stringWithFormat:@"Failed to load asset" " at URL %@ with no error message.", requestURL]; @@ -78,8 +85,8 @@ RCT_EXPORT_MODULE() [delegate URLRequest:cancellationBlock didCompleteWithError:error]; return cancellationBlock; } - - if (atomic_load(&cancelled)) { + + if (cancelled->load()) { return cancellationBlock; } @@ -149,7 +156,7 @@ RCT_EXPORT_MODULE() [delegate URLRequest:cancellationBlock didCompleteWithError:nil]; }]; } - + return cancellationBlock; } @@ -159,3 +166,7 @@ RCT_EXPORT_MODULE() } @end + +Class RCTAssetsLibraryRequestHandlerCls(void) { + return RCTAssetsLibraryRequestHandler.class; +} diff --git a/Libraries/CameraRoll/RCTCameraRollManager.m b/Libraries/CameraRoll/RCTCameraRollManager.mm similarity index 98% rename from Libraries/CameraRoll/RCTCameraRollManager.m rename to Libraries/CameraRoll/RCTCameraRollManager.mm index 59d64cbade9..794d147f613 100644 --- a/Libraries/CameraRoll/RCTCameraRollManager.m +++ b/Libraries/CameraRoll/RCTCameraRollManager.mm @@ -7,6 +7,7 @@ #import "RCTCameraRollManager.h" +#import #import #import #import @@ -21,6 +22,7 @@ #import #import +#import "RCTCameraRollPlugins.h" #import "RCTAssetsLibraryRequestHandler.h" @implementation RCTConvert (PHAssetCollectionSubtype) @@ -135,7 +137,7 @@ RCT_EXPORT_METHOD(saveToCameraRoll:(NSURLRequest *)request } }]; }; - + void (^loadBlock)(void) = ^void() { if ([type isEqualToString:@"video"]) { inputURI = request.URL; @@ -146,13 +148,13 @@ RCT_EXPORT_METHOD(saveToCameraRoll:(NSURLRequest *)request reject(kErrorUnableToLoad, nil, error); return; } - + inputImage = image; saveBlock(); }]; } }; - + requestPhotoLibraryAccess(reject, loadBlock); } @@ -214,13 +216,13 @@ RCT_EXPORT_METHOD(getPhotos:(NSDictionary *)params if (groupName != nil) { collectionFetchOptions.predicate = [NSPredicate predicateWithFormat:[NSString stringWithFormat:@"localizedTitle == '%@'", groupName]]; } - + requestPhotoLibraryAccess(reject, ^{ PHFetchResult *const assetCollectionFetchResult = [PHAssetCollection fetchAssetCollectionsWithType:collectionType subtype:collectionSubtype options:collectionFetchOptions]; [assetCollectionFetchResult enumerateObjectsUsingBlock:^(PHAssetCollection * _Nonnull assetCollection, NSUInteger collectionIdx, BOOL * _Nonnull stopCollections) { // Enumerate assets within the collection PHFetchResult *const assetsFetchResult = [PHAsset fetchAssetsInAssetCollection:assetCollection options:assetFetchOptions]; - + [assetsFetchResult enumerateObjectsUsingBlock:^(PHAsset * _Nonnull asset, NSUInteger assetIdx, BOOL * _Nonnull stopAssets) { NSString *const uri = [NSString stringWithFormat:@"ph://%@", [asset localIdentifier]]; if (afterCursor && !foundAfter) { @@ -229,18 +231,18 @@ RCT_EXPORT_METHOD(getPhotos:(NSDictionary *)params } return; // skip until we get to the first one } - + // Get underlying resources of an asset - this includes files as well as details about edited PHAssets if ([mimeTypes count] > 0) { NSArray *const assetResources = [PHAssetResource assetResourcesForAsset:asset]; if (![assetResources firstObject]) { return; } - + PHAssetResource *const _Nonnull resource = [assetResources firstObject]; CFStringRef const uti = (__bridge CFStringRef _Nonnull)(resource.uniformTypeIdentifier); NSString *const mimeType = (NSString *)CFBridgingRelease(UTTypeCopyPreferredTagWithClass(uti, kUTTagClassMIMEType)); - + BOOL __block mimeTypeFound = NO; [mimeTypes enumerateObjectsUsingBlock:^(NSString * _Nonnull mimeTypeFilter, NSUInteger idx, BOOL * _Nonnull stop) { if ([mimeType isEqualToString:mimeTypeFilter]) { @@ -248,12 +250,12 @@ RCT_EXPORT_METHOD(getPhotos:(NSDictionary *)params *stop = YES; } }]; - + if (!mimeTypeFound) { return; } } - + // If we've accumulated enough results to resolve a single promise if (first == assets.count) { *stopAssets = YES; @@ -264,7 +266,7 @@ RCT_EXPORT_METHOD(getPhotos:(NSDictionary *)params resolvedPromise = YES; return; } - + NSString *const assetMediaTypeLabel = (asset.mediaType == PHAssetMediaTypeVideo ? @"video" : (asset.mediaType == PHAssetMediaTypeImage @@ -273,7 +275,7 @@ RCT_EXPORT_METHOD(getPhotos:(NSDictionary *)params ? @"audio" : @"unknown"))); CLLocation *const loc = asset.location; - + // A note on isStored: in the previous code that used ALAssets, isStored // was always set to YES, probably because iCloud-synced images were never returned (?). // To get the "isStored" information and filename, we would need to actually request the @@ -304,7 +306,7 @@ RCT_EXPORT_METHOD(getPhotos:(NSDictionary *)params }]; }]; }]; - + // If we get this far and haven't resolved the promise yet, we reached the end of the list of photos if (!resolvedPromise) { hasNextPage = NO; @@ -345,3 +347,7 @@ static void checkPhotoLibraryConfig() } @end + +Class RCTCameraRollManagerCls(void) { + return RCTCameraRollManager.class; +} diff --git a/Libraries/CameraRoll/RCTCameraRollPlugins.h b/Libraries/CameraRoll/RCTCameraRollPlugins.h new file mode 100644 index 00000000000..af1b315b2b8 --- /dev/null +++ b/Libraries/CameraRoll/RCTCameraRollPlugins.h @@ -0,0 +1,43 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @generated by an internal plugin build system + */ + +#ifdef RN_DISABLE_OSS_PLUGIN_HEADER + +// FB Internal: Plugins.h is autogenerated by the build system. +#import "Plugins.h" + +#else + +// OSS-compatibility layer + +#import + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wreturn-type-c-linkage" + +#ifdef __cplusplus +extern "C" { +#endif + +// RCTTurboModuleManagerDelegate should call this to resolve module classes. +Class RCTCameraRollClassProvider(const char *name); + +// Lookup functions +Class RCTAssetsLibraryRequestHandlerCls(void); +Class RCTCameraRollManagerCls(void); +Class RCTImagePickerManagerCls(void); +Class RCTPhotoLibraryImageLoaderCls(void); + +#ifdef __cplusplus +} +#endif + +#pragma GCC diagnostic pop + +#endif // RN_DISABLE_OSS_PLUGIN_HEADER diff --git a/Libraries/CameraRoll/RCTCameraRollPlugins.mm b/Libraries/CameraRoll/RCTCameraRollPlugins.mm new file mode 100644 index 00000000000..f2510796e0d --- /dev/null +++ b/Libraries/CameraRoll/RCTCameraRollPlugins.mm @@ -0,0 +1,35 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @generated by an internal plugin build system + */ + +#ifndef RN_DISABLE_OSS_PLUGIN_HEADER + +// OSS-compatibility layer + +#import "RCTCameraRollPlugins.h" + +#import +#import + +Class RCTCameraRollClassProvider(const char *name) { + static std::unordered_map sCoreModuleClassMap = { + {"AssetsLibraryRequestHandler", RCTAssetsLibraryRequestHandlerCls}, + {"CameraRollManager", RCTCameraRollManagerCls}, + {"ImagePickerIOS", RCTImagePickerManagerCls}, + {"PhotoLibraryImageLoader", RCTPhotoLibraryImageLoaderCls}, + }; + + auto p = sCoreModuleClassMap.find(name); + if (p != sCoreModuleClassMap.end()) { + auto classFunc = p->second; + return classFunc(); + } + return nil; +} + +#endif // RN_DISABLE_OSS_PLUGIN_HEADER diff --git a/Libraries/CameraRoll/RCTImagePickerManager.m b/Libraries/CameraRoll/RCTImagePickerManager.mm similarity index 89% rename from Libraries/CameraRoll/RCTImagePickerManager.m rename to Libraries/CameraRoll/RCTImagePickerManager.mm index d7b57c7b7a2..9f0b2321087 100644 --- a/Libraries/CameraRoll/RCTImagePickerManager.m +++ b/Libraries/CameraRoll/RCTImagePickerManager.mm @@ -8,6 +8,7 @@ #import "RCTImagePickerManager.h" +#import #import #import @@ -16,6 +17,8 @@ #import #import +#import "RCTCameraRollPlugins.h" + @interface RCTImagePickerController : UIImagePickerController @property (nonatomic, assign) BOOL unmirrorFrontFacingCamera; @@ -26,8 +29,7 @@ @end -@interface RCTImagePickerManager () - +@interface RCTImagePickerManager () @end @implementation RCTImagePickerManager @@ -78,7 +80,7 @@ RCT_EXPORT_METHOD(canUseCamera:(RCTResponseSenderBlock)callback) callback(@[@([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])]); } -RCT_EXPORT_METHOD(openCameraDialog:(NSDictionary *)config +RCT_EXPORT_METHOD(openCameraDialog:(JS::NativeImagePickerIOS::SpecOpenCameraDialogConfig &)config successCallback:(RCTResponseSenderBlock)callback cancelCallback:(RCTResponseSenderBlock)cancelCallback) { @@ -92,9 +94,9 @@ RCT_EXPORT_METHOD(openCameraDialog:(NSDictionary *)config imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera; NSArray *availableMediaTypes = [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypeCamera]; imagePicker.mediaTypes = availableMediaTypes; - imagePicker.unmirrorFrontFacingCamera = [RCTConvert BOOL:config[@"unmirrorFrontFacingCamera"]]; + imagePicker.unmirrorFrontFacingCamera = config.unmirrorFrontFacingCamera() ? YES : NO; - if ([RCTConvert BOOL:config[@"videoMode"]]) { + if (config.videoMode()) { imagePicker.cameraCaptureMode = UIImagePickerControllerCameraCaptureModeVideo; } @@ -103,7 +105,7 @@ RCT_EXPORT_METHOD(openCameraDialog:(NSDictionary *)config cancelCallback:cancelCallback]; } -RCT_EXPORT_METHOD(openSelectDialog:(NSDictionary *)config +RCT_EXPORT_METHOD(openSelectDialog:(JS::NativeImagePickerIOS::SpecOpenSelectDialogConfig &)config successCallback:(RCTResponseSenderBlock)callback cancelCallback:(RCTResponseSenderBlock)cancelCallback) { @@ -117,10 +119,10 @@ RCT_EXPORT_METHOD(openSelectDialog:(NSDictionary *)config imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary; NSMutableArray *allowedTypes = [NSMutableArray new]; - if ([RCTConvert BOOL:config[@"showImages"]]) { + if (config.showImages()) { [allowedTypes addObject:(NSString *)kUTTypeImage]; } - if ([RCTConvert BOOL:config[@"showVideos"]]) { + if (config.showVideos()) { [allowedTypes addObject:(NSString *)kUTTypeMovie]; } @@ -222,4 +224,13 @@ didFinishPickingMediaWithInfo:(NSDictionary *)info } } +- (std::shared_ptr)getTurboModuleWithJsInvoker:(std::shared_ptr)jsInvoker +{ + return std::make_shared(self, jsInvoker); +} + @end + +Class RCTImagePickerManagerCls(void) { + return RCTImagePickerManager.class; +} diff --git a/Libraries/CameraRoll/RCTPhotoLibraryImageLoader.m b/Libraries/CameraRoll/RCTPhotoLibraryImageLoader.mm similarity index 94% rename from Libraries/CameraRoll/RCTPhotoLibraryImageLoader.m rename to Libraries/CameraRoll/RCTPhotoLibraryImageLoader.mm index ccdf3c27f73..8ac4029e1a5 100644 --- a/Libraries/CameraRoll/RCTPhotoLibraryImageLoader.m +++ b/Libraries/CameraRoll/RCTPhotoLibraryImageLoader.mm @@ -8,8 +8,14 @@ #import "RCTPhotoLibraryImageLoader.h" #import - +#import #import +#import + +#import "RCTCameraRollPlugins.h" + +@interface RCTPhotoLibraryImageLoader () +@end @implementation RCTPhotoLibraryImageLoader @@ -109,3 +115,7 @@ RCT_EXPORT_MODULE() } @end + +Class RCTPhotoLibraryImageLoaderCls(void) { + return RCTPhotoLibraryImageLoader.class; +}