Skip to content
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

Replaces bundle usage in the editor with a local database #19747

Merged
merged 11 commits into from
Dec 8, 2023

Conversation

antonis
Copy link
Contributor

@antonis antonis commented Dec 6, 2023

Partially #9685 and #19157

Description

This PR tries to mitigate the TransactionTooLargeException error in the editor by replacing Bundle for Parcelable objects with a custom database implementation.


To Test:

  • Make a sanity check in the editor
  • Verify that the information is stored and retrieved correctly from the database on configuration change
    1. Open the editor
    2. Make add some changes
    3. Put the app in the background and reopen
    4. Change the device orientation
    5. Verify that the app behaves as expected
  • Verify that the revision is retrieved correctly from history
    1. Open the editor
    2. Make add some changes and save
    3. Make some more changes and save
    4. Open the option menu and select History
    5. Select the desired revision
    6. Tap Load on the code editor
    7. Verify that the correct revision is loaded

Regression Notes

  1. Potential unintended areas of impact

    Editor

  2. What I did to test those areas of impact (or what existing automated tests I relied on)

    Manual testing

  3. What automated tests I added (or what prevented me from doing so)

    Added tests for the added local db


PR Submission Checklist:

  • I have completed the Regression Notes.
  • I have considered adding accessibility improvements for my changes.
  • I have considered if this change warrants user-facing release notes and have added them to RELEASE-NOTES.txt if necessary.

UI Changes Testing Checklist:

  • Portrait and landscape orientations.
  • Light and dark modes.
  • Fonts: Larger, smaller and bold text.
  • High contrast.
  • Talkback.
  • Languages with large words or with letters/accents not frequently used in English.
  • Right-to-left languages. (Even if translation isn’t complete, formatting should still respect the right-to-left layout)
  • Large and small screen sizes. (Tablet and smaller phones)
  • Multi-tasking: Split screen and Pop-up view. (Android 10 or higher)

@antonis antonis added [Type] Crash Gutenberg Editing and display of Gutenberg blocks. Do Not Merge In PRs with this label, our automation will fail a require check, preventing accidental merging labels Dec 6, 2023
@antonis antonis added this to the 23.9 milestone Dec 6, 2023
@antonis antonis requested a review from justtwago December 6, 2023 16:37
@wpmobilebot
Copy link
Contributor

wpmobilebot commented Dec 6, 2023

Jetpack📲 You can test the changes from this Pull Request in Jetpack by scanning the QR code below to install the corresponding build.
App NameJetpack Jetpack
FlavorJalapeno
Build TypeDebug
Versionpr19747-4e38515
Commit4e38515
Direct Downloadjetpack-prototype-build-pr19747-4e38515.apk
Note: Google Login is not supported on these builds.

@wpmobilebot
Copy link
Contributor

wpmobilebot commented Dec 6, 2023

WordPress📲 You can test the changes from this Pull Request in WordPress by scanning the QR code below to install the corresponding build.
App NameWordPress WordPress
FlavorJalapeno
Build TypeDebug
Versionpr19747-4e38515
Commit4e38515
Direct Downloadwordpress-prototype-build-pr19747-4e38515.apk
Note: Google Login is not supported on these builds.

@justtwago
Copy link
Contributor

Thank you for putting the Revision object to SavedInstanceDatabase is a very good direction! Unfortunately, I could reproduce the crash following the steps I described here: #9685 (comment)
I'm digging into this to figure out why it works it crashes when a text is just input but not for a saved draft.

@antonis
Copy link
Contributor Author

antonis commented Dec 7, 2023

Thank you for putting the Revision object to SavedInstanceDatabase is a very good direction! Unfortunately, I could reproduce the crash following the steps I described here: #9685 (comment)

Thank you for testing and your feedback @justtwago 🙇
Apart from the STATE_KEY_REVISION and the ARG_GUTENBERG_PROPS_BUILDER that I removed the largest part of the Bundle is the viewState (with a size 1202116 in your log). This is system data though and not extra payload we add on the application level. My understanding is that anything we add in the editor is translated to Android views due to the way React Native works. Thus a really large text results in a huge Bundle. I'm not sure there is a workaround on the app level for this 😞

I also experimented with removing views from the Bundle. Since you are able to reproduce this consistently could you give the patch below a try? 🙇

diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.java b/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.java
index 0ac9235b2b..270512d43e 100644
--- a/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.java
+++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostActivity.java
@@ -1158,6 +1158,8 @@ public class EditPostActivity extends LocaleAwareActivity implements
 
     @Override
     protected void onSaveInstanceState(Bundle outState) {
+        outState.remove("android:viewHierarchyState");
+        outState.remove("androidx.lifecycle.BundlableSavedStateRegistry.key");
         super.onSaveInstanceState(outState);
         // Saves both post objects so we can restore them in onCreate()
         updateAndSavePostAsync();

@antonis antonis removed Do Not Merge In PRs with this label, our automation will fail a require check, preventing accidental merging unit-tests-exemption labels Dec 7, 2023
@justtwago
Copy link
Contributor

Apart from the STATE_KEY_REVISION and the ARG_GUTENBERG_PROPS_BUILDER that I removed the largest part of the Bundle is the viewState (with a size 1202116 in your log). This is system data though and not extra payload we add on the application level. My understanding is that anything we add in the editor is translated to Android views due to the way React Native works. Thus a really large text results in a huge Bundle. I'm not sure there is a workaround on the app level for this 😞

Yeah, totally makes sense. I think that it's too extreme case that even crashes the app when I'm trying to put everything to a clipboard. 😄 I think that we can proceed with putting a revision to a local DB and monitoring the results on Sentry.

I also experimented with removing views from the Bundle. Since you are able to reproduce this consistently could you give the patch below a try? 🙇

Thank you for the idea! I tried it out, and it looks like the app doesn't crash 😄 Anyway, I'm not sure that it's something that we want to have in the app since when the app destroys the activity in the background we can't retrieve the views when are back to the app so it causes a crash (it happens for me once but I couldn't for this and reproduce it later to catch a stack trace.)

@justtwago
Copy link
Contributor

One more question is about putting/extracting a revision to/from DB:
Should we also handle the case I put below from onActivityResult method?

case RequestCodes.HISTORY_DETAIL:
                    if (data.hasExtra(KEY_REVISION)) {
                        mViewPager.setCurrentItem(PAGE_CONTENT);

                        mRevision = data.getParcelableExtra(KEY_REVISION);
                        new Handler().postDelayed(this::loadRevision,
                                getResources().getInteger(R.integer.full_screen_dialog_animation_duration));
                    }
                    break;

GitHub doesn't allow me to comment this block of code 😄

@antonis
Copy link
Contributor Author

antonis commented Dec 8, 2023

One more question is about putting/extracting a revision to/from DB:
Should we also handle the case I put below from onActivityResult method?

Great suggestion @justtwago 👍 I added the rest of the revision instances in the db with 3b61f82

@antonis
Copy link
Contributor Author

antonis commented Dec 8, 2023

I think that we can proceed with putting a revision to a local DB and monitoring the results on Sentry.

This makes sense to me too @justtwago 👍
I've investigated a bit more today for alternatives to handle the large view hierarchy but all solutions I tried are too hacky (example 4e38515) and I think they will affect the stability of the editor.

I prepared this PR for review to at least cover the data we add to the Bundle.

@antonis antonis marked this pull request as ready for review December 8, 2023 12:15
@antonis antonis requested a review from a team as a code owner December 8, 2023 12:15
@peril-wordpress-mobile
Copy link

peril-wordpress-mobile bot commented Dec 8, 2023

Warnings
⚠️ This PR is assigned to a milestone which is closing in less than 4 days Please, make sure to get it merged by then or assign it to a later expiring milestone
⚠️ PR has more than 300 lines of code changing. Consider splitting into smaller PRs if possible.

Generated by 🚫 dangerJS

@antonis antonis changed the title Replaces bundle usage in the editor with database Replaces bundle usage in the editor with a local database Dec 8, 2023
@wpmobilebot
Copy link
Contributor

2 Warnings
⚠️ This PR is larger than 300 lines of changes. Please consider splitting it into smaller PRs for easier and faster reviews.
⚠️ This PR is assigned to the milestone 23.9. This milestone is due in less than 4 days.
Please make sure to get it merged by then or assign it to a milestone with a later deadline.

Generated by 🚫 Danger

Copy link
Contributor

@justtwago justtwago left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Antonis, thank you for the amazing work on the fix!
I smoke-tested the editor and also used the Don't keep activities flag, and the DB seems to work perfectly. Fingers crossed for seeing some progress in Sentry after releasing it.

I left some minor comments for cosmetics stuff, but I'd merge it today to include the fix in the nearest release.

In addition, we could consider extracting the persistence logic to a separate gradle module in the future.

@justtwago justtwago merged commit 3d55ca2 into trunk Dec 8, 2023
2 checks passed
@justtwago justtwago deleted the fix/19157-TransactionTooLargeException branch December 8, 2023 18:11
@antonis
Copy link
Contributor Author

antonis commented Dec 8, 2023

Thank you for testing extensively and your feedback @justtwago 🙇
I opened a small PR handling the two minor suggestions #19761

In addition, we could consider extracting the persistence logic to a separate gradle module in the future.

That indeed a good idea. I was on the edge of adding this but thought that it would extend the scope of the change and preferred to use the editor for this. I think it makes sense to add it in a separate module or even a small independent reusable library 🗒️

@justtwago
Copy link
Contributor

That indeed a good idea. I was on the edge of adding this but thought that it would extend the scope of the change and preferred to use the editor for this. I think it makes sense to add it in a separate module or even a small independent reusable library 🗒️

Yeah, totally agree that it's out of this PR's scope. 💯

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Gutenberg Editing and display of Gutenberg blocks. [Type] Crash
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants