1ce247f03SCharlie Cruzan// Copyright 2018-present 650 Industries. All rights reserved.
2ce247f03SCharlie Cruzan
3ce247f03SCharlie Cruzan#import <EXScreenCapture/EXScreenCaptureModule.h>
4ce247f03SCharlie Cruzan
5*efd75decSTomasz Sapeta#import <ExpoModulesCore/EXEventEmitterService.h>
680a34b81SCharlie Cruzan
780a34b81SCharlie Cruzanstatic NSString * const onScreenshotEventName = @"onScreenshot";
880a34b81SCharlie Cruzan
9ce247f03SCharlie Cruzan@interface EXScreenCaptureModule ()
10ce247f03SCharlie Cruzan
11*efd75decSTomasz Sapeta@property (nonatomic, weak) EXModuleRegistry *moduleRegistry;
1280a34b81SCharlie Cruzan@property (nonatomic, assign) BOOL isListening;
1380a34b81SCharlie Cruzan@property (nonatomic, assign) BOOL isBeingObserved;
14*efd75decSTomasz Sapeta@property (nonatomic, weak) id<EXEventEmitterService> eventEmitter;
15ce247f03SCharlie Cruzan
16ce247f03SCharlie Cruzan@end
17ce247f03SCharlie Cruzan
18ce247f03SCharlie Cruzan@implementation EXScreenCaptureModule {
19ce247f03SCharlie Cruzan  UIView *_blockView;
20ce247f03SCharlie Cruzan}
21ce247f03SCharlie Cruzan
22*efd75decSTomasz SapetaEX_EXPORT_MODULE(ExpoScreenCapture);
2380a34b81SCharlie Cruzan
24*efd75decSTomasz Sapeta# pragma mark - EXModuleRegistryConsumer
2580a34b81SCharlie Cruzan
26*efd75decSTomasz Sapeta- (void)setModuleRegistry:(EXModuleRegistry *)moduleRegistry
2780a34b81SCharlie Cruzan{
2880a34b81SCharlie Cruzan  _moduleRegistry = moduleRegistry;
29*efd75decSTomasz Sapeta  _eventEmitter = [moduleRegistry getModuleImplementingProtocol:@protocol(EXEventEmitterService)];
3080a34b81SCharlie Cruzan}
3180a34b81SCharlie 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
4180a34b81SCharlie Cruzan# pragma mark - Exported methods
42ce247f03SCharlie Cruzan
43*efd75decSTomasz SapetaEX_EXPORT_METHOD_AS(preventScreenCapture,
44*efd75decSTomasz Sapeta                    preventScreenCaptureWithResolver:(EXPromiseResolveBlock)resolve
45*efd75decSTomasz Sapeta                    reject:(EXPromiseRejectBlock)reject)
46ce247f03SCharlie Cruzan{
47ce247f03SCharlie Cruzan  // If already recording, block it
48ce247f03SCharlie Cruzan  dispatch_async(dispatch_get_main_queue(), ^{
49ce247f03SCharlie Cruzan    [self preventScreenRecording];
50ce247f03SCharlie Cruzan  });
51ce247f03SCharlie Cruzan
52ce247f03SCharlie Cruzan  // Avoid setting duplicate observers
53ce247f03SCharlie Cruzan  [[NSNotificationCenter defaultCenter] removeObserver:self name:UIScreenCapturedDidChangeNotification object:nil];
54ce247f03SCharlie Cruzan
55ce247f03SCharlie Cruzan  [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(preventScreenRecording) name:UIScreenCapturedDidChangeNotification object:nil];
56ce247f03SCharlie Cruzan
57ce247f03SCharlie Cruzan  resolve([NSNull null]);
58ce247f03SCharlie Cruzan}
59ce247f03SCharlie Cruzan
60*efd75decSTomasz SapetaEX_EXPORT_METHOD_AS(allowScreenCapture,
61*efd75decSTomasz Sapeta                    allowScreenCaptureWithResolver:(EXPromiseResolveBlock)resolve
62*efd75decSTomasz Sapeta                    rejecter:(EXPromiseRejectBlock)reject)
63ce247f03SCharlie Cruzan{
64ce247f03SCharlie Cruzan  [[NSNotificationCenter defaultCenter] removeObserver:self name:UIScreenCapturedDidChangeNotification object:nil];
65ce247f03SCharlie Cruzan
66ce247f03SCharlie Cruzan  resolve([NSNull null]);
67ce247f03SCharlie Cruzan}
68ce247f03SCharlie Cruzan
69ce247f03SCharlie Cruzan- (void)preventScreenRecording {
70ce247f03SCharlie Cruzan  BOOL isCaptured = [[UIScreen mainScreen] isCaptured];
71ce247f03SCharlie Cruzan
72ce247f03SCharlie Cruzan  if (isCaptured) {
73ce247f03SCharlie Cruzan    [UIApplication.sharedApplication.keyWindow.subviews.firstObject addSubview:_blockView];
74ce247f03SCharlie Cruzan  } else {
75ce247f03SCharlie Cruzan    [_blockView removeFromSuperview];
76ce247f03SCharlie Cruzan  }
77ce247f03SCharlie Cruzan}
78ce247f03SCharlie Cruzan
79*efd75decSTomasz Sapeta# pragma mark - EXEventEmitter
8080a34b81SCharlie Cruzan
8180a34b81SCharlie Cruzan- (NSArray<NSString *> *)supportedEvents
8280a34b81SCharlie Cruzan{
8380a34b81SCharlie Cruzan  return @[onScreenshotEventName];
8480a34b81SCharlie Cruzan}
8580a34b81SCharlie Cruzan
8680a34b81SCharlie Cruzan- (void)startObserving
8780a34b81SCharlie Cruzan{
8880a34b81SCharlie Cruzan  [self setIsBeingObserved:YES];
8980a34b81SCharlie Cruzan}
9080a34b81SCharlie Cruzan
9180a34b81SCharlie Cruzan- (void)stopObserving
9280a34b81SCharlie Cruzan{
9380a34b81SCharlie Cruzan  [self setIsBeingObserved:NO];
9480a34b81SCharlie Cruzan}
9580a34b81SCharlie Cruzan
9680a34b81SCharlie Cruzan- (void)setIsBeingObserved:(BOOL)isBeingObserved
9780a34b81SCharlie Cruzan{
9880a34b81SCharlie Cruzan  _isBeingObserved = isBeingObserved;
9980a34b81SCharlie Cruzan  BOOL shouldListen = _isBeingObserved;
10080a34b81SCharlie Cruzan  if (shouldListen && !_isListening) {
10180a34b81SCharlie Cruzan    // Avoid setting duplicate observers
10280a34b81SCharlie Cruzan    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationUserDidTakeScreenshotNotification object:nil];
10380a34b81SCharlie Cruzan    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(listenForScreenCapture) name:UIApplicationUserDidTakeScreenshotNotification object:nil];
10480a34b81SCharlie Cruzan    _isListening = YES;
10580a34b81SCharlie Cruzan  } else if (!shouldListen && _isListening) {
10680a34b81SCharlie Cruzan    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationUserDidTakeScreenshotNotification object:nil];
10780a34b81SCharlie Cruzan    _isListening = NO;
10880a34b81SCharlie Cruzan  }
10980a34b81SCharlie Cruzan}
11080a34b81SCharlie Cruzan
11180a34b81SCharlie Cruzan- (void)listenForScreenCapture
11280a34b81SCharlie Cruzan{
11380a34b81SCharlie Cruzan  [_eventEmitter sendEventWithName:onScreenshotEventName body:nil];
11480a34b81SCharlie Cruzan}
11580a34b81SCharlie Cruzan
116ce247f03SCharlie Cruzan@end
117