/* * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #import "RCTDeviceInfo.h" #import #import #import #import #import #import #import #import "CoreModulesPlugins.h" using namespace facebook::react; @interface RCTDeviceInfo () @end @implementation RCTDeviceInfo { UIInterfaceOrientation _currentInterfaceOrientation; NSDictionary *_currentInterfaceDimensions; } @synthesize moduleRegistry = _moduleRegistry; @synthesize turboModuleRegistry = _turboModuleRegistry; RCT_EXPORT_MODULE() + (BOOL)requiresMainQueueSetup { return YES; } - (dispatch_queue_t)methodQueue { return dispatch_get_main_queue(); } - (void)setModuleRegistry:(RCTModuleRegistry *)moduleRegistry { _moduleRegistry = moduleRegistry; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didReceiveNewContentSizeMultiplier) name:RCTAccessibilityManagerDidUpdateMultiplierNotification object:[moduleRegistry moduleForName:"AccessibilityManager"]]; _currentInterfaceOrientation = [RCTSharedApplication() statusBarOrientation]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(interfaceOrientationDidChange) name:UIApplicationDidChangeStatusBarOrientationNotification object:nil]; _currentInterfaceDimensions = RCTExportedDimensions(_moduleRegistry); [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(interfaceFrameDidChange) name:UIApplicationDidBecomeActiveNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(interfaceFrameDidChange) name:RCTUserInterfaceStyleDidChangeNotification object:nil]; } static BOOL RCTIsIPhoneX() { static BOOL isIPhoneX = NO; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ RCTAssertMainQueue(); CGSize screenSize = [UIScreen mainScreen].nativeBounds.size; CGSize iPhoneXScreenSize = CGSizeMake(1125, 2436); CGSize iPhoneXMaxScreenSize = CGSizeMake(1242, 2688); CGSize iPhoneXRScreenSize = CGSizeMake(828, 1792); CGSize iPhone12ScreenSize = CGSizeMake(1170, 2532); CGSize iPhone12MiniScreenSize = CGSizeMake(1080, 2340); CGSize iPhone12ProMaxScreenSize = CGSizeMake(1284, 2778); isIPhoneX = CGSizeEqualToSize(screenSize, iPhoneXScreenSize) || CGSizeEqualToSize(screenSize, iPhoneXMaxScreenSize) || CGSizeEqualToSize(screenSize, iPhoneXRScreenSize) || CGSizeEqualToSize(screenSize, iPhone12ScreenSize) || CGSizeEqualToSize(screenSize, iPhone12MiniScreenSize) || CGSizeEqualToSize(screenSize, iPhone12ProMaxScreenSize); ; }); return isIPhoneX; } static NSDictionary *RCTExportedDimensions(RCTModuleRegistry *moduleRegistry) { RCTAssertMainQueue(); RCTDimensions dimensions; if (moduleRegistry) { dimensions = RCTGetDimensions( ((RCTAccessibilityManager *)[moduleRegistry moduleForName:"AccessibilityManager"]).multiplier ?: 1.0); } else { RCTAssert(false, @"ModuleRegistry must be set to properly init dimensions."); } __typeof(dimensions.window) window = dimensions.window; NSDictionary *dimsWindow = @{ @"width" : @(window.width), @"height" : @(window.height), @"scale" : @(window.scale), @"fontScale" : @(window.fontScale) }; __typeof(dimensions.screen) screen = dimensions.screen; NSDictionary *dimsScreen = @{ @"width" : @(screen.width), @"height" : @(screen.height), @"scale" : @(screen.scale), @"fontScale" : @(screen.fontScale) }; return @{@"window" : dimsWindow, @"screen" : dimsScreen}; } - (NSDictionary *)constantsToExport { return [self getConstants]; } - (NSDictionary *)getConstants { __block NSDictionary *constants; RCTModuleRegistry *moduleRegistry = _moduleRegistry; RCTUnsafeExecuteOnMainQueueSync(^{ constants = @{ @"Dimensions" : RCTExportedDimensions(moduleRegistry), // Note: // This prop is deprecated and will be removed in a future release. // Please use this only for a quick and temporary solution. // Use instead. @"isIPhoneX_deprecated" : @(RCTIsIPhoneX()), }; }); return constants; } - (void)didReceiveNewContentSizeMultiplier { RCTModuleRegistry *moduleRegistry = _moduleRegistry; RCTExecuteOnMainQueue(^{ // Report the event across the bridge. #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" [[moduleRegistry moduleForName:"EventDispatcher"] sendDeviceEventWithName:@"didUpdateDimensions" body:RCTExportedDimensions(moduleRegistry)]; #pragma clang diagnostic pop }); } - (void)interfaceOrientationDidChange { __weak __typeof(self) weakSelf = self; RCTExecuteOnMainQueue(^{ [weakSelf _interfaceOrientationDidChange]; }); } - (void)_interfaceOrientationDidChange { UIInterfaceOrientation nextOrientation = [RCTSharedApplication() statusBarOrientation]; // Update when we go from portrait to landscape, or landscape to portrait if ((UIInterfaceOrientationIsPortrait(_currentInterfaceOrientation) && !UIInterfaceOrientationIsPortrait(nextOrientation)) || (UIInterfaceOrientationIsLandscape(_currentInterfaceOrientation) && !UIInterfaceOrientationIsLandscape(nextOrientation))) { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" [[_moduleRegistry moduleForName:"EventDispatcher"] sendDeviceEventWithName:@"didUpdateDimensions" body:RCTExportedDimensions(_moduleRegistry)]; #pragma clang diagnostic pop } _currentInterfaceOrientation = nextOrientation; } - (void)interfaceFrameDidChange { __weak __typeof(self) weakSelf = self; RCTExecuteOnMainQueue(^{ [weakSelf _interfaceFrameDidChange]; }); } - (void)_interfaceFrameDidChange { NSDictionary *nextInterfaceDimensions = RCTExportedDimensions(_moduleRegistry); if (!([nextInterfaceDimensions isEqual:_currentInterfaceDimensions])) { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" [[_moduleRegistry moduleForName:"EventDispatcher"] sendDeviceEventWithName:@"didUpdateDimensions" body:nextInterfaceDimensions]; #pragma clang diagnostic pop } _currentInterfaceDimensions = nextInterfaceDimensions; } - (std::shared_ptr)getTurboModule:(const ObjCTurboModule::InitParams &)params { return std::make_shared(params); } @end Class RCTDeviceInfoCls(void) { return RCTDeviceInfo.class; }