Skip to content

Commit cb762b0

Browse files
andreicoman11bestander
authored andcommitted
Expose screen metrics and window metrics
Summary: public #4935 changed the window dimensions for android by replacing them with the actual screen dimensions. This changes the window dimensions back to their original values and adds `Dimensions.get('screen')` for the actual screen dimensions of the device. Reviewed By: astreet Differential Revision: D2921584 fb-gh-sync-id: 5d2677029c71d50691691dc651a11e9c8b115e8f shipit-source-id: 5d2677029c71d50691691dc651a11e9c8b115e8f
1 parent b74d007 commit cb762b0

File tree

16 files changed

+93
-34
lines changed

16 files changed

+93
-34
lines changed

Libraries/Utilities/Dimensions.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
*/
1212
'use strict';
1313

14+
var Platform = require('Platform');
1415
var UIManager = require('UIManager');
1516

1617
var invariant = require('invariant');
@@ -31,7 +32,21 @@ if (dimensions && dimensions.windowPhysicalPixels) {
3132
scale: windowPhysicalPixels.scale,
3233
fontScale: windowPhysicalPixels.fontScale,
3334
};
35+
if (Platform.OS === 'android') {
36+
// Screen and window dimensions are different on android
37+
var screenPhysicalPixels = dimensions.screenPhysicalPixels;
38+
dimensions.screen = {
39+
width: screenPhysicalPixels.width / screenPhysicalPixels.scale,
40+
height: screenPhysicalPixels.height / screenPhysicalPixels.scale,
41+
scale: screenPhysicalPixels.scale,
42+
fontScale: screenPhysicalPixels.fontScale,
43+
};
3444

45+
// delete so no callers rely on this existing
46+
delete dimensions.screenPhysicalPixels;
47+
} else {
48+
dimensions.screen = dimensions.window;
49+
}
3550
// delete so no callers rely on this existing
3651
delete dimensions.windowPhysicalPixels;
3752
}

ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManagerImpl.java

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -295,18 +295,20 @@ private static void initializeSoLoaderIfNecessary(Context applicationContext) {
295295
}
296296

297297
private static void setDisplayMetrics(Context context) {
298-
DisplayMetrics displayMetrics = new DisplayMetrics();
299-
displayMetrics.setTo(context.getResources().getDisplayMetrics());
298+
DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
299+
DisplayMetricsHolder.setWindowDisplayMetrics(displayMetrics);
300+
301+
DisplayMetrics screenDisplayMetrics = new DisplayMetrics();
302+
screenDisplayMetrics.setTo(displayMetrics);
300303
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
301304
Display display = wm.getDefaultDisplay();
302305

303306
// Get the real display metrics if we are using API level 17 or higher.
304307
// The real metrics include system decor elements (e.g. soft menu bar).
305308
//
306309
// See: http://developer.android.com/reference/android/view/Display.html#getRealMetrics(android.util.DisplayMetrics)
307-
if (Build.VERSION.SDK_INT >= 17){
308-
display.getRealMetrics(displayMetrics);
309-
310+
if (Build.VERSION.SDK_INT >= 17) {
311+
display.getRealMetrics(screenDisplayMetrics);
310312
} else {
311313
// For 14 <= API level <= 16, we need to invoke getRawHeight and getRawWidth to get the real dimensions.
312314
// Since react-native only supports API level 16+ we don't have to worry about other cases.
@@ -317,13 +319,13 @@ private static void setDisplayMetrics(Context context) {
317319
try {
318320
Method mGetRawH = Display.class.getMethod("getRawHeight");
319321
Method mGetRawW = Display.class.getMethod("getRawWidth");
320-
displayMetrics.widthPixels = (Integer) mGetRawW.invoke(display);
321-
displayMetrics.heightPixels = (Integer) mGetRawH.invoke(display);
322+
screenDisplayMetrics.widthPixels = (Integer) mGetRawW.invoke(display);
323+
screenDisplayMetrics.heightPixels = (Integer) mGetRawH.invoke(display);
322324
} catch (InvocationTargetException | IllegalAccessException | NoSuchMethodException e) {
323325
throw new RuntimeException("Error getting real dimensions for API level < 17", e);
324326
}
325327
}
326-
DisplayMetricsHolder.setDisplayMetrics(displayMetrics);
328+
DisplayMetricsHolder.setScreenDisplayMetrics(screenDisplayMetrics);
327329
}
328330

329331
/**

ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,7 @@ private KeyboardListener getKeyboardListener() {
390390
private class KeyboardListener implements ViewTreeObserver.OnGlobalLayoutListener {
391391
private final Rect mVisibleViewArea;
392392
private final int mMinKeyboardHeightDetected;
393-
393+
394394
private int mKeyboardHeight = 0;
395395

396396
/* package */ KeyboardListener() {
@@ -410,7 +410,7 @@ public void onGlobalLayout() {
410410

411411
getRootView().getWindowVisibleDisplayFrame(mVisibleViewArea);
412412
final int heightDiff =
413-
DisplayMetricsHolder.getDisplayMetrics().heightPixels - mVisibleViewArea.bottom;
413+
DisplayMetricsHolder.getWindowDisplayMetrics().heightPixels - mVisibleViewArea.bottom;
414414
if (mKeyboardHeight != heightDiff && heightDiff > mMinKeyboardHeightDetected) {
415415
// keyboard is now showing, or the keyboard height has changed
416416
mKeyboardHeight = heightDiff;

ReactAndroid/src/main/java/com/facebook/react/uimanager/DisplayMetricsHolder.java

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,39 @@
1414
/**
1515
* Holds an instance of the current DisplayMetrics so we don't have to thread it through all the
1616
* classes that need it.
17+
* Note: windowDisplayMetrics are deprecated in favor of ScreenDisplayMetrics: window metrics
18+
* are supposed to return the drawable area but there's no guarantee that they correspond to the
19+
* actual size of the {@link ReactRootView}. Moreover, they are not consistent with what iOS
20+
* returns. Screen metrics returns the metrics of the entire screen, is consistent with iOS and
21+
* should be used instead.
1722
*/
1823
public class DisplayMetricsHolder {
1924

20-
private static DisplayMetrics sCurrentDisplayMetrics;
25+
private static DisplayMetrics sWindowDisplayMetrics;
26+
private static DisplayMetrics sScreenDisplayMetrics;
2127

22-
public static void setDisplayMetrics(DisplayMetrics displayMetrics) {
23-
sCurrentDisplayMetrics = displayMetrics;
28+
/**
29+
* @deprecated Use {@link #setScreenDisplayMetrics(DisplayMetrics)} instead. See comment above as
30+
* to why this is not correct to use.
31+
*/
32+
public static void setWindowDisplayMetrics(DisplayMetrics displayMetrics) {
33+
sWindowDisplayMetrics = displayMetrics;
2434
}
2535

26-
public static DisplayMetrics getDisplayMetrics() {
27-
return sCurrentDisplayMetrics;
36+
/**
37+
* @deprecated Use {@link #getScreenDisplayMetrics()} instead. See comment above as to why this
38+
* is not correct to use.
39+
*/
40+
@Deprecated
41+
public static DisplayMetrics getWindowDisplayMetrics() {
42+
return sWindowDisplayMetrics;
43+
}
44+
45+
public static void setScreenDisplayMetrics(DisplayMetrics screenDisplayMetrics) {
46+
sScreenDisplayMetrics = screenDisplayMetrics;
47+
}
48+
49+
public static DisplayMetrics getScreenDisplayMetrics() {
50+
return sScreenDisplayMetrics;
2851
}
2952
}

ReactAndroid/src/main/java/com/facebook/react/uimanager/PixelUtil.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public static float toPixelFromDIP(float value) {
2323
return TypedValue.applyDimension(
2424
TypedValue.COMPLEX_UNIT_DIP,
2525
value,
26-
DisplayMetricsHolder.getDisplayMetrics());
26+
DisplayMetricsHolder.getWindowDisplayMetrics());
2727
}
2828

2929
/**
@@ -40,7 +40,7 @@ public static float toPixelFromSP(float value) {
4040
return TypedValue.applyDimension(
4141
TypedValue.COMPLEX_UNIT_SP,
4242
value,
43-
DisplayMetricsHolder.getDisplayMetrics());
43+
DisplayMetricsHolder.getWindowDisplayMetrics());
4444
}
4545

4646
/**
@@ -54,7 +54,7 @@ public static float toPixelFromSP(double value) {
5454
* Convert from PX to DP
5555
*/
5656
public static float toDIPFromPixel(float value) {
57-
return value / DisplayMetricsHolder.getDisplayMetrics().density;
57+
return value / DisplayMetricsHolder.getWindowDisplayMetrics().density;
5858
}
5959

6060
}

ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModuleConstants.java

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,8 @@ public static Map<String, Object> getConstants() {
9191
"ScaleAspectFill",
9292
ImageView.ScaleType.CENTER_CROP.ordinal())));
9393

94-
DisplayMetrics displayMetrics = DisplayMetricsHolder.getDisplayMetrics();
94+
DisplayMetrics displayMetrics = DisplayMetricsHolder.getWindowDisplayMetrics();
95+
DisplayMetrics screenDisplayMetrics = DisplayMetricsHolder.getScreenDisplayMetrics();
9596
constants.put(
9697
"Dimensions",
9798
MapBuilder.of(
@@ -106,7 +107,19 @@ public static Map<String, Object> getConstants() {
106107
"fontScale",
107108
displayMetrics.scaledDensity,
108109
"densityDpi",
109-
displayMetrics.densityDpi)));
110+
displayMetrics.densityDpi),
111+
"screenPhysicalPixels",
112+
MapBuilder.of(
113+
"width",
114+
screenDisplayMetrics.widthPixels,
115+
"height",
116+
screenDisplayMetrics.heightPixels,
117+
"scale",
118+
screenDisplayMetrics.density,
119+
"fontScale",
120+
screenDisplayMetrics.scaledDensity,
121+
"densityDpi",
122+
screenDisplayMetrics.densityDpi)));
110123

111124
constants.put(
112125
"StyleConstants",

ReactAndroid/src/main/java/com/facebook/react/views/art/ARTVirtualNode.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717

1818
import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
1919
import com.facebook.react.bridge.ReadableArray;
20-
import com.facebook.react.uimanager.ReactStylesDiffMap;
2120
import com.facebook.react.uimanager.DisplayMetricsHolder;
2221
import com.facebook.react.uimanager.annotations.ReactProp;
2322
import com.facebook.react.uimanager.ReactShadowNode;
@@ -39,7 +38,7 @@ public abstract class ARTVirtualNode extends ReactShadowNode {
3938
protected final float mScale;
4039

4140
public ARTVirtualNode() {
42-
mScale = DisplayMetricsHolder.getDisplayMetrics().density;
41+
mScale = DisplayMetricsHolder.getWindowDisplayMetrics().density;
4342
}
4443

4544
@Override

ReactAndroid/src/test/java/com/facebook/react/RootViewTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ public Object answer(InvocationOnMock invocation) throws Throwable {
8282
mReactContext = new ReactApplicationContext(RuntimeEnvironment.application);
8383
mReactContext.initializeWithInstance(mCatalystInstanceMock);
8484
DisplayMetrics displayMetrics = mReactContext.getResources().getDisplayMetrics();
85-
DisplayMetricsHolder.setDisplayMetrics(displayMetrics);
85+
DisplayMetricsHolder.setWindowDisplayMetrics(displayMetrics);
8686

8787
UIManagerModule uiManagerModuleMock = mock(UIManagerModule.class);
8888
when(mCatalystInstanceMock.getNativeModule(UIManagerModule.class))

ReactAndroid/src/test/java/com/facebook/react/uimanager/LayoutPropertyApplicatorTest.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,14 @@ public class LayoutPropertyApplicatorTest {
5454

5555
@Before
5656
public void setup() {
57-
DisplayMetricsHolder.setDisplayMetrics(new DisplayMetrics());
57+
DisplayMetricsHolder.setWindowDisplayMetrics(new DisplayMetrics());
58+
DisplayMetricsHolder.setScreenDisplayMetrics(new DisplayMetrics());
5859
}
5960

6061
@After
6162
public void teardown() {
62-
DisplayMetricsHolder.setDisplayMetrics(null);
63+
DisplayMetricsHolder.setWindowDisplayMetrics(null);
64+
DisplayMetricsHolder.setScreenDisplayMetrics(null);
6365
}
6466

6567
public ReactStylesDiffMap buildStyles(Object... keysAndValues) {
@@ -309,7 +311,7 @@ public void testEnumerations() {
309311
public void testPropertiesResetToDefault() {
310312
DisplayMetrics displayMetrics = new DisplayMetrics();
311313
displayMetrics.density = 1.0f;
312-
DisplayMetricsHolder.setDisplayMetrics(displayMetrics);
314+
DisplayMetricsHolder.setWindowDisplayMetrics(displayMetrics);
313315

314316
LayoutShadowNode reactShadowNode = spy(new LayoutShadowNode());
315317
ReactStylesDiffMap map = buildStyles(

ReactAndroid/src/test/java/com/facebook/react/uimanager/ReactPropConstantsTest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,8 @@ public void testNativePropsIncludeCorrectTypes() {
147147
List<ViewManager> viewManagers = Arrays.<ViewManager>asList(new ViewManagerUnderTest());
148148
ReactApplicationContext reactContext = new ReactApplicationContext(RuntimeEnvironment.application);
149149
DisplayMetrics displayMetrics = reactContext.getResources().getDisplayMetrics();
150-
DisplayMetricsHolder.setDisplayMetrics(displayMetrics);
150+
DisplayMetricsHolder.setWindowDisplayMetrics(displayMetrics);
151+
DisplayMetricsHolder.setScreenDisplayMetrics(displayMetrics);
151152
UIManagerModule uiManagerModule = new UIManagerModule(
152153
reactContext,
153154
viewManagers,

0 commit comments

Comments
 (0)