From 403853306a4bf0592bc3b65eed4a9f20ba90f871 Mon Sep 17 00:00:00 2001 From: Andrei Lazar Date: Fri, 14 Sep 2018 11:24:33 +0000 Subject: [PATCH] Bug 1480852 Crash in android.os.TransactionTooLargeException: data parcel size 1053364 bytes at android.os.BinderProxy.transactNative(Native Method) r=jchen Added an extra check of bundle size due to some unexpected transactions sizes that exceed the limit. The bundle gets lighter if the size exceeds the limit by removing the views' state as a last resort. Differential Revision: https://phabricator.services.mozilla.com/D5682 --HG-- extra : moz-landing-system : lando --- .../base/java/org/mozilla/gecko/BrowserApp.java | 12 ++++++++++++ .../base/java/org/mozilla/gecko/util/JavaUtil.java | 14 ++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java b/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java index da5d889b3d99..e0b377456667 100644 --- a/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java +++ b/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java @@ -183,6 +183,7 @@ import java.util.Locale; import java.util.regex.Pattern; import static org.mozilla.gecko.mma.MmaDelegate.NEW_TAB; +import static org.mozilla.gecko.util.JavaUtil.getBundleSizeInBytes; public class BrowserApp extends GeckoApp implements ActionModePresenter, @@ -213,6 +214,8 @@ public class BrowserApp extends GeckoApp private static final String BROWSER_SEARCH_TAG = "browser_search"; + private static final int MAX_BUNDLE_SIZE = 300000; // 300 kilobytes + // Request ID for startActivityForResult. public static final int ACTIVITY_REQUEST_PREFERENCES = 1001; private static final int ACTIVITY_REQUEST_TAB_QUEUE = 2001; @@ -2267,6 +2270,15 @@ public class BrowserApp extends GeckoApp super.onSaveInstanceState(outState); mDynamicToolbar.onSaveInstanceState(outState); outState.putInt(STATE_ABOUT_HOME_TOP_PADDING, mHomeScreenContainer.getPaddingTop()); + + // Under key “android:viewHierarchyState” the OS stores another object of type Bundle. + // This bundle stores the state of the view which is in a SparseArray that can grow pretty big. + // This in some cases can lead to TransactionTooLargeException as per + // [https://developer.android.com/reference/android/os/TransactionTooLargeException] it's + // specified that the limit is fixed to 1MB per process. + if (getBundleSizeInBytes(outState) > MAX_BUNDLE_SIZE) { + outState.remove("android:viewHierarchyState"); + } } /** diff --git a/mobile/android/base/java/org/mozilla/gecko/util/JavaUtil.java b/mobile/android/base/java/org/mozilla/gecko/util/JavaUtil.java index 9aa29c323ecc..1ffcbbb7ce1a 100644 --- a/mobile/android/base/java/org/mozilla/gecko/util/JavaUtil.java +++ b/mobile/android/base/java/org/mozilla/gecko/util/JavaUtil.java @@ -5,6 +5,9 @@ package org.mozilla.gecko.util; +import android.os.Bundle; +import android.os.Parcel; + import java.util.List; public class JavaUtil { @@ -21,4 +24,15 @@ public class JavaUtil { } list.set(to, movedTab); } + + public static int getBundleSizeInBytes(Bundle bundle) { + Parcel parcel = Parcel.obtain(); + int size; + + parcel.writeBundle(bundle); + size = parcel.dataSize(); + parcel.recycle(); + + return size; + } }