Skip to content

Commit

Permalink
BREAKING: Android: Correct value of Dimensions.get('screen').fontScale
Browse files Browse the repository at this point in the history
Summary:
The PR description has been updated to reflect the new approach.

**Breaking Change Summary**

On Android, the following properties now return a different number:
  - `Dimensions.get('window').fontScale`
  - `Dimensions.get('screen').fontScale`
  - `PixelRatio.getFontScale()`

This is a breaking change to anyone who was using these properties because the meaning of these properties has now changed.

These properties used to return a value representing font scale times density ([`DisplayMetrics.scaledDensity`](https://developer.android.com/reference/android/util/DisplayMetrics.html#scaledDensity)). Now they return a value representing just font scale ([`Configuration.fontScale`](https://developer.android.com/reference/android/content/res/Configuration.html#fontScale)).

**PR Description**

This PR changes a few things:
  - Correctly exposes the font scale to JavaScript as `Dimensions.get('screen').fontScale`. UIManager was exporting `DisplayMetrics.scaledDensity` under the name `fontScale`. How
Closes facebook#11008

Differential Revision: D4558207

Pulled By: astreet

fbshipit-source-id: 096ce7b28051325dfd45fdb2a14b5e9b7d3bc46f
  • Loading branch information
Adam Comella authored and dudeinthemirror committed Mar 1, 2017
1 parent f7ccd56 commit 053094b
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 54 deletions.
45 changes: 45 additions & 0 deletions Libraries/Utilities/Dimensions.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,15 @@
*/
'use strict';

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

var invariant = require('fbjs/lib/invariant');

var eventEmitter = new EventEmitter();
var dimensionsInitialized = false;
var dimensions = {};
class Dimensions {
/**
Expand Down Expand Up @@ -60,6 +63,15 @@ class Dimensions {
}

Object.assign(dimensions, dims);
if (dimensionsInitialized) {
// Don't fire 'change' the first time the dimensions are set.
eventEmitter.emit('change', {
window: dimensions.window,
screen: dimensions.screen
});
} else {
dimensionsInitialized = true;
}
}

/**
Expand All @@ -81,6 +93,39 @@ class Dimensions {
invariant(dimensions[dim], 'No dimension set for key ' + dim);
return dimensions[dim];
}

/**
* Add an event handler. Supported events:
*
* - `change`: Fires when a property within the `Dimensions` object changes. The argument
* to the event handler is an object with `window` and `screen` properties whose values
* are the same as the return values of `Dimensions.get('window')` and
* `Dimensions.get('screen')`, respectively.
*/
static addEventListener(
type: string,
handler: Function
) {
invariant(
'change' === type,
'Trying to subscribe to unknown event: "%s"', type
);
eventEmitter.addListener(type, handler);
}

/**
* Remove an event handler.
*/
static removeEventListener(
type: string,
handler: Function
) {
invariant(
'change' === type,
'Trying to remove listener for unknown event: "%s"', type
);
eventEmitter.removeListener(type, handler);
}
}

Dimensions.set(UIManager.Dimensions);
Expand Down
25 changes: 4 additions & 21 deletions ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java
Original file line number Diff line number Diff line change
Expand Up @@ -394,27 +394,10 @@ private void emitOrientationChanged(final int newRotation) {
}

private void emitUpdateDimensionsEvent() {
DisplayMetrics windowDisplayMetrics = DisplayMetricsHolder.getWindowDisplayMetrics();
DisplayMetrics screenDisplayMetrics = DisplayMetricsHolder.getScreenDisplayMetrics();

WritableMap windowDisplayMetricsMap = Arguments.createMap();
windowDisplayMetricsMap.putInt("width", windowDisplayMetrics.widthPixels);
windowDisplayMetricsMap.putInt("height", windowDisplayMetrics.heightPixels);
windowDisplayMetricsMap.putDouble("scale", windowDisplayMetrics.density);
windowDisplayMetricsMap.putDouble("fontScale", windowDisplayMetrics.scaledDensity);
windowDisplayMetricsMap.putDouble("densityDpi", windowDisplayMetrics.densityDpi);

WritableMap screenDisplayMetricsMap = Arguments.createMap();
screenDisplayMetricsMap.putInt("width", screenDisplayMetrics.widthPixels);
screenDisplayMetricsMap.putInt("height", screenDisplayMetrics.heightPixels);
screenDisplayMetricsMap.putDouble("scale", screenDisplayMetrics.density);
screenDisplayMetricsMap.putDouble("fontScale", screenDisplayMetrics.scaledDensity);
screenDisplayMetricsMap.putDouble("densityDpi", screenDisplayMetrics.densityDpi);

WritableMap dimensionsMap = Arguments.createMap();
dimensionsMap.putMap("windowPhysicalPixels", windowDisplayMetricsMap);
dimensionsMap.putMap("screenPhysicalPixels", screenDisplayMetricsMap);
sendEvent("didUpdateDimensions", dimensionsMap);
mReactInstanceManager
.getCurrentReactContext()
.getNativeModule(UIManagerModule.class)
.emitUpdateDimensionsEvent();
}

private void sendEvent(String eventName, @Nullable WritableMap params) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,10 @@
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.common.ReactConstants;
import com.facebook.react.module.annotations.ReactModule;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.facebook.react.uimanager.debug.NotThreadSafeViewHierarchyUpdateDebugListener;
import com.facebook.react.uimanager.events.EventDispatcher;
import com.facebook.systrace.Systrace;
Expand Down Expand Up @@ -88,6 +90,7 @@ public class UIManagerModule extends ReactContextBaseJavaModule implements
private final Map<String, Object> mModuleConstants;
private final UIImplementation mUIImplementation;
private final MemoryTrimCallback mMemoryTrimCallback = new MemoryTrimCallback();
private float mFontScale;

private int mNextRootViewTag = 1;
private int mBatchId = 0;
Expand All @@ -100,7 +103,8 @@ public UIManagerModule(
super(reactContext);
DisplayMetricsHolder.initDisplayMetricsIfNotInitialized(reactContext);
mEventDispatcher = new EventDispatcher(reactContext);
mModuleConstants = createConstants(viewManagerList, lazyViewManagersEnabled);
mFontScale = getReactApplicationContext().getResources().getConfiguration().fontScale;
mModuleConstants = createConstants(viewManagerList, lazyViewManagersEnabled, mFontScale);
mUIImplementation = uiImplementationProvider
.createUIImplementation(reactContext, viewManagerList, mEventDispatcher);

Expand Down Expand Up @@ -133,6 +137,12 @@ public void initialize() {
@Override
public void onHostResume() {
mUIImplementation.onHostResume();

float fontScale = getReactApplicationContext().getResources().getConfiguration().fontScale;
if (mFontScale != fontScale) {
mFontScale = fontScale;
emitUpdateDimensionsEvent();
}
}

@Override
Expand All @@ -156,13 +166,15 @@ public void onCatalystInstanceDestroy() {

private static Map<String, Object> createConstants(
List<ViewManager> viewManagerList,
boolean lazyViewManagersEnabled) {
boolean lazyViewManagersEnabled,
float fontScale) {
ReactMarker.logMarker(CREATE_UI_MANAGER_MODULE_CONSTANTS_START);
Systrace.beginSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, "CreateUIManagerConstants");
try {
return UIManagerModuleConstantsHelper.createConstants(
viewManagerList,
lazyViewManagersEnabled);
lazyViewManagersEnabled,
fontScale);
} finally {
Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
ReactMarker.logMarker(CREATE_UI_MANAGER_MODULE_CONSTANTS_END);
Expand Down Expand Up @@ -541,6 +553,16 @@ public void sendAccessibilityEvent(int tag, int eventType) {
mUIImplementation.sendAccessibilityEvent(tag, eventType);
}

public void emitUpdateDimensionsEvent() {
sendEvent("didUpdateDimensions", UIManagerModuleConstants.getDimensionsConstants(mFontScale));
}

private void sendEvent(String eventName, @Nullable WritableMap params) {
getReactApplicationContext()
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit(eventName, params);
}

/**
* Schedule a block to be executed on the UI thread. Useful if you need to execute
* view logic after all currently queued view updates have completed.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
import android.view.accessibility.AccessibilityEvent;
import android.widget.ImageView;

import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.common.MapBuilder;
import com.facebook.react.uimanager.events.TouchEventType;

Expand Down Expand Up @@ -81,7 +83,7 @@
.build();
}

public static Map<String, Object> getConstants() {
public static Map<String, Object> getConstants(float fontScale) {
HashMap<String, Object> constants = new HashMap<String, Object>();
constants.put(
"UIView",
Expand All @@ -95,35 +97,9 @@ public static Map<String, Object> getConstants() {
"ScaleAspectCenter",
ImageView.ScaleType.CENTER_INSIDE.ordinal())));

DisplayMetrics displayMetrics = DisplayMetricsHolder.getWindowDisplayMetrics();
DisplayMetrics screenDisplayMetrics = DisplayMetricsHolder.getScreenDisplayMetrics();
constants.put(
"Dimensions",
MapBuilder.of(
"windowPhysicalPixels",
MapBuilder.of(
"width",
displayMetrics.widthPixels,
"height",
displayMetrics.heightPixels,
"scale",
displayMetrics.density,
"fontScale",
displayMetrics.scaledDensity,
"densityDpi",
displayMetrics.densityDpi),
"screenPhysicalPixels",
MapBuilder.of(
"width",
screenDisplayMetrics.widthPixels,
"height",
screenDisplayMetrics.heightPixels,
"scale",
screenDisplayMetrics.density,
"fontScale",
screenDisplayMetrics.scaledDensity,
"densityDpi",
screenDisplayMetrics.densityDpi)));
getDimensionsConstants(fontScale));

constants.put(
"StyleConstants",
Expand Down Expand Up @@ -157,4 +133,29 @@ public static Map<String, Object> getConstants() {

return constants;
}

public static WritableMap getDimensionsConstants(float fontScale) {
DisplayMetrics windowDisplayMetrics = DisplayMetricsHolder.getWindowDisplayMetrics();
DisplayMetrics screenDisplayMetrics = DisplayMetricsHolder.getScreenDisplayMetrics();

WritableMap windowDisplayMetricsMap = Arguments.createMap();
windowDisplayMetricsMap.putInt("width", windowDisplayMetrics.widthPixels);
windowDisplayMetricsMap.putInt("height", windowDisplayMetrics.heightPixels);
windowDisplayMetricsMap.putDouble("scale", windowDisplayMetrics.density);
windowDisplayMetricsMap.putDouble("fontScale", fontScale);
windowDisplayMetricsMap.putDouble("densityDpi", windowDisplayMetrics.densityDpi);

WritableMap screenDisplayMetricsMap = Arguments.createMap();
screenDisplayMetricsMap.putInt("width", screenDisplayMetrics.widthPixels);
screenDisplayMetricsMap.putInt("height", screenDisplayMetrics.heightPixels);
screenDisplayMetricsMap.putDouble("scale", screenDisplayMetrics.density);
screenDisplayMetricsMap.putDouble("fontScale", fontScale);
screenDisplayMetricsMap.putDouble("densityDpi", screenDisplayMetrics.densityDpi);

WritableMap dimensionsMap = Arguments.createMap();
dimensionsMap.putMap("windowPhysicalPixels", windowDisplayMetricsMap);
dimensionsMap.putMap("screenPhysicalPixels", screenDisplayMetricsMap);

return dimensionsMap;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import java.util.List;
import java.util.Map;

import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.common.MapBuilder;
import com.facebook.systrace.Systrace;
import com.facebook.systrace.SystraceMessage;
Expand Down Expand Up @@ -42,8 +43,9 @@
*/
/* package */ static Map<String, Object> createConstants(
List<ViewManager> viewManagers,
boolean lazyViewManagersEnabled) {
Map<String, Object> constants = UIManagerModuleConstants.getConstants();
boolean lazyViewManagersEnabled,
float fontScale) {
Map<String, Object> constants = UIManagerModuleConstants.getConstants(fontScale);
Map bubblingEventTypesConstants = UIManagerModuleConstants.getBubblingEventTypeConstants();
Map directEventTypesConstants = UIManagerModuleConstants.getDirectEventTypeConstants();

Expand Down

0 comments on commit 053094b

Please sign in to comment.