Skip to content

Commit

Permalink
Merge pull request #19747 from wordpress-mobile/fix/19157-Transaction…
Browse files Browse the repository at this point in the history
…TooLargeException

Replaces bundle usage in the editor with a local database
  • Loading branch information
Artyom Vlasov authored Dec 8, 2023
2 parents 30b131c + 4e38515 commit 3d55ca2
Show file tree
Hide file tree
Showing 11 changed files with 360 additions and 34 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package org.wordpress.android.editor.savedinstance

import android.os.Parcelable
import dagger.hilt.android.testing.HiltAndroidTest
import org.junit.Assert.assertArrayEquals
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Test

@HiltAndroidTest
class ParcelableObjectTest {
private lateinit var parcelable: Parcelable

@Before
fun setUp() {
parcelable = TestParcelable("testData")
}

@Test
fun testConstructorWithParcelable() {
val parcelableObject = ParcelableObject(parcelable)
val parcelData = parcelableObject.toBytes()
val objectFromParcel = ParcelableObject(parcelData)
assertArrayEquals(objectFromParcel.toBytes(), parcelData)
}

@Test
fun testConstructorWithByteArray() {
val parcelableObject = ParcelableObject(parcelable)
val data = parcelableObject.toBytes()
val parcelableResult = ParcelableObject(data)
assertArrayEquals(parcelableObject.toBytes(), parcelableResult.toBytes())
}

@Test
fun getParcelReturnsTheSameParcelObject() {
val parcelableObject = ParcelableObject(parcelable)
val initialParcel = parcelableObject.getParcel()
val nextParcel = parcelableObject.getParcel()
assertEquals(initialParcel, nextParcel)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package org.wordpress.android.editor.savedinstance

import android.content.Context
import dagger.hilt.android.testing.HiltAndroidRule
import dagger.hilt.android.testing.HiltAndroidTest
import kotlinx.parcelize.parcelableCreator
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import javax.inject.Inject

@HiltAndroidTest
class SavedInstanceDatabaseTest {
@get:Rule
val hiltRule = HiltAndroidRule(this)

@Inject
lateinit var context: Context

private lateinit var db: SavedInstanceDatabase

@Before
fun setUp() {
hiltRule.inject()
db = SavedInstanceDatabase.getDatabase(context)!!
db.reset(db.writableDatabase)
}

@Test
fun testStoreAndRetrieve() {
val parcelId = "testParcelId"
val parcelData = TestParcelable("testData")
db.addParcel(parcelId, parcelData)
val result = db.getParcel(parcelId, parcelableCreator<TestParcelable>())
assertEquals(parcelData, result)
}

@Test
fun testHasParcel() {
val parcelId = "testParcelId"
val parcelData = TestParcelable("testData")
db.addParcel(parcelId, parcelData)
val result = db.hasParcel(parcelId)
assertTrue(result)
}

@Test
fun testHasNoParcel() {
val parcelId1 = "testParcelId1"
val parcelId2 = "testParcelId2"
val parcelData = TestParcelable("testData")
db.addParcel(parcelId1, parcelData)
val result = db.hasParcel(parcelId2)
assertFalse(result)
}

@Test
fun testNullParcel() {
val parcelId = "testParcelId"
db.addParcel(parcelId, null)
val result = db.hasParcel(parcelId)
assertFalse(result)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.wordpress.android.editor.savedinstance

import android.os.Parcelable
import kotlinx.parcelize.Parcelize

@Parcelize
data class TestParcelable(val data: String) : Parcelable
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import org.wordpress.android.analytics.AnalyticsTracker.Stat;
import org.wordpress.android.databinding.HistoryDetailContainerFragmentBinding;
import org.wordpress.android.editor.EditorMediaUtils;
import org.wordpress.android.editor.savedinstance.SavedInstanceDatabase;
import org.wordpress.android.fluxc.model.revisions.RevisionModel;
import org.wordpress.android.fluxc.store.PostStore;
import org.wordpress.android.ui.history.HistoryListItem.Revision;
Expand Down Expand Up @@ -245,7 +246,10 @@ public void onPrepareOptionsMenu(@NonNull Menu menu) {
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
if (item.getItemId() == R.id.history_load) {
Intent intent = new Intent();
intent.putExtra(KEY_REVISION, mRevision);
SavedInstanceDatabase db = SavedInstanceDatabase.Companion.getDatabase(WordPress.getContext());
if (db != null) {
db.addParcel(KEY_REVISION, mRevision);
}

requireActivity().setResult(Activity.RESULT_OK, intent);
requireActivity().finish();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import kotlinx.parcelize.parcelableCreator
import org.wordpress.android.R
import org.wordpress.android.WordPress
import org.wordpress.android.editor.savedinstance.SavedInstanceDatabase.Companion.getDatabase
import org.wordpress.android.ui.history.HistoryListItem.Revision
import org.wordpress.android.util.extensions.getParcelableCompat
import org.wordpress.android.widgets.DiffView

class HistoryDetailFragment : Fragment() {
Expand All @@ -16,10 +18,10 @@ class HistoryDetailFragment : Fragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

mRevision = if (savedInstanceState != null) {
savedInstanceState.getParcelableCompat(KEY_REVISION)
mRevision = if (getDatabase(WordPress.getContext())?.hasParcel(KEY_REVISION) == true) {
getDatabase(WordPress.getContext())?.getParcel(KEY_REVISION, parcelableCreator<Revision>())
} else {
arguments?.getParcelableCompat(EXTRA_REVISION)
getDatabase(WordPress.getContext())?.getParcel(EXTRA_REVISION, parcelableCreator<Revision>())
}
}

Expand All @@ -32,19 +34,16 @@ class HistoryDetailFragment : Fragment() {

override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putParcelable(KEY_REVISION, mRevision)
getDatabase(WordPress.getContext())?.addParcel(KEY_REVISION, mRevision)
}

companion object {
const val EXTRA_REVISION = "EXTRA_REVISION"
const val KEY_REVISION = "KEY_REVISION"

fun newInstance(revision: Revision): HistoryDetailFragment {
val fragment = HistoryDetailFragment()
val bundle = Bundle()
bundle.putParcelable(EXTRA_REVISION, revision)
fragment.arguments = bundle
return fragment
getDatabase(WordPress.getContext())?.addParcel(EXTRA_REVISION, revision)
return HistoryDetailFragment()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
import org.wordpress.android.editor.EditorMediaUtils;
import org.wordpress.android.editor.EditorThemeUpdateListener;
import org.wordpress.android.editor.ExceptionLogger;
import org.wordpress.android.editor.savedinstance.SavedInstanceDatabase;
import org.wordpress.android.editor.gutenberg.DialogVisibility;
import org.wordpress.android.editor.gutenberg.GutenbergEditorFragment;
import org.wordpress.android.editor.gutenberg.GutenbergPropsBuilder;
Expand Down Expand Up @@ -710,7 +711,11 @@ public void handleOnBackPressed() {
mIsNewPost = savedInstanceState.getBoolean(STATE_KEY_IS_NEW_POST, false);
updatePostLoadingAndDialogState(PostLoadingState.fromInt(
savedInstanceState.getInt(STATE_KEY_POST_LOADING_STATE, 0)));
mRevision = savedInstanceState.getParcelable(STATE_KEY_REVISION);

if (getDB() != null) {
mRevision = getDB().getParcel(STATE_KEY_REVISION, Revision.CREATOR);
}

mPostEditorAnalyticsSession = PostEditorAnalyticsSession
.fromBundle(savedInstanceState, STATE_KEY_EDITOR_SESSION_DATA, mAnalyticsTrackerWrapper);

Expand Down Expand Up @@ -1166,7 +1171,10 @@ protected void onSaveInstanceState(Bundle outState) {
outState.putBoolean(STATE_KEY_UNDO, mMenuHasUndo);
outState.putBoolean(STATE_KEY_REDO, mMenuHasRedo);
outState.putSerializable(WordPress.SITE, mSite);
outState.putParcelable(STATE_KEY_REVISION, mRevision);

if (getDB() != null) {
getDB().addParcel(STATE_KEY_REVISION, mRevision);
}

outState.putSerializable(STATE_KEY_EDITOR_SESSION_DATA, mPostEditorAnalyticsSession);
mIsConfigChange = true; // don't call sessionData.end() in onDestroy() if this is an Android config change
Expand Down Expand Up @@ -2373,8 +2381,7 @@ public Fragment getItem(int position) {
mIsJetpackSsoEnabled);

return GutenbergEditorFragment.newInstance(
"",
"",
WordPress.getContext(),
mIsNewPost,
gutenbergWebViewAuthorizationData,
gutenbergPropsBuilder,
Expand Down Expand Up @@ -2877,10 +2884,10 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) {
}
break;
case RequestCodes.HISTORY_DETAIL:
if (data.hasExtra(KEY_REVISION)) {
if (getDB() != null && getDB().hasParcel(KEY_REVISION)) {
mViewPager.setCurrentItem(PAGE_CONTENT);

mRevision = data.getParcelableExtra(KEY_REVISION);
mRevision = getDB().getParcel(KEY_REVISION, Revision.CREATOR);
new Handler().postDelayed(this::loadRevision,
getResources().getInteger(R.integer.full_screen_dialog_animation_duration));
}
Expand Down Expand Up @@ -3949,4 +3956,8 @@ public void showJetpackSettings() {
public LiveData<DialogVisibility> getSavingInProgressDialogVisibility() {
return mViewModel.getSavingInProgressDialogVisibility();
}

@Nullable private SavedInstanceDatabase getDB() {
return SavedInstanceDatabase.Companion.getDatabase(WordPress.getContext());
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.wordpress.android.editor.gutenberg;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.ViewGroup;

Expand All @@ -14,6 +15,7 @@
import org.wordpress.android.editor.BuildConfig;
import org.wordpress.android.editor.ExceptionLogger;
import org.wordpress.android.editor.R;
import org.wordpress.android.editor.savedinstance.SavedInstanceDatabase;
import org.wordpress.mobile.WPAndroidGlue.ShowSuggestionsUtil;
import org.wordpress.mobile.WPAndroidGlue.GutenbergProps;
import org.wordpress.mobile.WPAndroidGlue.RequestExecutor;
Expand Down Expand Up @@ -53,11 +55,12 @@ public class GutenbergContainerFragment extends Fragment {
private boolean mHasReceivedAnyContent;

private WPAndroidGlueCode mWPAndroidGlueCode;
public static GutenbergContainerFragment newInstance(GutenbergPropsBuilder gutenbergPropsBuilder) {
public static GutenbergContainerFragment newInstance(Context context, GutenbergPropsBuilder gutenbergPropsBuilder) {
GutenbergContainerFragment fragment = new GutenbergContainerFragment();
Bundle args = new Bundle();
args.putParcelable(ARG_GUTENBERG_PROPS_BUILDER, gutenbergPropsBuilder);
fragment.setArguments(args);
SavedInstanceDatabase db = SavedInstanceDatabase.Companion.getDatabase(context);
if (db != null) {
db.addParcel(ARG_GUTENBERG_PROPS_BUILDER, gutenbergPropsBuilder);
}
return fragment;
}

Expand Down Expand Up @@ -124,7 +127,11 @@ public void attachToContainer(ViewGroup viewGroup, OnMediaLibraryButtonListener
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

GutenbergPropsBuilder gutenbergPropsBuilder = getArguments().getParcelable(ARG_GUTENBERG_PROPS_BUILDER);
GutenbergPropsBuilder gutenbergPropsBuilder = null;
SavedInstanceDatabase db = SavedInstanceDatabase.Companion.getDatabase(getContext());
if (db != null) {
gutenbergPropsBuilder = db.getParcel(ARG_GUTENBERG_PROPS_BUILDER, GutenbergPropsBuilder.CREATOR);
}

Consumer<Exception> exceptionLogger = null;
Consumer<String> breadcrumbLogger = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
import org.wordpress.android.editor.EditorThemeUpdateListener;
import org.wordpress.android.editor.LiveTextWatcher;
import org.wordpress.android.editor.R;
import org.wordpress.android.editor.savedinstance.SavedInstanceDatabase;
import org.wordpress.android.editor.WPGutenbergWebViewActivity;
import org.wordpress.android.editor.gutenberg.GutenbergDialogFragment.GutenbergDialogNegativeClickInterface;
import org.wordpress.android.editor.gutenberg.GutenbergDialogFragment.GutenbergDialogPositiveClickInterface;
Expand Down Expand Up @@ -161,23 +162,23 @@ public class GutenbergEditorFragment extends EditorFragmentAbstract implements

private ProgressDialog mSavingContentProgressDialog;

public static GutenbergEditorFragment newInstance(String title,
String content,
public static GutenbergEditorFragment newInstance(Context context,
boolean isNewPost,
GutenbergWebViewAuthorizationData webViewAuthorizationData,
GutenbergPropsBuilder gutenbergPropsBuilder,
int storyBlockEditRequestCode,
boolean jetpackFeaturesEnabled) {
GutenbergEditorFragment fragment = new GutenbergEditorFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM_TITLE, title);
args.putString(ARG_PARAM_CONTENT, content);
args.putBoolean(ARG_IS_NEW_POST, isNewPost);
args.putParcelable(ARG_GUTENBERG_WEB_VIEW_AUTH_DATA, webViewAuthorizationData);
args.putParcelable(ARG_GUTENBERG_PROPS_BUILDER, gutenbergPropsBuilder);
args.putInt(ARG_STORY_EDITOR_REQUEST_CODE, storyBlockEditRequestCode);
args.putBoolean(ARG_JETPACK_FEATURES_ENABLED, jetpackFeaturesEnabled);
fragment.setArguments(args);
SavedInstanceDatabase db = SavedInstanceDatabase.Companion.getDatabase(context);
if (db != null) {
db.addParcel(ARG_GUTENBERG_WEB_VIEW_AUTH_DATA, webViewAuthorizationData);
db.addParcel(ARG_GUTENBERG_PROPS_BUILDER, gutenbergPropsBuilder);
}
return fragment;
}

Expand All @@ -199,12 +200,17 @@ public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

if (getGutenbergContainerFragment() == null) {
GutenbergPropsBuilder gutenbergPropsBuilder = getArguments().getParcelable(ARG_GUTENBERG_PROPS_BUILDER);
GutenbergPropsBuilder gutenbergPropsBuilder = null;
SavedInstanceDatabase db = SavedInstanceDatabase.Companion.getDatabase(getContext());
if (db != null) {
gutenbergPropsBuilder = db.getParcel(ARG_GUTENBERG_PROPS_BUILDER, GutenbergPropsBuilder.CREATOR);
}
mCurrentGutenbergPropsBuilder = gutenbergPropsBuilder;

FragmentManager fragmentManager = getChildFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
GutenbergContainerFragment fragment = GutenbergContainerFragment.newInstance(gutenbergPropsBuilder);
GutenbergContainerFragment fragment =
GutenbergContainerFragment.newInstance(requireContext(), gutenbergPropsBuilder);
fragment.setRetainInstance(true);
fragmentTransaction.add(fragment, GutenbergContainerFragment.TAG);
fragmentTransaction.commitNow();
Expand Down Expand Up @@ -645,9 +651,16 @@ private void initializeSavingProgressDialog() {
}
}

private GutenbergWebViewAuthorizationData getGutenbergWebViewAuthorizationData() {
SavedInstanceDatabase db = SavedInstanceDatabase.Companion.getDatabase(getContext());
if (db != null) {
return db.getParcel(ARG_GUTENBERG_WEB_VIEW_AUTH_DATA, GutenbergWebViewAuthorizationData.CREATOR);
}
return null;
}

private void openGutenbergWebViewActivity(String content, String blockId, String blockName, String blockTitle) {
GutenbergWebViewAuthorizationData gutenbergWebViewAuthData =
getArguments().getParcelable(ARG_GUTENBERG_WEB_VIEW_AUTH_DATA);
GutenbergWebViewAuthorizationData gutenbergWebViewAuthData = getGutenbergWebViewAuthorizationData();

// There is a chance that isJetpackSsoEnabled has changed on the server
// so we need to make sure that we have fresh value of it.
Expand Down Expand Up @@ -727,8 +740,8 @@ private ArrayList<MediaOption> initOtherMediaImageOptions() {
}

boolean jetpackFeaturesEnabled = arguments.getBoolean(ARG_JETPACK_FEATURES_ENABLED);
GutenbergWebViewAuthorizationData gutenbergWebViewAuthorizationData =
arguments.getParcelable(ARG_GUTENBERG_WEB_VIEW_AUTH_DATA);
GutenbergWebViewAuthorizationData gutenbergWebViewAuthorizationData = getGutenbergWebViewAuthorizationData();

boolean supportStockPhotos = gutenbergWebViewAuthorizationData.isSiteUsingWPComRestAPI()
&& jetpackFeaturesEnabled;
boolean supportsTenor = jetpackFeaturesEnabled;
Expand Down
Loading

0 comments on commit 3d55ca2

Please sign in to comment.