1616import android .view .View ;
1717import android .webkit .CookieManager ;
1818import android .webkit .JavascriptInterface ;
19+ import android .webkit .RenderProcessGoneDetail ;
1920import android .webkit .WebResourceRequest ;
2021import android .webkit .WebResourceResponse ;
2122import android .webkit .WebSettings ;
5859public class PdfViewer extends AppCompatActivity implements LoaderManager .LoaderCallbacks <List <CharSequence >> {
5960 private static final String TAG = "PdfViewer" ;
6061
62+ private static final String STATE_WEBVIEW_CRASHED = "webview_crashed" ;
6163 private static final String STATE_URI = "uri" ;
6264 private static final String STATE_PAGE = "page" ;
6365 private static final String STATE_ZOOM_RATIO = "zoomRatio" ;
@@ -116,6 +118,7 @@ public class PdfViewer extends AppCompatActivity implements LoaderManager.Loader
116118 private static final int STATE_END = 2 ;
117119 private static final int PADDING = 10 ;
118120
121+ private boolean webViewCrashed ;
119122 private Uri mUri ;
120123 public int mPage ;
121124 public int mNumPages ;
@@ -264,10 +267,19 @@ public String getPassword() {
264267 }
265268 }
266269
270+ private void showWebViewCrashed () {
271+ binding .webviewAlertTitle .setText (getString (R .string .webview_crash_title ));
272+ binding .webviewAlertMessage .setText (getString (R .string .webview_crash_message ));
273+ binding .webviewAlertLayout .setVisibility (View .VISIBLE );
274+ binding .webviewAlertReload .setVisibility (View .VISIBLE );
275+ binding .webview .setVisibility (View .GONE );
276+ }
277+
267278 @ Override
268279 @ SuppressLint ({"SetJavaScriptEnabled" })
269280 protected void onCreate (Bundle savedInstanceState ) {
270281 super .onCreate (savedInstanceState );
282+
271283 binding = PdfviewerBinding .inflate (getLayoutInflater ());
272284 setContentView (binding .getRoot ());
273285 setSupportActionBar (binding .toolbar );
@@ -395,6 +407,17 @@ public void onPageFinished(WebView view, String url) {
395407 invalidateOptionsMenu ();
396408 loadPdfWithPassword (mEncryptedDocumentPassword );
397409 }
410+
411+ @ Override
412+ public boolean onRenderProcessGone (WebView view , RenderProcessGoneDetail detail ) {
413+ if (detail .didCrash ()) {
414+ webViewCrashed = true ;
415+ showWebViewCrashed ();
416+ purgeWebView ();
417+ return true ;
418+ }
419+ return false ;
420+ }
398421 });
399422
400423 GestureHelper .attach (PdfViewer .this , binding .webview ,
@@ -455,6 +478,7 @@ public void onZoomEnd() {
455478 }
456479
457480 if (savedInstanceState != null ) {
481+ webViewCrashed = savedInstanceState .getBoolean (STATE_WEBVIEW_CRASHED );
458482 if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .TIRAMISU ) {
459483 mUri = savedInstanceState .getParcelable (STATE_URI , Uri .class );
460484 } else {
@@ -468,7 +492,14 @@ public void onZoomEnd() {
468492 mEncryptedDocumentPassword = savedInstanceState .getString (STATE_ENCRYPTED_DOCUMENT_PASSWORD );
469493 }
470494
471- if (mUri != null ) {
495+ binding .webviewAlertReload .setOnClickListener (v -> {
496+ webViewCrashed = false ;
497+ recreate ();
498+ });
499+
500+ if (webViewCrashed ) {
501+ showWebViewCrashed ();
502+ } else if (mUri != null ) {
472503 if ("file" .equals (mUri .getScheme ())) {
473504 snackbar .setText (R .string .legacy_file_uri ).show ();
474505 return ;
@@ -478,14 +509,16 @@ public void onZoomEnd() {
478509 }
479510 }
480511
481-
512+ private void purgeWebView () {
513+ binding .webview .removeJavascriptInterface ("channel" );
514+ binding .getRoot ().removeView (binding .webview );
515+ binding .webview .destroy ();
516+ }
482517
483518 @ Override
484519 protected void onDestroy () {
485520 super .onDestroy ();
486- binding .webview .removeJavascriptInterface ("channel" );
487- binding .getRoot ().removeView (binding .webview );
488- binding .webview .destroy ();
521+ purgeWebView ();
489522 maybeCloseInputStream ();
490523 }
491524
@@ -525,15 +558,18 @@ private void setToolbarTitleWithDocumentName() {
525558 protected void onResume () {
526559 super .onResume ();
527560
528- // The user could have left the activity to update the WebView
529- invalidateOptionsMenu ();
530- if (getWebViewRelease () >= MIN_WEBVIEW_RELEASE ) {
531- binding .webviewOutOfDateLayout .setVisibility (View .GONE );
532- binding .webview .setVisibility (View .VISIBLE );
533- } else {
534- binding .webview .setVisibility (View .GONE );
535- binding .webviewOutOfDateMessage .setText (getString (R .string .webview_out_of_date_message , getWebViewRelease (), MIN_WEBVIEW_RELEASE ));
536- binding .webviewOutOfDateLayout .setVisibility (View .VISIBLE );
561+ if (!webViewCrashed ) {
562+ // The user could have left the activity to update the WebView
563+ invalidateOptionsMenu ();
564+ if (getWebViewRelease () >= MIN_WEBVIEW_RELEASE ) {
565+ binding .webviewAlertLayout .setVisibility (View .GONE );
566+ binding .webview .setVisibility (View .VISIBLE );
567+ } else {
568+ binding .webview .setVisibility (View .GONE );
569+ binding .webviewAlertTitle .setText (getString (R .string .webview_out_of_date_title ));
570+ binding .webviewAlertMessage .setText (getString (R .string .webview_out_of_date_message , getWebViewRelease (), MIN_WEBVIEW_RELEASE ));
571+ binding .webviewAlertLayout .setVisibility (View .VISIBLE );
572+ }
537573 }
538574 }
539575
@@ -645,6 +681,7 @@ private void hideSystemUi() {
645681 @ Override
646682 public void onSaveInstanceState (@ NonNull Bundle savedInstanceState ) {
647683 super .onSaveInstanceState (savedInstanceState );
684+ savedInstanceState .putBoolean (STATE_WEBVIEW_CRASHED , webViewCrashed );
648685 savedInstanceState .putParcelable (STATE_URI , mUri );
649686 savedInstanceState .putInt (STATE_PAGE , mPage );
650687 savedInstanceState .putFloat (STATE_ZOOM_RATIO , mZoomRatio );
@@ -703,14 +740,23 @@ public boolean onPrepareOptionsMenu(@NonNull Menu menu) {
703740 mDocumentState = STATE_END ;
704741 }
705742
706- enableDisableMenuItem (menu .findItem (R .id .action_open ), getWebViewRelease () >= MIN_WEBVIEW_RELEASE );
743+
744+ enableDisableMenuItem (menu .findItem (R .id .action_open ),
745+ !webViewCrashed && getWebViewRelease () >= MIN_WEBVIEW_RELEASE );
707746 enableDisableMenuItem (menu .findItem (R .id .action_share ), mUri != null );
708747 enableDisableMenuItem (menu .findItem (R .id .action_next ), mPage < mNumPages );
709748 enableDisableMenuItem (menu .findItem (R .id .action_previous ), mPage > 1 );
710749 enableDisableMenuItem (menu .findItem (R .id .action_save_as ), mUri != null );
711750
712751 menu .findItem (R .id .action_outline ).setVisible (viewModel .hasOutline ());
713752
753+ if (webViewCrashed ) {
754+ for (final int id : ids ) {
755+ final MenuItem item = menu .findItem (id );
756+ enableDisableMenuItem (item , false );
757+ }
758+ }
759+
714760 return true ;
715761 }
716762
0 commit comments