PrintDocumentAdapter printDocumentAdapter = currentWebView.createPrintDocumentAdapter();
// Print the document.
- printManager.print(getString(R.string.privacy_browser_web_page), printDocumentAdapter, null);
+ printManager.print(getString(R.string.privacy_browser_webpage), printDocumentAdapter, null);
// Consume the event.
return true;
assert dialog != null;
// Get handles for the views in the dialog fragment.
- EditText createFolderNameEditText = dialog.findViewById(R.id.create_folder_name_edittext);
- RadioButton defaultFolderIconRadioButton = dialog.findViewById(R.id.create_folder_default_icon_radiobutton);
- ImageView folderIconImageView = dialog.findViewById(R.id.create_folder_default_icon);
+ EditText folderNameEditText = dialog.findViewById(R.id.folder_name_edittext);
+ RadioButton defaultIconRadioButton = dialog.findViewById(R.id.default_icon_radiobutton);
+ ImageView defaultIconImageView = dialog.findViewById(R.id.default_icon_imageview);
// Get new folder name string.
- String folderNameString = createFolderNameEditText.getText().toString();
+ String folderNameString = folderNameEditText.getText().toString();
// Create a folder icon bitmap.
Bitmap folderIconBitmap;
// Set the folder icon bitmap according to the dialog.
- if (defaultFolderIconRadioButton.isChecked()) { // Use the default folder icon.
+ if (defaultIconRadioButton.isChecked()) { // Use the default folder icon.
// Get the default folder icon drawable.
- Drawable folderIconDrawable = folderIconImageView.getDrawable();
+ Drawable folderIconDrawable = defaultIconImageView.getDrawable();
// Convert the folder icon drawable to a bitmap drawable.
BitmapDrawable folderIconBitmapDrawable = (BitmapDrawable) folderIconDrawable;
assert dialog != null;
// Get handles for the views from the dialog.
- EditText editFolderNameEditText = dialog.findViewById(R.id.edit_folder_name_edittext);
- RadioButton currentFolderIconRadioButton = dialog.findViewById(R.id.edit_folder_current_icon_radiobutton);
- RadioButton defaultFolderIconRadioButton = dialog.findViewById(R.id.edit_folder_default_icon_radiobutton);
- ImageView defaultFolderIconImageView = dialog.findViewById(R.id.edit_folder_default_icon_imageview);
+ RadioButton currentFolderIconRadioButton = dialog.findViewById(R.id.current_icon_radiobutton);
+ RadioButton defaultFolderIconRadioButton = dialog.findViewById(R.id.default_icon_radiobutton);
+ ImageView defaultFolderIconImageView = dialog.findViewById(R.id.default_icon_imageview);
+ EditText editFolderNameEditText = dialog.findViewById(R.id.folder_name_edittext);
// Get the new folder name.
String newFolderNameString = editFolderNameEditText.getText().toString();
// Update the folder icon in the database.
bookmarksDatabaseHelper.updateFolder(selectedFolderDatabaseId, newFolderIconByteArray);
} else { // The folder icon and the name have changed.
- // Get the new folder icon `Bitmap`.
+ // Get the new folder icon bitmap.
Bitmap folderIconBitmap;
if (defaultFolderIconRadioButton.isChecked()) {
// Get the default folder icon drawable.
@Override
public void onDrawerClosed(@NonNull View drawerView) {
+ // Reset the drawer icon when the drawer is closed. Otherwise, it is an arrow if the drawer is open when the app is restarted.
+ actionBarDrawerToggle.syncState();
}
@Override
}
private void addNewTab(String url, boolean moveToTab) {
+ // Clear the focus from the URL edit text, so that it will be populated with the information from the new tab.
+ urlEditText.clearFocus();
+
// Get the new page number. The page numbers are 0 indexed, so the new page number will match the current count.
int newTabNumber = tabLayout.getTabCount();
}
private void closeCurrentTab() {
- // Pause the current WebView. This prevents buffered audio from playing after the tab is closed.
- currentWebView.onPause();
-
// Get the current tab number.
int currentTabNumber = tabLayout.getSelectedTabPosition();
// Delete the current tab.
tabLayout.removeTabAt(currentTabNumber);
- // Delete the current page. If the selected page number did not change during the delete, it will return true, meaning that the current WebView must be reset.
+ // Delete the current page. If the selected page number did not change during the delete (because the newly selected tab has has same number as the previously deleted tab), it will return true,
+ // meaning that the current WebView must be reset. Otherwise it will happen automatically as the selected tab number changes.
if (webViewPagerAdapter.deletePage(currentTabNumber, webViewPager)) {
setCurrentWebView(currentTabNumber);
}
-
- // Expand the app bar if it is currently collapsed.
- appBarLayout.setExpanded(true);
}
private void saveWebpageArchive(String filePath) {
// Get the WebView tab fragment.
WebViewTabFragment webViewTabFragment = webViewPagerAdapter.getPageFragment(i);
- // Get the fragment view.
- View fragmentView = webViewTabFragment.getView();
+ // Get the WebView fragment view.
+ View webViewFragmentView = webViewTabFragment.getView();
// Only clear the cache if the WebView exists.
- if (fragmentView != null) {
+ if (webViewFragmentView != null) {
// Get the nested scroll WebView from the tab fragment.
- NestedScrollWebView nestedScrollWebView = fragmentView.findViewById(R.id.nestedscroll_webview);
+ NestedScrollWebView nestedScrollWebView = webViewFragmentView.findViewById(R.id.nestedscroll_webview);
// Clear the cache for this WebView.
nestedScrollWebView.clearCache(true);
// Get the WebView tab fragment.
WebViewTabFragment webViewTabFragment = webViewPagerAdapter.getPageFragment(i);
- // Get the fragment view.
- View fragmentView = webViewTabFragment.getView();
+ // Get the WebView frame layout.
+ FrameLayout webViewFrameLayout = (FrameLayout) webViewTabFragment.getView();
// Only wipe out the WebView if it exists.
- if (fragmentView != null) {
+ if (webViewFrameLayout != null) {
// Get the nested scroll WebView from the tab fragment.
- NestedScrollWebView nestedScrollWebView = fragmentView.findViewById(R.id.nestedscroll_webview);
+ NestedScrollWebView nestedScrollWebView = webViewFrameLayout.findViewById(R.id.nestedscroll_webview);
// Clear SSL certificate preferences for this WebView.
nestedScrollWebView.clearSslPreferences();
// Clear the back/forward history for this WebView.
nestedScrollWebView.clearHistory();
+ // Remove all the views from the frame layout.
+ webViewFrameLayout.removeAllViews();
+
// Destroy the internal state of the WebView.
nestedScrollWebView.destroy();
}
// Get the file name from the content disposition.
String fileNameString = PrepareSaveDialog.getFileNameFromHeaders(this, contentDisposition, mimetype, downloadUrl);
+ // Prevent the dialog from displaying if the app window is not visible.
+ // The download listener continues to function even when the WebView is paused. Attempting to display a dialog in that state leads to a crash.
+ while (!activity.getWindow().isActive()) {
+ try {
+ // The window is not active. Wait 1 second.
+ wait(1000);
+ } catch (InterruptedException e) {
+ // Do nothing.
+ }
+ }
+
// Instantiate the save dialog.
DialogFragment saveDialogFragment = SaveWebpageDialog.saveWebpage(StoragePermissionDialog.SAVE_URL, downloadUrl, formattedFileSizeString, fileNameString, userAgent,
nestedScrollWebView.getAcceptFirstPartyCookies());
// Store the SSL error handler.
nestedScrollWebView.setSslErrorHandler(handler);
+ // Prevent the dialog from displaying if the app window is not visible.
+ // The SSL error handler continues to function even when the WebView is paused. Attempting to display a dialog in that state leads to a crash.
+ while (!activity.getWindow().isActive()) {
+ try {
+ // The window is not active. Wait 1 second.
+ wait(1000);
+ } catch (InterruptedException e) {
+ // Do nothing.
+ }
+ }
+
// Instantiate an SSL certificate error alert dialog.
DialogFragment sslCertificateErrorDialogFragment = SslCertificateErrorDialog.displayDialog(error, nestedScrollWebView.getWebViewFragmentId());