Skip to content

Commit 7f22494

Browse files
NickGerlemanfacebook-github-bot
authored andcommitted
Disable Android Workarounds for Attachment Metrics (#52446)
Summary: Pull Request resolved: #52446 The logic for retrieving metrics from a placeholder character is kind of insane, and has been around since inline views were added built into TextView in Paper. One of the workarounds, for old versions of Android on Samsung phones (no more info to bound the versions) causes incorrect behavior, at least in the case where we have RTL text in LTR layout. Another, explicitly mentions `singleLine` with RTL para, a deprecated TextView prop, that doesn't apply to us here (and also could never apply to BoringLayout, since RTL chars are not boring). We don't have these workarounds anywhere else (though we have some other workarounds for bidi crash in old Android), including other frameworks I could find. Let's bias to cleaning this old code up. Changelog: [Android][Fixed] - Fix incorrect positioning of inline view at the end of string when RTL text in LTR container Reviewed By: javache Differential Revision: D77703906 fbshipit-source-id: f25a5e2f05100f0288f3889132b658cdabf26f22
1 parent 7cd0b42 commit 7f22494

21 files changed

Lines changed: 195 additions & 75 deletions

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<64faf70fad18019fc27e77681ff41d05>>
7+
* @generated SignedSource<<9b580dfb56a10ebe9e80bc7ce0c2ca36>>
88
*/
99

1010
/**
@@ -54,6 +54,12 @@ public object ReactNativeFeatureFlags {
5454
@JvmStatic
5555
public fun disableMountItemReorderingAndroid(): Boolean = accessor.disableMountItemReorderingAndroid()
5656

57+
/**
58+
* Disable some workarounds for old Android versions in TextLayoutManager logic for retrieving attachment metrics
59+
*/
60+
@JvmStatic
61+
public fun disableOldAndroidAttachmentMetricsWorkarounds(): Boolean = accessor.disableOldAndroidAttachmentMetricsWorkarounds()
62+
5763
/**
5864
* Turns off the global measurement cache used by TextLayoutManager on Android.
5965
*/

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<d09b78184190ec69fcaa937031cd7f04>>
7+
* @generated SignedSource<<99871d495699fdea7f67b3b29af2d28f>>
88
*/
99

1010
/**
@@ -24,6 +24,7 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces
2424
private var cxxNativeAnimatedEnabledCache: Boolean? = null
2525
private var cxxNativeAnimatedRemoveJsSyncCache: Boolean? = null
2626
private var disableMountItemReorderingAndroidCache: Boolean? = null
27+
private var disableOldAndroidAttachmentMetricsWorkaroundsCache: Boolean? = null
2728
private var disableTextLayoutManagerCacheAndroidCache: Boolean? = null
2829
private var enableAccessibilityOrderCache: Boolean? = null
2930
private var enableAccumulatedUpdatesInRawPropsAndroidCache: Boolean? = null
@@ -114,6 +115,15 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces
114115
return cached
115116
}
116117

118+
override fun disableOldAndroidAttachmentMetricsWorkarounds(): Boolean {
119+
var cached = disableOldAndroidAttachmentMetricsWorkaroundsCache
120+
if (cached == null) {
121+
cached = ReactNativeFeatureFlagsCxxInterop.disableOldAndroidAttachmentMetricsWorkarounds()
122+
disableOldAndroidAttachmentMetricsWorkaroundsCache = cached
123+
}
124+
return cached
125+
}
126+
117127
override fun disableTextLayoutManagerCacheAndroid(): Boolean {
118128
var cached = disableTextLayoutManagerCacheAndroidCache
119129
if (cached == null) {

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<b9aa0387de9705e781bac7e522461224>>
7+
* @generated SignedSource<<cfa7407ac0b1fe6cfb92dbc22449bae2>>
88
*/
99

1010
/**
@@ -36,6 +36,8 @@ public object ReactNativeFeatureFlagsCxxInterop {
3636

3737
@DoNotStrip @JvmStatic public external fun disableMountItemReorderingAndroid(): Boolean
3838

39+
@DoNotStrip @JvmStatic public external fun disableOldAndroidAttachmentMetricsWorkarounds(): Boolean
40+
3941
@DoNotStrip @JvmStatic public external fun disableTextLayoutManagerCacheAndroid(): Boolean
4042

4143
@DoNotStrip @JvmStatic public external fun enableAccessibilityOrder(): Boolean

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<fdcaa94192d003c28fa3a1d538fc859c>>
7+
* @generated SignedSource<<21fdb20c1fca274a6096de088bdd85ff>>
88
*/
99

1010
/**
@@ -31,6 +31,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi
3131

3232
override fun disableMountItemReorderingAndroid(): Boolean = false
3333

34+
override fun disableOldAndroidAttachmentMetricsWorkarounds(): Boolean = true
35+
3436
override fun disableTextLayoutManagerCacheAndroid(): Boolean = false
3537

3638
override fun enableAccessibilityOrder(): Boolean = false

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<d645897d5c2e27e7de611605686d8413>>
7+
* @generated SignedSource<<09d954a90ac197146c441b71a7352c24>>
88
*/
99

1010
/**
@@ -28,6 +28,7 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
2828
private var cxxNativeAnimatedEnabledCache: Boolean? = null
2929
private var cxxNativeAnimatedRemoveJsSyncCache: Boolean? = null
3030
private var disableMountItemReorderingAndroidCache: Boolean? = null
31+
private var disableOldAndroidAttachmentMetricsWorkaroundsCache: Boolean? = null
3132
private var disableTextLayoutManagerCacheAndroidCache: Boolean? = null
3233
private var enableAccessibilityOrderCache: Boolean? = null
3334
private var enableAccumulatedUpdatesInRawPropsAndroidCache: Boolean? = null
@@ -122,6 +123,16 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
122123
return cached
123124
}
124125

126+
override fun disableOldAndroidAttachmentMetricsWorkarounds(): Boolean {
127+
var cached = disableOldAndroidAttachmentMetricsWorkaroundsCache
128+
if (cached == null) {
129+
cached = currentProvider.disableOldAndroidAttachmentMetricsWorkarounds()
130+
accessedFeatureFlags.add("disableOldAndroidAttachmentMetricsWorkarounds")
131+
disableOldAndroidAttachmentMetricsWorkaroundsCache = cached
132+
}
133+
return cached
134+
}
135+
125136
override fun disableTextLayoutManagerCacheAndroid(): Boolean {
126137
var cached = disableTextLayoutManagerCacheAndroidCache
127138
if (cached == null) {

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<8168412a7d792853fa19e10a621012c4>>
7+
* @generated SignedSource<<50a3f126540e1b2afd4a4ce85a4d1ac3>>
88
*/
99

1010
/**
@@ -31,6 +31,8 @@ public interface ReactNativeFeatureFlagsProvider {
3131

3232
@DoNotStrip public fun disableMountItemReorderingAndroid(): Boolean
3333

34+
@DoNotStrip public fun disableOldAndroidAttachmentMetricsWorkarounds(): Boolean
35+
3436
@DoNotStrip public fun disableTextLayoutManagerCacheAndroid(): Boolean
3537

3638
@DoNotStrip public fun enableAccessibilityOrder(): Boolean

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManager.kt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1102,7 +1102,8 @@ internal object TextLayoutManager {
11021102
// There's a bug on Samsung devices where calling getPrimaryHorizontal on
11031103
// the last offset in the layout will result in an endless loop. Work around
11041104
// this bug by avoiding getPrimaryHorizontal in that case.
1105-
if (start == text.length - 1) {
1105+
if (!ReactNativeFeatureFlags.disableOldAndroidAttachmentMetricsWorkarounds() &&
1106+
start == text.length - 1) {
11061107
val endsWithNewLine = text.length > 0 && text[layout.getLineEnd(line) - 1] == '\n'
11071108
val lineWidth = if (endsWithNewLine) layout.getLineMax(line) else layout.getLineWidth(line)
11081109
placeholderLeftPosition =
@@ -1127,7 +1128,9 @@ internal object TextLayoutManager {
11271128
placeholderLeftPosition =
11281129
if (characterAndParagraphDirectionMatch) layout.getPrimaryHorizontal(start)
11291130
else layout.getSecondaryHorizontal(start)
1130-
if (isRtlParagraph && !isRtlChar) {
1131+
if (!ReactNativeFeatureFlags.disableOldAndroidAttachmentMetricsWorkarounds() &&
1132+
isRtlParagraph &&
1133+
!isRtlChar) {
11311134
// Adjust `placeholderLeftPosition` to work around an Android bug.
11321135
// The bug is when the paragraph is RTL and `setSingleLine(true)`, some layout
11331136
// methods such as `getPrimaryHorizontal`, `getSecondaryHorizontal`, and

packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<2a33de4ea9c5d0c332845046053a9598>>
7+
* @generated SignedSource<<d106cd4237f65206b31428ec09344536>>
88
*/
99

1010
/**
@@ -63,6 +63,12 @@ class ReactNativeFeatureFlagsJavaProvider
6363
return method(javaProvider_);
6464
}
6565

66+
bool disableOldAndroidAttachmentMetricsWorkarounds() override {
67+
static const auto method =
68+
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("disableOldAndroidAttachmentMetricsWorkarounds");
69+
return method(javaProvider_);
70+
}
71+
6672
bool disableTextLayoutManagerCacheAndroid() override {
6773
static const auto method =
6874
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("disableTextLayoutManagerCacheAndroid");
@@ -405,6 +411,11 @@ bool JReactNativeFeatureFlagsCxxInterop::disableMountItemReorderingAndroid(
405411
return ReactNativeFeatureFlags::disableMountItemReorderingAndroid();
406412
}
407413

414+
bool JReactNativeFeatureFlagsCxxInterop::disableOldAndroidAttachmentMetricsWorkarounds(
415+
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
416+
return ReactNativeFeatureFlags::disableOldAndroidAttachmentMetricsWorkarounds();
417+
}
418+
408419
bool JReactNativeFeatureFlagsCxxInterop::disableTextLayoutManagerCacheAndroid(
409420
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
410421
return ReactNativeFeatureFlags::disableTextLayoutManagerCacheAndroid();
@@ -713,6 +724,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() {
713724
makeNativeMethod(
714725
"disableMountItemReorderingAndroid",
715726
JReactNativeFeatureFlagsCxxInterop::disableMountItemReorderingAndroid),
727+
makeNativeMethod(
728+
"disableOldAndroidAttachmentMetricsWorkarounds",
729+
JReactNativeFeatureFlagsCxxInterop::disableOldAndroidAttachmentMetricsWorkarounds),
716730
makeNativeMethod(
717731
"disableTextLayoutManagerCacheAndroid",
718732
JReactNativeFeatureFlagsCxxInterop::disableTextLayoutManagerCacheAndroid),

packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<509e0e4d8b2568e2b682797cfb83c79a>>
7+
* @generated SignedSource<<42e5e857fdfb9ad780ccc3f942638891>>
88
*/
99

1010
/**
@@ -42,6 +42,9 @@ class JReactNativeFeatureFlagsCxxInterop
4242
static bool disableMountItemReorderingAndroid(
4343
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
4444

45+
static bool disableOldAndroidAttachmentMetricsWorkarounds(
46+
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
47+
4548
static bool disableTextLayoutManagerCacheAndroid(
4649
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
4750

packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<6288be2bb9b5d8fcb318ae01ab3854c3>>
7+
* @generated SignedSource<<0ebe67635de9568917a9ed02d92a88e2>>
88
*/
99

1010
/**
@@ -42,6 +42,10 @@ bool ReactNativeFeatureFlags::disableMountItemReorderingAndroid() {
4242
return getAccessor().disableMountItemReorderingAndroid();
4343
}
4444

45+
bool ReactNativeFeatureFlags::disableOldAndroidAttachmentMetricsWorkarounds() {
46+
return getAccessor().disableOldAndroidAttachmentMetricsWorkarounds();
47+
}
48+
4549
bool ReactNativeFeatureFlags::disableTextLayoutManagerCacheAndroid() {
4650
return getAccessor().disableTextLayoutManagerCacheAndroid();
4751
}

0 commit comments

Comments
 (0)