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,18 @@ 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+ invalidateOptionsMenu ();
417+ purgeWebView ();
418+ return true ;
419+ }
420+ return false ;
421+ }
398422 });
399423
400424 GestureHelper .attach (PdfViewer .this , binding .webview ,
@@ -455,6 +479,7 @@ public void onZoomEnd() {
455479 }
456480
457481 if (savedInstanceState != null ) {
482+ webViewCrashed = savedInstanceState .getBoolean (STATE_WEBVIEW_CRASHED );
458483 if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .TIRAMISU ) {
459484 mUri = savedInstanceState .getParcelable (STATE_URI , Uri .class );
460485 } else {
@@ -468,7 +493,14 @@ public void onZoomEnd() {
468493 mEncryptedDocumentPassword = savedInstanceState .getString (STATE_ENCRYPTED_DOCUMENT_PASSWORD );
469494 }
470495
471- if (mUri != null ) {
496+ binding .webviewAlertReload .setOnClickListener (v -> {
497+ webViewCrashed = false ;
498+ recreate ();
499+ });
500+
501+ if (webViewCrashed ) {
502+ showWebViewCrashed ();
503+ } else if (mUri != null ) {
472504 if ("file" .equals (mUri .getScheme ())) {
473505 snackbar .setText (R .string .legacy_file_uri ).show ();
474506 return ;
@@ -478,14 +510,16 @@ public void onZoomEnd() {
478510 }
479511 }
480512
481-
513+ private void purgeWebView () {
514+ binding .webview .removeJavascriptInterface ("channel" );
515+ binding .getRoot ().removeView (binding .webview );
516+ binding .webview .destroy ();
517+ }
482518
483519 @ Override
484520 protected void onDestroy () {
485521 super .onDestroy ();
486- binding .webview .removeJavascriptInterface ("channel" );
487- binding .getRoot ().removeView (binding .webview );
488- binding .webview .destroy ();
522+ purgeWebView ();
489523 maybeCloseInputStream ();
490524 }
491525
@@ -525,15 +559,18 @@ private void setToolbarTitleWithDocumentName() {
525559 protected void onResume () {
526560 super .onResume ();
527561
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 );
562+ if (!webViewCrashed ) {
563+ // The user could have left the activity to update the WebView
564+ invalidateOptionsMenu ();
565+ if (getWebViewRelease () >= MIN_WEBVIEW_RELEASE ) {
566+ binding .webviewAlertLayout .setVisibility (View .GONE );
567+ binding .webview .setVisibility (View .VISIBLE );
568+ } else {
569+ binding .webview .setVisibility (View .GONE );
570+ binding .webviewAlertTitle .setText (getString (R .string .webview_out_of_date_title ));
571+ binding .webviewAlertMessage .setText (getString (R .string .webview_out_of_date_message , getWebViewRelease (), MIN_WEBVIEW_RELEASE ));
572+ binding .webviewAlertLayout .setVisibility (View .VISIBLE );
573+ }
537574 }
538575 }
539576
@@ -645,6 +682,7 @@ private void hideSystemUi() {
645682 @ Override
646683 public void onSaveInstanceState (@ NonNull Bundle savedInstanceState ) {
647684 super .onSaveInstanceState (savedInstanceState );
685+ savedInstanceState .putBoolean (STATE_WEBVIEW_CRASHED , webViewCrashed );
648686 savedInstanceState .putParcelable (STATE_URI , mUri );
649687 savedInstanceState .putInt (STATE_PAGE , mPage );
650688 savedInstanceState .putFloat (STATE_ZOOM_RATIO , mZoomRatio );
@@ -703,14 +741,22 @@ public boolean onPrepareOptionsMenu(@NonNull Menu menu) {
703741 mDocumentState = STATE_END ;
704742 }
705743
706- enableDisableMenuItem (menu .findItem (R .id .action_open ), getWebViewRelease () >= MIN_WEBVIEW_RELEASE );
744+
745+ enableDisableMenuItem (menu .findItem (R .id .action_open ),
746+ !webViewCrashed && getWebViewRelease () >= MIN_WEBVIEW_RELEASE );
707747 enableDisableMenuItem (menu .findItem (R .id .action_share ), mUri != null );
708748 enableDisableMenuItem (menu .findItem (R .id .action_next ), mPage < mNumPages );
709749 enableDisableMenuItem (menu .findItem (R .id .action_previous ), mPage > 1 );
710750 enableDisableMenuItem (menu .findItem (R .id .action_save_as ), mUri != null );
711751
712752 menu .findItem (R .id .action_outline ).setVisible (viewModel .hasOutline ());
713753
754+ if (webViewCrashed ) {
755+ for (final int id : ids ) {
756+ enableDisableMenuItem (menu .findItem (id ), false );
757+ }
758+ }
759+
714760 return true ;
715761 }
716762
0 commit comments