import android.net.Uri;
import android.net.http.SslCertificate;
import android.net.http.SslError;
-import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import com.stoutner.privacybrowser.R;
import com.stoutner.privacybrowser.adapters.WebViewPagerAdapter;
-import com.stoutner.privacybrowser.asynctasks.GetHostIpAddresses;
-import com.stoutner.privacybrowser.asynctasks.PopulateBlocklists;
-import com.stoutner.privacybrowser.asynctasks.PrepareSaveDialog;
import com.stoutner.privacybrowser.asynctasks.SaveUrl;
import com.stoutner.privacybrowser.asynctasks.SaveWebpageImage;
-import com.stoutner.privacybrowser.dataclasses.PendingDialog;
+import com.stoutner.privacybrowser.coroutines.GetHostIpAddressesCoroutine;
+import com.stoutner.privacybrowser.coroutines.PopulateBlocklistsCoroutine;
+import com.stoutner.privacybrowser.coroutines.PrepareSaveDialogCoroutine;
+import com.stoutner.privacybrowser.dataclasses.PendingDialogDataClass;
import com.stoutner.privacybrowser.dialogs.CreateBookmarkDialog;
import com.stoutner.privacybrowser.dialogs.CreateBookmarkFolderDialog;
import com.stoutner.privacybrowser.dialogs.CreateHomeScreenShortcutDialog;
public class MainWebViewActivity extends AppCompatActivity implements CreateBookmarkDialog.CreateBookmarkListener, CreateBookmarkFolderDialog.CreateBookmarkFolderListener,
FontSizeDialog.UpdateFontSizeListener, NavigationView.OnNavigationItemSelectedListener, OpenDialog.OpenListener, PinnedMismatchDialog.PinnedMismatchListener,
- PopulateBlocklists.PopulateBlocklistsListener, SaveDialog.SaveListener, UrlHistoryDialog.NavigateHistoryListener, WebViewTabFragment.NewTabListener {
+ PopulateBlocklistsCoroutine.PopulateBlocklistsListener, SaveDialog.SaveListener, UrlHistoryDialog.NavigateHistoryListener, WebViewTabFragment.NewTabListener {
// Define the public static variables.
public static final ExecutorService executorService = Executors.newFixedThreadPool(4);
public static String orbotStatus = "unknown";
- public static final ArrayList<PendingDialog> pendingDialogsArrayList = new ArrayList<>();
+ public static final ArrayList<PendingDialogDataClass> pendingDialogsArrayList = new ArrayList<>();
public static String proxyMode = ProxyHelper.NONE;
// Declare the public static variables.
private int savedTabPosition;
private String savedProxyMode;
- // Define the class variables.
- @SuppressWarnings("rawtypes")
- AsyncTask populateBlocklists;
-
// The current WebView is used in `onCreate()`, `onPrepareOptionsMenu()`, `onOptionsItemSelected()`, `onNavigationItemSelected()`, `onRestart()`, `onCreateContextMenu()`, `findPreviousOnPage()`,
// `findNextOnPage()`, `closeFindOnPage()`, `loadUrlFromTextBox()`, `onSslMismatchBack()`, `applyProxy()`, and `applyDomainSettings()`.
private NestedScrollWebView currentWebView;
} else if (displayingFullScreenVideo) { // A full screen video is shown.
// Exit the full screen video.
exitFullScreenVideo();
- } else if (currentWebView.canGoBack()) { // There is at least one item in the current WebView history.
+ // It shouldn't be possible for the currentWebView to be null, but crash logs indicate it sometimes happens.
+ } else if ((currentWebView != null) && (currentWebView.canGoBack())) { // There is at least one item in the current WebView history.
// Get the current web back forward list.
WebBackForwardList webBackForwardList = currentWebView.copyBackForwardList();
// Register the on back pressed callback.
getOnBackPressedDispatcher().addCallback(this, onBackPressedCallback);
+ // Instantiate the populate blocklists coroutine.
+ PopulateBlocklistsCoroutine populateBlocklistsCoroutine = new PopulateBlocklistsCoroutine(this);
+
// Populate the blocklists.
- populateBlocklists = new PopulateBlocklists(this, this).execute();
+ populateBlocklistsCoroutine.populateBlocklists(this);
}
@Override
// Show any pending dialogs.
for (int i = 0; i < pendingDialogsArrayList.size(); i++) {
// Get the pending dialog from the array list.
- PendingDialog pendingDialog = pendingDialogsArrayList.get(i);
+ PendingDialogDataClass pendingDialogDataClass = pendingDialogsArrayList.get(i);
// Show the pending dialog.
- pendingDialog.dialogFragment.show(getSupportFragmentManager(), pendingDialog.tag);
+ pendingDialogDataClass.dialogFragment.show(getSupportFragmentManager(), pendingDialogDataClass.tag);
}
// Clear the pending dialogs array list.
bookmarksDatabaseHelper.close();
}
- // Stop populating the blocklists if the AsyncTask is running in the background.
- if (populateBlocklists != null) {
- populateBlocklists.cancel(true);
- }
-
// Run the default commands.
super.onDestroy();
}
downloadUrlWithExternalApp(currentWebView.getCurrentUrl());
} else { // Handle the download inside of Privacy Browser.
// Prepare the save dialog. The dialog will be displayed once the file size and the content disposition have been acquired.
- new PrepareSaveDialog(this, this, getSupportFragmentManager(), currentWebView.getSettings().getUserAgentString(),
- currentWebView.getAcceptCookies()).execute(currentWebView.getCurrentUrl());
+ PrepareSaveDialogCoroutine.prepareSaveDialog(this, getSupportFragmentManager(), currentWebView.getCurrentUrl(), currentWebView.getSettings().getUserAgentString(),
+ currentWebView.getAcceptCookies());
}
// Consume the event.
} else if (menuItemId == R.id.add_to_homescreen) { // Add to homescreen.
// Instantiate the create home screen shortcut dialog.
DialogFragment createHomeScreenShortcutDialogFragment = CreateHomeScreenShortcutDialog.createDialog(currentWebView.getTitle(), currentWebView.getUrl(),
- currentWebView.getFavoriteOrDefaultIcon());
+ currentWebView.getFavoriteIcon());
// Show the create home screen shortcut dialog.
createHomeScreenShortcutDialogFragment.show(getSupportFragmentManager(), getString(R.string.create_shortcut));
downloadUrlWithExternalApp(linkUrl);
} else { // Handle the download inside of Privacy Browser.
// Prepare the save dialog. The dialog will be displayed once the file size and the content disposition have been acquired.
- new PrepareSaveDialog(this, this, getSupportFragmentManager(), currentWebView.getSettings().getUserAgentString(),
- currentWebView.getAcceptCookies()).execute(linkUrl);
+ PrepareSaveDialogCoroutine.prepareSaveDialog(this, getSupportFragmentManager(), linkUrl, currentWebView.getSettings().getUserAgentString(), currentWebView.getAcceptCookies());
}
// Consume the event.
downloadUrlWithExternalApp(imageUrl);
} else { // Handle the download inside of Privacy Browser.
// Prepare the save dialog. The dialog will be displayed once the file size and the content disposition have been acquired.
- new PrepareSaveDialog(this, this, getSupportFragmentManager(), currentWebView.getSettings().getUserAgentString(),
- currentWebView.getAcceptCookies()).execute(imageUrl);
+ PrepareSaveDialogCoroutine.prepareSaveDialog(this, getSupportFragmentManager(), imageUrl, currentWebView.getSettings().getUserAgentString(), currentWebView.getAcceptCookies());
}
// Consume the event.
downloadUrlWithExternalApp(imageUrl);
} else { // Handle the download inside of Privacy Browser.
// Prepare the save dialog. The dialog will be displayed once the file size and the content disposition have been acquired.
- new PrepareSaveDialog(this, this, getSupportFragmentManager(), currentWebView.getSettings().getUserAgentString(),
- currentWebView.getAcceptCookies()).execute(imageUrl);
+ PrepareSaveDialogCoroutine.prepareSaveDialog(this, getSupportFragmentManager(), imageUrl, currentWebView.getSettings().getUserAgentString(), currentWebView.getAcceptCookies());
}
// Consume the event.
downloadUrlWithExternalApp(linkUrl);
} else { // Handle the download inside of Privacy Browser.
// Prepare the save dialog. The dialog will be displayed once the file size and the content disposition have been acquired.
- new PrepareSaveDialog(this, this, getSupportFragmentManager(), currentWebView.getSettings().getUserAgentString(),
- currentWebView.getAcceptCookies()).execute(linkUrl);
+ PrepareSaveDialogCoroutine.prepareSaveDialog(this, getSupportFragmentManager(), linkUrl, currentWebView.getSettings().getUserAgentString(), currentWebView.getAcceptCookies());
}
// Consume the event.
@Override
public void onTabReselected(TabLayout.Tab tab) {
// Instantiate the View SSL Certificate dialog.
- DialogFragment viewSslCertificateDialogFragment = ViewSslCertificateDialog.displayDialog(currentWebView.getWebViewFragmentId(), currentWebView.getFavoriteOrDefaultIcon());
+ DialogFragment viewSslCertificateDialogFragment = ViewSslCertificateDialog.displayDialog(currentWebView.getWebViewFragmentId(), currentWebView.getFavoriteIcon());
// Display the View SSL Certificate dialog.
viewSslCertificateDialogFragment.show(getSupportFragmentManager(), getString(R.string.view_ssl_certificate));
// Set the launch bookmarks activity FAB to launch the bookmarks activity.
launchBookmarksActivityFab.setOnClickListener(v -> {
// Get a copy of the favorite icon bitmap.
- Bitmap favoriteIconBitmap = currentWebView.getFavoriteOrDefaultIcon();
+ Bitmap favoriteIconBitmap = currentWebView.getFavoriteIcon();
// Create a favorite icon byte array output stream.
ByteArrayOutputStream favoriteIconByteArrayOutputStream = new ByteArrayOutputStream();
// Set the create new bookmark folder FAB to display an alert dialog.
createBookmarkFolderFab.setOnClickListener(v -> {
// Create a create bookmark folder dialog.
- DialogFragment createBookmarkFolderDialog = CreateBookmarkFolderDialog.createBookmarkFolder(currentWebView.getFavoriteOrDefaultIcon());
+ DialogFragment createBookmarkFolderDialog = CreateBookmarkFolderDialog.createBookmarkFolder(currentWebView.getFavoriteIcon());
// Show the create bookmark folder dialog.
createBookmarkFolderDialog.show(getSupportFragmentManager(), getString(R.string.create_folder));
// Set the create new bookmark FAB to display an alert dialog.
createBookmarkFab.setOnClickListener(view -> {
// Instantiate the create bookmark dialog.
- DialogFragment createBookmarkDialog = CreateBookmarkDialog.createBookmark(currentWebView.getUrl(), currentWebView.getTitle(), currentWebView.getFavoriteOrDefaultIcon());
+ DialogFragment createBookmarkDialog = CreateBookmarkDialog.createBookmark(currentWebView.getUrl(), currentWebView.getTitle(), currentWebView.getFavoriteIcon());
// Display the create bookmark dialog.
createBookmarkDialog.show(getSupportFragmentManager(), getString(R.string.create_bookmark));
TextView tabTitleTextView = tabCustomView.findViewById(R.id.title_textview);
// Set the default favorite icon as the favorite icon for this tab.
- tabFavoriteIconImageView.setImageBitmap(Bitmap.createScaledBitmap(nestedScrollWebView.getFavoriteOrDefaultIcon(), 64, 64, true));
+ tabFavoriteIconImageView.setImageBitmap(Bitmap.createScaledBitmap(nestedScrollWebView.getFavoriteIcon(), 64, 64, true));
// Set the loading title text.
tabTitleTextView.setText(R.string.loading);
waitingForProxyDialogFragment.show(getSupportFragmentManager(), getString(R.string.waiting_for_proxy_dialog));
} catch (Exception waitingForTorException) {
// Add the dialog to the pending dialog array list. It will be displayed in `onStart()`.
- pendingDialogsArrayList.add(new PendingDialog(waitingForProxyDialogFragment, getString(R.string.waiting_for_proxy_dialog)));
+ pendingDialogsArrayList.add(new PendingDialogDataClass(waitingForProxyDialogFragment, getString(R.string.waiting_for_proxy_dialog)));
}
}
}
orbotNotInstalledDialogFragment.show(getSupportFragmentManager(), getString(R.string.proxy_not_installed_dialog));
} catch (Exception orbotNotInstalledException) {
// Add the dialog to the pending dialog array list. It will be displayed in `onStart()`.
- pendingDialogsArrayList.add(new PendingDialog(orbotNotInstalledDialogFragment, getString(R.string.proxy_not_installed_dialog)));
+ pendingDialogsArrayList.add(new PendingDialogDataClass(orbotNotInstalledDialogFragment, getString(R.string.proxy_not_installed_dialog)));
}
}
}
i2pNotInstalledDialogFragment.show(getSupportFragmentManager(), getString(R.string.proxy_not_installed_dialog));
} catch (Exception i2pNotInstalledException) {
// Add the dialog to the pending dialog array list. It will be displayed in `onStart()`.
- pendingDialogsArrayList.add(new PendingDialog(i2pNotInstalledDialogFragment, getString(R.string.proxy_not_installed_dialog)));
+ pendingDialogsArrayList.add(new PendingDialogDataClass(i2pNotInstalledDialogFragment, getString(R.string.proxy_not_installed_dialog)));
}
}
}
}
// Get the file name from the content disposition.
- String fileNameString = PrepareSaveDialog.getFileNameFromHeaders(this, contentDisposition, mimetype, downloadUrl);
+ String fileNameString = PrepareSaveDialogCoroutine.getFileNameFromHeaders(this, contentDisposition, mimetype, downloadUrl);
// Instantiate the save dialog.
DialogFragment saveDialogFragment = SaveDialog.saveUrl(downloadUrl, formattedFileSizeString, fileNameString, userAgent,
saveDialogFragment.show(getSupportFragmentManager(), getString(R.string.save_dialog));
} catch (Exception exception) { // The dialog could not be shown.
// Add the dialog to the pending dialog array list. It will be displayed in `onStart()`.
- pendingDialogsArrayList.add(new PendingDialog(saveDialogFragment, getString(R.string.save_dialog)));
+ pendingDialogsArrayList.add(new PendingDialogDataClass(saveDialogFragment, getString(R.string.save_dialog)));
}
}
});
// Set the favorite icon when it changes.
@Override
public void onReceivedIcon(WebView view, Bitmap icon) {
- // Only update the favorite icon if the website has finished loading.
- if (progressBar.getVisibility() == View.GONE) {
+ // Only update the favorite icon if the website has finished loading and the new favorite icon height is greater than the current favorite icon height. This prevents low resolution icons from replacing high resolution one.
+ if ((progressBar.getVisibility() == View.GONE) && (icon.getHeight() > nestedScrollWebView.getFavoriteIconHeight())) {
// Store the new favorite icon.
- nestedScrollWebView.setFavoriteOrDefaultIcon(icon);
+ nestedScrollWebView.setFavoriteIcon(icon);
// Get the current page position.
int currentPosition = webViewPagerAdapter.getPositionForId(nestedScrollWebView.getWebViewFragmentId());
// Get a URI for the current URL.
Uri currentUri = Uri.parse(url);
- // Get the IP addresses for the host.
- new GetHostIpAddresses(activity, getSupportFragmentManager(), nestedScrollWebView).execute(currentUri.getHost());
+ // Get the current domain name.
+ String currentDomainName = currentUri.getHost();
+
+ if ((currentDomainName != null) && !currentDomainName.isEmpty()) {
+ // Get the IP addresses for the current URI.
+ GetHostIpAddressesCoroutine.getAddresses(currentDomainName, nestedScrollWebView, getSupportFragmentManager(), getString(R.string.pinned_mismatch));
+ }
// Replace Refresh with Stop if the options menu has been created. (The first WebView typically begins loading before the menu items are instantiated.)
if (optionsMenu != null) {
sslCertificateErrorDialogFragment.show(getSupportFragmentManager(), getString(R.string.ssl_certificate_error));
} catch (Exception exception) {
// Add the dialog to the pending dialog array list. It will be displayed in `onStart()`.
- pendingDialogsArrayList.add(new PendingDialog(sslCertificateErrorDialogFragment, getString(R.string.ssl_certificate_error)));
+ pendingDialogsArrayList.add(new PendingDialogDataClass(sslCertificateErrorDialogFragment, getString(R.string.ssl_certificate_error)));
}
}
}