Skip to content

Commit e5f9ec1

Browse files
NickGerlemanDmitry Rykun
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 b16a3be commit e5f9ec1

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
@@ -550,6 +550,10 @@ public void maybeSetText(ReactTextUpdate reactTextUpdate) {
550550
new SpannableStringBuilder(reactTextUpdate.getText());
551551

552552
manageSpans(spannableStringBuilder, reactTextUpdate.mContainsMultipleFragments);
553+
554+
// Mitigation for https://github.com/facebook/react-native/issues/35936 (S318090)
555+
stripAbsoluteSizeSpans(spannableStringBuilder);
556+
553557
mContainsImages = reactTextUpdate.containsImages();
554558

555559
// When we update text, we trigger onChangeText code that will
@@ -623,6 +627,27 @@ private void manageSpans(
623627
}
624628
}
625629

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

0 commit comments

Comments
 (0)