Skip to content

Commit

Permalink
Merge pull request #20139 from wordpress-mobile/issue/9685-webview-tr…
Browse files Browse the repository at this point in the history
…ansactiontoolarge

Prevents TransactionTooLargeException error in WebViewActivity
  • Loading branch information
mkevins authored Feb 7, 2024
2 parents 2f0f5e0 + 3a947fd commit 9328435
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 4 deletions.
1 change: 1 addition & 0 deletions RELEASE-NOTES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
* [*] [Jetpack-only] Site Monitoring: Add Metrics, PHP Logs, and Web Server Logs under Site Monitoring [https://github.com/wordpress-mobile/WordPress-Android/issues/20067]
* [**] Prevent images from temporarily disappearing when uploading media [https://github.com/WordPress/gutenberg/pull/57869]
* [***] [Jetpack-only] Reader: introduced new UI/UX for content navigation and filtering [https://github.com/wordpress-mobile/WordPress-Android/pull/19978]
* [**] Prevents crashes when the webview state is too big [https://github.com/wordpress-mobile/WordPress-Android/pull/20139]

24.1
-----
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@

import org.wordpress.android.R;
import org.wordpress.android.WordPress;
import org.wordpress.android.analytics.AnalyticsTracker;
import org.wordpress.android.util.extensions.CompatExtensionsKt;

import java.util.HashMap;
import java.util.Map;

/**
Expand All @@ -28,6 +30,9 @@ public abstract class WebViewActivity extends LocaleAwareActivity {

private static final String URL = "url";

private static final String WEBVIEW_CHROMIUM_STATE = "WEBVIEW_CHROMIUM_STATE";
private static final int WEBVIEW_CHROMIUM_STATE_THRESHOLD = 300 * 1024; // 300 KB

protected WebView mWebView;

@Override
Expand Down Expand Up @@ -84,18 +89,43 @@ protected void loadContent() {
* save the webView state with the bundle so it can be restored
*/
@Override
protected void onSaveInstanceState(Bundle outState) {
protected void onSaveInstanceState(@NonNull Bundle outState) {
mWebView.saveState(outState);

// If the WebView state is too large, remove it from the bundle and track the error. This workaround is
// necessary since the Android system cannot handle large states without a crash.
// Note that Chromium `WebViewBrowserFragment` uses a similar workaround for this issue:
// https://source.chromium.org/chromium/chromium/src/+/27a9bbd3dcd7005ac9f3862dc2e356b557023de9
byte[] webViewState = outState.getByteArray(WEBVIEW_CHROMIUM_STATE);
if (webViewState != null && webViewState.length > WEBVIEW_CHROMIUM_STATE_THRESHOLD) {
outState.remove(WEBVIEW_CHROMIUM_STATE);

// Save the URL so it can be restored later
String url = mWebView.getUrl();
outState.putString(URL, url);

// Track the error to better understand the root of the issue
Map<String, String> properties = new HashMap<>();
properties.put(URL, url);
AnalyticsTracker.track(AnalyticsTracker.Stat.WEBVIEW_TOO_LARGE_PAYLOAD_ERROR, properties);
}
super.onSaveInstanceState(outState);
}

/*
* restore the webView state saved above
*/
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
mWebView.restoreState(savedInstanceState);
if (savedInstanceState.containsKey(WEBVIEW_CHROMIUM_STATE)) {
mWebView.restoreState(savedInstanceState);
} else {
String url = savedInstanceState.getString(URL);
if (url != null) {
mWebView.loadUrl(url);
}
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1106,7 +1106,8 @@ public enum Stat {
SITE_MONITORING_SCREEN_SHOWN,
OPENED_SITE_MONITORING,
SITE_MONITORING_TAB_SHOWN,
SITE_MONITORING_TAB_LOADING_ERROR
SITE_MONITORING_TAB_LOADING_ERROR,
WEBVIEW_TOO_LARGE_PAYLOAD_ERROR,
}

private static final List<Tracker> TRACKERS = new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2707,6 +2707,8 @@ public static String getEventNameForStat(AnalyticsTracker.Stat stat) {
return "site_monitoring_tab_shown";
case SITE_MONITORING_TAB_LOADING_ERROR:
return "site_monitoring_tab_loading_error";
case WEBVIEW_TOO_LARGE_PAYLOAD_ERROR:
return "webview_too_large_payload_error";
}
return null;
}
Expand Down

0 comments on commit 9328435

Please sign in to comment.