Skip to content

Commit 616fca2

Browse files
NickGerlemanRiccardo Cipolleschi
authored andcommitted
Mitigation for Samsung TextInput Hangs (#35967)
Summary: Pull Request resolved: #35967 In #35936 we observed that the presence of AbsoluteSizeSpan may lead to hangs when using the Grammarly keyboard on Samsung. This mitigation makes it so that we do not emit this span in any case where it is sufficient to rely on already set EditText textSize. In simple cases, tested on two devices, it causes typing into the TextInput to no longer hang. This does not fully resolve the issue for TextInputs which meaningfully use layout-effecting spans (or at least font size), such as non-uniform text size within the input. We instead just try to reduce to minimum AbsoluteSizeSpan possible. Testing the first commit was able to resolve hangs in some simpler inputs tested, by me and cortinico. Changelog: [Android][Fixed] - Mitigation for Samsung TextInput Hangs Reviewed By: cortinico Differential Revision: D42721684 fbshipit-source-id: e0388dfb4617f0217bc1d0b71752c733e10261dd
1 parent 279fb52 commit 616fca2

File tree

1 file changed

+25
-0
lines changed

1 file changed

+25
-0
lines changed

ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,10 @@ public void maybeSetText(ReactTextUpdate reactTextUpdate) {
555555
new SpannableStringBuilder(reactTextUpdate.getText());
556556

557557
manageSpans(spannableStringBuilder, reactTextUpdate.mContainsMultipleFragments);
558+
559+
// Mitigation for https://github.com/facebook/react-native/issues/35936 (S318090)
560+
stripAbsoluteSizeSpans(spannableStringBuilder);
561+
558562
mContainsImages = reactTextUpdate.containsImages();
559563

560564
// When we update text, we trigger onChangeText code that will
@@ -628,6 +632,27 @@ private void manageSpans(
628632
}
629633
}
630634

635+
private void stripAbsoluteSizeSpans(SpannableStringBuilder sb) {
636+
// We have already set a font size on the EditText itself. We can safely remove sizing spans
637+
// which are the same as the set font size, and not otherwise overlapped.
638+
final int effectiveFontSize = mTextAttributes.getEffectiveFontSize();
639+
ReactAbsoluteSizeSpan[] spans = sb.getSpans(0, sb.length(), ReactAbsoluteSizeSpan.class);
640+
641+
outerLoop:
642+
for (ReactAbsoluteSizeSpan span : spans) {
643+
ReactAbsoluteSizeSpan[] overlappingSpans =
644+
sb.getSpans(sb.getSpanStart(span), sb.getSpanEnd(span), ReactAbsoluteSizeSpan.class);
645+
646+
for (ReactAbsoluteSizeSpan overlappingSpan : overlappingSpans) {
647+
if (span.getSize() != effectiveFontSize) {
648+
continue outerLoop;
649+
}
650+
}
651+
652+
sb.removeSpan(span);
653+
}
654+
}
655+
631656
private static boolean sameTextForSpan(
632657
final Editable oldText,
633658
final SpannableStringBuilder newText,

0 commit comments

Comments
 (0)