From 47d8ed59deef3ad6a91a10419ea750f13b92bc9a Mon Sep 17 00:00:00 2001 From: Mathieu Acthernoene Date: Wed, 13 Aug 2025 19:37:32 +0200 Subject: [PATCH 1/2] Fix Dimensions window values on Android < 15 --- .../ReactAndroid/api/ReactAndroid.api | 6 +- .../ReactAndroid/build.gradle.kts | 1 + .../facebook/react/ReactInstanceManager.java | 13 ++++- .../com/facebook/react/ReactRootView.java | 11 ++-- .../modules/deviceinfo/DeviceInfoModule.kt | 6 +- .../facebook/react/runtime/ReactHostImpl.kt | 6 +- .../facebook/react/runtime/ReactInstance.kt | 5 +- .../react/uimanager/DisplayMetricsHolder.kt | 58 +++++++++++++------ .../react/uimanager/UIManagerModule.java | 13 ++++- .../java/com/facebook/react/RootViewTest.kt | 3 +- .../react-native/gradle/libs.versions.toml | 2 + 11 files changed, 90 insertions(+), 34 deletions(-) diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 8708804f63c0e0..d581a3329d545e 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -3358,8 +3358,10 @@ public final class com/facebook/react/uimanager/DisplayMetricsHolder { public static final fun getDisplayMetricsWritableMap (D)Lcom/facebook/react/bridge/WritableMap; public static final fun getScreenDisplayMetrics ()Landroid/util/DisplayMetrics; public static final fun getWindowDisplayMetrics ()Landroid/util/DisplayMetrics; - public static final fun initDisplayMetrics (Landroid/content/Context;)V - public static final fun initDisplayMetricsIfNotInitialized (Landroid/content/Context;)V + public static final fun initScreenDisplayMetrics (Landroid/content/Context;)V + public static final fun initWindowDisplayMetrics (Landroid/content/Context;)V + public static final fun initScreenDisplayMetricsIfNotInitialized (Landroid/content/Context;)V + public static final fun initWindowDisplayMetricsIfNotInitialized (Landroid/content/Context;)V public static final fun setScreenDisplayMetrics (Landroid/util/DisplayMetrics;)V public static final fun setWindowDisplayMetrics (Landroid/util/DisplayMetrics;)V } diff --git a/packages/react-native/ReactAndroid/build.gradle.kts b/packages/react-native/ReactAndroid/build.gradle.kts index fc96244df45ab7..2b5410065e7f6c 100644 --- a/packages/react-native/ReactAndroid/build.gradle.kts +++ b/packages/react-native/ReactAndroid/build.gradle.kts @@ -665,6 +665,7 @@ dependencies { api(libs.androidx.autofill) api(libs.androidx.swiperefreshlayout) api(libs.androidx.tracing) + api(libs.androidx.window) api(libs.fbjni) api(libs.fresco) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java index 18c93e63d86c19..2519e91bde3a63 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java @@ -264,7 +264,11 @@ public static ReactInstanceManagerBuilder builder() { FLog.d(TAG, "ReactInstanceManager.ctor()"); initializeSoLoaderIfNecessary(applicationContext); - DisplayMetricsHolder.initDisplayMetricsIfNotInitialized(applicationContext); + DisplayMetricsHolder.initScreenDisplayMetricsIfNotInitialized(applicationContext); + + if (currentActivity != null) { + DisplayMetricsHolder.initWindowDisplayMetricsIfNotInitialized(currentActivity); + } // See {@code ReactInstanceManagerBuilder} for description of all flags here. mApplicationContext = applicationContext; @@ -929,6 +933,13 @@ public void onConfigurationChanged(Context updatedContext, @Nullable Configurati ReactContext currentReactContext = getCurrentReactContext(); if (currentReactContext != null) { + DisplayMetricsHolder.initScreenDisplayMetrics(currentReactContext); + Activity currentActivity = currentReactContext.getCurrentActivity(); + + if (currentActivity != null) { + DisplayMetricsHolder.initWindowDisplayMetrics(currentActivity); + } + AppearanceModule appearanceModule = currentReactContext.getNativeModule(AppearanceModule.class); diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java index cf143a7c6a67b6..80671b7709ff92 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java @@ -136,9 +136,8 @@ private void init() { setRootViewTag(ReactRootViewTagGenerator.getNextRootViewTag()); setClipChildren(false); - if (ReactNativeFeatureFlags.enableFontScaleChangesUpdatingLayout()) { - DisplayMetricsHolder.initDisplayMetrics(getContext().getApplicationContext()); - } + DisplayMetricsHolder.initScreenDisplayMetrics(getContext()); + DisplayMetricsHolder.initWindowDisplayMetrics(getContext()); } @Override @@ -883,7 +882,8 @@ private class CustomGlobalLayoutListener implements ViewTreeObserver.OnGlobalLay private int mDeviceRotation = 0; /* package */ CustomGlobalLayoutListener() { - DisplayMetricsHolder.initDisplayMetricsIfNotInitialized(getContext().getApplicationContext()); + DisplayMetricsHolder.initScreenDisplayMetricsIfNotInitialized(getContext()); + DisplayMetricsHolder.initWindowDisplayMetricsIfNotInitialized(getContext()); mVisibleViewArea = new Rect(); mMinKeyboardHeightDetected = (int) PixelUtil.toPixelFromDIP(60); } @@ -1006,7 +1006,8 @@ private void checkForDeviceOrientationChanges() { return; } mDeviceRotation = rotation; - DisplayMetricsHolder.initDisplayMetrics(getContext().getApplicationContext()); + DisplayMetricsHolder.initScreenDisplayMetrics(getContext()); + DisplayMetricsHolder.initWindowDisplayMetrics(getContext()); emitOrientationChanged(rotation); } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/deviceinfo/DeviceInfoModule.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/deviceinfo/DeviceInfoModule.kt index 9c3a0a625d3a58..03d826f8ad1330 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/deviceinfo/DeviceInfoModule.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/deviceinfo/DeviceInfoModule.kt @@ -15,7 +15,8 @@ import com.facebook.react.bridge.ReactSoftExceptionLogger import com.facebook.react.bridge.ReadableMap import com.facebook.react.module.annotations.ReactModule import com.facebook.react.uimanager.DisplayMetricsHolder.getDisplayMetricsWritableMap -import com.facebook.react.uimanager.DisplayMetricsHolder.initDisplayMetricsIfNotInitialized +import com.facebook.react.uimanager.DisplayMetricsHolder.initScreenDisplayMetricsIfNotInitialized +import com.facebook.react.uimanager.DisplayMetricsHolder.initWindowDisplayMetricsIfNotInitialized import com.facebook.react.views.view.isEdgeToEdgeFeatureFlagOn /** Module that exposes Android Constants to JS. */ @@ -26,7 +27,8 @@ internal class DeviceInfoModule(reactContext: ReactApplicationContext) : private var previousDisplayMetrics: ReadableMap? = null init { - initDisplayMetricsIfNotInitialized(reactContext) + initScreenDisplayMetricsIfNotInitialized(reactContext) + reactContext.currentActivity?.let { initWindowDisplayMetricsIfNotInitialized(it) } reactContext.addLifecycleEventListener(this) } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImpl.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImpl.kt index 28b6616f4a2418..040ffa61a49b99 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImpl.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImpl.kt @@ -655,9 +655,8 @@ public class ReactHostImpl( override fun onConfigurationChanged(context: Context) { val currentReactContext = this.currentReactContext if (currentReactContext != null) { - if (ReactNativeFeatureFlags.enableFontScaleChangesUpdatingLayout()) { - DisplayMetricsHolder.initDisplayMetrics(currentReactContext) - } + DisplayMetricsHolder.initScreenDisplayMetrics(currentReactContext) + currentReactContext.currentActivity?.let { DisplayMetricsHolder.initWindowDisplayMetrics(it) } val appearanceModule = currentReactContext.getNativeModule(AppearanceModule::class.java) appearanceModule?.onConfigurationChanged(context) @@ -967,6 +966,7 @@ public class ReactHostImpl( val instance = ReactInstance( reactContext, + currentActivity, reactHostDelegate, componentFactory, devSupportManager, diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactInstance.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactInstance.kt index 96bb76b3b2a092..10928f2c19fc41 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactInstance.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactInstance.kt @@ -7,6 +7,7 @@ package com.facebook.react.runtime +import android.app.Activity import android.content.res.AssetManager import android.view.View import com.facebook.common.logging.FLog @@ -88,6 +89,7 @@ import kotlin.jvm.JvmStatic @UnstableReactNativeAPI internal class ReactInstance( private val context: BridgelessReactContext, + private val activity: Activity?, delegate: ReactHostDelegate, componentFactory: ComponentFactory, devSupportManager: DevSupportManager, @@ -250,7 +252,8 @@ internal class ReactInstance( FabricUIManager(context, ViewManagerRegistry(viewManagerResolver), eventBeatManager) // Misc initialization that needs to be done before Fabric init - DisplayMetricsHolder.initDisplayMetricsIfNotInitialized(context) + DisplayMetricsHolder.initScreenDisplayMetricsIfNotInitialized(context) + activity?.let { DisplayMetricsHolder.initWindowDisplayMetricsIfNotInitialized(it) } val binding = FabricUIManagerBinding() binding.register( diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/DisplayMetricsHolder.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/DisplayMetricsHolder.kt index adaff375674f84..a1e8fd92b07291 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/DisplayMetricsHolder.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/DisplayMetricsHolder.kt @@ -13,17 +13,21 @@ import android.util.DisplayMetrics import android.view.WindowManager import androidx.core.view.ViewCompat import androidx.core.view.WindowInsetsCompat +import androidx.window.layout.WindowMetricsCalculator import com.facebook.react.bridge.WritableMap import com.facebook.react.bridge.WritableNativeMap import com.facebook.react.uimanager.PixelUtil.pxToDp +import com.facebook.react.views.view.isEdgeToEdgeFeatureFlagOn /** * Holds an instance of the current DisplayMetrics so we don't have to thread it through all the * classes that need it. */ public object DisplayMetricsHolder { - private const val INITIALIZATION_MISSING_MESSAGE = - "DisplayMetricsHolder must be initialized with initDisplayMetricsIfNotInitialized or initDisplayMetrics" + private const val SCREEN_INITIALIZATION_MISSING_MESSAGE = + "DisplayMetricsHolder must be initialized with initScreenDisplayMetricsIfNotInitialized or initScreenDisplayMetrics" + private const val WINDOW_INITIALIZATION_MISSING_MESSAGE = + "DisplayMetricsHolder must be initialized with initWindowDisplayMetricsIfNotInitialized or initWindowDisplayMetrics" @JvmStatic private var windowDisplayMetrics: DisplayMetrics? = null @JvmStatic private var screenDisplayMetrics: DisplayMetrics? = null @@ -31,7 +35,7 @@ public object DisplayMetricsHolder { /** The metrics of the window associated to the Context used to initialize ReactNative */ @JvmStatic public fun getWindowDisplayMetrics(): DisplayMetrics { - checkNotNull(windowDisplayMetrics) { INITIALIZATION_MISSING_MESSAGE } + checkNotNull(windowDisplayMetrics) { WINDOW_INITIALIZATION_MISSING_MESSAGE } return windowDisplayMetrics as DisplayMetrics } @@ -43,7 +47,7 @@ public object DisplayMetricsHolder { /** Screen metrics returns the metrics of the default screen on the device. */ @JvmStatic public fun getScreenDisplayMetrics(): DisplayMetrics { - checkNotNull(screenDisplayMetrics) { INITIALIZATION_MISSING_MESSAGE } + checkNotNull(screenDisplayMetrics) { SCREEN_INITIALIZATION_MISSING_MESSAGE } return screenDisplayMetrics as DisplayMetrics } @@ -53,33 +57,53 @@ public object DisplayMetricsHolder { } @JvmStatic - public fun initDisplayMetricsIfNotInitialized(context: Context) { - if (screenDisplayMetrics != null) { - return + public fun initScreenDisplayMetricsIfNotInitialized(context: Context) { + if (screenDisplayMetrics == null) { + initScreenDisplayMetrics(context) } - initDisplayMetrics(context) } @JvmStatic - public fun initDisplayMetrics(context: Context) { - val displayMetrics = context.resources.displayMetrics - windowDisplayMetrics = displayMetrics - val screenDisplayMetrics = DisplayMetrics() - screenDisplayMetrics.setTo(displayMetrics) + public fun initWindowDisplayMetricsIfNotInitialized(context: Context) { + if (windowDisplayMetrics == null) { + initWindowDisplayMetrics(context) + } + } + + @JvmStatic + public fun initScreenDisplayMetrics(context: Context) { + val displayMetrics = DisplayMetrics() + displayMetrics.setTo(context.resources.displayMetrics) + val wm = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager // 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) - @Suppress("DEPRECATION") wm.defaultDisplay.getRealMetrics(screenDisplayMetrics) - DisplayMetricsHolder.screenDisplayMetrics = screenDisplayMetrics + @Suppress("DEPRECATION") wm.defaultDisplay.getRealMetrics(displayMetrics) + screenDisplayMetrics = displayMetrics + } + + @JvmStatic + public fun initWindowDisplayMetrics(context: Context) { + val displayMetrics = DisplayMetrics() + displayMetrics.setTo(context.resources.displayMetrics) + + if (isEdgeToEdgeFeatureFlagOn) { + WindowMetricsCalculator.getOrCreate().computeCurrentWindowMetrics(context).let { + displayMetrics.widthPixels = it.bounds.width() + displayMetrics.heightPixels = it.bounds.height() + } + } + + windowDisplayMetrics = displayMetrics } @JvmStatic public fun getDisplayMetricsWritableMap(fontScale: Double): WritableMap { - checkNotNull(windowDisplayMetrics) { INITIALIZATION_MISSING_MESSAGE } - checkNotNull(screenDisplayMetrics) { INITIALIZATION_MISSING_MESSAGE } + checkNotNull(windowDisplayMetrics) { WINDOW_INITIALIZATION_MISSING_MESSAGE } + checkNotNull(screenDisplayMetrics) { SCREEN_INITIALIZATION_MISSING_MESSAGE } return WritableNativeMap().apply { putMap( diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModule.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModule.java index fab7bf4f808fa5..10e892bbc0502f 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModule.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModule.java @@ -12,6 +12,7 @@ import static com.facebook.react.uimanager.common.UIManagerType.FABRIC; import static com.facebook.react.uimanager.common.UIManagerType.LEGACY; +import android.app.Activity; import android.content.ComponentCallbacks2; import android.content.res.Configuration; import android.view.View; @@ -128,7 +129,11 @@ public UIManagerModule( ViewManagerResolver viewManagerResolver, int minTimeLeftInFrameForNonBatchedOperationMs) { super(reactContext); - DisplayMetricsHolder.initDisplayMetricsIfNotInitialized(reactContext); + DisplayMetricsHolder.initScreenDisplayMetricsIfNotInitialized(reactContext); + Activity currentActivity = reactContext.getCurrentActivity(); + if (currentActivity != null) { + DisplayMetricsHolder.initWindowDisplayMetricsIfNotInitialized(currentActivity); + } mEventDispatcher = new EventDispatcherImpl(reactContext); mModuleConstants = createConstants(viewManagerResolver); mCustomDirectEvents = UIManagerModuleConstants.directEventTypeConstants; @@ -148,7 +153,11 @@ public UIManagerModule( List viewManagersList, int minTimeLeftInFrameForNonBatchedOperationMs) { super(reactContext); - DisplayMetricsHolder.initDisplayMetricsIfNotInitialized(reactContext); + DisplayMetricsHolder.initScreenDisplayMetricsIfNotInitialized(reactContext); + Activity currentActivity = reactContext.getCurrentActivity(); + if (currentActivity != null) { + DisplayMetricsHolder.initWindowDisplayMetricsIfNotInitialized(currentActivity); + } mEventDispatcher = new EventDispatcherImpl(reactContext); mCustomDirectEvents = MapBuilder.newHashMap(); mModuleConstants = createConstants(viewManagersList, null, mCustomDirectEvents); diff --git a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/RootViewTest.kt b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/RootViewTest.kt index 820e184b2df722..0cf4acd68f80bc 100644 --- a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/RootViewTest.kt +++ b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/RootViewTest.kt @@ -71,7 +71,8 @@ class RootViewTest { reactContext = spy(BridgeReactContext(RuntimeEnvironment.getApplication())) reactContext.initializeWithInstance(catalystInstanceMock) - DisplayMetricsHolder.initDisplayMetricsIfNotInitialized(reactContext) + DisplayMetricsHolder.initScreenDisplayMetricsIfNotInitialized(reactContext) + DisplayMetricsHolder.initWindowDisplayMetricsIfNotInitialized(reactContext) val uiManagerModuleMock: UIManagerModule = mock() whenever(catalystInstanceMock.getNativeModule(UIManagerModule::class.java)) .thenReturn(uiManagerModuleMock) diff --git a/packages/react-native/gradle/libs.versions.toml b/packages/react-native/gradle/libs.versions.toml index f21668ffff842f..8dfb000851a8e8 100644 --- a/packages/react-native/gradle/libs.versions.toml +++ b/packages/react-native/gradle/libs.versions.toml @@ -16,6 +16,7 @@ androidx-swiperefreshlayout = "1.1.0" androidx-test = "1.5.0" androidx-test-junit = "1.2.1" androidx-tracing = "1.1.0" +androidx-window = "1.4.0" assertj = "3.21.0" binary-compatibility-validator = "0.13.2" download = "5.4.0" @@ -64,6 +65,7 @@ androidx-test-rules = { module = "androidx.test:rules", version.ref = "androidx- androidx-test-runner = { module = "androidx.test:runner", version.ref = "androidx-test" } androidx-tracing = { module = "androidx.tracing:tracing", version.ref = "androidx-tracing" } androidx-uiautomator = { group = "androidx.test.uiautomator", name = "uiautomator", version.ref = "uiautomator" } +androidx-window = { module = "androidx.window:window", version.ref = "androidx-window" } fbjni = { module = "com.facebook.fbjni:fbjni", version.ref = "fbjni" } fresco = { module = "com.facebook.fresco:fresco", version.ref = "fresco" } From 6b5397a428530753c6b6184ec657abea75ffe75e Mon Sep 17 00:00:00 2001 From: Mathieu Acthernoene Date: Wed, 20 Aug 2025 14:20:53 +0200 Subject: [PATCH 2/2] Fix tests --- .../PerfMonitorOverlayViewManager.kt | 2 +- .../com/facebook/react/uimanager/PixelUtil.kt | 8 ++--- .../uimanager/DisplayMetricsHolderTest.kt | 36 +++++++++++++------ 3 files changed, 30 insertions(+), 16 deletions(-) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/PerfMonitorOverlayViewManager.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/PerfMonitorOverlayViewManager.kt index 3b6c05c2800cf7..32c6ba11e5e800 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/PerfMonitorOverlayViewManager.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/PerfMonitorOverlayViewManager.kt @@ -97,7 +97,7 @@ internal class PerfMonitorOverlayViewManager( return } val context = contextSupplier.get() ?: return - DisplayMetricsHolder.initDisplayMetricsIfNotInitialized(context) + DisplayMetricsHolder.initScreenDisplayMetricsIfNotInitialized(context) createDialog(context) createButton(context) initialized = true diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/PixelUtil.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/PixelUtil.kt index facc32f99c673c..5682b1643fd1c9 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/PixelUtil.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/PixelUtil.kt @@ -22,7 +22,7 @@ public object PixelUtil { return TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, value, - DisplayMetricsHolder.getWindowDisplayMetrics(), + DisplayMetricsHolder.getScreenDisplayMetrics(), ) } @@ -40,7 +40,7 @@ public object PixelUtil { return Float.NaN } - val displayMetrics = DisplayMetricsHolder.getWindowDisplayMetrics() + val displayMetrics = DisplayMetricsHolder.getScreenDisplayMetrics() val scaledValue = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, value, displayMetrics) if (maxFontScale >= 1) { @@ -63,13 +63,13 @@ public object PixelUtil { return Float.NaN } - return value / DisplayMetricsHolder.getWindowDisplayMetrics().density + return value / DisplayMetricsHolder.getScreenDisplayMetrics().density } /** @return [Float] that represents the density of the display metrics for device screen. */ @JvmStatic public fun getDisplayMetricDensity(): Float = - DisplayMetricsHolder.getWindowDisplayMetrics().density + DisplayMetricsHolder.getScreenDisplayMetrics().density /* Kotlin extensions */ public fun Int.dpToPx(): Float = toPixelFromDIP(this.toFloat()) diff --git a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/uimanager/DisplayMetricsHolderTest.kt b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/uimanager/DisplayMetricsHolderTest.kt index 042613d98da0e9..fb61a1144ac7f3 100644 --- a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/uimanager/DisplayMetricsHolderTest.kt +++ b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/uimanager/DisplayMetricsHolderTest.kt @@ -87,25 +87,37 @@ class DisplayMetricsHolderTest { } @Test - fun initDisplayMetrics_setsMetrics() { - DisplayMetricsHolder.initDisplayMetrics(context) - assertThat(DisplayMetricsHolder.getWindowDisplayMetrics()).isNotNull() + fun initScreenDisplayMetrics_setsMetrics() { + DisplayMetricsHolder.initScreenDisplayMetrics(context) assertThat(DisplayMetricsHolder.getScreenDisplayMetrics()).isNotNull() } @Test - fun initDisplayMetricsIfNotInitialized_onlyInitializesOnce() { - DisplayMetricsHolder.initDisplayMetricsIfNotInitialized(context) - val firstWindow = DisplayMetricsHolder.getWindowDisplayMetrics() + fun initWindowDisplayMetrics_setsMetrics() { + DisplayMetricsHolder.initWindowDisplayMetrics(context) + assertThat(DisplayMetricsHolder.getWindowDisplayMetrics()).isNotNull() + } + + @Test + fun initScreenDisplayMetricsIfNotInitialized_onlyInitializesOnce() { + DisplayMetricsHolder.initScreenDisplayMetricsIfNotInitialized(context) val firstScreen = DisplayMetricsHolder.getScreenDisplayMetrics() // Should not reinitialize - DisplayMetricsHolder.initDisplayMetricsIfNotInitialized(context) - val secondWindow = DisplayMetricsHolder.getWindowDisplayMetrics() + DisplayMetricsHolder.initScreenDisplayMetricsIfNotInitialized(context) val secondScreen = DisplayMetricsHolder.getScreenDisplayMetrics() - assertThat(secondWindow).isEqualTo(firstWindow) assertThat(secondScreen).isEqualTo(firstScreen) } + @Test + fun initWindowDisplayMetricsIfNotInitialized_onlyInitializesOnce() { + DisplayMetricsHolder.initWindowDisplayMetricsIfNotInitialized(context) + val firstWindow = DisplayMetricsHolder.getWindowDisplayMetrics() + // Should not reinitialize + DisplayMetricsHolder.initWindowDisplayMetricsIfNotInitialized(context) + val secondWindow = DisplayMetricsHolder.getWindowDisplayMetrics() + assertThat(secondWindow).isEqualTo(firstWindow) + } + @Test(expected = IllegalStateException::class) fun getDisplayMetricsWritableMap_failsIfNotInitialized() { DisplayMetricsHolder.getDisplayMetricsWritableMap(1.0) @@ -114,7 +126,8 @@ class DisplayMetricsHolderTest { @Test fun getDisplayMetricsWritableMap_returnsCorrectMap() { // Use the official initialization method to ensure both metrics are set - DisplayMetricsHolder.initDisplayMetrics(context) + DisplayMetricsHolder.initScreenDisplayMetrics(context) + DisplayMetricsHolder.initWindowDisplayMetrics(context) val map: WritableMap = DisplayMetricsHolder.getDisplayMetricsWritableMap(1.0) assertThat(map.hasKey("windowPhysicalPixels")).isTrue() assertThat(map.hasKey("screenPhysicalPixels")).isTrue() @@ -132,7 +145,8 @@ class DisplayMetricsHolderTest { @Test @TargetApi(30) fun getEncodedScreenSizeWithoutVerticalInsets_returnsEncodedValue() { - DisplayMetricsHolder.initDisplayMetrics(context) + DisplayMetricsHolder.initScreenDisplayMetrics(context) + DisplayMetricsHolder.initWindowDisplayMetrics(context) val activity: Activity = mock() val window: Window = mock()