Allow image loaders to enable/disable image telemetry

Summary:
When shouldEnableLoggingForRequestUrl is false, ImageTelemetry is not initialized, and no logging is done.

* Replace `- (NSString *)loaderModuleNameForRequestUrl:(NSURL *)url` with `- (BOOL)shouldEnableLoggingForRequestUrl:(NSURL *)url`
* Rename RCTImageLoaderInstrumentableProtocol.h -> RCTImageLoaderLoggableProtocol.h

Reviewed By: fkgozali

Differential Revision: D24523984

fbshipit-source-id: a5463eceea1c40f9452b0ad2ee6bf047f71a02c1
This commit is contained in:
Paige Sun 2020-10-29 21:57:46 -07:00 коммит произвёл Facebook GitHub Bot
Родитель 1b71ec4e81
Коммит e37708dfb6
9 изменённых файлов: 48 добавлений и 45 удалений

Просмотреть файл

@ -15,9 +15,9 @@
#import <React/RCTImageURLLoader.h>
#import <React/RCTImageCache.h>
#import <React/RCTImageLoaderProtocol.h>
#import <React/RCTImageLoaderInstrumentableProtocol.h>
#import <React/RCTImageLoaderLoggable.h>
@interface RCTImageLoader : NSObject <RCTBridgeModule, RCTImageLoaderProtocol, RCTImageLoaderInstrumentableProtocol>
@interface RCTImageLoader : NSObject <RCTBridgeModule, RCTImageLoaderProtocol, RCTImageLoaderLoggableProtocol>
- (instancetype)init;
- (instancetype)initWithRedirectDelegate:(id<RCTImageRedirectProtocol>)redirectDelegate NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithRedirectDelegate:(id<RCTImageRedirectProtocol>)redirectDelegate

Просмотреть файл

@ -839,12 +839,12 @@ static UIImage *RCTResizeImageIfNeeded(UIImage *image,
return [[RCTImageURLLoaderRequest alloc] initWithRequestId:loaderRequest.requestId imageURL:imageURLRequest.URL cancellationBlock:cancellationBlock];
}
- (NSString *)loaderModuleNameForRequestUrl:(NSURL *)url {
- (BOOL)shouldEnablePerfLoggingForRequestUrl:(NSURL *)url {
id<RCTImageURLLoader> loadHandler = [self imageURLLoaderForURL:url];
if ([loadHandler respondsToSelector:@selector(loaderModuleNameForRequestUrl:)]) {
return [(id<RCTImageURLLoaderWithAttribution>)loadHandler loaderModuleNameForRequestUrl:url];
if ([loadHandler respondsToSelector:@selector(shouldEnablePerfLogging)]) {
return [(id<RCTImageURLLoaderWithAttribution>)loadHandler shouldEnablePerfLogging];
}
return nil;
return NO;
}
- (void)trackURLImageVisibilityForRequest:(RCTImageURLLoaderRequest *)loaderRequest imageView:(UIView *)imageView

Просмотреть файл

@ -1,15 +0,0 @@
/*
* 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.
*/
@protocol RCTImageLoaderInstrumentableProtocol
/**
* Image instrumentation - get name of the image loader module
*/
- (NSString *)loaderModuleNameForRequestUrl:(NSURL *)url;
@end

Просмотреть файл

@ -0,0 +1,30 @@
/*
* 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.
*/
/**
* The image loader (i.e. RCTImageLoader) implement this to declare whether image performance should be logged.
*/
@protocol RCTImageLoaderLoggableProtocol
/**
* Image instrumentation - declares whether its caller should log images
*/
- (BOOL)shouldEnablePerfLoggingForRequestUrl:(NSURL *)url;
@end
/**
* Image handlers in the image loader implement this to declare whether image performance should be logged.
*/
@protocol RCTImageLoaderLoggable
/**
* Image instrumentation - declares whether its caller should log images
*/
- (BOOL)shouldEnablePerfLogging;
@end

Просмотреть файл

@ -9,7 +9,6 @@
#import <React/RCTImageLoaderProtocol.h>
#import <React/RCTImageURLLoaderWithAttribution.h>
#import <React/RCTImageLoaderInstrumentableProtocol.h>
RCT_EXTERN BOOL RCTImageLoadingInstrumentationEnabled(void);
RCT_EXTERN BOOL RCTImageLoadingPerfInstrumentationEnabled(void);
@ -19,7 +18,7 @@ RCT_EXTERN void RCTEnableImageLoadingPerfInstrumentation(BOOL enabled);
RCT_EXTERN BOOL RCTGetImageLoadingPerfInstrumentationForFabricEnabled();
RCT_EXTERN void RCTSetImageLoadingPerfInstrumentationForFabricEnabledBlock(BOOL (^getEnabled)());
@protocol RCTImageLoaderWithAttributionProtocol<RCTImageLoaderProtocol, RCTImageLoaderInstrumentableProtocol>
@protocol RCTImageLoaderWithAttributionProtocol<RCTImageLoaderProtocol, RCTImageLoaderLoggableProtocol>
// TODO (T61325135): Remove C++ checks
#ifdef __cplusplus

Просмотреть файл

@ -7,7 +7,7 @@
#import <React/RCTImageURLLoader.h>
#import <React/RCTImageLoaderProtocol.h>
#import <React/RCTImageLoaderInstrumentableProtocol.h>
#import <React/RCTImageLoaderLoggable.h>
// TODO (T61325135): Remove C++ checks
#ifdef __cplusplus
@ -39,7 +39,7 @@ struct ImageURLLoaderAttribution {
* Same as the RCTImageURLLoader interface, but allows passing in optional `attribution` information.
* This is useful for per-app logging and other instrumentation.
*/
@protocol RCTImageURLLoaderWithAttribution <RCTImageURLLoader, RCTImageLoaderInstrumentableProtocol>
@protocol RCTImageURLLoaderWithAttribution <RCTImageURLLoader, RCTImageLoaderLoggable>
// TODO (T61325135): Remove C++ checks
#ifdef __cplusplus

Просмотреть файл

@ -19,14 +19,6 @@ SurfaceId ImageTelemetry::getSurfaceId() const {
return surfaceId_;
}
std::string ImageTelemetry::getLoaderModuleName() const {
return loaderModuleName_;
}
void ImageTelemetry::setLoaderModuleName(std::string const &loaderModuleName) {
loaderModuleName_ = loaderModuleName;
}
TelemetryTimePoint ImageTelemetry::getWillRequestUrlTime() const {
assert(willRequestUrlTime_ != kTelemetryUndefinedTimePoint);
return willRequestUrlTime_;

Просмотреть файл

@ -31,14 +31,11 @@ class ImageTelemetry final {
TelemetryTimePoint getWillRequestUrlTime() const;
SurfaceId getSurfaceId() const;
std::string getLoaderModuleName() const;
void setLoaderModuleName(std::string const &loaderModuleName);
private:
TelemetryTimePoint willRequestUrlTime_{kTelemetryUndefinedTimePoint};
const SurfaceId surfaceId_;
std::string loaderModuleName_{""};
};
} // namespace react

Просмотреть файл

@ -40,8 +40,15 @@ using namespace facebook::react;
{
SystraceSection s("RCTImageManager::requestImage");
auto telemetry = std::make_shared<ImageTelemetry>(surfaceId);
telemetry->willRequestUrl();
NSURLRequest *request = NSURLRequestFromImageSource(imageSource);
std::shared_ptr<ImageTelemetry> telemetry;
if ([self->_imageLoader shouldEnablePerfLoggingForRequestUrl:request.URL]) {
telemetry = std::make_shared<ImageTelemetry>(surfaceId);
telemetry->willRequestUrl();
} else {
telemetry = nullptr;
}
auto imageRequest = ImageRequest(imageSource, telemetry);
auto weakObserverCoordinator =
(std::weak_ptr<const ImageResponseObserverCoordinator>)imageRequest.getSharedObserverCoordinator();
@ -49,13 +56,6 @@ using namespace facebook::react;
auto sharedCancelationFunction = SharedFunction<>();
imageRequest.setCancelationFunction(sharedCancelationFunction);
NSURLRequest *request = NSURLRequestFromImageSource(imageSource);
BOOL hasModuleName = [self->_imageLoader respondsToSelector:@selector(loaderModuleNameForRequestUrl:)];
NSString *moduleName = hasModuleName ? [self->_imageLoader loaderModuleNameForRequestUrl:request.URL] : nil;
std::string moduleCString =
std::string([moduleName UTF8String], [moduleName lengthOfBytesUsingEncoding:NSUTF8StringEncoding]);
telemetry->setLoaderModuleName(moduleCString);
/*
* Even if an image is being loaded asynchronously on some other background thread, some other preparation
* work (such as creating an `NSURLRequest` object and some obscure logic inside `RCTImageLoader`) can take a couple