6/6 Log image-rendered for Fabric image logging

Reviewed By: fkgozali

Differential Revision: D23450649

fbshipit-source-id: 58265a2c7855a2f4371d68637f09a07921821adf
This commit is contained in:
Paige Sun
2020-09-11 15:09:12 -07:00
committed by Facebook GitHub Bot
parent c17333d4c1
commit acda299453
15 changed files with 63 additions and 33 deletions
+22 -18
View File
@@ -375,7 +375,9 @@ static UIImage *RCTResizeImageIfNeeded(UIImage *image,
attribution:{}
progressBlock:progressBlock
partialLoadBlock:partialLoadBlock
completionBlock:completionBlock];
completionBlock:^(NSError *error, UIImage *image, id metadata) {
completionBlock(error, image);
}];
return ^{
[request cancel];
};
@@ -457,7 +459,7 @@ static UIImage *RCTResizeImageIfNeeded(UIImage *image,
attribution:(const ImageURLLoaderAttribution &)attribution
progressBlock:(RCTImageLoaderProgressBlock)progressHandler
partialLoadBlock:(RCTImageLoaderPartialLoadBlock)partialLoadHandler
completionBlock:(void (^)(NSError *error, id imageOrData, BOOL cacheResult, NSURLResponse *response))completionBlock
completionBlock:(void (^)(NSError *error, id imageOrData, id imageMetadata, BOOL cacheResult, NSURLResponse *response))completionBlock
{
{
NSMutableURLRequest *mutableRequest = [request mutableCopy];
@@ -491,7 +493,7 @@ static UIImage *RCTResizeImageIfNeeded(UIImage *image,
__block NSLock *cancelLoadLock = [NSLock new];
NSString *requestId = [NSString stringWithFormat:@"%@-%llu",[[NSUUID UUID] UUIDString], monotonicTimeGetCurrentNanoseconds()];
void (^completionHandler)(NSError *, id, NSURLResponse *) = ^(NSError *error, id imageOrData, NSURLResponse *response) {
void (^completionHandler)(NSError *, id, id, NSURLResponse *) = ^(NSError *error, id imageOrData, id imageMetadata, NSURLResponse *response) {
[cancelLoadLock lock];
cancelLoad = nil;
[cancelLoadLock unlock];
@@ -503,11 +505,11 @@ static UIImage *RCTResizeImageIfNeeded(UIImage *image,
// expecting it, and may do expensive post-processing in the callback
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
if (!std::atomic_load(cancelled.get())) {
completionBlock(error, imageOrData, cacheResult, response);
completionBlock(error, imageOrData, imageMetadata, cacheResult, response);
}
});
} else if (!std::atomic_load(cancelled.get())) {
completionBlock(error, imageOrData, cacheResult, response);
completionBlock(error, imageOrData, imageMetadata, cacheResult, response);
}
};
@@ -524,8 +526,8 @@ static UIImage *RCTResizeImageIfNeeded(UIImage *image,
attribution:attributionCopy
progressHandler:progressHandler
partialLoadHandler:partialLoadHandler
completionHandler:^(NSError *error, UIImage *image) {
completionHandler(error, image, nil);
completionHandler:^(NSError *error, UIImage *image, id metadata) {
completionHandler(error, image, metadata, nil);
}];
}
RCTImageLoaderCancellationBlock cb = [loadHandler loadImageForURL:request.URL
@@ -535,7 +537,7 @@ static UIImage *RCTResizeImageIfNeeded(UIImage *image,
progressHandler:progressHandler
partialLoadHandler:partialLoadHandler
completionHandler:^(NSError *error, UIImage *image) {
completionHandler(error, image, nil);
completionHandler(error, image, nil, nil);
}];
return [[RCTImageURLLoaderRequest alloc] initWithRequestId:nil imageURL:request.URL cancellationBlock:cb];
}
@@ -564,8 +566,8 @@ static UIImage *RCTResizeImageIfNeeded(UIImage *image,
attribution:attributionCopy
progressHandler:progressHandler
partialLoadHandler:partialLoadHandler
completionHandler:^(NSError *error, UIImage *image) {
completionHandler(error, image, nil);
completionHandler:^(NSError *error, UIImage *image, id metadata) {
completionHandler(error, image, metadata, nil);
}];
cancelLoadLocal = loaderRequest.cancellationBlock;
} else {
@@ -576,7 +578,7 @@ static UIImage *RCTResizeImageIfNeeded(UIImage *image,
progressHandler:progressHandler
partialLoadHandler:partialLoadHandler
completionHandler:^(NSError *error, UIImage *image) {
completionHandler(error, image, nil);
completionHandler(error, image, nil, nil);
}];
}
[cancelLoadLock lock];
@@ -592,12 +594,14 @@ static UIImage *RCTResizeImageIfNeeded(UIImage *image,
}
if (image) {
completionHandler(nil, image, nil);
completionHandler(nil, image, nil, nil);
} else {
// Use networking module to load image
dispatch_block_t cancelLoadLocal = [strongSelf _loadURLRequest:request
progressBlock:progressHandler
completionBlock:completionHandler];
completionBlock:^(NSError *error, id imageOrData, NSURLResponse *response) {
completionHandler(error, imageOrData, nil, response);
}];
[cancelLoadLock lock];
cancelLoad = cancelLoadLocal;
[cancelLoadLock unlock];
@@ -746,7 +750,7 @@ static UIImage *RCTResizeImageIfNeeded(UIImage *image,
attribution:(const ImageURLLoaderAttribution &)attribution
progressBlock:(RCTImageLoaderProgressBlock)progressBlock
partialLoadBlock:(RCTImageLoaderPartialLoadBlock)partialLoadBlock
completionBlock:(RCTImageLoaderCompletionBlock)completionBlock
completionBlock:(RCTImageLoaderCompletionBlockWithMetadata)completionBlock
{
auto cancelled = std::make_shared<std::atomic<int>>(0);
__block dispatch_block_t cancelLoad = nil;
@@ -766,7 +770,7 @@ static UIImage *RCTResizeImageIfNeeded(UIImage *image,
};
__weak RCTImageLoader *weakSelf = self;
void (^completionHandler)(NSError *, id, BOOL, NSURLResponse *) = ^(NSError *error, id imageOrData, BOOL cacheResult, NSURLResponse *response) {
void (^completionHandler)(NSError *, id, id, BOOL, NSURLResponse *) = ^(NSError *error, id imageOrData, id imageMetadata, BOOL cacheResult, NSURLResponse *response) {
__typeof(self) strongSelf = weakSelf;
if (std::atomic_load(cancelled.get()) || !strongSelf) {
return;
@@ -776,7 +780,7 @@ static UIImage *RCTResizeImageIfNeeded(UIImage *image,
[cancelLoadLock lock];
cancelLoad = nil;
[cancelLoadLock unlock];
completionBlock(error, imageOrData);
completionBlock(error, imageOrData, imageMetadata);
return;
}
@@ -793,7 +797,7 @@ static UIImage *RCTResizeImageIfNeeded(UIImage *image,
[cancelLoadLock lock];
cancelLoad = nil;
[cancelLoadLock unlock];
completionBlock(error_, image);
completionBlock(error_, image, nil);
};
dispatch_block_t cancelLoadLocal = [strongSelf decodeImageData:imageOrData
size:size
@@ -987,7 +991,7 @@ static UIImage *RCTResizeImageIfNeeded(UIImage *image,
- (RCTImageLoaderCancellationBlock)getImageSizeForURLRequest:(NSURLRequest *)imageURLRequest
block:(void(^)(NSError *error, CGSize size))callback
{
void (^completion)(NSError *, id, BOOL, NSURLResponse *) = ^(NSError *error, id imageOrData, BOOL cacheResult, NSURLResponse *response) {
void (^completion)(NSError *, id, id, BOOL, NSURLResponse *) = ^(NSError *error, id imageOrData, id imageMetadata, BOOL cacheResult, NSURLResponse *response) {
CGSize size;
if ([imageOrData isKindOfClass:[NSData class]]) {
NSDictionary *meta = RCTGetImageMetadata(imageOrData);
@@ -33,7 +33,7 @@ RCT_EXTERN void RCTEnableImageLoadingPerfInstrumentation(BOOL enabled);
attribution:(const facebook::react::ImageURLLoaderAttribution &)attribution
progressBlock:(RCTImageLoaderProgressBlock)progressBlock
partialLoadBlock:(RCTImageLoaderPartialLoadBlock)partialLoadBlock
completionBlock:(RCTImageLoaderCompletionBlock)completionBlock;
completionBlock:(RCTImageLoaderCompletionBlockWithMetadata)completionBlock;
#endif
/**
+3
View File
@@ -15,6 +15,9 @@ NS_ASSUME_NONNULL_BEGIN
typedef void (^RCTImageLoaderProgressBlock)(int64_t progress, int64_t total);
typedef void (^RCTImageLoaderPartialLoadBlock)(UIImage *image);
typedef void (^RCTImageLoaderCompletionBlock)(NSError * _Nullable error, UIImage * _Nullable image);
// Metadata is passed as a id in an additional parameter because there are forks of RN without this parameter,
// and the complexity of RCTImageLoader would make using protocols here difficult to typecheck.
typedef void (^RCTImageLoaderCompletionBlockWithMetadata)(NSError * _Nullable error, UIImage * _Nullable image, id _Nullable metadata);
typedef dispatch_block_t RCTImageLoaderCancellationBlock;
/**
@@ -56,7 +56,7 @@ struct ImageURLLoaderAttribution {
attribution:(const facebook::react::ImageURLLoaderAttribution &)attribution
progressHandler:(RCTImageLoaderProgressBlock)progressHandler
partialLoadHandler:(RCTImageLoaderPartialLoadBlock)partialLoadHandler
completionHandler:(RCTImageLoaderCompletionBlock)completionHandler;
completionHandler:(RCTImageLoaderCompletionBlockWithMetadata)completionHandler;
#endif
/**
+1 -1
View File
@@ -332,7 +332,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithFrame:(CGRect)frame)
imageScale = source.scale;
}
RCTImageLoaderCompletionBlock completionHandler = ^(NSError *error, UIImage *loadedImage) {
RCTImageLoaderCompletionBlockWithMetadata completionHandler = ^(NSError *error, UIImage *loadedImage, id metadata) {
[weakSelf imageLoaderLoadedImage:loadedImage error:error forImageSource:source partial:NO];
};
@@ -128,7 +128,7 @@ using namespace facebook::react;
#pragma mark - RCTImageResponseDelegate
- (void)didReceiveImage:(UIImage *)image fromObserver:(void const *)observer
- (void)didReceiveImage:(UIImage *)image metadata:(id)metadata fromObserver:(void const *)observer
{
if (!_eventEmitter || !_stateTeller.isValid()) {
// Notifications are delivered asynchronously and might arrive after the view is already recycled.
@@ -320,7 +320,7 @@ using namespace facebook::react;
#pragma mark - RCTImageResponseDelegate
- (void)didReceiveImage:(UIImage *)image fromObserver:(void const *)observer
- (void)didReceiveImage:(UIImage *)image metadata:(id)metadata fromObserver:(void const *)observer
{
if (observer == &_trackImageResponseObserverProxy) {
self.trackImage = image;
+1 -1
View File
@@ -11,7 +11,7 @@ NS_ASSUME_NONNULL_BEGIN
@protocol RCTImageResponseDelegate <NSObject>
- (void)didReceiveImage:(UIImage *)image fromObserver:(void const *)observer;
- (void)didReceiveImage:(UIImage *)image metadata:(id)metadata fromObserver:(void const *)observer;
- (void)didReceiveProgress:(float)progress fromObserver:(void const *)observer;
- (void)didReceiveFailureFromObserver:(void const *)observer;
@@ -23,10 +23,11 @@ RCTImageResponseObserverProxy::RCTImageResponseObserverProxy(id<RCTImageResponse
void RCTImageResponseObserverProxy::didReceiveImage(ImageResponse const &imageResponse) const
{
UIImage *image = (UIImage *)unwrapManagedObject(imageResponse.getImage());
id metadata = unwrapManagedObject(imageResponse.getMetadata());
id<RCTImageResponseDelegate> delegate = delegate_;
auto this_ = this;
RCTExecuteOnMainQueue(^{
[delegate didReceiveImage:image fromObserver:this_];
[delegate didReceiveImage:image metadata:metadata fromObserver:this_];
});
}
@@ -10,12 +10,18 @@
namespace facebook {
namespace react {
ImageResponse::ImageResponse(const std::shared_ptr<void> &image)
: image_(image) {}
ImageResponse::ImageResponse(
const std::shared_ptr<void> &image,
const std::shared_ptr<void> &metadata)
: image_(image), metadata_(metadata) {}
std::shared_ptr<void> ImageResponse::getImage() const {
return image_;
}
std::shared_ptr<void> ImageResponse::getMetadata() const {
return metadata_;
}
} // namespace react
} // namespace facebook
@@ -23,12 +23,18 @@ class ImageResponse final {
Failed,
};
ImageResponse(const std::shared_ptr<void> &image);
ImageResponse(
const std::shared_ptr<void> &image,
const std::shared_ptr<void> &metadata);
std::shared_ptr<void> getImage() const;
std::shared_ptr<void> getMetadata() const;
private:
std::shared_ptr<void> image_{};
std::shared_ptr<void> metadata_{};
};
} // namespace react
@@ -24,8 +24,9 @@ void ImageResponseObserverCoordinator::addObserver(
}
case ImageResponse::Status::Completed: {
auto imageData = imageData_;
auto imageMetadata = imageMetadata_;
mutex_.unlock();
observer.didReceiveImage(ImageResponse{imageData});
observer.didReceiveImage(ImageResponse{imageData, imageMetadata});
break;
}
case ImageResponse::Status::Failed: {
@@ -63,6 +64,7 @@ void ImageResponseObserverCoordinator::nativeImageResponseComplete(
ImageResponse const &imageResponse) const {
mutex_.lock();
imageData_ = imageResponse.getImage();
imageMetadata_ = imageResponse.getMetadata();
assert(status_ == ImageResponse::Status::Loading);
status_ = ImageResponse::Status::Completed;
auto observers = observers_;
@@ -73,6 +73,12 @@ class ImageResponseObserverCoordinator {
*/
mutable std::shared_ptr<void> imageData_;
/*
* Cache image metadata.
* Mutable: protected by mutex_.
*/
mutable std::shared_ptr<void> imageMetadata_;
/*
* Observer and data mutex.
*/
@@ -70,14 +70,15 @@ using namespace facebook::react;
std::string([moduleName UTF8String], [moduleName lengthOfBytesUsingEncoding:NSUTF8StringEncoding]);
telemetry->setLoaderModuleName(moduleCString);
auto completionBlock = ^(NSError *error, UIImage *image) {
auto completionBlock = ^(NSError *error, UIImage *image, id metadata) {
auto observerCoordinator = weakObserverCoordinator.lock();
if (!observerCoordinator) {
return;
}
if (image && !error) {
observerCoordinator->nativeImageResponseComplete(ImageResponse(wrapManagedObject(image)));
auto wrappedMetadata = metadata ? wrapManagedObject(metadata) : nullptr;
observerCoordinator->nativeImageResponseComplete(ImageResponse(wrapManagedObject(image), wrappedMetadata));
} else {
observerCoordinator->nativeImageResponseFailed();
}
@@ -50,14 +50,15 @@ using namespace facebook::react;
NSURLRequest *request = NSURLRequestFromImageSource(imageSource);
auto completionBlock = ^(NSError *error, UIImage *image) {
auto completionBlock = ^(NSError *error, UIImage *image, id metadata) {
auto observerCoordinator = weakObserverCoordinator.lock();
if (!observerCoordinator) {
return;
}
if (image && !error) {
observerCoordinator->nativeImageResponseComplete(ImageResponse(wrapManagedObject(image)));
auto wrappedMetadata = metadata ? wrapManagedObject(metadata) : nullptr;
observerCoordinator->nativeImageResponseComplete(ImageResponse(wrapManagedObject(image), wrappedMetadata));
} else {
observerCoordinator->nativeImageResponseFailed();
}