Permalink
Browse files

Introduce `DeviceInfo` as a new native module

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 17, 2017
1 parent 238fd4a commit 95c192619372e6b3dfdc55aeafa8f44faf013ecf
Showing with 345 additions and 125 deletions.
  1. +20 −0 Libraries/Utilities/DeviceInfo.js
  2. +2 −2 Libraries/Utilities/Dimensions.js
  3. +1 −0 Libraries/react-native/react-native-implementation.js
  4. +17 −0 React/Modules/RCTDeviceInfo.h
  5. +116 −0 React/Modules/RCTDeviceInfo.m
  6. +0 −57 React/Modules/RCTUIManager.m
  7. +12 −0 React/React.xcodeproj/project.pbxproj
  8. +12 −0 React/ReactCxx.xcodeproj/project.pbxproj
  9. +1 −0 ReactAndroid/src/androidTest/java/com/facebook/react/tests/BUCK
  10. +2 −0 ...droid/src/androidTest/java/com/facebook/react/tests/CatalystNativeJSToJavaParametersTestCase.java
  11. +2 −0 ...ndroid/src/androidTest/java/com/facebook/react/tests/CatalystNativeJavaToJSArgumentsTestCase.java
  12. +2 −0 ...oid/src/androidTest/java/com/facebook/react/tests/CatalystNativeJavaToJSReturnValuesTestCase.java
  13. +2 −0 ReactAndroid/src/androidTest/java/com/facebook/react/tests/CatalystUIManagerTestCase.java
  14. +2 −0 ReactAndroid/src/androidTest/java/com/facebook/react/tests/JSLocaleTest.java
  15. +2 −0 ReactAndroid/src/androidTest/java/com/facebook/react/tests/ProgressBarTestCase.java
  16. +2 −0 ReactAndroid/src/androidTest/java/com/facebook/react/tests/ViewRenderingTestCase.java
  17. +1 −0 ReactAndroid/src/main/java/com/facebook/react/BUCK
  18. +9 −0 ReactAndroid/src/main/java/com/facebook/react/CoreModulesPackage.java
  19. +2 −2 ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java
  20. +17 −0 ReactAndroid/src/main/java/com/facebook/react/modules/deviceinfo/BUCK
  21. +105 −0 ReactAndroid/src/main/java/com/facebook/react/modules/deviceinfo/DeviceInfoModule.java
  22. +3 −23 ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModule.java
  23. +1 −30 ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModuleConstants.java
  24. +2 −3 ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModuleConstantsHelper.java
  25. +10 −8 jest/setup.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;
@@ -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');
@@ -128,7 +128,7 @@ class Dimensions {
}
}
Dimensions.set(UIManager.Dimensions);
Dimensions.set(DeviceInfo.Dimensions);
RCTDeviceEventEmitter.addListener('didUpdateDimensions', function(update) {
Dimensions.set(update);
});
@@ -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'); },
@@ -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
@@ -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
@@ -225,9 +225,6 @@ @implementation RCTUIManager
NSDictionary *_componentDataByName;
NSMutableSet<id<RCTComponent>> *_bridgeTransactionListeners;
#if !TARGET_OS_TV
UIInterfaceOrientation _currentInterfaceOrientation;
#endif
}
@synthesize bridge = _bridge;
@@ -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
@@ -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
{
/**
@@ -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];
}
@@ -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)
@@ -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 */
@@ -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>"; };
@@ -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 */,
@@ -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 */,
@@ -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 */,
@@ -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 */,
@@ -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;
};
Oops, something went wrong.

2 comments on commit 95c1926

@rbressi

This comment has been minimized.

Show comment
Hide comment
@rbressi

rbressi Jun 9, 2017

The addition of this module broke functionality in AccessibilityManager for iOS (as per #14043). Is this being looked at?

The addition of this module broke functionality in AccessibilityManager for iOS (as per #14043). Is this being looked at?

@rbressi

This comment has been minimized.

Show comment
Hide comment
@rbressi

rbressi Jun 18, 2017

@fkgozali, @ashwinb: Following up on this, as #14043 was not fixed in v0.45 and is hence still blocking upgrades to v0.44 and above.

@fkgozali, @ashwinb: Following up on this, as #14043 was not fixed in v0.45 and is hence still blocking upgrades to v0.44 and above.

Please sign in to comment.