Skip to content

[Investigation] ANRs Using Multiline TextInput on Samsung Devices #35936

Closed
@NickGerleman

Description

@NickGerleman

NEW UPDATE: we have now released patch releases containing the second wave of fix for:


UPDATE: we have now released a patch release containing the first mitigation for all the supported versions of React Native plus 0.68 (since it's still used by a significant number of users):

Please upgrade to those versions and report back here if it helps! We are still planning to do further investigation, but don't expect any new releases concerning this topic for at least a couple weeks (unless something unexpected happens).


There have been repeated and persistent signals of ANRs (hangs) when typing into a multiline TextInput on Samsung phones. This is most reported by using the out-of-the-box keyboard provided by Samsung One UI 5. We have been able to locally reproduce the hangs on two separate Galaxy S22 devices. Most devices will not be as fast as the ones we have tested on.

Impact

The issue presents as repeated hangs or ANRs when typing into a TextInput which has a large amount of text. It is specific to the Samsung soft keyboard, and does not reproduce when using other keyboards like GBoard on the same device. There are a different set of TextInputs where we have confirmed impact depending on whether Fabric is enabled or disabled.

Fabric enabled

Both controlled and uncontrolled TextInputs are impacted.

Fabric disabled

Controlled TextInputs and uncontrolled TextInputs which set an initial value via child are impacted.

Root causing

Root causing the issue focused on:

  1. Locally profiling the hang under different scenarios
  2. Examining which span differences create the hang
  3. Reproducing the issue outside of React Native

Profiling

We saw similar results to the trace already shared in #35590. A Java sampling profiler shows the process com.samsung.android.honeyboard has a very long running frame, delivering input.

image

This triggers code on the main thread, in the app process, where we see a hang happen while committing a text change from the IME to the underlying Spannable backing the EditText. The hang happens in an event handler which has subscribed to changes to the underlying text. The long-running work seems to be laying out the text.

image

Because the hang happens in response to an edit to the underlying Spannable, investigation focused on the Spannable content differences in scenarios which created ANRs vs not.

Spannable differences between hang/no hang

We examined typing into the below example, which may hang on Fabric but not Paper:

<TextInput multiline={true} />

Grammarly annotations were present as SuggestionSpan spans on both platforms. On Fabric but not paper there was the presence of AbsoluteSizeSpan spans, which set the font size within the text. This is akin to setting <span style=”font-size: 12px”}>Text</span> within a browser.

When we stubbed out platform code in React Native which set an AbsoluteSizeSpan, that example along with another previously hanging example would no longer hang. The hang was possible to trigger in an uncontrolled TextInput with a short string like “Text Here” as a child, so we attempted to repro the logical extreme, where we add a single span setting font size to the TextInput.

Reproducing outside of React Native

We discovered that adding even a single inclusive span (specifically setting font size) is enough to create hangs. This can reproduced by:

  1. Adding an EditText with an inputType of textMultiLine.
  2. Adding an inclusive span setting font size: E.g. str.setSpan(new AbsoluteSizeSpan(55), 0, string.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE)
  3. Pasting a large amount of text then starting to type.

We were able to create a repro for this on top of a template Android application. The issue only happens when using the Samsung keyboard.

reproducervideo.mp4

Grammarly annotations are not shown locally when changing the appId and namespace of the repro to com.facebook.katana (the ID of the Facebook app). This implies the Facebook app may be being special-cased, contributing to the lack of internal signal on the issue. This only happened on 1/2 devices, so it's possible there might be some setting or association that wasn't fresh.

Remediation

While the underlying issue seems to be outside of React Native, the issue still has a real-world effect on our users. We are starting the process to mitigate the issue by working to notify Samsung. This issue has already shown signs of impacting the Android app ecosystem outside of React Native and the ability to set spans with formatting like font size is a fundamentally important part of the platform.

We hope this issue will be addressed in a future update from Samsung, but this does not address the already-present impact of the issue. A potential mitigation which we are exploring is whether React Native could avoid adding AbsoluteSizeSpan (or formatting spans in general) in more common cases.

There have been previously discovered workarounds for the issue, such as setting keyboardType to visible-password. We recommend against preemptively using these workarounds, due to impact on UX and accessibility.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions