2014 snapchat source code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

226 lines
7.6 KiB

  1. //
  2. // SCFeatureFlashImpl.m
  3. // SCCamera
  4. //
  5. // Created by Kristian Bauer on 3/27/18.
  6. //
  7. #import "SCFeatureFlashImpl.h"
  8. #import "SCCapturer.h"
  9. #import "SCFlashButton.h"
  10. #import "SCManagedCapturerListener.h"
  11. #import "SCManagedCapturerState.h"
  12. #import <SCFoundation/SCLocale.h>
  13. #import <SCFoundation/SCLog.h>
  14. #import <SCFoundation/SCTraceODPCompatible.h>
  15. #import <SCLogger/SCLogger.h>
  16. #import <SCUIKit/SCNavigationBarButtonItem.h>
  17. static CGFloat const kSCFlashButtonInsets = -2.f;
  18. static CGRect const kSCFlashButtonFrame = {0, 0, 36, 44};
  19. static NSString *const kSCFlashEventName = @"TOGGLE_CAMERA_FLASH_BUTTON";
  20. static NSString *const kSCFlashEventParameterFlashName = @"flash_on";
  21. static NSString *const kSCFlashEventParameterCameraName = @"front_facing_camera_on";
  22. @interface SCFeatureFlashImpl ()
  23. @property (nonatomic, strong, readwrite) id<SCCapturer> capturer;
  24. @property (nonatomic, strong, readwrite) SCLogger *logger;
  25. @property (nonatomic, strong, readwrite) SCFlashButton *flashButton;
  26. @property (nonatomic, weak, readwrite) UIView<SCFeatureContainerView> *containerView;
  27. @property (nonatomic, strong, readwrite) SCManagedCapturerState *managedCapturerState;
  28. @property (nonatomic, assign, readwrite) BOOL canEnable;
  29. @end
  30. @interface SCFeatureFlashImpl (SCManagedCapturerListener) <SCManagedCapturerListener>
  31. @end
  32. @implementation SCFeatureFlashImpl
  33. @synthesize navigationBarButtonItem = _navigationBarButtonItem;
  34. - (instancetype)initWithCapturer:(id<SCCapturer>)capturer logger:(SCLogger *)logger
  35. {
  36. SCTraceODPCompatibleStart(2);
  37. self = [super init];
  38. if (self) {
  39. _capturer = capturer;
  40. [_capturer addListener:self];
  41. _logger = logger;
  42. }
  43. return self;
  44. }
  45. - (void)dealloc
  46. {
  47. SCTraceODPCompatibleStart(2);
  48. [_capturer removeListener:self];
  49. }
  50. #pragma mark - SCFeature
  51. - (void)configureWithView:(UIView<SCFeatureContainerView> *)view
  52. {
  53. SCTraceODPCompatibleStart(2);
  54. _containerView = view;
  55. }
  56. - (BOOL)shouldBlockTouchAtPoint:(CGPoint)point
  57. {
  58. SCTraceODPCompatibleStart(2);
  59. SC_GUARD_ELSE_RETURN_VALUE(_flashButton.userInteractionEnabled && !_flashButton.hidden, NO);
  60. CGPoint convertedPoint = [_flashButton convertPoint:point fromView:_containerView];
  61. return [_flashButton pointInside:convertedPoint withEvent:nil];
  62. }
  63. #pragma mark - SCFeatureFlash
  64. - (void)interruptGestures
  65. {
  66. SCTraceODPCompatibleStart(2);
  67. [_flashButton interruptGestures];
  68. }
  69. - (SCNavigationBarButtonItem *)navigationBarButtonItem
  70. {
  71. SCTraceODPCompatibleStart(2);
  72. SC_GUARD_ELSE_RETURN_VALUE(!_navigationBarButtonItem, _navigationBarButtonItem);
  73. _navigationBarButtonItem = [[SCNavigationBarButtonItem alloc] initWithCustomView:self.flashButton];
  74. return _navigationBarButtonItem;
  75. }
  76. #pragma mark - Getters
  77. - (SCFlashButton *)flashButton
  78. {
  79. SCTraceODPCompatibleStart(2);
  80. SC_GUARD_ELSE_RETURN_VALUE(!_flashButton, _flashButton);
  81. _flashButton = [[SCFlashButton alloc] initWithFrame:kSCFlashButtonFrame];
  82. _flashButton.layer.sublayerTransform = CATransform3DMakeTranslation(kSCFlashButtonInsets, 0, 0);
  83. _flashButton.buttonState = SCFlashButtonStateOff;
  84. _flashButton.maximumScale = 1.1111f;
  85. [_flashButton addTarget:self action:@selector(_flashTapped)];
  86. _flashButton.accessibilityIdentifier = @"flash";
  87. _flashButton.accessibilityLabel = SCLocalizedString(@"flash", 0);
  88. return _flashButton;
  89. }
  90. #pragma mark - Setters
  91. - (void)setCanEnable:(BOOL)canEnable
  92. {
  93. SCTraceODPCompatibleStart(2);
  94. SCLogCameraFeatureInfo(@"[%@] setCanEnable new: %@ old: %@", NSStringFromClass([self class]),
  95. canEnable ? @"YES" : @"NO", _canEnable ? @"YES" : @"NO");
  96. self.flashButton.userInteractionEnabled = canEnable;
  97. }
  98. #pragma mark - Internal Helpers
  99. - (void)_flashTapped
  100. {
  101. SCTraceODPCompatibleStart(2);
  102. BOOL flashActive = !_managedCapturerState.flashActive;
  103. SCLogCameraFeatureInfo(@"[%@] _flashTapped flashActive new: %@ old: %@", NSStringFromClass([self class]),
  104. flashActive ? @"YES" : @"NO", !flashActive ? @"YES" : @"NO");
  105. _containerView.userInteractionEnabled = NO;
  106. @weakify(self);
  107. [_capturer setFlashActive:flashActive
  108. completionHandler:^{
  109. @strongify(self);
  110. SCLogCameraFeatureInfo(@"[%@] _flashTapped setFlashActive completion", NSStringFromClass([self class]));
  111. self.containerView.userInteractionEnabled = YES;
  112. }
  113. context:SCCapturerContext];
  114. NSDictionary *loggingParameters = @{
  115. kSCFlashEventParameterFlashName : @(flashActive),
  116. kSCFlashEventParameterCameraName :
  117. @(_managedCapturerState.devicePosition == SCManagedCaptureDevicePositionFront)
  118. };
  119. [_logger logEvent:kSCFlashEventName parameters:loggingParameters];
  120. }
  121. - (BOOL)_shouldHideForState:(SCManagedCapturerState *)state
  122. {
  123. SCTraceODPCompatibleStart(2);
  124. return (!state.flashSupported && !state.torchSupported &&
  125. state.devicePosition != SCManagedCaptureDevicePositionFront) ||
  126. state.arSessionActive;
  127. }
  128. @end
  129. @implementation SCFeatureFlashImpl (SCManagedCapturerListener)
  130. - (void)managedCapturer:(id<SCCapturer>)managedCapturer didChangeFlashActive:(SCManagedCapturerState *)state
  131. {
  132. SCTraceODPCompatibleStart(2);
  133. SCLogCameraFeatureInfo(@"[%@] didChangeFlashActive flashActive: %@", NSStringFromClass([self class]),
  134. state.flashActive ? @"YES" : @"NO");
  135. self.flashButton.buttonState = state.flashActive ? SCFlashButtonStateOn : SCFlashButtonStateOff;
  136. }
  137. - (void)managedCapturer:(id<SCCapturer>)managedCapturer
  138. didChangeFlashSupportedAndTorchSupported:(SCManagedCapturerState *)state
  139. {
  140. SCTraceODPCompatibleStart(2);
  141. SCLogCameraFeatureInfo(
  142. @"[%@] didChangeFlashSupportedAndTorchSupported flashSupported: %@ torchSupported: %@ devicePosition: %@",
  143. NSStringFromClass([self class]), state.flashSupported ? @"YES" : @"NO", state.torchSupported ? @"YES" : @"NO",
  144. state.devicePosition == SCManagedCaptureDevicePositionFront ? @"front" : @"back");
  145. self.flashButton.hidden = [self _shouldHideForState:state];
  146. }
  147. - (void)managedCapturer:(id<SCCapturer>)managedCapturer didChangeState:(SCManagedCapturerState *)state
  148. {
  149. SCTraceODPCompatibleStart(2);
  150. _managedCapturerState = [state copy];
  151. }
  152. - (void)managedCapturer:(id<SCCapturer>)managedCapturer didChangeARSessionActive:(SCManagedCapturerState *)state
  153. {
  154. SCTraceODPCompatibleStart(2);
  155. SCLogCameraFeatureInfo(@"[%@] didChangeARSessionActive: %@", NSStringFromClass([self class]),
  156. state.arSessionActive ? @"YES" : @"NO");
  157. self.flashButton.hidden = [self _shouldHideForState:state];
  158. }
  159. - (void)managedCapturer:(id<SCCapturer>)managedCapturer
  160. didBeginVideoRecording:(SCManagedCapturerState *)state
  161. session:(SCVideoCaptureSessionInfo)session
  162. {
  163. SCTraceODPCompatibleStart(2);
  164. self.canEnable = NO;
  165. }
  166. - (void)managedCapturer:(id<SCCapturer>)managedCapturer
  167. didFinishRecording:(SCManagedCapturerState *)state
  168. session:(SCVideoCaptureSessionInfo)session
  169. recordedVideo:(SCManagedRecordedVideo *)recordedVideo
  170. {
  171. SCTraceODPCompatibleStart(2);
  172. self.canEnable = YES;
  173. }
  174. - (void)managedCapturer:(id<SCCapturer>)managedCapturer
  175. didFailRecording:(SCManagedCapturerState *)state
  176. session:(SCVideoCaptureSessionInfo)session
  177. error:(NSError *)error
  178. {
  179. SCTraceODPCompatibleStart(2);
  180. self.canEnable = YES;
  181. }
  182. - (void)managedCapturer:(id<SCCapturer>)managedCapturer
  183. didCancelRecording:(SCManagedCapturerState *)state
  184. session:(SCVideoCaptureSessionInfo)session
  185. {
  186. SCTraceODPCompatibleStart(2);
  187. self.canEnable = YES;
  188. }
  189. @end