1ce247f03SCharlie Cruzan// Copyright 2018-present 650 Industries. All rights reserved.
2ce247f03SCharlie Cruzan
3ce247f03SCharlie Cruzan#import <EXScreenCapture/EXScreenCaptureModule.h>
4ce247f03SCharlie Cruzan
5*80a34b81SCharlie Cruzan#import <UMCore/UMEventEmitterService.h>
6*80a34b81SCharlie Cruzan
7*80a34b81SCharlie Cruzanstatic NSString * const onScreenshotEventName = @"onScreenshot";
8*80a34b81SCharlie Cruzan
9ce247f03SCharlie Cruzan@interface EXScreenCaptureModule ()
10ce247f03SCharlie Cruzan
11ce247f03SCharlie Cruzan@property (nonatomic, weak) UMModuleRegistry *moduleRegistry;
12*80a34b81SCharlie Cruzan@property (nonatomic, assign) BOOL isListening;
13*80a34b81SCharlie Cruzan@property (nonatomic, assign) BOOL isBeingObserved;
14*80a34b81SCharlie Cruzan@property (nonatomic, weak) id<UMEventEmitterService> eventEmitter;
15ce247f03SCharlie Cruzan
16ce247f03SCharlie Cruzan@end
17ce247f03SCharlie Cruzan
18ce247f03SCharlie Cruzan@implementation EXScreenCaptureModule {
19ce247f03SCharlie Cruzan  UIView *_blockView;
20ce247f03SCharlie Cruzan}
21ce247f03SCharlie Cruzan
22*80a34b81SCharlie CruzanUM_EXPORT_MODULE(ExpoScreenCapture);
23*80a34b81SCharlie Cruzan
24*80a34b81SCharlie Cruzan# pragma mark - UMModuleRegistryConsumer
25*80a34b81SCharlie Cruzan
26*80a34b81SCharlie Cruzan- (void)setModuleRegistry:(UMModuleRegistry *)moduleRegistry
27*80a34b81SCharlie Cruzan{
28*80a34b81SCharlie Cruzan  _moduleRegistry = moduleRegistry;
29*80a34b81SCharlie Cruzan  _eventEmitter = [moduleRegistry getModuleImplementingProtocol:@protocol(UMEventEmitterService)];
30*80a34b81SCharlie Cruzan}
31*80a34b81SCharlie Cruzan
32ce247f03SCharlie Cruzan- (instancetype)init {
33ce247f03SCharlie Cruzan  if (self = [super init]) {
34ce247f03SCharlie Cruzan    CGFloat boundLength = MAX([[UIScreen mainScreen] bounds].size.width, [[UIScreen mainScreen] bounds].size.height);
35ce247f03SCharlie Cruzan    _blockView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, boundLength, boundLength)];
36ce247f03SCharlie Cruzan    _blockView.backgroundColor = UIColor.blackColor;
37ce247f03SCharlie Cruzan  }
38ce247f03SCharlie Cruzan  return self;
39ce247f03SCharlie Cruzan}
40ce247f03SCharlie Cruzan
41*80a34b81SCharlie Cruzan# pragma mark - Exported methods
42ce247f03SCharlie Cruzan
43ce247f03SCharlie CruzanUM_EXPORT_METHOD_AS(preventScreenCapture,
44ce247f03SCharlie Cruzan                    preventScreenCaptureWithResolver:(UMPromiseResolveBlock)resolve
45ce247f03SCharlie Cruzan                    reject:(UMPromiseRejectBlock)reject)
46ce247f03SCharlie Cruzan{
47ce247f03SCharlie Cruzan  if (@available(iOS 11.0, *) ) {
48ce247f03SCharlie Cruzan    // If already recording, block it
49ce247f03SCharlie Cruzan    dispatch_async(dispatch_get_main_queue(), ^{
50ce247f03SCharlie Cruzan      [self preventScreenRecording];
51ce247f03SCharlie Cruzan    });
52ce247f03SCharlie Cruzan
53ce247f03SCharlie Cruzan    // Avoid setting duplicate observers
54ce247f03SCharlie Cruzan    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIScreenCapturedDidChangeNotification object:nil];
55ce247f03SCharlie Cruzan
56ce247f03SCharlie Cruzan    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(preventScreenRecording) name:UIScreenCapturedDidChangeNotification object:nil];
57ce247f03SCharlie Cruzan  }
58ce247f03SCharlie Cruzan
59ce247f03SCharlie Cruzan  resolve([NSNull null]);
60ce247f03SCharlie Cruzan}
61ce247f03SCharlie Cruzan
62ce247f03SCharlie CruzanUM_EXPORT_METHOD_AS(allowScreenCapture,
63ce247f03SCharlie Cruzan                    allowScreenCaptureWithResolver:(UMPromiseResolveBlock)resolve
64ce247f03SCharlie Cruzan                    rejecter:(UMPromiseRejectBlock)reject)
65ce247f03SCharlie Cruzan{
66ce247f03SCharlie Cruzan  if (@available(iOS 11.0, *)) {
67ce247f03SCharlie Cruzan    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIScreenCapturedDidChangeNotification object:nil];
68ce247f03SCharlie Cruzan  }
69ce247f03SCharlie Cruzan
70ce247f03SCharlie Cruzan  resolve([NSNull null]);
71ce247f03SCharlie Cruzan}
72ce247f03SCharlie Cruzan
73ce247f03SCharlie Cruzan- (void)preventScreenRecording {
74ce247f03SCharlie Cruzan  if (@available(iOS 11.0, *)) {
75ce247f03SCharlie Cruzan    BOOL isCaptured = [[UIScreen mainScreen] isCaptured];
76ce247f03SCharlie Cruzan
77ce247f03SCharlie Cruzan    if (isCaptured) {
78ce247f03SCharlie Cruzan      [UIApplication.sharedApplication.keyWindow.subviews.firstObject addSubview:_blockView];
79ce247f03SCharlie Cruzan    } else {
80ce247f03SCharlie Cruzan      [_blockView removeFromSuperview];
81ce247f03SCharlie Cruzan    }
82ce247f03SCharlie Cruzan  }
83ce247f03SCharlie Cruzan}
84ce247f03SCharlie Cruzan
85*80a34b81SCharlie Cruzan# pragma mark - UMEventEmitter
86*80a34b81SCharlie Cruzan
87*80a34b81SCharlie Cruzan- (NSArray<NSString *> *)supportedEvents
88*80a34b81SCharlie Cruzan{
89*80a34b81SCharlie Cruzan  return @[onScreenshotEventName];
90*80a34b81SCharlie Cruzan}
91*80a34b81SCharlie Cruzan
92*80a34b81SCharlie Cruzan- (void)startObserving
93*80a34b81SCharlie Cruzan{
94*80a34b81SCharlie Cruzan  [self setIsBeingObserved:YES];
95*80a34b81SCharlie Cruzan}
96*80a34b81SCharlie Cruzan
97*80a34b81SCharlie Cruzan- (void)stopObserving
98*80a34b81SCharlie Cruzan{
99*80a34b81SCharlie Cruzan  [self setIsBeingObserved:NO];
100*80a34b81SCharlie Cruzan}
101*80a34b81SCharlie Cruzan
102*80a34b81SCharlie Cruzan- (void)setIsBeingObserved:(BOOL)isBeingObserved
103*80a34b81SCharlie Cruzan{
104*80a34b81SCharlie Cruzan  _isBeingObserved = isBeingObserved;
105*80a34b81SCharlie Cruzan  BOOL shouldListen = _isBeingObserved;
106*80a34b81SCharlie Cruzan  if (shouldListen && !_isListening) {
107*80a34b81SCharlie Cruzan    // Avoid setting duplicate observers
108*80a34b81SCharlie Cruzan    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationUserDidTakeScreenshotNotification object:nil];
109*80a34b81SCharlie Cruzan    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(listenForScreenCapture) name:UIApplicationUserDidTakeScreenshotNotification object:nil];
110*80a34b81SCharlie Cruzan    _isListening = YES;
111*80a34b81SCharlie Cruzan  } else if (!shouldListen && _isListening) {
112*80a34b81SCharlie Cruzan    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationUserDidTakeScreenshotNotification object:nil];
113*80a34b81SCharlie Cruzan    _isListening = NO;
114*80a34b81SCharlie Cruzan  }
115*80a34b81SCharlie Cruzan}
116*80a34b81SCharlie Cruzan
117*80a34b81SCharlie Cruzan- (void)listenForScreenCapture
118*80a34b81SCharlie Cruzan{
119*80a34b81SCharlie Cruzan  [_eventEmitter sendEventWithName:onScreenshotEventName body:nil];
120*80a34b81SCharlie Cruzan}
121*80a34b81SCharlie Cruzan
122ce247f03SCharlie Cruzan@end
123