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

Prevents TransactionTooLargeException error in WebViewActivity #20139

Merged
merged 4 commits into from
Feb 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading