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