diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 3bda89c153ed8b..c92611f9f2b595 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -3348,10 +3348,8 @@ 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 initScreenDisplayMetrics (Landroid/content/Context;)V - public static final fun initScreenDisplayMetricsIfNotInitialized (Landroid/content/Context;)V - public static final fun initWindowDisplayMetrics (Landroid/content/Context;)V - public static final fun initWindowDisplayMetricsIfNotInitialized (Landroid/content/Context;)V + public static final fun initDisplayMetrics (Landroid/content/Context;)V + public static final fun initDisplayMetricsIfNotInitialized (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 faa0d8816a1d4e..98ab7976caf9b0 100644 --- a/packages/react-native/ReactAndroid/build.gradle.kts +++ b/packages/react-native/ReactAndroid/build.gradle.kts @@ -630,7 +630,6 @@ 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 f5bb7352ac9161..075f3e98a0039b 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 @@ -262,11 +262,7 @@ public static ReactInstanceManagerBuilder builder() { FLog.d(TAG, "ReactInstanceManager.ctor()"); initializeSoLoaderIfNecessary(applicationContext); - DisplayMetricsHolder.initScreenDisplayMetricsIfNotInitialized(applicationContext); - - if (currentActivity != null) { - DisplayMetricsHolder.initWindowDisplayMetricsIfNotInitialized(currentActivity); - } + DisplayMetricsHolder.initDisplayMetricsIfNotInitialized(applicationContext); // See {@code ReactInstanceManagerBuilder} for description of all flags here. mApplicationContext = applicationContext; @@ -931,13 +927,6 @@ 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 80671b7709ff92..cf143a7c6a67b6 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,8 +136,9 @@ private void init() { setRootViewTag(ReactRootViewTagGenerator.getNextRootViewTag()); setClipChildren(false); - DisplayMetricsHolder.initScreenDisplayMetrics(getContext()); - DisplayMetricsHolder.initWindowDisplayMetrics(getContext()); + if (ReactNativeFeatureFlags.enableFontScaleChangesUpdatingLayout()) { + DisplayMetricsHolder.initDisplayMetrics(getContext().getApplicationContext()); + } } @Override @@ -882,8 +883,7 @@ private class CustomGlobalLayoutListener implements ViewTreeObserver.OnGlobalLay private int mDeviceRotation = 0; /* package */ CustomGlobalLayoutListener() { - DisplayMetricsHolder.initScreenDisplayMetricsIfNotInitialized(getContext()); - DisplayMetricsHolder.initWindowDisplayMetricsIfNotInitialized(getContext()); + DisplayMetricsHolder.initDisplayMetricsIfNotInitialized(getContext().getApplicationContext()); mVisibleViewArea = new Rect(); mMinKeyboardHeightDetected = (int) PixelUtil.toPixelFromDIP(60); } @@ -1006,8 +1006,7 @@ private void checkForDeviceOrientationChanges() { return; } mDeviceRotation = rotation; - DisplayMetricsHolder.initScreenDisplayMetrics(getContext()); - DisplayMetricsHolder.initWindowDisplayMetrics(getContext()); + DisplayMetricsHolder.initDisplayMetrics(getContext().getApplicationContext()); 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 a0165a64e393c4..6d570f224ca7c7 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,8 +15,7 @@ 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.initScreenDisplayMetricsIfNotInitialized -import com.facebook.react.uimanager.DisplayMetricsHolder.initWindowDisplayMetricsIfNotInitialized +import com.facebook.react.uimanager.DisplayMetricsHolder.initDisplayMetricsIfNotInitialized import com.facebook.react.views.view.isEdgeToEdgeFeatureFlagOn /** Module that exposes Android Constants to JS. */ @@ -27,8 +26,7 @@ internal class DeviceInfoModule(reactContext: ReactApplicationContext) : private var previousDisplayMetrics: ReadableMap? = null init { - initScreenDisplayMetricsIfNotInitialized(reactContext) - reactContext.currentActivity?.let { initWindowDisplayMetricsIfNotInitialized(it) } + initDisplayMetricsIfNotInitialized(reactContext) 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 e7f7fc692209e7..627330cde16268 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 @@ -625,8 +625,9 @@ public class ReactHostImpl( override fun onConfigurationChanged(context: Context) { val currentReactContext = this.currentReactContext if (currentReactContext != null) { - DisplayMetricsHolder.initScreenDisplayMetrics(currentReactContext) - currentReactContext.currentActivity?.let { DisplayMetricsHolder.initWindowDisplayMetrics(it) } + if (ReactNativeFeatureFlags.enableFontScaleChangesUpdatingLayout()) { + DisplayMetricsHolder.initDisplayMetrics(currentReactContext) + } val appearanceModule = currentReactContext.getNativeModule(AppearanceModule::class.java) appearanceModule?.onConfigurationChanged(context) @@ -917,7 +918,6 @@ 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 986b01c53f5d9f..c7546e718e53f7 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,7 +7,6 @@ package com.facebook.react.runtime -import android.app.Activity import android.content.res.AssetManager import android.view.View import com.facebook.common.logging.FLog @@ -89,7 +88,6 @@ import kotlin.jvm.JvmStatic @UnstableReactNativeAPI internal class ReactInstance( private val context: BridgelessReactContext, - private val activity: Activity?, delegate: ReactHostDelegate, componentFactory: ComponentFactory, devSupportManager: DevSupportManager, @@ -242,8 +240,7 @@ internal class ReactInstance( FabricUIManager(context, ViewManagerRegistry(viewManagerResolver), eventBeatManager) // Misc initialization that needs to be done before Fabric init - DisplayMetricsHolder.initScreenDisplayMetricsIfNotInitialized(context) - activity?.let { DisplayMetricsHolder.initWindowDisplayMetricsIfNotInitialized(it) } + DisplayMetricsHolder.initDisplayMetricsIfNotInitialized(context) 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 05762d98026b7a..055312c2a995eb 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,21 +13,17 @@ 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 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" + private const val INITIALIZATION_MISSING_MESSAGE = + "DisplayMetricsHolder must be initialized with initDisplayMetricsIfNotInitialized or initDisplayMetrics" @JvmStatic private var windowDisplayMetrics: DisplayMetrics? = null @JvmStatic private var screenDisplayMetrics: DisplayMetrics? = null @@ -35,7 +31,7 @@ public object DisplayMetricsHolder { /** The metrics of the window associated to the Context used to initialize ReactNative */ @JvmStatic public fun getWindowDisplayMetrics(): DisplayMetrics { - checkNotNull(windowDisplayMetrics) { WINDOW_INITIALIZATION_MISSING_MESSAGE } + checkNotNull(windowDisplayMetrics) { INITIALIZATION_MISSING_MESSAGE } return windowDisplayMetrics as DisplayMetrics } @@ -47,7 +43,7 @@ public object DisplayMetricsHolder { /** Screen metrics returns the metrics of the default screen on the device. */ @JvmStatic public fun getScreenDisplayMetrics(): DisplayMetrics { - checkNotNull(screenDisplayMetrics) { SCREEN_INITIALIZATION_MISSING_MESSAGE } + checkNotNull(screenDisplayMetrics) { INITIALIZATION_MISSING_MESSAGE } return screenDisplayMetrics as DisplayMetrics } @@ -57,58 +53,33 @@ public object DisplayMetricsHolder { } @JvmStatic - public fun initScreenDisplayMetricsIfNotInitialized(context: Context) { - if (screenDisplayMetrics == null) { - initScreenDisplayMetrics(context) + public fun initDisplayMetricsIfNotInitialized(context: Context) { + if (screenDisplayMetrics != null) { + return } + initDisplayMetrics(context) } @JvmStatic - public fun initWindowDisplayMetricsIfNotInitialized(context: Context) { - if (windowDisplayMetrics == null) { - initWindowDisplayMetrics(context) - } - } - - @JvmStatic - public fun initScreenDisplayMetrics(context: Context) { - val displayMetrics = DisplayMetrics() - displayMetrics.setTo(context.resources.displayMetrics) - + public fun initDisplayMetrics(context: Context) { + val displayMetrics = context.resources.displayMetrics + windowDisplayMetrics = displayMetrics + val screenDisplayMetrics = DisplayMetrics() + screenDisplayMetrics.setTo(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(displayMetrics) - screenDisplayMetrics = displayMetrics - } - - /* - * NOTE: Unlike [initScreenDisplayMetrics], this method needs a UiContext (Activity of - * InputMethodService) else WindowMetircsCalculator will throw an exception. - */ - @JvmStatic - public fun initWindowDisplayMetrics(context: Context) { - val displayMetrics = DisplayMetrics() - displayMetrics.setTo(context.resources.displayMetrics) - - if (isEdgeToEdgeFeatureFlagOn) { - WindowMetricsCalculator.getOrCreate().computeCurrentWindowMetrics(context).let { windowMetrics - -> - displayMetrics.widthPixels = windowMetrics.bounds.width() - displayMetrics.heightPixels = windowMetrics.bounds.height() - } - } - - windowDisplayMetrics = displayMetrics + @Suppress("DEPRECATION") wm.defaultDisplay.getRealMetrics(screenDisplayMetrics) + DisplayMetricsHolder.screenDisplayMetrics = screenDisplayMetrics } @JvmStatic public fun getDisplayMetricsWritableMap(fontScale: Double): WritableMap { - checkNotNull(windowDisplayMetrics) { WINDOW_INITIALIZATION_MISSING_MESSAGE } - checkNotNull(screenDisplayMetrics) { SCREEN_INITIALIZATION_MISSING_MESSAGE } + checkNotNull(windowDisplayMetrics) { INITIALIZATION_MISSING_MESSAGE } + checkNotNull(screenDisplayMetrics) { 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 8d7309fbe58fce..671abca4ba1de5 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,7 +12,6 @@ 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; @@ -127,11 +126,7 @@ public UIManagerModule( ViewManagerResolver viewManagerResolver, int minTimeLeftInFrameForNonBatchedOperationMs) { super(reactContext); - DisplayMetricsHolder.initScreenDisplayMetricsIfNotInitialized(reactContext); - Activity currentActivity = reactContext.getCurrentActivity(); - if (currentActivity != null) { - DisplayMetricsHolder.initWindowDisplayMetricsIfNotInitialized(currentActivity); - } + DisplayMetricsHolder.initDisplayMetricsIfNotInitialized(reactContext); mEventDispatcher = new EventDispatcherImpl(reactContext); mModuleConstants = createConstants(viewManagerResolver); mCustomDirectEvents = UIManagerModuleConstants.directEventTypeConstants; @@ -151,11 +146,7 @@ public UIManagerModule( List viewManagersList, int minTimeLeftInFrameForNonBatchedOperationMs) { super(reactContext); - DisplayMetricsHolder.initScreenDisplayMetricsIfNotInitialized(reactContext); - Activity currentActivity = reactContext.getCurrentActivity(); - if (currentActivity != null) { - DisplayMetricsHolder.initWindowDisplayMetricsIfNotInitialized(currentActivity); - } + DisplayMetricsHolder.initDisplayMetricsIfNotInitialized(reactContext); 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 e142136826cb42..4ee6636e0b0cff 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,8 +71,7 @@ class RootViewTest { reactContext = spy(BridgeReactContext(RuntimeEnvironment.getApplication())) reactContext.initializeWithInstance(catalystInstanceMock) - DisplayMetricsHolder.initScreenDisplayMetricsIfNotInitialized(reactContext) - DisplayMetricsHolder.initWindowDisplayMetricsIfNotInitialized(reactContext) + DisplayMetricsHolder.initDisplayMetricsIfNotInitialized(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 b90f66e6bc56b4..58ec8b5535e0db 100644 --- a/packages/react-native/gradle/libs.versions.toml +++ b/packages/react-native/gradle/libs.versions.toml @@ -16,7 +16,6 @@ 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" @@ -65,7 +64,6 @@ 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" }