Jonny Banana
6 years ago
committed by
GitHub
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 750 additions and 0 deletions
-
66Logging/SCCoreCameraLogger.h
-
304Logging/SCCoreCameraLogger.m
-
53Logging/SCLogger+Camera.h
-
303Logging/SCLogger+Camera.m
-
24Logging/SCManiphestTicketCreator.h
@ -0,0 +1,66 @@ |
|||
// |
|||
// SCCoreCameraLogger.h |
|||
// Snapchat |
|||
// |
|||
// Created by Chao Pang on 3/6/18. |
|||
// |
|||
|
|||
#import <Foundation/Foundation.h> |
|||
|
|||
/** |
|||
* CAMERA_CREATION_DELAY event |
|||
*/ |
|||
extern NSString *const kSCCameraCreationDelayEventStartTimeKey; |
|||
extern NSString *const kSCCameraCreationDelayEventStartTimeAdjustmentKey; |
|||
extern NSString *const kSCCameraCreationDelayEventEndTimeKey; |
|||
extern NSString *const kSCCameraCreationDelayEventCaptureSessionIdKey; |
|||
extern NSString *const kSCCameraCreationDelayEventFilterLensIdKey; |
|||
extern NSString *const kSCCameraCreationDelayEventNightModeDetectedKey; |
|||
extern NSString *const kSCCameraCreationDelayEventNightModeActiveKey; |
|||
extern NSString *const kSCCameraCreationDelayEventCameraApiKey; |
|||
extern NSString *const kSCCameraCreationDelayEventCameraLevelKey; |
|||
extern NSString *const kSCCameraCreationDelayEventCameraPositionKey; |
|||
extern NSString *const kSCCameraCreationDelayEventCameraOpenSourceKey; |
|||
extern NSString *const kSCCameraCreationDelayEventContentDurationKey; |
|||
extern NSString *const kSCCameraCreationDelayEventMediaTypeKey; |
|||
extern NSString *const kSCCameraCreationDelayEventStartTypeKey; |
|||
extern NSString *const kSCCameraCreationDelayEventStartSubTypeKey; |
|||
extern NSString *const kSCCameraCreationDelayEventAnalyticsVersion; |
|||
|
|||
@interface SCCoreCameraLogger : NSObject |
|||
|
|||
+ (instancetype)sharedInstance; |
|||
|
|||
/** |
|||
* CAMERA_CREATION_DELAY event |
|||
*/ |
|||
- (void)logCameraCreationDelayEventStartWithCaptureSessionId:(NSString *)captureSessionId |
|||
filterLensId:(NSString *)filterLensId |
|||
underLowLightCondition:(BOOL)underLowLightCondition |
|||
isNightModeActive:(BOOL)isNightModeActive |
|||
isBackCamera:(BOOL)isBackCamera |
|||
isMainCamera:(BOOL)isMainCamera; |
|||
|
|||
- (void)logCameraCreationDelaySplitPointRecordingGestureFinished; |
|||
|
|||
- (void)logCameraCreationDelaySplitPointStillImageCaptureApi:(NSString *)api; |
|||
|
|||
- (void)logCameraCreationDelaySplitPointPreCaptureOperationRequested; |
|||
|
|||
- (void)logCameraCreationDelaySplitPointPreCaptureOperationFinishedAt:(CFTimeInterval)time; |
|||
|
|||
- (void)updatedCameraCreationDelayWithContentDuration:(CFTimeInterval)duration; |
|||
|
|||
- (void)logCameraCreationDelaySplitPointCameraCaptureContentReady; |
|||
|
|||
- (void)logCameraCreationDelaySplitPointPreviewFinishedPreparation; |
|||
|
|||
- (void)logCameraCreationDelaySplitPointPreviewDisplayedForImage:(BOOL)isImage; |
|||
|
|||
- (void)logCameraCreationDelaySplitPointPreviewAnimationComplete:(BOOL)isImage; |
|||
|
|||
- (void)logCameraCreationDelaySplitPointPreviewFirstFramePlayed:(BOOL)isImage; |
|||
|
|||
- (void)cancelCameraCreationDelayEvent; |
|||
|
|||
@end |
@ -0,0 +1,304 @@ |
|||
// |
|||
// SCCoreCameraLogger.m |
|||
// Snapchat |
|||
// |
|||
// Created by Chao Pang on 3/6/18. |
|||
// |
|||
|
|||
#import "SCCoreCameraLogger.h" |
|||
|
|||
#import <BlizzardSchema/SCAEvents.h> |
|||
#import <SCFoundation/SCQueuePerformer.h> |
|||
#import <SCGhostToSnappable/SCGhostToSnappableSignal.h> |
|||
#import <SCLogger/SCCameraMetrics+CameraCreationDelay.h> |
|||
|
|||
static const char *kSCCoreCameraLoggerQueueLabel = "com.snapchat.core-camera-logger-queue"; |
|||
|
|||
NSString *const kSCCameraCreationDelayEventStartTimeKey = @"start_time"; |
|||
NSString *const kSCCameraCreationDelayEventStartTimeAdjustmentKey = @"start_time_adjustment"; |
|||
NSString *const kSCCameraCreationDelayEventEndTimeKey = @"end_time"; |
|||
NSString *const kSCCameraCreationDelayEventCaptureSessionIdKey = @"capture_session_id"; |
|||
NSString *const kSCCameraCreationDelayEventFilterLensIdKey = @"filter_lens_id"; |
|||
NSString *const kSCCameraCreationDelayEventNightModeDetectedKey = @"night_mode_detected"; |
|||
NSString *const kSCCameraCreationDelayEventNightModeActiveKey = @"night_mode_active"; |
|||
NSString *const kSCCameraCreationDelayEventCameraApiKey = @"camera_api"; |
|||
NSString *const kSCCameraCreationDelayEventCameraLevelKey = @"camera_level"; |
|||
NSString *const kSCCameraCreationDelayEventCameraPositionKey = @"camera_position"; |
|||
NSString *const kSCCameraCreationDelayEventCameraOpenSourceKey = @"camera_open_source"; |
|||
NSString *const kSCCameraCreationDelayEventContentDurationKey = @"content_duration"; |
|||
NSString *const kSCCameraCreationDelayEventMediaTypeKey = @"media_type"; |
|||
NSString *const kSCCameraCreationDelayEventStartTypeKey = @"start_type"; |
|||
NSString *const kSCCameraCreationDelayEventStartSubTypeKey = @"start_sub_type"; |
|||
NSString *const kSCCameraCreationDelayEventAnalyticsVersion = @"ios_v1"; |
|||
|
|||
static inline NSUInteger SCTimeToMS(CFTimeInterval time) |
|||
{ |
|||
return (NSUInteger)(time * 1000); |
|||
} |
|||
|
|||
static NSString *SCDictionaryToJSONString(NSDictionary *dictionary) |
|||
{ |
|||
NSData *dictData = [NSJSONSerialization dataWithJSONObject:dictionary options:0 error:nil]; |
|||
return [[NSString alloc] initWithData:dictData encoding:NSUTF8StringEncoding]; |
|||
} |
|||
|
|||
@implementation SCCoreCameraLogger { |
|||
SCQueuePerformer *_performer; |
|||
NSMutableDictionary *_cameraCreationDelayParameters; |
|||
NSMutableDictionary *_cameraCreationDelaySplits; |
|||
} |
|||
|
|||
- (instancetype)init |
|||
{ |
|||
self = [super init]; |
|||
if (self) { |
|||
_cameraCreationDelayParameters = [NSMutableDictionary dictionary]; |
|||
_cameraCreationDelaySplits = [NSMutableDictionary dictionary]; |
|||
_performer = [[SCQueuePerformer alloc] initWithLabel:kSCCoreCameraLoggerQueueLabel |
|||
qualityOfService:QOS_CLASS_UNSPECIFIED |
|||
queueType:DISPATCH_QUEUE_SERIAL |
|||
context:SCQueuePerformerContextCoreCamera]; |
|||
} |
|||
return self; |
|||
} |
|||
|
|||
+ (instancetype)sharedInstance |
|||
{ |
|||
static SCCoreCameraLogger *sharedInstance; |
|||
static dispatch_once_t onceToken; |
|||
dispatch_once(&onceToken, ^{ |
|||
sharedInstance = [[SCCoreCameraLogger alloc] init]; |
|||
}); |
|||
return sharedInstance; |
|||
} |
|||
|
|||
// Camera creation delay metrics |
|||
|
|||
- (void)logCameraCreationDelayEventStartWithCaptureSessionId:(NSString *)captureSessionId |
|||
filterLensId:(NSString *)filterLensId |
|||
underLowLightCondition:(BOOL)underLowLightCondition |
|||
isNightModeActive:(BOOL)isNightModeActive |
|||
isBackCamera:(BOOL)isBackCamera |
|||
isMainCamera:(BOOL)isMainCamera |
|||
{ |
|||
CFTimeInterval startTime = CACurrentMediaTime(); |
|||
[_performer perform:^{ |
|||
[_cameraCreationDelayParameters removeAllObjects]; |
|||
[_cameraCreationDelaySplits removeAllObjects]; |
|||
_cameraCreationDelayParameters[kSCCameraCreationDelayEventStartTimeKey] = @(startTime); |
|||
_cameraCreationDelayParameters[kSCCameraCreationDelayEventCaptureSessionIdKey] = captureSessionId ?: @"null"; |
|||
_cameraCreationDelayParameters[kSCCameraCreationDelayEventFilterLensIdKey] = filterLensId ?: @"null"; |
|||
_cameraCreationDelayParameters[kSCCameraCreationDelayEventNightModeDetectedKey] = @(underLowLightCondition); |
|||
_cameraCreationDelayParameters[kSCCameraCreationDelayEventNightModeActiveKey] = @(isNightModeActive); |
|||
_cameraCreationDelayParameters[kSCCameraCreationDelayEventCameraPositionKey] = |
|||
isBackCamera ? @"back" : @"front"; |
|||
_cameraCreationDelayParameters[kSCCameraCreationDelayEventCameraOpenSourceKey] = |
|||
isMainCamera ? @"main_camera" : @"reply_camera"; |
|||
_cameraCreationDelayParameters[kSCCameraCreationDelayEventStartTypeKey] = SCLaunchType() ?: @"null"; |
|||
_cameraCreationDelayParameters[kSCCameraCreationDelayEventStartSubTypeKey] = SCLaunchSubType() ?: @"null"; |
|||
}]; |
|||
} |
|||
|
|||
- (void)logCameraCreationDelaySplitPointRecordingGestureFinished |
|||
{ |
|||
CFTimeInterval time = CACurrentMediaTime(); |
|||
[_performer perform:^{ |
|||
CFTimeInterval endRecordingTimeOffset = |
|||
time - [_cameraCreationDelayParameters[kSCCameraCreationDelayEventStartTimeKey] doubleValue]; |
|||
NSNumber *recordStartTimeMillis = |
|||
(NSNumber *)_cameraCreationDelaySplits[kSCCameraSubmetricsPreCaptureOperationFinished]; |
|||
if (recordStartTimeMillis) { |
|||
CFTimeInterval timeDisplacement = ([recordStartTimeMillis doubleValue] / 1000.0) - endRecordingTimeOffset; |
|||
_cameraCreationDelayParameters[kSCCameraCreationDelayEventStartTimeAdjustmentKey] = @(timeDisplacement); |
|||
} |
|||
[self _addSplitPointForKey:kSCCameraSubmetricsRecordingGestureFinished atTime:time]; |
|||
}]; |
|||
} |
|||
|
|||
- (void)logCameraCreationDelaySplitPointStillImageCaptureApi:(NSString *)api |
|||
{ |
|||
CFTimeInterval time = CACurrentMediaTime(); |
|||
[_performer perform:^{ |
|||
if (api) { |
|||
_cameraCreationDelayParameters[kSCCameraCreationDelayEventCameraApiKey] = api; |
|||
} |
|||
[self _addSplitPointForKey:kSCCameraSubmetricsPreCaptureOperationRequested atTime:time]; |
|||
}]; |
|||
} |
|||
|
|||
- (void)logCameraCreationDelaySplitPointPreCaptureOperationRequested |
|||
{ |
|||
CFTimeInterval time = CACurrentMediaTime(); |
|||
[_performer perform:^{ |
|||
[self _addSplitPointForKey:kSCCameraSubmetricsPreCaptureOperationRequested atTime:time]; |
|||
}]; |
|||
} |
|||
|
|||
- (void)logCameraCreationDelaySplitPointPreCaptureOperationFinishedAt:(CFTimeInterval)time |
|||
{ |
|||
[_performer perform:^{ |
|||
[self _addSplitPointForKey:kSCCameraSubmetricsPreCaptureOperationFinished atTime:time]; |
|||
}]; |
|||
} |
|||
|
|||
- (void)updatedCameraCreationDelayWithContentDuration:(CFTimeInterval)duration |
|||
{ |
|||
[_performer perform:^{ |
|||
_cameraCreationDelayParameters[kSCCameraCreationDelayEventContentDurationKey] = @(SCTimeToMS(duration)); |
|||
}]; |
|||
} |
|||
|
|||
- (void)logCameraCreationDelaySplitPointCameraCaptureContentReady |
|||
{ |
|||
CFTimeInterval time = CACurrentMediaTime(); |
|||
[_performer perform:^{ |
|||
[self _addSplitPointForKey:kSCCameraSubmetricsCameraCaptureContentReady atTime:time]; |
|||
}]; |
|||
} |
|||
|
|||
- (void)logCameraCreationDelaySplitPointPreviewFinishedPreparation |
|||
{ |
|||
CFTimeInterval time = CACurrentMediaTime(); |
|||
[_performer perform:^{ |
|||
[self _addSplitPointForKey:kSCCameraSubmetricsCameraCaptureContentReady atTime:time]; |
|||
}]; |
|||
} |
|||
|
|||
- (void)logCameraCreationDelaySplitPointPreviewDisplayedForImage:(BOOL)isImage |
|||
{ |
|||
CFTimeInterval time = CACurrentMediaTime(); |
|||
[_performer perform:^{ |
|||
[self _addSplitPointForKey:kSCCameraSubmetricsPreviewLayoutReady atTime:time]; |
|||
}]; |
|||
} |
|||
|
|||
- (void)logCameraCreationDelaySplitPointPreviewAnimationComplete:(BOOL)isImage |
|||
{ |
|||
CFTimeInterval time = CACurrentMediaTime(); |
|||
[_performer perform:^{ |
|||
[self _addSplitPointForKey:kSCCameraSubmetricsPreviewAnimationFinish atTime:time]; |
|||
if (_cameraCreationDelaySplits[kSCCameraSubmetricsPreviewPlayerReady]) { |
|||
[self _completeLogCameraCreationDelayEventWithIsImage:isImage atTime:time]; |
|||
} |
|||
}]; |
|||
} |
|||
|
|||
- (void)logCameraCreationDelaySplitPointPreviewFirstFramePlayed:(BOOL)isImage |
|||
{ |
|||
CFTimeInterval time = CACurrentMediaTime(); |
|||
[_performer perform:^{ |
|||
[self _addSplitPointForKey:kSCCameraSubmetricsPreviewPlayerReady atTime:time]; |
|||
if (_cameraCreationDelaySplits[kSCCameraSubmetricsPreviewAnimationFinish]) { |
|||
[self _completeLogCameraCreationDelayEventWithIsImage:isImage atTime:time]; |
|||
} |
|||
}]; |
|||
} |
|||
|
|||
- (void)cancelCameraCreationDelayEvent |
|||
{ |
|||
[_performer perform:^{ |
|||
[_cameraCreationDelayParameters removeAllObjects]; |
|||
[_cameraCreationDelaySplits removeAllObjects]; |
|||
}]; |
|||
} |
|||
|
|||
#pragma - Private methods |
|||
|
|||
- (void)_completeLogCameraCreationDelayEventWithIsImage:(BOOL)isImage atTime:(CFTimeInterval)time |
|||
{ |
|||
SCAssertPerformer(_performer); |
|||
if (_cameraCreationDelayParameters[kSCCameraCreationDelayEventCaptureSessionIdKey]) { |
|||
_cameraCreationDelayParameters[kSCCameraCreationDelayEventMediaTypeKey] = isImage ? @"image" : @"video"; |
|||
_cameraCreationDelayParameters[kSCCameraCreationDelayEventEndTimeKey] = @(time); |
|||
[self _logCameraCreationDelayBlizzardEvent]; |
|||
} |
|||
[_cameraCreationDelayParameters removeAllObjects]; |
|||
[_cameraCreationDelaySplits removeAllObjects]; |
|||
} |
|||
|
|||
- (void)_addSplitPointForKey:(NSString *)key atTime:(CFTimeInterval)time |
|||
{ |
|||
SCAssertPerformer(_performer); |
|||
if (key) { |
|||
CFTimeInterval timeOffset = |
|||
time - [_cameraCreationDelayParameters[kSCCameraCreationDelayEventStartTimeKey] doubleValue]; |
|||
NSNumber *timeAdjustment = |
|||
_cameraCreationDelayParameters[kSCCameraCreationDelayEventStartTimeAdjustmentKey] ?: @(0); |
|||
_cameraCreationDelaySplits[key] = @(SCTimeToMS(timeOffset + [timeAdjustment doubleValue])); |
|||
} |
|||
} |
|||
|
|||
- (void)_logCameraCreationDelayBlizzardEvent |
|||
{ |
|||
SCAssertPerformer(_performer); |
|||
SCASharedCameraMetricParams *sharedCameraMetricsParams = [[SCASharedCameraMetricParams alloc] init]; |
|||
[sharedCameraMetricsParams setAnalyticsVersion:kSCCameraCreationDelayEventAnalyticsVersion]; |
|||
NSString *mediaType = _cameraCreationDelayParameters[kSCCameraCreationDelayEventMediaTypeKey]; |
|||
if (mediaType) { |
|||
if ([mediaType isEqualToString:@"image"]) { |
|||
[sharedCameraMetricsParams setMediaType:SCAMediaType_IMAGE]; |
|||
} else if ([mediaType isEqualToString:@"video"]) { |
|||
[sharedCameraMetricsParams setMediaType:SCAMediaType_VIDEO]; |
|||
} |
|||
} |
|||
if (_cameraCreationDelayParameters[kSCCameraCreationDelayEventNightModeDetectedKey] && |
|||
_cameraCreationDelayParameters[kSCCameraCreationDelayEventNightModeActiveKey]) { |
|||
BOOL isNightModeDetected = |
|||
[_cameraCreationDelayParameters[kSCCameraCreationDelayEventNightModeDetectedKey] boolValue]; |
|||
BOOL isNightModeActive = |
|||
[_cameraCreationDelayParameters[kSCCameraCreationDelayEventNightModeActiveKey] boolValue]; |
|||
if (!isNightModeDetected) { |
|||
[sharedCameraMetricsParams setLowLightStatus:SCALowLightStatus_NOT_DETECTED]; |
|||
} else if (!isNightModeActive) { |
|||
[sharedCameraMetricsParams setLowLightStatus:SCALowLightStatus_DETECTED]; |
|||
} else if (isNightModeActive) { |
|||
[sharedCameraMetricsParams setLowLightStatus:SCALowLightStatus_ENABLED]; |
|||
} |
|||
} |
|||
|
|||
[sharedCameraMetricsParams setPowerMode:[[NSProcessInfo processInfo] isLowPowerModeEnabled] |
|||
? @"LOW_POWER_MODE_ENABLED" |
|||
: @"LOW_POWER_MODE_DISABLED"]; |
|||
[sharedCameraMetricsParams |
|||
setFilterLensId:_cameraCreationDelayParameters[kSCCameraCreationDelayEventFilterLensIdKey] ?: @"null"]; |
|||
[sharedCameraMetricsParams |
|||
setCaptureSessionId:_cameraCreationDelayParameters[kSCCameraCreationDelayEventCaptureSessionIdKey] ?: @"null"]; |
|||
[sharedCameraMetricsParams |
|||
setCameraApi:_cameraCreationDelayParameters[kSCCameraCreationDelayEventCameraApiKey] ?: @"null"]; |
|||
[sharedCameraMetricsParams |
|||
setCameraPosition:_cameraCreationDelayParameters[kSCCameraCreationDelayEventCameraPositionKey] ?: @"null"]; |
|||
[sharedCameraMetricsParams |
|||
setCameraOpenSource:_cameraCreationDelayParameters[kSCCameraCreationDelayEventCameraOpenSourceKey] ?: @"null"]; |
|||
[sharedCameraMetricsParams |
|||
setCameraLevel:_cameraCreationDelayParameters[kSCCameraCreationDelayEventCameraLevelKey] ?: @"null"]; |
|||
[sharedCameraMetricsParams |
|||
setStartType:_cameraCreationDelayParameters[kSCCameraCreationDelayEventStartTypeKey] ?: @"null"]; |
|||
[sharedCameraMetricsParams |
|||
setStartSubType:_cameraCreationDelayParameters[kSCCameraCreationDelayEventStartSubTypeKey] ?: @"null"]; |
|||
[sharedCameraMetricsParams setSplits:SCDictionaryToJSONString(_cameraCreationDelaySplits)]; |
|||
|
|||
SCACameraSnapCreateDelay *creationDelay = [[SCACameraSnapCreateDelay alloc] init]; |
|||
if (_cameraCreationDelayParameters[kSCCameraCreationDelayEventStartTimeKey] && |
|||
_cameraCreationDelayParameters[kSCCameraCreationDelayEventEndTimeKey]) { |
|||
double startTime = [_cameraCreationDelayParameters[kSCCameraCreationDelayEventStartTimeKey] doubleValue]; |
|||
double endTime = [_cameraCreationDelayParameters[kSCCameraCreationDelayEventEndTimeKey] doubleValue]; |
|||
NSNumber *timeAdjustment = |
|||
_cameraCreationDelayParameters[kSCCameraCreationDelayEventStartTimeAdjustmentKey] ?: @(0); |
|||
[creationDelay setLatencyMillis:SCTimeToMS(endTime - startTime + [timeAdjustment doubleValue])]; |
|||
} else { |
|||
[creationDelay setLatencyMillis:0]; |
|||
} |
|||
|
|||
if (_cameraCreationDelayParameters[kSCCameraCreationDelayEventContentDurationKey]) { |
|||
[creationDelay |
|||
setContentDurationMillis:SCTimeToMS( |
|||
[_cameraCreationDelayParameters[kSCCameraCreationDelayEventContentDurationKey] |
|||
doubleValue])]; |
|||
} else { |
|||
[creationDelay setContentDurationMillis:0]; |
|||
} |
|||
[creationDelay setSharedCameraMetricParams:sharedCameraMetricsParams]; |
|||
[[SCLogger sharedInstance] logUserTrackedEvent:creationDelay]; |
|||
} |
|||
|
|||
@end |
@ -0,0 +1,53 @@ |
|||
// |
|||
// SCLogger+Camera.h |
|||
// Snapchat |
|||
// |
|||
// Created by Derek Peirce on 5/8/17. |
|||
// Copyright © 2017 Snapchat, Inc. All rights reserved. |
|||
// |
|||
|
|||
#import "AVCameraViewEnums.h" |
|||
|
|||
#import <SCBase/SCSignPost.h> |
|||
#import <SCLogger/SCLogger.h> |
|||
|
|||
#import <CoreMedia/CoreMedia.h> |
|||
|
|||
typedef NS_ENUM(NSUInteger, CameraCreationDelayLoggingStatus) { |
|||
CAMERA_CREATION_DELAY_LOGGING_START, |
|||
CAMERA_CREATION_DELAY_LOGGINT_LAST_STEP, |
|||
CAMERA_CREATION_DELAY_LOGGING_END, |
|||
}; |
|||
|
|||
@interface SCLogger (Camera) |
|||
|
|||
@property (nonatomic, strong) NSNumber *cameraCreationDelayLoggingStatus; |
|||
|
|||
- (void)logCameraCreationStartWithMethod:(SCCameraRecordingMethod)method |
|||
lensesEnabled:(BOOL)lensesEnabled |
|||
activeLensId:(NSString *)activeLensId |
|||
captureSessionId:(NSString *)captureSessionId; |
|||
- (void)logStillImageCaptureApi:(NSString *)api; |
|||
- (void)logPreCaptureOperationRequestedAt:(CFTimeInterval)requestTime; |
|||
- (void)logPreCaptureOperationFinishedAt:(CFTimeInterval)time; |
|||
- (void)logCameraCaptureRecordingGestureFinishedAtTime:(CFTimeInterval)endRecordingTime; |
|||
- (void)logCameraCaptureFinishedWithDuration:(CFTimeInterval)duration; |
|||
- (void)logCameraCaptureContentReady; |
|||
- (void)logPreviewFinishedPreparation; |
|||
- (void)logPreviewDisplayedForImage:(BOOL)isImage; |
|||
- (void)logPreviewAnimationComplete:(BOOL)isImage; |
|||
- (void)logPreviewFirstFramePlayed:(BOOL)isImage; |
|||
- (void)cancelCameraCreationEvent; |
|||
|
|||
- (void)logRecordingMayBeTooShortWithMethod:(SCCameraRecordingMethod)method; |
|||
- (void)logRecordingWasTooShortWithFirstFrame:(CMTime)firstFrame |
|||
frontFacingCamera:(BOOL)isFrontFacing |
|||
cameraFlips:(NSInteger)cameraFlips; |
|||
|
|||
- (void)logManagedCapturerSettingFailure:(NSString *)settingTask error:(NSError *)error; |
|||
- (void)logCameraExposureAdjustmentDelayStart; |
|||
- (void)logCameraExposureAdjustmentDelayEndWithStrategy:(NSString *)strategy; |
|||
- (void)logCameraCreationDelaySubMetricsStartWithSignCode:(kSCSignPostCodeEnum)signPostCode; |
|||
- (void)logCameraCreationDelaySubMetricsEndWithSignCode:(kSCSignPostCodeEnum)signPostCod; |
|||
|
|||
@end |
@ -0,0 +1,303 @@ |
|||
// |
|||
// SCLogger+Camera.m |
|||
// Snapchat |
|||
// |
|||
// Created by Derek Peirce on 5/8/17. |
|||
// Copyright © 2017 Snapchat, Inc. All rights reserved. |
|||
// |
|||
|
|||
#import "SCLogger+Camera.h" |
|||
|
|||
#import "SCCameraTweaks.h" |
|||
|
|||
#import <SCFoundation/SCTrace.h> |
|||
#import <SCFoundation/SCTraceODPCompatible.h> |
|||
#import <SCLogger/SCCameraMetrics+CameraCreationDelay.h> |
|||
#import <SCLogger/SCCameraMetrics.h> |
|||
#import <SCLogger/SCLogger+Performance.h> |
|||
|
|||
#import <objc/runtime.h> |
|||
|
|||
@implementation SCLogger (Camera) |
|||
|
|||
@dynamic cameraCreationDelayLoggingStatus; |
|||
|
|||
- (NSNumber *)cameraCreationDelayLoggingStatus |
|||
{ |
|||
return objc_getAssociatedObject(self, @selector(cameraCreationDelayLoggingStatus)); |
|||
} |
|||
|
|||
- (void)setCameraCreationDelayLoggingStatus:(NSNumber *)status |
|||
{ |
|||
objc_setAssociatedObject(self, @selector(cameraCreationDelayLoggingStatus), status, |
|||
OBJC_ASSOCIATION_RETAIN_NONATOMIC); |
|||
} |
|||
|
|||
- (BOOL)shouldLogCameraCreationDelay |
|||
{ |
|||
return [[self cameraCreationDelayLoggingStatus] intValue] != CAMERA_CREATION_DELAY_LOGGING_END; |
|||
} |
|||
|
|||
- (void)logCameraCreationDelayEnd |
|||
{ |
|||
if ([[self cameraCreationDelayLoggingStatus] intValue] == CAMERA_CREATION_DELAY_LOGGINT_LAST_STEP) { |
|||
SCTraceSignPostEndForMetrics(kSCSignPostCameraCreationDelay, 0, 0, 0, 0); |
|||
[self setCameraCreationDelayLoggingStatus:@(CAMERA_CREATION_DELAY_LOGGING_END)]; |
|||
} else { |
|||
[self setCameraCreationDelayLoggingStatus:@(CAMERA_CREATION_DELAY_LOGGINT_LAST_STEP)]; |
|||
} |
|||
} |
|||
|
|||
- (void)logCameraCreationStartWithMethod:(SCCameraRecordingMethod)method |
|||
lensesEnabled:(BOOL)lensesEnabled |
|||
activeLensId:(NSString *)activeLensId |
|||
captureSessionId:(NSString *)captureSessionId |
|||
{ |
|||
NSMutableDictionary *parameters = [@{ |
|||
@"lens_ui_enabled" : @(lensesEnabled), |
|||
@"analytics_version" : kSCCameraDelayEventVersion, |
|||
@"method" : @(method), |
|||
} mutableCopy]; |
|||
if (lensesEnabled && activeLensId) { |
|||
[parameters setObject:activeLensId forKey:@"lens_id"]; |
|||
} |
|||
if (captureSessionId) { |
|||
[parameters setObject:captureSessionId forKey:@"capture_session_id"]; |
|||
} |
|||
[self setCameraCreationDelayLoggingStatus:@(CAMERA_CREATION_DELAY_LOGGING_START)]; |
|||
[self logCameraCreationDelaySubMetricsStartWithSignCode:kSCSignPostCameraCreationDelay]; |
|||
[self logCameraCreationDelaySubMetricsStartWithSignCode:kSCSignPostCameraRecordingGestureFinished]; |
|||
[self logCameraCreationDelaySubMetricsStartWithSignCode:kSCSignPostCameraPreCaptureOperationRequested]; |
|||
[[SCLogger sharedInstance] logTimedEventStart:kSCCameraCaptureDelayEvent |
|||
uniqueId:@"" |
|||
isUniqueEvent:NO |
|||
parameters:parameters |
|||
shouldLogStartTime:YES]; |
|||
} |
|||
|
|||
- (void)logCameraExposureAdjustmentDelayStart |
|||
{ |
|||
[[SCLogger sharedInstance] logTimedEventStart:kSCCameraExposureAdjustmentDelay |
|||
uniqueId:@"" |
|||
isUniqueEvent:NO |
|||
parameters:nil |
|||
shouldLogStartTime:YES]; |
|||
} |
|||
|
|||
- (void)logCameraExposureAdjustmentDelayEndWithStrategy:(NSString *)strategy |
|||
{ |
|||
[[SCLogger sharedInstance] logTimedEventEnd:kSCCameraExposureAdjustmentDelay |
|||
uniqueId:@"" |
|||
parameters:@{ |
|||
@"strategy" : strategy |
|||
}]; |
|||
} |
|||
|
|||
- (void)logCameraCaptureRecordingGestureFinishedAtTime:(CFTimeInterval)endRecordingTime |
|||
{ |
|||
[self logCameraCreationDelaySubMetricsEndWithSignCode:kSCSignPostCameraRecordingGestureFinished]; |
|||
[[SCLogger sharedInstance] |
|||
updateLogTimedEvent:kSCCameraCaptureDelayEvent |
|||
uniqueId:@"" |
|||
update:^(NSMutableDictionary *startParameters) { |
|||
NSMutableDictionary *eventParameters = |
|||
startParameters[SCPerformanceMetricsKey.kSCLoggerStartEventParametersKey]; |
|||
NSNumber *recordStartTime = |
|||
(NSNumber *)eventParameters[kSCCameraSubmetricsPreCaptureOperationFinished]; |
|||
CFTimeInterval endRecordingTimeOffset = |
|||
endRecordingTime - |
|||
[startParameters[SCPerformanceMetricsKey.kSCLoggerStartEventTimeKey] doubleValue]; |
|||
if (recordStartTime) { |
|||
CFTimeInterval timeDisplacement = |
|||
([recordStartTime doubleValue] / 1000.0) - endRecordingTimeOffset; |
|||
[eventParameters setObject:@(timeDisplacement) |
|||
forKey:SCPerformanceMetricsKey.kSCLoggerStartEventTimeAdjustmentKey]; |
|||
} |
|||
[self addSplitPoint:kSCCameraSubmetricsRecordingGestureFinished |
|||
atTime:endRecordingTime |
|||
toEvent:startParameters]; |
|||
}]; |
|||
} |
|||
|
|||
- (void)logStillImageCaptureApi:(NSString *)api |
|||
{ |
|||
[self logCameraCreationDelaySubMetricsEndWithSignCode:kSCSignPostCameraPreCaptureOperationRequested]; |
|||
[self logCameraCreationDelaySubMetricsStartWithSignCode:kSCSignPostCameraPreCaptureOperationFinished]; |
|||
[self logCameraCreationDelaySubMetricsStartWithSignCode:kSCSignPostCameraCaptureContentReady]; |
|||
CFTimeInterval requestTime = CACurrentMediaTime(); |
|||
[self updateLogTimedEvent:kSCCameraCaptureDelayEvent |
|||
uniqueId:@"" |
|||
update:^(NSMutableDictionary *startParameters) { |
|||
NSMutableDictionary *eventParameters = |
|||
startParameters[SCPerformanceMetricsKey.kSCLoggerStartEventParametersKey]; |
|||
[eventParameters setObject:api forKey:@"api_type"]; |
|||
[eventParameters setObject:@(1) forKey:@"camera_api_level"]; |
|||
[self addSplitPoint:@"PRE_CAPTURE_OPERATION_REQUESTED" |
|||
atTime:requestTime |
|||
toEvent:startParameters]; |
|||
}]; |
|||
} |
|||
|
|||
- (void)logPreCaptureOperationRequestedAt:(CFTimeInterval)requestTime |
|||
{ |
|||
[self logCameraCreationDelaySubMetricsEndWithSignCode:kSCSignPostCameraPreCaptureOperationRequested]; |
|||
[self logCameraCreationDelaySubMetricsStartWithSignCode:kSCSignPostCameraPreCaptureOperationFinished]; |
|||
[self logCameraCreationDelaySubMetricsStartWithSignCode:kSCSignPostCameraCaptureContentReady]; |
|||
[self updateLogTimedEvent:kSCCameraCaptureDelayEvent |
|||
uniqueId:@"" |
|||
splitPoint:kSCCameraSubmetricsPreCaptureOperationRequested |
|||
time:requestTime]; |
|||
} |
|||
|
|||
- (void)logPreCaptureOperationFinishedAt:(CFTimeInterval)time |
|||
{ |
|||
[self logCameraCreationDelaySubMetricsEndWithSignCode:kSCSignPostCameraPreCaptureOperationFinished]; |
|||
[self logCameraCreationDelaySubMetricsStartWithSignCode:kSCSignPostCameraPreviewPlayerReady]; |
|||
[self updateLogTimedEvent:kSCCameraCaptureDelayEvent |
|||
uniqueId:@"" |
|||
splitPoint:kSCCameraSubmetricsPreCaptureOperationFinished |
|||
time:time]; |
|||
} |
|||
|
|||
- (void)logCameraCaptureFinishedWithDuration:(CFTimeInterval)duration |
|||
{ |
|||
[[SCLogger sharedInstance] |
|||
updateLogTimedEvent:kSCCameraCaptureDelayEvent |
|||
uniqueId:@"" |
|||
update:^(NSMutableDictionary *startParameters) { |
|||
NSMutableDictionary *eventParameters = |
|||
startParameters[SCPerformanceMetricsKey.kSCLoggerStartEventParametersKey]; |
|||
[eventParameters setObject:@(SCTimeInMillisecond(duration)) forKey:@"content_duration"]; |
|||
}]; |
|||
} |
|||
|
|||
- (void)logCameraCaptureContentReady |
|||
{ |
|||
[self logCameraCreationDelaySubMetricsEndWithSignCode:kSCSignPostCameraCaptureContentReady]; |
|||
[[SCLogger sharedInstance] updateLogTimedEvent:kSCCameraCaptureDelayEvent |
|||
uniqueId:@"" |
|||
splitPoint:kSCCameraSubmetricsCameraCaptureContentReady]; |
|||
} |
|||
|
|||
- (void)logPreviewFinishedPreparation |
|||
{ |
|||
[self logCameraCreationDelaySubMetricsEndWithSignCode:kSCSignPostCameraPreviewFinishPreparation]; |
|||
[self logCameraCreationDelaySubMetricsStartWithSignCode:kSCSignPostCameraPreviewAnimationFinish]; |
|||
[self updateLogTimedEvent:kSCCameraCaptureDelayEvent |
|||
uniqueId:@"" |
|||
splitPoint:kSCCameraSubmetricsPreviewFinishPreparation]; |
|||
} |
|||
|
|||
- (void)logPreviewDisplayedForImage:(BOOL)isImage |
|||
{ |
|||
[self logCameraCreationDelaySubMetricsEndWithSignCode:kSCSignPostCameraPreviewLayoutReady]; |
|||
[self updateLogTimedEvent:kSCCameraCaptureDelayEvent uniqueId:@"" splitPoint:kSCCameraSubmetricsPreviewLayoutReady]; |
|||
} |
|||
|
|||
- (void)logPreviewAnimationComplete:(BOOL)isImage |
|||
{ |
|||
[self updateLogTimedEvent:kSCCameraCaptureDelayEvent |
|||
uniqueId:@"" |
|||
splitPoint:kSCCameraSubmetricsPreviewAnimationFinish]; |
|||
[self logCameraCreationDelaySubMetricsEndWithSignCode:kSCSignPostCameraPreviewAnimationFinish]; |
|||
[self logCameraCreationDelayEnd]; |
|||
[self conditionallyLogTimedEventEnd:kSCCameraCaptureDelayEvent |
|||
uniqueId:@"" |
|||
parameters:@{ |
|||
@"type" : isImage ? @"image" : @"video", |
|||
} |
|||
shouldLog:^BOOL(NSDictionary *startParameters) { |
|||
// For video, PREVIEW_PLAYER_READY and PREVIEW_ANIMATION_FINISH can happen in either |
|||
// order. So here we check for existence of this key, and end timer if the other |
|||
// event have happened. |
|||
NSMutableDictionary *eventParameters = |
|||
startParameters[SCPerformanceMetricsKey.kSCLoggerStartEventParametersKey]; |
|||
return eventParameters[kSCCameraSubmetricsPreviewPlayerReady] != nil; |
|||
}]; |
|||
} |
|||
|
|||
- (void)logPreviewFirstFramePlayed:(BOOL)isImage |
|||
{ |
|||
[self updateLogTimedEvent:kSCCameraCaptureDelayEvent uniqueId:@"" splitPoint:kSCCameraSubmetricsPreviewPlayerReady]; |
|||
[self logCameraCreationDelaySubMetricsEndWithSignCode:kSCSignPostCameraPreviewPlayerReady]; |
|||
[self logCameraCreationDelayEnd]; |
|||
[self conditionallyLogTimedEventEnd:kSCCameraCaptureDelayEvent |
|||
uniqueId:@"" |
|||
parameters:@{ |
|||
@"type" : isImage ? @"image" : @"video", |
|||
} |
|||
shouldLog:^BOOL(NSDictionary *startParameters) { |
|||
NSMutableDictionary *eventParameters = |
|||
startParameters[SCPerformanceMetricsKey.kSCLoggerStartEventParametersKey]; |
|||
// See the comment above for PREVIEW_PLAYER_READY and PREVIEW_ANIMATION_FINISH. |
|||
return eventParameters[kSCCameraSubmetricsPreviewAnimationFinish] != nil; |
|||
}]; |
|||
} |
|||
|
|||
- (void)cancelCameraCreationEvent |
|||
{ |
|||
[self cancelLogTimedEvent:kSCCameraCaptureDelayEvent uniqueId:@""]; |
|||
} |
|||
|
|||
- (void)logRecordingMayBeTooShortWithMethod:(SCCameraRecordingMethod)method |
|||
{ |
|||
[[SCLogger sharedInstance] cancelLogTimedEvent:kSCCameraMetricsRecordingTooShort uniqueId:@""]; |
|||
[[SCLogger sharedInstance] logTimedEventStart:kSCCameraMetricsRecordingTooShort |
|||
uniqueId:@"" |
|||
isUniqueEvent:NO |
|||
parameters:@{ |
|||
@"method" : @(method), |
|||
@"analytics_version" : kSCCameraRecordingTooShortVersion, |
|||
} |
|||
shouldLogStartTime:YES]; |
|||
} |
|||
|
|||
- (void)logRecordingWasTooShortWithFirstFrame:(CMTime)firstFrame |
|||
frontFacingCamera:(BOOL)isFrontFacing |
|||
cameraFlips:(NSInteger)cameraFlips |
|||
{ |
|||
[self logTimedEventEnd:kSCCameraMetricsRecordingTooShort |
|||
uniqueId:@"" |
|||
update:^(NSDictionary *startParameters, CFTimeInterval eventEndTime, CFTimeInterval adjustedTime) { |
|||
NSMutableDictionary *eventParameters = |
|||
startParameters[SCPerformanceMetricsKey.kSCLoggerStartEventParametersKey]; |
|||
if (CMTIME_IS_VALID(firstFrame)) { |
|||
CFTimeInterval startTime = |
|||
[startParameters[SCPerformanceMetricsKey.kSCLoggerStartEventTimeKey] doubleValue]; |
|||
CFTimeInterval firstFrameRelative = CMTimeGetSeconds(firstFrame) - startTime; |
|||
[eventParameters setObject:@(firstFrameRelative) forKey:@"first_frame_s"]; |
|||
} |
|||
[eventParameters setObject:@(isFrontFacing) forKey:@"is_front_facing"]; |
|||
if (cameraFlips) { |
|||
[eventParameters setObject:@(cameraFlips > 0) forKey:@"has_camera_been_flipped"]; |
|||
} |
|||
}]; |
|||
} |
|||
|
|||
- (void)logManagedCapturerSettingFailure:(NSString *)settingTask error:(NSError *)error |
|||
{ |
|||
NSMutableDictionary *parameters = [[NSMutableDictionary alloc] init]; |
|||
parameters[@"setting_task"] = settingTask; |
|||
if (error) { |
|||
parameters[@"setting error"] = error; |
|||
} |
|||
[[SCLogger sharedInstance] logTimedEventEnd:kSCCameraManagedCaptureSettingFailure |
|||
uniqueId:@"" |
|||
parameters:parameters]; |
|||
} |
|||
|
|||
- (void)logCameraCreationDelaySubMetricsStartWithSignCode:(kSCSignPostCodeEnum)signPostCode |
|||
{ |
|||
if ([self shouldLogCameraCreationDelay]) { |
|||
SCTraceSignPostStartForMetrics(signPostCode, 0, 0, 0, 0); |
|||
} |
|||
} |
|||
|
|||
- (void)logCameraCreationDelaySubMetricsEndWithSignCode:(kSCSignPostCodeEnum)signPostCode |
|||
{ |
|||
if ([self shouldLogCameraCreationDelay]) { |
|||
SCTraceSignPostEndForMetrics(signPostCode, 0, 0, 0, 0); |
|||
} |
|||
} |
|||
|
|||
@end |
@ -0,0 +1,24 @@ |
|||
// |
|||
// SCManiphestTicketCreator.h |
|||
// SCCamera |
|||
// |
|||
// Created by Michel Loenngren on 4/16/18. |
|||
// |
|||
|
|||
#import <Foundation/Foundation.h> |
|||
|
|||
/** |
|||
Protocol for filing jira tickets and beta s2r. |
|||
*/ |
|||
@protocol SCManiphestTicketCreator |
|||
|
|||
- (void)createAndFile:(NSData *)image |
|||
creationTime:(long)reportCreationTime |
|||
description:(NSString *)bugDescription |
|||
email:(NSString *)otherEmail |
|||
project:(NSString *)projectName |
|||
subproject:(NSString *)subprojectName; |
|||
|
|||
- (void)createAndFileBetaReport:(NSString *)msg; |
|||
|
|||
@end |
Write
Preview
Loading…
Cancel
Save
Reference in new issue