Skip to content

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

Closed

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.

Activity

  1. pinned this issue on Jan 24, 2023
  2. jefflewis commented on Jan 24, 2023

    @jefflewis

    One solution we've tried that doesn't involve changing the field type to get rid of suggestive text and avoid the entire problem class is a horrible hacky solution that can work... We made a web view and post a message from the onchange listener to the react view. Maybe that helps find a workaround?

    So a native app, with the react runtime, running a webview with a textinput whose sole purpose is to provide state back to the react view. 😅
    CleanShot 2023-01-23 at 16 36 30@2x

  3. econner commented on Jan 24, 2023

    @econner

    Hi, this issue also affects Pixel phones based on our logs of ANRs as well as many comments in the other thread. Are you also notifying Google? Or is there another potential issue w/ Pixel phones?

    See:
    #35155 (comment)
    #35155 (comment)
    https://support.google.com/pixelphone/thread/181332682/keyboard-freezing-after-android-13-update?hl=en

    Thanks.

  4. nandinicbit1981 commented on Jan 24, 2023

    @nandinicbit1981
  5. NickGerleman commented on Jan 24, 2023

    @NickGerleman
    ContributorAuthor

    Hi, this issue also affects Pixel phones based on our logs of ANRs as well as many comments in the other thread. Are you also notifying Google? Or is there another potential issue w/ Pixel phones?

    See: #35155 (comment) #35155 (comment) https://support.google.com/pixelphone/thread/181332682/keyboard-freezing-after-android-13-update?hl=en

    Thanks.

    Would you mind creating a separate issue for this? It's hard to tell if the issue is related, but using GBoard on Samsung devices does not repro this specific issue we are tracking.

  6. nandinicbit1981 commented on Jan 24, 2023

    @nandinicbit1981
  7. smali-kazmi commented on Jan 25, 2023

    @smali-kazmi
  8. smali-kazmi commented on Jan 25, 2023

    @smali-kazmi
  9. efstathiosntonas commented on Jan 25, 2023

    @efstathiosntonas
  10. migueldaipre commented on Jan 25, 2023

    @migueldaipre
  11. 367 remaining items

  12. kelset commented on Apr 19, 2023

    @kelset
    Contributor

    Hey everyone - a quick update on this: we've just released:

    Both contain @NickGerleman's multi-commit fix to address this problem - early signs in 0.72 RC1 suggested that they indeed address the problem, so we hope that by upgrading to these new versions you'll see improvements! Upgrade to those and let us know!

    We are planning to also backport these fixes back to 68 and 69 - but the harsh reality is that the further back we go in the codebase, the more complicated this process of backporting gets (I literally attempted to bring back these fixes to 69 three separate times without much success 😭). We'll keep working on this and make it land in those older versions, but it will probably take a bit longer.

  13. mhammerc commented on Apr 20, 2023

    @mhammerc

    Hello!

    So far so good, early signs show that react-native 0.70.9 partially fixed the bug for us.

    We found some of our users still have hangs (ANR?) while writing in TextInput: Android 13 and Google Pixel 6a.

    After some more updates, we found that this issue keybase/client#25396 fix more TextInput hangs. (with this patch: https://phab.comm.dev/D6193)

    We had a FlatList inverted, and it was enough to cause problems with Android 13 and TextInputs on the same screen. At least, this patch fixed hangs to some of our users, but 0.70.9 didn't.

    For now, react-native 0.70.9 and the above patch fix all our problems, but we are waiting for more feedbacks from our users.

    Thank you very much for all your work to all the team!

    EDIT: The reply below referenced this is a known issue: #35983 (comment)

    For anyone that didn't knew that issue, it was night and day on our app. Worth a try.

  14. AbdulBsit commented on Apr 20, 2023

    @AbdulBsit

    @mhammerc Your issue is related to the different issue, in which user's facing hang with inverted list, I solved it with this #35983 (comment)

  15. brunoducattii commented on Apr 20, 2023

    @brunoducattii

    iOS TextInput S.O.S: #36872

  16. kelset commented on Apr 25, 2023

    @kelset
    Contributor

    Hey everyone - a quick update on this: the 0.69.10 release is out, bringing the fixes back to the last minor in the release window: https://github.com/facebook/react-native/releases/tag/v0.69.10

    We're also backporting it to 68, will start working on that asap.

  17. kelset commented on Apr 26, 2023

    @kelset
    Contributor

    Hey everyone - as promised, we've backported the fixes to 0.68 too: https://github.com/facebook/react-native/releases/tag/v0.68.7

    Please bear in mind that this 0.68 patch release was done as an exceptional measure to help address this very impactful problem. We do not expect to do more patches for this minor, as it is out of the release support window. Please upgrade to newer versions asap.


    Given the general silence since this new round of patches, we are assuming that it means that the problem is indeed addressed - massive props to @NickGerleman for his work in working on this!

    We'll leave the issue open a few more days to see how things evolve just in case, after which we'll close.

  18. tarouboy commented on May 1, 2023

    @tarouboy

    After upgrading to 0.71.7 started to get the content oversize error.
    93% from Android 13 devices, seems it happened when large amount of text being entered, put the app to background, and crash when coming back from background.

    Caused by android.os.TransactionTooLargeException
    data parcel size 1031804 bytes
    android.os.BinderProxy.transactNative (BinderProxy.java)
    android.os.BinderProxy.transact (BinderProxy.java:643)
    android.app.IActivityClientController$Stub$Proxy.activityStopped (IActivityClientController.java:1248)
    android.app.ActivityClient.activityStopped (ActivityClient.java:85)
    android.app.servertransaction.PendingTransactionActions$StopInfo.run (PendingTransactionActions.java:143)
    android.os.Handler.handleCallback (Handler.java:942)
    android.os.Handler.dispatchMessage (Handler.java:99)
    android.os.Looper.loopOnce (Looper.java:210)
    android.os.Looper.loop (Looper.java:299)
    android.app.ActivityThread.main (ActivityThread.java:8116)
    java.lang.reflect.Method.invoke (Method.java)
    com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:559)
    com.android.internal.os.ZygoteInit.main (ZygoteInit.java:950)
    
  19. kelset commented on May 3, 2023

    @kelset
    Contributor

    @tarouboy

    when large amount of text being entered, put the app to background, and crash when coming back from background.

    since this seems to be a separate behaviour/problem, can I ask you to open a new issue with this report (plus a repro) so that we can track it separately? this issue already has 90+ comments and GH starts to struggle after a certain point 😅

  20. kelset commented on May 9, 2023

    @kelset
    Contributor

    I'm going to close this as no new reports specific about the TextInput issue combo that we wanted to address (TextInput, Grammarly, Samsung) have been produced - so we can consider it addressed. If you can create a new repro that does not involve an inverted FlatList (since that's an existing problem we are aware of, and has been reported many times), please open a new issue.

  21. Saad-Bashar commented on May 12, 2023

    @Saad-Bashar

    Sorry for the ping, Can someone please confirm this solution also works well with the controlled inputs in react native? and we can use the value prop? Previously we changed our controlled inputs to uncontrolled inputs because of the issue. Thanks a lot!

  22. danieltaub commented on Oct 1, 2023

    @danieltaub

    We are using RN 0.71.8 together with expo 48.0 and the issue is still happens to all of our Samsung users for some reason, any ideas?

  23. chengweibo commented on Jan 8, 2024

    @chengweibo

    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.

    Sumsung Galaxy A71 , Sumsung Galaxy A32, Sumsung Galaxy A53 phone the following crash occurs , hope to give me solution,thanks
    Fatal Exception: java.lang.IndexOutOfBoundsException: offset(1) should be less than line limit(0)
    at android.text.TextLine.measure(TextLine.java:389)
    at android.text.Layout.getHorizontal(Layout.java:1254)
    at android.text.Layout.getHorizontal(Layout.java:1230)
    at android.text.Layout.getPrimaryHorizontal(Layout.java:1200)
    at android.widget.TextView.bringPointIntoView(TextView.java:11046)
    at android.widget.TextView.updateAfterEdit(TextView.java:11983)
    at android.widget.Editor.finishBatchEdit(Editor.java:2086)
    at android.widget.Editor.endBatchEdit(Editor.java:2068)
    at android.widget.TextView.endBatchEdit(TextView.java:9931)
    at android.widget.TextView.doKeyDown(TextView.java:9505)
    at android.widget.TextView.onKeyDown(TextView.java:9275)
    at android.view.KeyEvent.dispatch(KeyEvent.java:3508)
    at android.view.View.dispatchKeyEvent(View.java:15395)
    at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1978)
    at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1978)
    at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1978)
    at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1978)
    at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1978)
    at android.widget.ScrollView.dispatchKeyEvent(ScrollView.java:738)
    at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1978)
    at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1978)
    at com.facebook.react.ReactRootView.dispatchKeyEvent(ReactRootView.java:234)
    at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1978)
    at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1978)
    at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1978)
    at com.android.internal.policy.DecorView.superDispatchKeyEvent(DecorView.java:1100)
    at com.android.internal.policy.PhoneWindow.superDispatchKeyEvent(PhoneWindow.java:1961)
    at android.app.Activity.dispatchKeyEvent(Activity.java:4342)
    at androidx.core.app.ComponentActivity.superDispatchKeyEvent(ComponentActivity.java:122)
    at androidx.core.view.KeyEventDispatcher.dispatchKeyEvent(KeyEventDispatcher.java:84)
    at androidx.core.app.ComponentActivity.dispatchKeyEvent(ComponentActivity.java:140)
    at com.android.internal.policy.DecorView.dispatchKeyEvent(DecorView.java:924)
    at android.view.ViewRootImpl$ViewPostImeInputStage.processKeyEvent(ViewRootImpl.java:8056)
    at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:7864)
    at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:7213)
    at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:7270)
    at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:7236)
    at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:7434)
    at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:7244)
    at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:7491)
    at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:7217)
    at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:7270)
    at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:7236)
    at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:7244)
    at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:7217)
    at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:10788)
    at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:10676)
    at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:10632)
    at android.view.ViewRootImpl$ViewRootHandler.handleMessageImpl(ViewRootImpl.java:6822)
    at android.view.ViewRootImpl$ViewRootHandler.handleMessage(ViewRootImpl.java:6697)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loopOnce(Looper.java:226)
    at android.os.Looper.loop(Looper.java:313)
    at android.app.ActivityThread.main(ActivityThread.java:8757)
    at java.lang.reflect.Method.invoke(Method.java)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:571)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1067)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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