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.

92 lines
2.3 KiB

  1. //
  2. // SCBlackCameraPreviewDetector.m
  3. // Snapchat
  4. //
  5. // Created by Derek Wang on 25/01/2018.
  6. //
  7. #import "SCBlackCameraPreviewDetector.h"
  8. #import "SCBlackCameraReporter.h"
  9. #import "SCMetalUtils.h"
  10. #import <SCCrashLogger/SCCrashLogger.h>
  11. #import <SCFoundation/SCQueuePerformer.h>
  12. #import <SCFoundation/SCThreadHelpers.h>
  13. #import <SCFoundation/SCZeroDependencyExperiments.h>
  14. // Check whether preview is visible when AVCaptureSession is running
  15. static CGFloat const kSCBlackCameraCheckingDelay = 0.5;
  16. @interface SCBlackCameraPreviewDetector () {
  17. BOOL _previewVisible;
  18. dispatch_block_t _checkingBlock;
  19. }
  20. @property (nonatomic) SCQueuePerformer *queuePerformer;
  21. @property (nonatomic) SCBlackCameraReporter *reporter;
  22. @end
  23. @implementation SCBlackCameraPreviewDetector
  24. - (instancetype)initWithPerformer:(SCQueuePerformer *)performer reporter:(SCBlackCameraReporter *)reporter
  25. {
  26. self = [super init];
  27. if (self) {
  28. _queuePerformer = performer;
  29. _reporter = reporter;
  30. }
  31. return self;
  32. }
  33. - (void)capturePreviewDidBecomeVisible:(BOOL)visible
  34. {
  35. [_queuePerformer perform:^{
  36. _previewVisible = visible;
  37. }];
  38. }
  39. - (void)sessionDidChangeIsRunning:(BOOL)running
  40. {
  41. if (running) {
  42. [self _scheduleCheck];
  43. } else {
  44. [_queuePerformer perform:^{
  45. if (_checkingBlock) {
  46. dispatch_block_cancel(_checkingBlock);
  47. _checkingBlock = nil;
  48. }
  49. }];
  50. }
  51. }
  52. - (void)_scheduleCheck
  53. {
  54. [_queuePerformer perform:^{
  55. @weakify(self);
  56. _checkingBlock = dispatch_block_create(0, ^{
  57. @strongify(self);
  58. SC_GUARD_ELSE_RETURN(self);
  59. self->_checkingBlock = nil;
  60. [self _checkPreviewState];
  61. });
  62. [_queuePerformer perform:_checkingBlock after:kSCBlackCameraCheckingDelay];
  63. }];
  64. }
  65. - (void)_checkPreviewState
  66. {
  67. if (!_previewVisible) {
  68. runOnMainThreadAsynchronously(^{
  69. // Make sure the app is in foreground
  70. SC_GUARD_ELSE_RETURN([UIApplication sharedApplication].applicationState == UIApplicationStateActive);
  71. SCBlackCameraCause cause =
  72. SCDeviceSupportsMetal() ? SCBlackCameraRenderingPaused : SCBlackCameraPreviewIsHidden;
  73. [_reporter reportBlackCameraWithCause:cause];
  74. [_reporter fileShakeTicketWithCause:cause];
  75. });
  76. }
  77. }
  78. @end