Made UIManager set displayContstants

Reviewed By: andreicoman11

Differential Revision: D3281309

fbshipit-source-id: f5568f2127e7e26dcbd77b3845092346ac06c0db
This commit is contained in:
Konstantin Raev 2016-05-10 08:33:54 -07:00 committed by Facebook Github Bot 1
parent ff7f260ce9
commit 4c3286f2a2
9 changed files with 57 additions and 70 deletions

View File

@ -11,8 +11,6 @@ package com.facebook.react;
import javax.annotation.Nullable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@ -26,12 +24,8 @@ import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.View;
import android.view.WindowManager;
import com.facebook.common.logging.FLog;
import com.facebook.infer.annotation.Assertions;
@ -285,7 +279,7 @@ import static com.facebook.react.bridge.ReactMarkerConstants.RUN_JS_BUNDLE_START
// TODO(9577825): remove this
ApplicationHolder.setApplication((Application) applicationContext.getApplicationContext());
setDisplayMetrics(applicationContext);
DisplayMetricsHolder.initDisplayMetricsIfNotInitialized(applicationContext);
mApplicationContext = applicationContext;
mCurrentActivity = currentActivity;
@ -328,40 +322,6 @@ import static com.facebook.react.bridge.ReactMarkerConstants.RUN_JS_BUNDLE_START
SoLoader.init(applicationContext, /* native exopackage */ false);
}
private static void setDisplayMetrics(Context context) {
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(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.
//
// Reflection exceptions are rethrown at runtime.
//
// See: http://stackoverflow.com/questions/14341041/how-to-get-real-screen-height-and-width/23861333#23861333
try {
Method mGetRawH = Display.class.getMethod("getRawHeight");
Method mGetRawW = Display.class.getMethod("getRawWidth");
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.setScreenDisplayMetrics(screenDisplayMetrics);
}
/**
* Trigger react context initialization asynchronously in a background async task. This enables
* applications to pre-load the application JS, and execute global code before

View File

@ -9,7 +9,18 @@
package com.facebook.react.uimanager;
import android.content.Context;
import android.os.Build;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.WindowManager;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import javax.annotation.Nullable;
import com.facebook.infer.annotation.Assertions;
/**
* Holds an instance of the current DisplayMetrics so we don't have to thread it through all the
@ -22,8 +33,8 @@ import android.util.DisplayMetrics;
*/
public class DisplayMetricsHolder {
private static DisplayMetrics sWindowDisplayMetrics;
private static DisplayMetrics sScreenDisplayMetrics;
private static @Nullable DisplayMetrics sWindowDisplayMetrics;
private static @Nullable DisplayMetrics sScreenDisplayMetrics;
/**
* @deprecated Use {@link #setScreenDisplayMetrics(DisplayMetrics)} instead. See comment above as
@ -32,6 +43,46 @@ public class DisplayMetricsHolder {
public static void setWindowDisplayMetrics(DisplayMetrics displayMetrics) {
sWindowDisplayMetrics = displayMetrics;
}
public static void initDisplayMetricsIfNotInitialized(Context context) {
if (DisplayMetricsHolder.getScreenDisplayMetrics() != null) {
return;
}
DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
DisplayMetricsHolder.setWindowDisplayMetrics(displayMetrics);
DisplayMetrics screenDisplayMetrics = new DisplayMetrics();
screenDisplayMetrics.setTo(displayMetrics);
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Assertions.assertNotNull(
wm,
"WindowManager is null!");
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(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.
//
// Reflection exceptions are rethrown at runtime.
//
// See: http://stackoverflow.com/questions/14341041/how-to-get-real-screen-height-and-width/23861333#23861333
try {
Method mGetRawH = Display.class.getMethod("getRawHeight");
Method mGetRawW = Display.class.getMethod("getRawWidth");
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.setScreenDisplayMetrics(screenDisplayMetrics);
}
/**
* @deprecated Use {@link #getScreenDisplayMetrics()} instead. See comment above as to why this

View File

@ -23,6 +23,7 @@ import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.uimanager.DisplayMetricsHolder;
import com.facebook.react.uimanager.debug.NotThreadSafeViewHierarchyUpdateDebugListener;
import com.facebook.react.uimanager.events.EventDispatcher;
import com.facebook.systrace.Systrace;
@ -76,6 +77,7 @@ public class UIManagerModule extends ReactContextBaseJavaModule implements
List<ViewManager> viewManagerList,
UIImplementation uiImplementation) {
super(reactContext);
DisplayMetricsHolder.initDisplayMetricsIfNotInitialized(reactContext);
mEventDispatcher = new EventDispatcher(reactContext);
mModuleConstants = createConstants(viewManagerList);
mUIImplementation = uiImplementation;

View File

@ -81,8 +81,7 @@ public class RootViewTest {
mCatalystInstanceMock = ReactTestHelper.createMockCatalystInstance();
mReactContext = new ReactApplicationContext(RuntimeEnvironment.application);
mReactContext.initializeWithInstance(mCatalystInstanceMock);
DisplayMetrics displayMetrics = mReactContext.getResources().getDisplayMetrics();
DisplayMetricsHolder.setWindowDisplayMetrics(displayMetrics);
DisplayMetricsHolder.initDisplayMetricsIfNotInitialized(mReactContext);
UIManagerModule uiManagerModuleMock = mock(UIManagerModule.class);
when(mCatalystInstanceMock.getNativeModule(UIManagerModule.class))

View File

@ -13,7 +13,6 @@ import java.util.Arrays;
import java.util.List;
import java.util.Map;
import android.util.DisplayMetrics;
import android.view.View;
import com.facebook.react.bridge.ReactApplicationContext;
@ -146,9 +145,6 @@ public class ReactPropConstantsTest {
public void testNativePropsIncludeCorrectTypes() {
List<ViewManager> viewManagers = Arrays.<ViewManager>asList(new ViewManagerUnderTest());
ReactApplicationContext reactContext = new ReactApplicationContext(RuntimeEnvironment.application);
DisplayMetrics displayMetrics = reactContext.getResources().getDisplayMetrics();
DisplayMetricsHolder.setWindowDisplayMetrics(displayMetrics);
DisplayMetricsHolder.setScreenDisplayMetrics(displayMetrics);
UIManagerModule uiManagerModule = new UIManagerModule(
reactContext,
viewManagers,

View File

@ -13,8 +13,6 @@ import java.util.Arrays;
import java.util.List;
import java.util.Map;
import android.util.DisplayMetrics;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.common.MapBuilder;
@ -58,10 +56,6 @@ public class UIManagerModuleConstantsTest {
public void setUp() {
mReactContext = new ReactApplicationContext(RuntimeEnvironment.application);
mUIImplementation = mock(UIImplementation.class);
DisplayMetrics displayMetrics = mReactContext.getResources().getDisplayMetrics();
DisplayMetricsHolder.setWindowDisplayMetrics(displayMetrics);
DisplayMetricsHolder.setScreenDisplayMetrics(displayMetrics);
}
@Test

View File

@ -14,7 +14,6 @@ import java.util.Arrays;
import java.util.List;
import android.graphics.Color;
import android.util.DisplayMetrics;
import android.view.Choreographer;
import android.view.View;
import android.view.ViewGroup;
@ -108,10 +107,6 @@ public class UIManagerModuleTest {
mReactContext = new ReactApplicationContext(RuntimeEnvironment.application);
mReactContext.initializeWithInstance(mCatalystInstanceMock);
DisplayMetrics displayMetrics = mReactContext.getResources().getDisplayMetrics();
DisplayMetricsHolder.setWindowDisplayMetrics(displayMetrics);
DisplayMetricsHolder.setScreenDisplayMetrics(displayMetrics);
UIManagerModule uiManagerModuleMock = mock(UIManagerModule.class);
when(mCatalystInstanceMock.getNativeModule(UIManagerModule.class))
.thenReturn(uiManagerModuleMock);

View File

@ -24,7 +24,6 @@ import android.text.TextUtils;
import android.text.style.AbsoluteSizeSpan;
import android.text.style.StrikethroughSpan;
import android.text.style.UnderlineSpan;
import android.util.DisplayMetrics;
import android.view.Choreographer;
import android.widget.TextView;
@ -34,7 +33,6 @@ import com.facebook.react.bridge.JavaOnlyArray;
import com.facebook.react.bridge.JavaOnlyMap;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactTestHelper;
import com.facebook.react.uimanager.DisplayMetricsHolder;
import com.facebook.react.uimanager.ReactChoreographer;
import com.facebook.react.uimanager.UIImplementation;
import com.facebook.react.uimanager.UIManagerModule;
@ -428,9 +426,6 @@ public class ReactTextTest {
public UIManagerModule getUIManagerModule() {
ReactApplicationContext reactContext = ReactTestHelper.createCatalystContextForTest();
DisplayMetrics displayMetrics = reactContext.getResources().getDisplayMetrics();
DisplayMetricsHolder.setWindowDisplayMetrics(displayMetrics);
DisplayMetricsHolder.setScreenDisplayMetrics(displayMetrics);
List<ViewManager> viewManagers = Arrays.asList(
new ViewManager[] {
new ReactTextViewManager(),

View File

@ -13,7 +13,6 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import android.util.DisplayMetrics;
import android.view.Choreographer;
import android.widget.EditText;
@ -23,7 +22,6 @@ import com.facebook.react.bridge.JavaOnlyArray;
import com.facebook.react.bridge.JavaOnlyMap;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactTestHelper;
import com.facebook.react.uimanager.DisplayMetricsHolder;
import com.facebook.react.uimanager.ReactChoreographer;
import com.facebook.react.uimanager.UIImplementation;
import com.facebook.react.uimanager.UIManagerModule;
@ -182,9 +180,6 @@ public class TextInputTest {
new ViewManager[] {
new ReactTextInputManager(),
});
DisplayMetrics displayMetrics = reactContext.getResources().getDisplayMetrics();
DisplayMetricsHolder.setWindowDisplayMetrics(displayMetrics);
DisplayMetricsHolder.setScreenDisplayMetrics(displayMetrics);
UIManagerModule uiManagerModule = new UIManagerModule(
reactContext,
viewManagers,