-
Notifications
You must be signed in to change notification settings - Fork 116
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix DynamicLayout Crash - Round 2 #813
Conversation
text.insert(dend, temp) | ||
temp = "" // discard the original source parameter as an ouput from this InputFilter | ||
// use HTML from the new text to set the state of the editText directly | ||
fromHtml(toFormattedHtml(newText), false) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just thinking aloud here - we discussed this of course but I'm not sure about doing such a radical thing for everyone with Android 8.x just as you already rightfully commented on the PR description:
Also, in that PR, strict criteria must be met before the fix is applied. One such criterion is that the selection must be a caret (i.e. no selection). This means certain edge cases will still encounter the crash.
We may want to narrow down the cases so this doesn't introduce a regression for other users who maybe weren't experiencing the problem so, thinking in that direction it seems to me it'd be nice if we kept the "case detection logic" (such as the big if
clause that was up there) and add / remove more constraints as we see fit. I'm not really convinced on one way or the other, so please take this comment just as to keep the conversation going and see what we can get from it rather than an indication / suggestion of "what seems right" in code 👍
OTOH it may be the only way to cover "all" the possibilities where the issue may appear. I believe we're still spot on in that Images are the ones internally using DynamicLayout
so it seems right to do the search for it (as in, the broader case).
I'll do some more smoke tests, another thing that comes to mind is maybe we also need to try and keep the caret position as well? Though we may want to address that as a separate PR if it starts to get convoluted
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and add / remove more constraints as we see fit
I totally agree with this. So far, these are the conditions that must be met:
- Android API version must be either 26 or 27.
- The crash preventer must not already be "in progress" (i.e. no recursion).
- At least one character must follow the selection / caret.
- The character immediately following the selection / caret must have at least one
AztecImageSpan
(i.e. it is an image).
Conditions 2 and 3 are set in the outer-most conditional of the filter. Condition 4 requires querying of the Spannable
, and thus lives inside that outer conditional. If there is a way to determine whether we are on a version of Oreo which has been patched, we could narrow condition 1 further, but I'm not sure this is currently possible.
If you have other conditions that come to mind, we can add them. Note: I intentionally left out the condition regarding the new line character because this approach was different enough, I thought it best to test the behavior separately. Do you know if the current state reproduces (regresses) the issue that condition was added for?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
another thing that comes to mind is maybe we also need to try and keep the caret position as well? Though we may want to address that as a separate PR if it starts to get convoluted
I noticed this on develop
as well, so I think a separate PR would be better, with an issue to track it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: I intentionally left out the condition regarding the new line character because this approach was different enough, I thought it best to test the behavior separately. Do you know if the current state reproduces (regresses) the issue that condition was added for?
I think you're right - just tested that the conditions this PR here #809 was fixing are not met with this PR anymore and wasn't able to reproduce the crash so, I think we're good 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've been testing this on WPAndroid with the following PRs: With the content in this report I've tried with other long posts and can see the lag Aztec already had before so, not a pointer that this solution in particular may be problematic (or should I say, be more problematic than it was before). I think we should test a bit more but, generally, looks good as to try it! Let's fix the lint issues and we can try ship a new version of Aztec at next cycle, sounds good @mkevins ? |
We had @daniloercoli's eyes on this one as well and approved merging so, merging |
Tested and worked as expected. Also tried tests on this PR 🎉 |
Fix
This PR is an attempt to address the issue described here: wordpress-mobile/WordPress-Android#8828. This issue is related to #516 and #729 which were addressed with PR #801. This is a workaround to attempt to avoid encountering the underlying Android OS bug described here and patched here.
This workaround utilizes an
InputFilter
as in #801. The code in that PR covers many scenarios that lead to a crash, however, there are still some that cannot be addressed with that approach. One limitation of the InputFilter approach is that we may only modify the text being inserted during a change, but cannot modify the text being removed. Also, in that PR, strict criteria must be met before the fix is applied. One such criterion is that the selection must be a caret (i.e. no selection). This means certain edge cases will still encounter the crash.One odd note is that if we set up the Demo App content with text, followed by two images, and then some more text, we can trigger the crash by deleting the text preceding the image only after we have edited that text at least once. Also, even after having edited that text, if we used the
undo
andredo
buttons to attain the same state, we could then delete the text without a crash.Somehow, setting the content in full (as occurs when the app first loads) will put the app into a "safe" state. I also noticed that when the first change happens above the images, the images move vertically by a very small amount.
In order to make use of this in a new workaround, we can set the text within the
InputFilter
. This is accomplished by utilizing thefromHtml
method, passing in the output fromtoFormattedHtml
. In order to do so with the new state of the content, we must overload thetoFormattedHtml
method to accept aSpannable
, whereas the default behavior is to generate the html from the unedited content (which would merely revert our changes, disallowing modification by the user).The nature of this PR is to expand the number of cases it addresses by relaxing the criteria for which it is applied. This also means that any side effects that such a workaround may introduce have the potential to affect more users. Since an unrecoverable crash is a fairly severe condition, it holds some weight, but, some consideration should also be given to the volume of users that are currently not experiencing this crash. It would be helpful if we could test these changes as thoroughly as possible so ensure we do not introduce any regressions.
Test
Follow steps here: wordpress-mobile/WordPress-Android#8828 (comment).
Also, here: #516 (comment).
And here: #729 (comment).
Any more tests in those threads would also be good candidates for testing this PR.
Review
@mzorz