Skip to content

Commit

Permalink
Expose screen metrics and window metrics
Browse files Browse the repository at this point in the history
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
  • Loading branch information
andreicoman11 authored and facebook-github-bot-3 committed Feb 11, 2016
1 parent 6f1417c commit 228a1fe
Show file tree
Hide file tree
Showing 16 changed files with 93 additions and 34 deletions.
15 changes: 15 additions & 0 deletions Libraries/Utilities/Dimensions.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
*/
'use strict';

var Platform = require('Platform');
var UIManager = require('UIManager');

var invariant = require('invariant');
Expand All @@ -31,7 +32,21 @@ if (dimensions && dimensions.windowPhysicalPixels) {
scale: windowPhysicalPixels.scale,
fontScale: windowPhysicalPixels.fontScale,
};
if (Platform.OS === 'android') {
// Screen and window dimensions are different on android
var screenPhysicalPixels = dimensions.screenPhysicalPixels;
dimensions.screen = {
width: screenPhysicalPixels.width / screenPhysicalPixels.scale,
height: screenPhysicalPixels.height / screenPhysicalPixels.scale,
scale: screenPhysicalPixels.scale,
fontScale: screenPhysicalPixels.fontScale,
};

// delete so no callers rely on this existing
delete dimensions.screenPhysicalPixels;
} else {
dimensions.screen = dimensions.window;
}
// delete so no callers rely on this existing
delete dimensions.windowPhysicalPixels;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -308,18 +308,20 @@ private static void initializeSoLoaderIfNecessary(Context applicationContext) {
}

private static void setDisplayMetrics(Context context) {
DisplayMetrics displayMetrics = new DisplayMetrics();
displayMetrics.setTo(context.getResources().getDisplayMetrics());
DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
DisplayMetricsHolder.setWindowDisplayMetrics(displayMetrics);

DisplayMetrics screenDisplayMetrics = new DisplayMetrics();
screenDisplayMetrics.setTo(displayMetrics);
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();

// Get the real display metrics if we are using API level 17 or higher.
// The real metrics include system decor elements (e.g. soft menu bar).
//
// See: http://developer.android.com/reference/android/view/Display.html#getRealMetrics(android.util.DisplayMetrics)
if (Build.VERSION.SDK_INT >= 17){
display.getRealMetrics(displayMetrics);

if (Build.VERSION.SDK_INT >= 17) {
display.getRealMetrics(screenDisplayMetrics);
} else {
// For 14 <= API level <= 16, we need to invoke getRawHeight and getRawWidth to get the real dimensions.
// Since react-native only supports API level 16+ we don't have to worry about other cases.
Expand All @@ -330,13 +332,13 @@ private static void setDisplayMetrics(Context context) {
try {
Method mGetRawH = Display.class.getMethod("getRawHeight");
Method mGetRawW = Display.class.getMethod("getRawWidth");
displayMetrics.widthPixels = (Integer) mGetRawW.invoke(display);
displayMetrics.heightPixels = (Integer) mGetRawH.invoke(display);
screenDisplayMetrics.widthPixels = (Integer) mGetRawW.invoke(display);
screenDisplayMetrics.heightPixels = (Integer) mGetRawH.invoke(display);
} catch (InvocationTargetException | IllegalAccessException | NoSuchMethodException e) {
throw new RuntimeException("Error getting real dimensions for API level < 17", e);
}
}
DisplayMetricsHolder.setDisplayMetrics(displayMetrics);
DisplayMetricsHolder.setScreenDisplayMetrics(screenDisplayMetrics);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ private KeyboardListener getKeyboardListener() {
private class KeyboardListener implements ViewTreeObserver.OnGlobalLayoutListener {
private final Rect mVisibleViewArea;
private final int mMinKeyboardHeightDetected;

private int mKeyboardHeight = 0;

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

getRootView().getWindowVisibleDisplayFrame(mVisibleViewArea);
final int heightDiff =
DisplayMetricsHolder.getDisplayMetrics().heightPixels - mVisibleViewArea.bottom;
DisplayMetricsHolder.getWindowDisplayMetrics().heightPixels - mVisibleViewArea.bottom;
if (mKeyboardHeight != heightDiff && heightDiff > mMinKeyboardHeightDetected) {
// keyboard is now showing, or the keyboard height has changed
mKeyboardHeight = heightDiff;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,39 @@
/**
* Holds an instance of the current DisplayMetrics so we don't have to thread it through all the
* classes that need it.
* Note: windowDisplayMetrics are deprecated in favor of ScreenDisplayMetrics: window metrics
* are supposed to return the drawable area but there's no guarantee that they correspond to the
* actual size of the {@link ReactRootView}. Moreover, they are not consistent with what iOS
* returns. Screen metrics returns the metrics of the entire screen, is consistent with iOS and
* should be used instead.
*/
public class DisplayMetricsHolder {

private static DisplayMetrics sCurrentDisplayMetrics;
private static DisplayMetrics sWindowDisplayMetrics;
private static DisplayMetrics sScreenDisplayMetrics;

public static void setDisplayMetrics(DisplayMetrics displayMetrics) {
sCurrentDisplayMetrics = displayMetrics;
/**
* @deprecated Use {@link #setScreenDisplayMetrics(DisplayMetrics)} instead. See comment above as
* to why this is not correct to use.
*/
public static void setWindowDisplayMetrics(DisplayMetrics displayMetrics) {
sWindowDisplayMetrics = displayMetrics;
}

public static DisplayMetrics getDisplayMetrics() {
return sCurrentDisplayMetrics;
/**
* @deprecated Use {@link #getScreenDisplayMetrics()} instead. See comment above as to why this
* is not correct to use.
*/
@Deprecated
public static DisplayMetrics getWindowDisplayMetrics() {
return sWindowDisplayMetrics;
}

public static void setScreenDisplayMetrics(DisplayMetrics screenDisplayMetrics) {
sScreenDisplayMetrics = screenDisplayMetrics;
}

public static DisplayMetrics getScreenDisplayMetrics() {
return sScreenDisplayMetrics;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public static float toPixelFromDIP(float value) {
return TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
value,
DisplayMetricsHolder.getDisplayMetrics());
DisplayMetricsHolder.getWindowDisplayMetrics());
}

/**
Expand All @@ -40,7 +40,7 @@ public static float toPixelFromSP(float value) {
return TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_SP,
value,
DisplayMetricsHolder.getDisplayMetrics());
DisplayMetricsHolder.getWindowDisplayMetrics());
}

/**
Expand All @@ -54,7 +54,7 @@ public static float toPixelFromSP(double value) {
* Convert from PX to DP
*/
public static float toDIPFromPixel(float value) {
return value / DisplayMetricsHolder.getDisplayMetrics().density;
return value / DisplayMetricsHolder.getWindowDisplayMetrics().density;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,8 @@ public static Map<String, Object> getConstants() {
"ScaleAspectFill",
ImageView.ScaleType.CENTER_CROP.ordinal())));

DisplayMetrics displayMetrics = DisplayMetricsHolder.getDisplayMetrics();
DisplayMetrics displayMetrics = DisplayMetricsHolder.getWindowDisplayMetrics();
DisplayMetrics screenDisplayMetrics = DisplayMetricsHolder.getScreenDisplayMetrics();
constants.put(
"Dimensions",
MapBuilder.of(
Expand All @@ -106,7 +107,19 @@ public static Map<String, Object> getConstants() {
"fontScale",
displayMetrics.scaledDensity,
"densityDpi",
displayMetrics.densityDpi)));
displayMetrics.densityDpi),
"screenPhysicalPixels",
MapBuilder.of(
"width",
screenDisplayMetrics.widthPixels,
"height",
screenDisplayMetrics.heightPixels,
"scale",
screenDisplayMetrics.density,
"fontScale",
screenDisplayMetrics.scaledDensity,
"densityDpi",
screenDisplayMetrics.densityDpi)));

constants.put(
"StyleConstants",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@

import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.uimanager.ReactStylesDiffMap;
import com.facebook.react.uimanager.DisplayMetricsHolder;
import com.facebook.react.uimanager.annotations.ReactProp;
import com.facebook.react.uimanager.ReactShadowNode;
Expand All @@ -39,7 +38,7 @@ public abstract class ARTVirtualNode extends ReactShadowNode {
protected final float mScale;

public ARTVirtualNode() {
mScale = DisplayMetricsHolder.getDisplayMetrics().density;
mScale = DisplayMetricsHolder.getWindowDisplayMetrics().density;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public Object answer(InvocationOnMock invocation) throws Throwable {
mReactContext = new ReactApplicationContext(RuntimeEnvironment.application);
mReactContext.initializeWithInstance(mCatalystInstanceMock);
DisplayMetrics displayMetrics = mReactContext.getResources().getDisplayMetrics();
DisplayMetricsHolder.setDisplayMetrics(displayMetrics);
DisplayMetricsHolder.setWindowDisplayMetrics(displayMetrics);

UIManagerModule uiManagerModuleMock = mock(UIManagerModule.class);
when(mCatalystInstanceMock.getNativeModule(UIManagerModule.class))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,14 @@ public class LayoutPropertyApplicatorTest {

@Before
public void setup() {
DisplayMetricsHolder.setDisplayMetrics(new DisplayMetrics());
DisplayMetricsHolder.setWindowDisplayMetrics(new DisplayMetrics());
DisplayMetricsHolder.setScreenDisplayMetrics(new DisplayMetrics());
}

@After
public void teardown() {
DisplayMetricsHolder.setDisplayMetrics(null);
DisplayMetricsHolder.setWindowDisplayMetrics(null);
DisplayMetricsHolder.setScreenDisplayMetrics(null);
}

public ReactStylesDiffMap buildStyles(Object... keysAndValues) {
Expand Down Expand Up @@ -309,7 +311,7 @@ public void testEnumerations() {
public void testPropertiesResetToDefault() {
DisplayMetrics displayMetrics = new DisplayMetrics();
displayMetrics.density = 1.0f;
DisplayMetricsHolder.setDisplayMetrics(displayMetrics);
DisplayMetricsHolder.setWindowDisplayMetrics(displayMetrics);

LayoutShadowNode reactShadowNode = spy(new LayoutShadowNode());
ReactStylesDiffMap map = buildStyles(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,8 @@ public void testNativePropsIncludeCorrectTypes() {
List<ViewManager> viewManagers = Arrays.<ViewManager>asList(new ViewManagerUnderTest());
ReactApplicationContext reactContext = new ReactApplicationContext(RuntimeEnvironment.application);
DisplayMetrics displayMetrics = reactContext.getResources().getDisplayMetrics();
DisplayMetricsHolder.setDisplayMetrics(displayMetrics);
DisplayMetricsHolder.setWindowDisplayMetrics(displayMetrics);
DisplayMetricsHolder.setScreenDisplayMetrics(displayMetrics);
UIManagerModule uiManagerModule = new UIManagerModule(
reactContext,
viewManagers,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ public void setUp() {
mUIImplementation = mock(UIImplementation.class);

DisplayMetrics displayMetrics = mReactContext.getResources().getDisplayMetrics();
DisplayMetricsHolder.setDisplayMetrics(displayMetrics);
DisplayMetricsHolder.setWindowDisplayMetrics(displayMetrics);
DisplayMetricsHolder.setScreenDisplayMetrics(displayMetrics);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,8 @@ public Object answer(InvocationOnMock invocation) throws Throwable {
mReactContext.initializeWithInstance(mCatalystInstanceMock);

DisplayMetrics displayMetrics = mReactContext.getResources().getDisplayMetrics();
DisplayMetricsHolder.setDisplayMetrics(displayMetrics);
DisplayMetricsHolder.setWindowDisplayMetrics(displayMetrics);
DisplayMetricsHolder.setScreenDisplayMetrics(displayMetrics);

UIManagerModule uiManagerModuleMock = mock(UIManagerModule.class);
when(mCatalystInstanceMock.getNativeModule(UIManagerModule.class))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,12 @@ public void setup() {
mContext.initializeWithInstance(mCatalystInstanceMock);
mThemeContext = new ThemedReactContext(mContext, mContext);
Fresco.initialize(mContext);
DisplayMetricsHolder.setDisplayMetrics(new DisplayMetrics());
DisplayMetricsHolder.setWindowDisplayMetrics(new DisplayMetrics());
}

@After
public void teardown() {
DisplayMetricsHolder.setDisplayMetrics(null);
DisplayMetricsHolder.setWindowDisplayMetrics(null);
}

public ReactStylesDiffMap buildStyles(Object... keysAndValues) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,8 @@ private void executePendingChoreographerCallbacks() {
public UIManagerModule getUIManagerModule() {
ReactApplicationContext reactContext = ReactTestHelper.createCatalystContextForTest();
DisplayMetrics displayMetrics = reactContext.getResources().getDisplayMetrics();
DisplayMetricsHolder.setDisplayMetrics(displayMetrics);
DisplayMetricsHolder.setWindowDisplayMetrics(displayMetrics);
DisplayMetricsHolder.setScreenDisplayMetrics(displayMetrics);
List<ViewManager> viewManagers = Arrays.asList(
new ViewManager[] {
new ReactTextViewManager(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public void setup() {
mContext.initializeWithInstance(mCatalystInstanceMock);
mThemedContext = new ThemedReactContext(mContext, mContext);
mManager = new ReactTextInputManager();
DisplayMetricsHolder.setDisplayMetrics(new DisplayMetrics());
DisplayMetricsHolder.setWindowDisplayMetrics(new DisplayMetrics());
}

public ReactStylesDiffMap buildStyles(Object... keysAndValues) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,8 @@ public UIManagerModule getUIManagerModule() {
new ReactTextInputManager(),
});
DisplayMetrics displayMetrics = reactContext.getResources().getDisplayMetrics();
DisplayMetricsHolder.setDisplayMetrics(displayMetrics);
DisplayMetricsHolder.setWindowDisplayMetrics(displayMetrics);
DisplayMetricsHolder.setScreenDisplayMetrics(displayMetrics);
UIManagerModule uiManagerModule = new UIManagerModule(
reactContext,
viewManagers,
Expand Down

0 comments on commit 228a1fe

Please sign in to comment.