Skip to content

Commit

Permalink
Introduce DeviceInfo as a new native module
Browse files Browse the repository at this point in the history
Summary:
The `UIManager` already has a lot of responsibilities and is deeply
tied with React Native's view architecture. This diff separates out a
`DeviceInfo` native module to provide information about screen dimensions and
font scale, etc.

Reviewed By: fkgozali

Differential Revision: D4713834

fbshipit-source-id: f2ee93acf876a4221c29a8c731f5abeffbb97974
  • Loading branch information
ashwinb authored and facebook-github-bot committed Mar 18, 2017
1 parent 238fd4a commit 95c1926
Show file tree
Hide file tree
Showing 25 changed files with 345 additions and 125 deletions.
20 changes: 20 additions & 0 deletions Libraries/Utilities/DeviceInfo.js
@@ -0,0 +1,20 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule DeviceInfo
* @flow
*/
'use strict';

const DeviceInfo = require('NativeModules').DeviceInfo;

const invariant = require('invariant');

invariant(DeviceInfo, 'DeviceInfo native module is not installed correctly');

module.exports = DeviceInfo;
4 changes: 2 additions & 2 deletions Libraries/Utilities/Dimensions.js
Expand Up @@ -11,9 +11,9 @@
*/
'use strict';

var DeviceInfo = require('DeviceInfo');
var EventEmitter = require('EventEmitter');
var Platform = require('Platform');
var UIManager = require('UIManager');
var RCTDeviceEventEmitter = require('RCTDeviceEventEmitter');

var invariant = require('fbjs/lib/invariant');
Expand Down Expand Up @@ -128,7 +128,7 @@ class Dimensions {
}
}

Dimensions.set(UIManager.Dimensions);
Dimensions.set(DeviceInfo.Dimensions);
RCTDeviceEventEmitter.addListener('didUpdateDimensions', function(update) {
Dimensions.set(update);
});
Expand Down
1 change: 1 addition & 0 deletions Libraries/react-native/react-native-implementation.js
Expand Up @@ -85,6 +85,7 @@ const ReactNative = {
get CameraRoll() { return require('CameraRoll'); },
get Clipboard() { return require('Clipboard'); },
get DatePickerAndroid() { return require('DatePickerAndroid'); },
get DeviceInfo() { return require('DeviceInfo'); },
get Dimensions() { return require('Dimensions'); },
get Easing() { return require('Easing'); },
get I18nManager() { return require('I18nManager'); },
Expand Down
17 changes: 17 additions & 0 deletions React/Modules/RCTDeviceInfo.h
@@ -0,0 +1,17 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/

#import <UIKit/UIKit.h>

#import <React/RCTBridge.h>
#import <React/RCTBridgeModule.h>

@interface RCTDeviceInfo : NSObject <RCTBridgeModule, RCTInvalidating>

@end
116 changes: 116 additions & 0 deletions React/Modules/RCTDeviceInfo.m
@@ -0,0 +1,116 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/

#import "RCTDeviceInfo.h"

#import "RCTAccessibilityManager.h"
#import "RCTAssert.h"
#import "RCTEventDispatcher.h"
#import "RCTUtils.h"

@implementation RCTDeviceInfo {
#if !TARGET_OS_TV
UIInterfaceOrientation _currentInterfaceOrientation;
#endif
}

@synthesize bridge = _bridge;

RCT_EXPORT_MODULE()

- (dispatch_queue_t)methodQueue
{
return dispatch_get_main_queue();
}

- (void)setBridge:(RCTBridge *)bridge
{
_bridge = bridge;

[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(didReceiveNewContentSizeMultiplier)
name:RCTAccessibilityManagerDidUpdateMultiplierNotification
object:_bridge.accessibilityManager];
#if !TARGET_OS_TV
_currentInterfaceOrientation = [RCTSharedApplication() statusBarOrientation];

[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(interfaceOrientationDidChange)
name:UIApplicationDidChangeStatusBarOrientationNotification
object:nil];
#endif
}

static NSDictionary *RCTExportedDimensions(RCTBridge *bridge)
{
RCTAssertMainQueue();

// Don't use RCTScreenSize since it the interface orientation doesn't apply to it
CGRect screenSize = [[UIScreen mainScreen] bounds];
NSDictionary *dims = @{
@"width": @(screenSize.size.width),
@"height": @(screenSize.size.height),
@"scale": @(RCTScreenScale()),
@"fontScale": @(bridge.accessibilityManager.multiplier)
};
return @{
@"window": dims,
@"screen": dims
};
}

- (void)invalidate
{
dispatch_async(dispatch_get_main_queue(), ^{
self->_bridge = nil;
[[NSNotificationCenter defaultCenter] removeObserver:self];
});
}

- (NSDictionary<NSString *, id> *)constantsToExport
{
NSMutableDictionary<NSString *, NSDictionary *> *constants = [NSMutableDictionary new];
constants[@"Dimensions"] = RCTExportedDimensions(_bridge);
return constants;
}

- (void)didReceiveNewContentSizeMultiplier
{
// Report the event across the bridge.
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
[_bridge.eventDispatcher sendDeviceEventWithName:@"didUpdateDimensions"
body:RCTExportedDimensions(_bridge)];
#pragma clang diagnostic pop
}


- (void)interfaceOrientationDidChange
{
#if !TARGET_OS_TV
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"
[_bridge.eventDispatcher sendDeviceEventWithName:@"didUpdateDimensions"
body:RCTExportedDimensions(_bridge)];
#pragma clang diagnostic pop
}

_currentInterfaceOrientation = nextOrientation;
#endif
}


@end
57 changes: 0 additions & 57 deletions React/Modules/RCTUIManager.m
Expand Up @@ -225,9 +225,6 @@ @implementation RCTUIManager
NSDictionary *_componentDataByName;

NSMutableSet<id<RCTComponent>> *_bridgeTransactionListeners;
#if !TARGET_OS_TV
UIInterfaceOrientation _currentInterfaceOrientation;
#endif
}

@synthesize bridge = _bridge;
Expand All @@ -239,8 +236,6 @@ - (void)didReceiveNewContentSizeMultiplier
// Report the event across the bridge.
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
[_bridge.eventDispatcher sendDeviceEventWithName:@"didUpdateDimensions"
body:RCTExportedDimensions(_bridge)];
[_bridge.eventDispatcher sendDeviceEventWithName:@"didUpdateContentSizeMultiplier"
body:@([_bridge.accessibilityManager multiplier])];
#pragma clang diagnostic pop
Expand All @@ -252,28 +247,6 @@ - (void)didReceiveNewContentSizeMultiplier
});
}

- (void)interfaceOrientationDidChange
{
#if !TARGET_OS_TV
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"
[_bridge.eventDispatcher sendDeviceEventWithName:@"didUpdateDimensions"
body:RCTExportedDimensions(_bridge)];
#pragma clang diagnostic pop
}

_currentInterfaceOrientation = nextOrientation;
#endif
}

- (void)invalidate
{
/**
Expand Down Expand Up @@ -351,13 +324,6 @@ - (void)setBridge:(RCTBridge *)bridge
selector:@selector(didReceiveNewContentSizeMultiplier)
name:RCTAccessibilityManagerDidUpdateMultiplierNotification
object:_bridge.accessibilityManager];
#if !TARGET_OS_TV
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(interfaceOrientationDidChange)
name:UIApplicationDidChangeStatusBarOrientationNotification
object:nil];
#endif

[RCTAnimation initializeStatics];
}

Expand Down Expand Up @@ -1544,35 +1510,12 @@ static void RCTMeasureLayout(RCTShadowView *view,
constants[name] = moduleConstants;
}];

#if !TARGET_OS_TV
_currentInterfaceOrientation = [RCTSharedApplication() statusBarOrientation];
#endif

constants[@"customBubblingEventTypes"] = bubblingEvents;
constants[@"customDirectEventTypes"] = directEvents;
constants[@"Dimensions"] = RCTExportedDimensions(_bridge);

return constants;
}

static NSDictionary *RCTExportedDimensions(RCTBridge *bridge)
{
RCTAssertMainQueue();

// Don't use RCTScreenSize since it the interface orientation doesn't apply to it
CGRect screenSize = [[UIScreen mainScreen] bounds];
NSDictionary *dims = @{
@"width": @(screenSize.size.width),
@"height": @(screenSize.size.height),
@"scale": @(RCTScreenScale()),
@"fontScale": @(bridge.accessibilityManager.multiplier)
};
return @{
@"window": dims,
@"screen": dims
};
}

RCT_EXPORT_METHOD(configureNextLayoutAnimation:(NSDictionary *)config
withCallback:(RCTResponseSenderBlock)callback
errorCallback:(__unused RCTResponseSenderBlock)errorCallback)
Expand Down
12 changes: 12 additions & 0 deletions React/React.xcodeproj/project.pbxproj
Expand Up @@ -738,6 +738,10 @@
B50558421E43E14000F71A00 /* RCTDevSettings.mm in Sources */ = {isa = PBXBuildFile; fileRef = B505583D1E43DFB900F71A00 /* RCTDevSettings.mm */; };
B50558431E43E64600F71A00 /* RCTDevSettings.h in Headers */ = {isa = PBXBuildFile; fileRef = B505583C1E43DFB900F71A00 /* RCTDevSettings.h */; };
B95154321D1B34B200FE7B80 /* RCTActivityIndicatorView.m in Sources */ = {isa = PBXBuildFile; fileRef = B95154311D1B34B200FE7B80 /* RCTActivityIndicatorView.m */; };
CF85BC321E79EC6B00F1EF3B /* RCTDeviceInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = CF85BC301E79EC6B00F1EF3B /* RCTDeviceInfo.h */; };
CF85BC331E79EC6B00F1EF3B /* RCTDeviceInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = CF85BC311E79EC6B00F1EF3B /* RCTDeviceInfo.m */; };
CF85BC341E79EC7A00F1EF3B /* RCTDeviceInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = CF85BC301E79EC6B00F1EF3B /* RCTDeviceInfo.h */; };
CF85BC351E79EC7D00F1EF3B /* RCTDeviceInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = CF85BC311E79EC6B00F1EF3B /* RCTDeviceInfo.m */; };
E9B20B7B1B500126007A2DA7 /* RCTAccessibilityManager.m in Sources */ = {isa = PBXBuildFile; fileRef = E9B20B7A1B500126007A2DA7 /* RCTAccessibilityManager.m */; };
/* End PBXBuildFile section */

Expand Down Expand Up @@ -1381,6 +1385,8 @@
B505583D1E43DFB900F71A00 /* RCTDevSettings.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = RCTDevSettings.mm; sourceTree = "<group>"; };
B95154301D1B34B200FE7B80 /* RCTActivityIndicatorView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTActivityIndicatorView.h; sourceTree = "<group>"; };
B95154311D1B34B200FE7B80 /* RCTActivityIndicatorView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTActivityIndicatorView.m; sourceTree = "<group>"; };
CF85BC301E79EC6B00F1EF3B /* RCTDeviceInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTDeviceInfo.h; sourceTree = "<group>"; };
CF85BC311E79EC6B00F1EF3B /* RCTDeviceInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTDeviceInfo.m; sourceTree = "<group>"; };
E3BBC8EB1ADE6F47001BBD81 /* RCTTextDecorationLineType.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RCTTextDecorationLineType.h; sourceTree = "<group>"; };
E9B20B791B500126007A2DA7 /* RCTAccessibilityManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTAccessibilityManager.h; sourceTree = "<group>"; };
E9B20B7A1B500126007A2DA7 /* RCTAccessibilityManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTAccessibilityManager.m; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1456,6 +1462,8 @@
B505583B1E43DFB900F71A00 /* RCTDevMenu.m */,
B505583C1E43DFB900F71A00 /* RCTDevSettings.h */,
B505583D1E43DFB900F71A00 /* RCTDevSettings.mm */,
CF85BC301E79EC6B00F1EF3B /* RCTDeviceInfo.h */,
CF85BC311E79EC6B00F1EF3B /* RCTDeviceInfo.m */,
13D9FEE91CDCCECF00158BD7 /* RCTEventEmitter.h */,
13D9FEEA1CDCCECF00158BD7 /* RCTEventEmitter.m */,
13B07FE91A69327A00A75B9A /* RCTExceptionsManager.h */,
Expand Down Expand Up @@ -1869,6 +1877,7 @@
3D302F3E1DF828F800D6DDAE /* RCTKeyCommands.h in Headers */,
3D302F3F1DF828F800D6DDAE /* RCTLog.h in Headers */,
3D302F401DF828F800D6DDAE /* RCTModuleData.h in Headers */,
CF85BC341E79EC7A00F1EF3B /* RCTDeviceInfo.h in Headers */,
3D302F411DF828F800D6DDAE /* RCTModuleMethod.h in Headers */,
3D302F421DF828F800D6DDAE /* RCTMultipartDataTask.h in Headers */,
3D302F431DF828F800D6DDAE /* RCTMultipartStreamReader.h in Headers */,
Expand Down Expand Up @@ -2055,6 +2064,7 @@
A12E9E2A1E5DEB860029001B /* RCTReconnectingWebSocket.h in Headers */,
3D80DA311DF820620028D040 /* RCTJavaScriptLoader.h in Headers */,
3D80DA321DF820620028D040 /* RCTJSStackFrame.h in Headers */,
CF85BC321E79EC6B00F1EF3B /* RCTDeviceInfo.h in Headers */,
3D80DA331DF820620028D040 /* RCTKeyCommands.h in Headers */,
3D80DA341DF820620028D040 /* RCTLog.h in Headers */,
3D80DA351DF820620028D040 /* RCTModuleData.h in Headers */,
Expand Down Expand Up @@ -2465,6 +2475,7 @@
2D3B5EC21D9B093B00451313 /* RCTProfile.m in Sources */,
2D3B5ECB1D9B096200451313 /* RCTConvert+CoreLocation.m in Sources */,
A12E9E261E5DEB510029001B /* RCTPackagerClientResponder.m in Sources */,
CF85BC351E79EC7D00F1EF3B /* RCTDeviceInfo.m in Sources */,
2D3B5EEE1D9B09DA00451313 /* RCTView.m in Sources */,
594AD5D01E46D87500B07237 /* RCTScrollContentShadowView.m in Sources */,
2D3B5E981D9B089500451313 /* RCTConvert.m in Sources */,
Expand Down Expand Up @@ -2675,6 +2686,7 @@
945929C41DD62ADD00653A7D /* RCTConvert+Transform.m in Sources */,
13AB90C11B6FA36700713B4F /* RCTComponentData.m in Sources */,
13B0801B1A69489C00A75B9A /* RCTNavigatorManager.m in Sources */,
CF85BC331E79EC6B00F1EF3B /* RCTDeviceInfo.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down

0 comments on commit 95c1926

Please sign in to comment.