Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<eb0bafceba60cb439a4be3d68b890725>>
* @generated SignedSource<<cfa7aa53731059247d858fd8fb6e914b>>
*/

/**
Expand Down Expand Up @@ -564,6 +564,12 @@ public object ReactNativeFeatureFlags {
@JvmStatic
public fun useTurboModuleInterop(): Boolean = accessor.useTurboModuleInterop()

/**
* Keeps the window density in the screen display metrics instead of the physical display density, so text is measured at the density the window renders at.
*/
@JvmStatic
public fun useWindowDensityForDisplayMetricsAndroid(): Boolean = accessor.useWindowDensityForDisplayMetricsAndroid()

/**
* Outset the culling context frame with the provided ratio. The culling context frame size will be outset by width * ratio on the left and right, and height * ratio on the top and bottom.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<0107593110db613063b6f4ceb50d8e58>>
* @generated SignedSource<<71d0554dc45df7d5365f81b7ec8c3d5b>>
*/

/**
Expand Down Expand Up @@ -109,6 +109,7 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces
private var useSharedAnimatedBackendCache: Boolean? = null
private var useTraitHiddenOnAndroidCache: Boolean? = null
private var useTurboModuleInteropCache: Boolean? = null
private var useWindowDensityForDisplayMetricsAndroidCache: Boolean? = null
private var viewCullingOutsetRatioCache: Double? = null
private var viewTransitionEnabledCache: Boolean? = null
private var viewTransitionUseHardwareBitmapAndroidCache: Boolean? = null
Expand Down Expand Up @@ -915,6 +916,15 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces
return cached
}

override fun useWindowDensityForDisplayMetricsAndroid(): Boolean {
var cached = useWindowDensityForDisplayMetricsAndroidCache
if (cached == null) {
cached = ReactNativeFeatureFlagsCxxInterop.useWindowDensityForDisplayMetricsAndroid()
useWindowDensityForDisplayMetricsAndroidCache = cached
}
return cached
}

override fun viewCullingOutsetRatio(): Double {
var cached = viewCullingOutsetRatioCache
if (cached == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<fa0374808e3cbe7122ca993780c0b627>>
* @generated SignedSource<<312cec99bd429d22e25f4e82d7fc4ee7>>
*/

/**
Expand Down Expand Up @@ -206,6 +206,8 @@ public object ReactNativeFeatureFlagsCxxInterop {

@DoNotStrip @JvmStatic public external fun useTurboModuleInterop(): Boolean

@DoNotStrip @JvmStatic public external fun useWindowDensityForDisplayMetricsAndroid(): Boolean

@DoNotStrip @JvmStatic public external fun viewCullingOutsetRatio(): Double

@DoNotStrip @JvmStatic public external fun viewTransitionEnabled(): Boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<768077a22c110aa98ab02bc96eec695b>>
* @generated SignedSource<<669f16e131d4a5ddc026ffecc6893575>>
*/

/**
Expand Down Expand Up @@ -201,6 +201,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi

override fun useTurboModuleInterop(): Boolean = false

override fun useWindowDensityForDisplayMetricsAndroid(): Boolean = false

override fun viewCullingOutsetRatio(): Double = 0.0

override fun viewTransitionEnabled(): Boolean = false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<86ebc7307e7ebe2023e909a868ed3117>>
* @generated SignedSource<<ee4c0f9c1e7c6af3b0d15948ebc519b3>>
*/

/**
Expand Down Expand Up @@ -113,6 +113,7 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
private var useSharedAnimatedBackendCache: Boolean? = null
private var useTraitHiddenOnAndroidCache: Boolean? = null
private var useTurboModuleInteropCache: Boolean? = null
private var useWindowDensityForDisplayMetricsAndroidCache: Boolean? = null
private var viewCullingOutsetRatioCache: Double? = null
private var viewTransitionEnabledCache: Boolean? = null
private var viewTransitionUseHardwareBitmapAndroidCache: Boolean? = null
Expand Down Expand Up @@ -1008,6 +1009,16 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
return cached
}

override fun useWindowDensityForDisplayMetricsAndroid(): Boolean {
var cached = useWindowDensityForDisplayMetricsAndroidCache
if (cached == null) {
cached = currentProvider.useWindowDensityForDisplayMetricsAndroid()
accessedFeatureFlags.add("useWindowDensityForDisplayMetricsAndroid")
useWindowDensityForDisplayMetricsAndroidCache = cached
}
return cached
}

override fun viewCullingOutsetRatio(): Double {
var cached = viewCullingOutsetRatioCache
if (cached == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<c83fba10dc6f7d596e3bcd9725c64e6e>>
* @generated SignedSource<<18267103ef4f3eb22f23a15b808528c2>>
*/

/**
Expand Down Expand Up @@ -201,6 +201,8 @@ public interface ReactNativeFeatureFlagsProvider {

@DoNotStrip public fun useTurboModuleInterop(): Boolean

@DoNotStrip public fun useWindowDensityForDisplayMetricsAndroid(): Boolean

@DoNotStrip public fun viewCullingOutsetRatio(): Double

@DoNotStrip public fun viewTransitionEnabled(): Boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import android.util.DisplayMetrics
import android.view.WindowManager
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags
import com.facebook.react.uimanager.PixelUtil.pxToDp

/**
Expand Down Expand Up @@ -61,6 +62,13 @@ public object DisplayMetricsHolder {
// Non-visual contexts (e.g. Application) may throw on API 30+.
// Falls back to resource display metrics copied via setTo() above.
}
if (
displayMetrics.densityDpi != screenDisplayMetrics.densityDpi &&
ReactNativeFeatureFlags.useWindowDensityForDisplayMetricsAndroid()
) {
screenDisplayMetrics.density = displayMetrics.density
screenDisplayMetrics.densityDpi = displayMetrics.densityDpi
}
// Preserve fontScale from the configuration because getRealMetrics() returns
// physical display metrics without the system font scale setting.
// This is needed for proper text scaling when fontScale < 1.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<200266835197634d13de07182d80a2c1>>
* @generated SignedSource<<568d6e4175fb51e09bc3d4441ffa9741>>
*/

/**
Expand Down Expand Up @@ -573,6 +573,12 @@ class ReactNativeFeatureFlagsJavaProvider
return method(javaProvider_);
}

bool useWindowDensityForDisplayMetricsAndroid() override {
static const auto method =
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("useWindowDensityForDisplayMetricsAndroid");
return method(javaProvider_);
}

double viewCullingOutsetRatio() override {
static const auto method =
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jdouble()>("viewCullingOutsetRatio");
Expand Down Expand Up @@ -1046,6 +1052,11 @@ bool JReactNativeFeatureFlagsCxxInterop::useTurboModuleInterop(
return ReactNativeFeatureFlags::useTurboModuleInterop();
}

bool JReactNativeFeatureFlagsCxxInterop::useWindowDensityForDisplayMetricsAndroid(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
return ReactNativeFeatureFlags::useWindowDensityForDisplayMetricsAndroid();
}

double JReactNativeFeatureFlagsCxxInterop::viewCullingOutsetRatio(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
return ReactNativeFeatureFlags::viewCullingOutsetRatio();
Expand Down Expand Up @@ -1364,6 +1375,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() {
makeNativeMethod(
"useTurboModuleInterop",
JReactNativeFeatureFlagsCxxInterop::useTurboModuleInterop),
makeNativeMethod(
"useWindowDensityForDisplayMetricsAndroid",
JReactNativeFeatureFlagsCxxInterop::useWindowDensityForDisplayMetricsAndroid),
makeNativeMethod(
"viewCullingOutsetRatio",
JReactNativeFeatureFlagsCxxInterop::viewCullingOutsetRatio),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<13aa248dae556b06b31c25a28e448460>>
* @generated SignedSource<<2e0f936c003aafc456ab3f960ca4b2f3>>
*/

/**
Expand Down Expand Up @@ -297,6 +297,9 @@ class JReactNativeFeatureFlagsCxxInterop
static bool useTurboModuleInterop(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);

static bool useWindowDensityForDisplayMetricsAndroid(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);

static double viewCullingOutsetRatio(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ import android.view.View
import android.view.Window
import android.view.WindowInsets
import androidx.annotation.RequiresApi
import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags
import com.facebook.react.internal.featureflags.ReactNativeFeatureFlagsDefaults
import com.facebook.react.internal.featureflags.ReactNativeFeatureFlagsForTests
import com.facebook.testutils.shadows.ShadowNativeLoader
import com.facebook.testutils.shadows.ShadowNativeMap
import com.facebook.testutils.shadows.ShadowReadableNativeMap
Expand Down Expand Up @@ -52,6 +55,7 @@ class DisplayMetricsHolderTest {

@Before
fun setUp() {
ReactNativeFeatureFlagsForTests.setUp()
context = RuntimeEnvironment.getApplication()
displayMetrics = context.resources.displayMetrics
DisplayMetricsHolder.setScreenDisplayMetrics(null)
Expand All @@ -60,6 +64,7 @@ class DisplayMetricsHolderTest {
@After
fun tearDown() {
DisplayMetricsHolder.setScreenDisplayMetrics(null)
ReactNativeFeatureFlags.dangerouslyReset()
}

@Test(expected = IllegalStateException::class)
Expand Down Expand Up @@ -142,6 +147,41 @@ class DisplayMetricsHolderTest {
assertThat(screenMetrics.scaledDensity).isEqualTo(customScaledDensity)
}

@Test
fun initDisplayMetrics_withWindowDensityFlag_usesTheWindowDensity() {
overrideWindowDensityFlag(true)
setWindowDensityTo400Dpi()

DisplayMetricsHolder.initDisplayMetrics(context)

val screenMetrics = DisplayMetricsHolder.getScreenDisplayMetrics()
assertThat(screenMetrics.density).isEqualTo(2.5f)
assertThat(screenMetrics.densityDpi).isEqualTo(DisplayMetrics.DENSITY_400)
assertThat(PixelUtil.toDIPFromPixel(PixelUtil.toPixelFromSP(16f))).isEqualTo(16f)
}

@Test
fun initDisplayMetrics_withoutWindowDensityFlag_usesTheDisplayDensity() {
DisplayMetricsHolder.initDisplayMetrics(context)
val displayDensityDpi = DisplayMetricsHolder.getScreenDisplayMetrics().densityDpi
overrideWindowDensityFlag(false)
setWindowDensityTo400Dpi()

DisplayMetricsHolder.initDisplayMetrics(context)

assertThat(DisplayMetricsHolder.getScreenDisplayMetrics().densityDpi)
.isEqualTo(displayDensityDpi)
.isNotEqualTo(DisplayMetrics.DENSITY_400)
}

@Test
fun initDisplayMetrics_withMatchingDensities_doesNotReadFeatureFlags() {
DisplayMetricsHolder.initDisplayMetrics(context)
overrideWindowDensityFlag(true)

assertThat(ReactNativeFeatureFlags.useWindowDensityForDisplayMetricsAndroid()).isTrue()
}

@Test
fun initDisplayMetrics_doesNotCrashWithNonVisualContext() {
val mockContext: Context = mock()
Expand All @@ -164,4 +204,19 @@ class DisplayMetricsHolderTest {
// Metrics should still be set from resource display metrics
assertThat(DisplayMetricsHolder.getScreenDisplayMetrics()).isNotNull()
}

private fun overrideWindowDensityFlag(enabled: Boolean) {
ReactNativeFeatureFlags.override(
object : ReactNativeFeatureFlagsDefaults() {
override fun useWindowDensityForDisplayMetricsAndroid(): Boolean = enabled
},
)
}

private fun setWindowDensityTo400Dpi() {
val resourceMetrics = context.resources.displayMetrics
resourceMetrics.density = 2.5f
resourceMetrics.densityDpi = DisplayMetrics.DENSITY_400
resourceMetrics.scaledDensity = 2.5f
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import android.content.Context
import android.content.res.Configuration
import android.content.res.Resources
import android.util.DisplayMetrics
import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags
import com.facebook.react.internal.featureflags.ReactNativeFeatureFlagsForTests
import com.facebook.testutils.shadows.ShadowNativeLoader
import com.facebook.testutils.shadows.ShadowSoLoader
import kotlin.math.abs
Expand All @@ -36,13 +38,15 @@ class PixelUtilTest {

@Before
fun setUp() {
ReactNativeFeatureFlagsForTests.setUp()
context = RuntimeEnvironment.getApplication()
DisplayMetricsHolder.setScreenDisplayMetrics(null)
}

@After
fun tearDown() {
DisplayMetricsHolder.setScreenDisplayMetrics(null)
ReactNativeFeatureFlags.dangerouslyReset()
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<fc4b67b43c846eac0085ed4a5528a170>>
* @generated SignedSource<<f90778065a9a5f48383dd9b4606bd862>>
*/

/**
Expand Down Expand Up @@ -382,6 +382,10 @@ bool ReactNativeFeatureFlags::useTurboModuleInterop() {
return getAccessor().useTurboModuleInterop();
}

bool ReactNativeFeatureFlags::useWindowDensityForDisplayMetricsAndroid() {
return getAccessor().useWindowDensityForDisplayMetricsAndroid();
}

double ReactNativeFeatureFlags::viewCullingOutsetRatio() {
return getAccessor().viewCullingOutsetRatio();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<1a9a8a587b477b6aa0d3aa57e30272c2>>
* @generated SignedSource<<62dbb584d6aaf595314636a81346e3e5>>
*/

/**
Expand Down Expand Up @@ -486,6 +486,11 @@ class ReactNativeFeatureFlags {
*/
RN_EXPORT static bool useTurboModuleInterop();

/**
* Keeps the window density in the screen display metrics instead of the physical display density, so text is measured at the density the window renders at.
*/
RN_EXPORT static bool useWindowDensityForDisplayMetricsAndroid();

/**
* Outset the culling context frame with the provided ratio. The culling context frame size will be outset by width * ratio on the left and right, and height * ratio on the top and bottom.
*/
Expand Down
Loading
Loading