From e8616c342d1e33e8c935dd88a824657a2362578a Mon Sep 17 00:00:00 2001 From: Shreesh Ayachit Date: Mon, 28 Sep 2026 11:24:56 -0700 Subject: [PATCH] Use ConfigurationCompat for device locale lookup Summary: `I18nUtil` directly called `Configuration.getLocales()`, which is unavailable before API 24. Read the preferred locale through `ConfigurationCompat` instead and fall back to the process default when the locale list is empty. Add an API-23 Robolectric regression test that exercises RTL detection on an Arabic locale. Changelog: [Android][Fixed] - Prevent a crash when resolving RTL layout direction on Android 6 Reviewed By: cortinico Differential Revision: D122147089 --- .../react/modules/i18nmanager/I18nUtil.kt | 7 +++- .../react/modules/i18nmanager/I18nUtilTest.kt | 38 +++++++++++++++++++ 2 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 packages/react-native/ReactAndroid/src/test/java/com/facebook/react/modules/i18nmanager/I18nUtilTest.kt diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/i18nmanager/I18nUtil.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/i18nmanager/I18nUtil.kt index 3177d0efe3d..b991a34bdcf 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/i18nmanager/I18nUtil.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/i18nmanager/I18nUtil.kt @@ -10,7 +10,9 @@ package com.facebook.react.modules.i18nmanager import android.content.Context import android.content.pm.ApplicationInfo import android.view.View +import androidx.core.os.ConfigurationCompat import androidx.core.text.TextUtilsCompat +import java.util.Locale public class I18nUtil private constructor() { /** @@ -61,8 +63,9 @@ public class I18nUtil private constructor() { // Check if the current device language is RTL private fun isDevicePreferredLanguageRTL(context: Context): Boolean { - val directionality = - TextUtilsCompat.getLayoutDirectionFromLocale(context.resources.configuration.locales[0]) + val locale = + ConfigurationCompat.getLocales(context.resources.configuration)[0] ?: Locale.getDefault() + val directionality = TextUtilsCompat.getLayoutDirectionFromLocale(locale) return directionality == View.LAYOUT_DIRECTION_RTL } diff --git a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/modules/i18nmanager/I18nUtilTest.kt b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/modules/i18nmanager/I18nUtilTest.kt new file mode 100644 index 00000000000..cee9e18a989 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/modules/i18nmanager/I18nUtilTest.kt @@ -0,0 +1,38 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +package com.facebook.react.modules.i18nmanager + +import android.content.Context +import android.content.pm.ApplicationInfo +import org.assertj.core.api.Assertions.assertThat +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner +import org.robolectric.RuntimeEnvironment +import org.robolectric.annotation.Config + +@RunWith(RobolectricTestRunner::class) +internal class I18nUtilTest { + private lateinit var context: Context + + @Before + fun setUp() { + context = RuntimeEnvironment.getApplication() + context.applicationInfo.flags = + context.applicationInfo.flags or ApplicationInfo.FLAG_SUPPORTS_RTL + I18nUtil.instance.allowRTL(context, true) + I18nUtil.instance.forceRTL(context, false) + } + + @Test + @Config(sdk = [23], qualifiers = "ar") + fun isRTL_onApi23_usesPreferredLocale() { + assertThat(I18nUtil.instance.isRTL(context)).isTrue() + } +}