// The request items are public static so they can be accessed by `BlockListHelper`, `RequestsArrayAdapter`, and `ViewRequestsDialog`. They are also used in `onCreate()` and `onPrepareOptionsMenu()`.
public static List<String[]> resourceRequests;
public static String[] whiteListResultStringArray;
- int blockedRequests;
- int easyListBlockedRequests;
- int easyPrivacyBlockedRequests;
- int fanboysAnnoyanceListBlockedRequests;
- int fanboysSocialBlockingListBlockedRequests;
- int ultraPrivacyBlockedRequests;
- int thirdPartyBlockedRequests;
+ private int blockedRequests;
+ private int easyListBlockedRequests;
+ private int easyPrivacyBlockedRequests;
+ private int fanboysAnnoyanceListBlockedRequests;
+ private int fanboysSocialBlockingListBlockedRequests;
+ private int ultraPrivacyBlockedRequests;
+ private int thirdPartyBlockedRequests;
public final static int REQUEST_DISPOSITION = 0;
public final static int REQUEST_URL = 1;
private MenuItem fanboysAnnoyanceListMenuItem;
private MenuItem fanboysSocialBlockingListMenuItem;
private MenuItem ultraPrivacyMenuItem;
- private MenuItem blockAllThirdParyRequestsMenuItem;
+ private MenuItem blockAllThirdPartyRequestsMenuItem;
// The blocklist variables are used in `onCreate()`, `onPrepareOptionsMenu()`, `onOptionsItemSelected()`, and `applyAppSettings()`.
private boolean easyListEnabled;
// `ignorePinnedSslCertificateForDomain` is used in `onCreate()`, `onSslMismatchProceed()`, and `applyDomainSettings()`.
private boolean ignorePinnedSslCertificate;
- // `orbotStatusBroadcastReciever` is used in `onCreate()` and `onDestroy()`.
+ // `orbotStatusBroadcastReceiver` is used in `onCreate()` and `onDestroy()`.
private BroadcastReceiver orbotStatusBroadcastReceiver;
// `waitingForOrbot` is used in `onCreate()`, `onResume()`, and `applyAppSettings()`.
// `pinnedDomainSslCertificate` is used in `onCreate()` and `applyDomainSettings()`.
private boolean pinnedDomainSslCertificate;
- // `bookmarksDatabaseHelper` is used in `onCreate()`, `onCreateBookmark()`, `onCreateBookmarkFolder()`, `onSaveEditBookmark()`, `onSaveEditBookmarkFolder()`, and `loadBookmarksFolder()`.
+ // `bookmarksDatabaseHelper` is used in `onCreate()`, `onDestroy`, `onOptionsItemSelected()`, `onCreateBookmark()`, `onCreateBookmarkFolder()`, `onSaveEditBookmark()`, `onSaveEditBookmarkFolder()`,
+ // and `loadBookmarksFolder()`.
private BookmarksDatabaseHelper bookmarksDatabaseHelper;
// `bookmarksListView` is used in `onCreate()`, `onCreateBookmark()`, `onCreateBookmarkFolder()`, and `loadBookmarksFolder()`.
// `bookmarksTitleTextView` is used in `onCreate()` and `loadBookmarksFolder()`.
private TextView bookmarksTitleTextView;
- // `bookmarksCursor` is used in `onCreateBookmark()`, `onCreateBookmarkFolder()`, `onSaveEditBookmark()`, `onSaveEditBookmarkFolder()`, and `loadBookmarksFolder()`.
+ // `bookmarksCursor` is used in `onDestroy()`, `onOptionsItemSelected()`, `onCreateBookmark()`, `onCreateBookmarkFolder()`, `onSaveEditBookmark()`, `onSaveEditBookmarkFolder()`, and `loadBookmarksFolder()`.
private Cursor bookmarksCursor;
// `bookmarksCursorAdapter` is used in `onCreateBookmark()`, `onCreateBookmarkFolder()` `onSaveEditBookmark()`, `onSaveEditBookmarkFolder()`, and `loadBookmarksFolder()`.
// Store the content of the status message in `orbotStatus`.
orbotStatus = intent.getStringExtra("org.torproject.android.intent.extra.STATUS");
- // If we are waiting on Orbot, load the website now that Orbot is connected.
+ // If Privacy Browser is waiting on Orbot, load the website now that Orbot is connected.
if (orbotStatus.equals("ON") && waitingForOrbot) {
// Reset `waitingForOrbot`.
waitingForOrbot = false;
// Show the `BannerAd` in the free flavor.
if (BuildConfig.FLAVOR.contentEquals("free")) {
// Reload the ad. The AdView is destroyed and recreated, which changes the ID, every time it is reloaded to handle possible rotations.
- AdHelper.loadAd(findViewById(R.id.adview), getApplicationContext(), getString(R.string.ad_id));
+ AdHelper.loadAd(findViewById(R.id.adview), getApplicationContext(), getString(R.string.ad_unit_id));
}
// Remove the translucent navigation bar flag if it is set.
mainWebView.evaluateJavascript("(function() {var parent = document.getElementsByTagName('head').item(0); var style = document.createElement('style'); style.type = 'text/css'; " +
"style.innerHTML = '* {background-color: #212121 !important; color: #BDBDBD !important; box-shadow: none !important; text-decoration: none !important;" +
"text-shadow: none !important; border: none !important;} a {color: #1565C0 !important;}'; parent.appendChild(style)})()", value -> {
- // Initialize a `Handler` to display `mainWebView`.
+ // Initialize a handler to display `mainWebView`.
Handler displayWebViewHandler = new Handler();
- // Setup a `Runnable` to display `mainWebView` after a delay to allow the CSS to be applied.
+ // Setup a runnable to display `mainWebView` after a delay to allow the CSS to be applied.
Runnable displayWebViewRunnable = () -> {
// Only display `mainWebView` if the progress bar is one. This prevents the display of the `WebView` while it is still loading.
if (progressBar.getVisibility() == View.GONE) {
}
};
- // Use `displayWebViewHandler` to delay the displaying of `mainWebView` for 500 milliseconds.
+ // Displaying of `mainWebView` after 500 milliseconds.
displayWebViewHandler.postDelayed(displayWebViewRunnable, 500);
});
}
// Show the `BannerAd` in the free flavor.
if (BuildConfig.FLAVOR.contentEquals("free")) {
// Initialize the ad. The AdView is destroyed and recreated, which changes the ID, every time it is reloaded to handle possible rotations.
- AdHelper.initializeAds(findViewById(R.id.adview), getApplicationContext(), getFragmentManager(), getString(R.string.ad_id));
+ AdHelper.initializeAds(findViewById(R.id.adview), getApplicationContext(), getFragmentManager(), getString(R.string.google_app_id), getString(R.string.ad_unit_id));
}
// Remove any `SYSTEM_UI` flags from `rootCoordinatorLayout`.
// Show the ad if this is the free flavor.
if (BuildConfig.FLAVOR.contentEquals("free")) {
// Reload the ad. The AdView is destroyed and recreated, which changes the ID, every time it is reloaded to handle possible rotations.
- AdHelper.loadAd(findViewById(R.id.adview), getApplicationContext(), getString(R.string.ad_id));
+ AdHelper.loadAd(findViewById(R.id.adview), getApplicationContext(), getString(R.string.ad_unit_id));
}
}
// Show a dialog if the user has previously denied the permission.
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) { // Show a dialog explaining the request first.
- // Get a handle for the download location permission alert dialog and set the download type to DOWNLOAD_FILE.
+ // Instantiate the download location permission alert dialog and set the download type to DOWNLOAD_FILE.
DialogFragment downloadLocationPermissionDialogFragment = DownloadLocationPermissionDialog.downloadType(DownloadLocationPermissionDialog.DOWNLOAD_FILE);
// Show the download location permission alert dialog. The permission will be requested when the the dialog is closed.
// Request the permission. The download dialog will be launched by `onRequestPermissionResult()`.
ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE}, DOWNLOAD_FILE_REQUEST_CODE);
}
- } else { // The WRITE_EXTERNAL_STORAGE permission has already been granted.
+ } else { // The storage permission has already been granted.
// Get a handle for the download file alert dialog.
AppCompatDialogFragment downloadFileDialogFragment = DownloadFileDialog.fromUrl(url, contentDisposition, contentLength);
activity.runOnUiThread(() -> {
navigationRequestsMenuItem.setTitle(getString(R.string.requests) + " - " + blockedRequests);
blocklistsMenuItem.setTitle(getString(R.string.requests) + " - " + blockedRequests);
- blockAllThirdParyRequestsMenuItem.setTitle(thirdPartyBlockedRequests + " - " + getString(R.string.block_all_third_party_requests));
+ blockAllThirdPartyRequestsMenuItem.setTitle(thirdPartyBlockedRequests + " - " + getString(R.string.block_all_third_party_requests));
});
// Add the request to the log.
// Add the request to the log because it hasn't been processed by any of the previous checks.
if (whiteListResultStringArray != null ) { // The request was processed by a whitelist.
resourceRequests.add(whiteListResultStringArray);
- } else { // The request didn't match any blocklist entry. Log it as a defult request.
+ } else { // The request didn't match any blocklist entry. Log it as a default request.
resourceRequests.add(new String[]{String.valueOf(REQUEST_DEFAULT), url});
}
// It is necessary to update `formattedUrlString` and `urlTextBox` after the page finishes loading because the final URL can change during load.
@Override
public void onPageFinished(WebView view, String url) {
+ // Reset the wide view port if it has been turned off by the waiting for Orbot message.
+ if (!waitingForOrbot) {
+ mainWebView.getSettings().setUseWideViewPort(true);
+ }
+
// Flush any cookies to persistent storage. `CookieManager` has become very lazy about flushing cookies in recent versions.
if (firstPartyCookiesEnabled && Build.VERSION.SDK_INT >= 21) {
cookieManager.flush();
// Display a message to the user if waiting for Orbot.
if (waitingForOrbot && !orbotStatus.equals("ON")) {
+ // Disable the wide view port so that the waiting for Orbot text is displayed correctly.
+ mainWebView.getSettings().setUseWideViewPort(false);
+
// Load a waiting page. `null` specifies no encoding, which defaults to ASCII.
mainWebView.loadData(waitingForOrbotHTMLString, "text/html", null);
}
// Unregister the Orbot status broadcast receiver.
this.unregisterReceiver(orbotStatusBroadcastReceiver);
+ // Close the bookmarks cursor and database.
+ bookmarksCursor.close();
+ bookmarksDatabaseHelper.close();
+
// Run the default commands.
super.onDestroy();
}
fanboysAnnoyanceListMenuItem = menu.findItem(R.id.fanboys_annoyance_list);
fanboysSocialBlockingListMenuItem = menu.findItem(R.id.fanboys_social_blocking_list);
ultraPrivacyMenuItem = menu.findItem(R.id.ultraprivacy);
- blockAllThirdParyRequestsMenuItem = menu.findItem(R.id.block_all_third_party_requests);
+ blockAllThirdPartyRequestsMenuItem = menu.findItem(R.id.block_all_third_party_requests);
MenuItem adConsentMenuItem = menu.findItem(R.id.ad_consent);
// Only display third-party cookies if API >= 21
fanboysAnnoyanceListMenuItem.setChecked(fanboysAnnoyanceListEnabled);
fanboysSocialBlockingListMenuItem.setChecked(fanboysSocialBlockingListEnabled);
ultraPrivacyMenuItem.setChecked(ultraPrivacyEnabled);
- blockAllThirdParyRequestsMenuItem.setChecked(blockAllThirdPartyRequests);
+ blockAllThirdPartyRequestsMenuItem.setChecked(blockAllThirdPartyRequests);
swipeToRefreshMenuItem.setChecked(swipeRefreshLayout.isEnabled());
displayImagesMenuItem.setChecked(mainWebView.getSettings().getLoadsImagesAutomatically());
nightModeMenuItem.setChecked(nightMode);
fanboysAnnoyanceListMenuItem.setTitle(fanboysAnnoyanceListBlockedRequests + " - " + getString(R.string.fanboys_annoyance_list));
fanboysSocialBlockingListMenuItem.setTitle(fanboysSocialBlockingListBlockedRequests + " - " + getString(R.string.fanboys_social_blocking_list));
ultraPrivacyMenuItem.setTitle(ultraPrivacyBlockedRequests + " - " + getString(R.string.ultraprivacy));
- blockAllThirdParyRequestsMenuItem.setTitle(thirdPartyBlockedRequests + " - " + getString(R.string.block_all_third_party_requests));
+ blockAllThirdPartyRequestsMenuItem.setTitle(thirdPartyBlockedRequests + " - " + getString(R.string.block_all_third_party_requests));
// Get the current user agent.
String currentUserAgent = mainWebView.getSettings().getUserAgentString();
startActivity(settingsIntent);
break;
+ case R.id.import_export:
+ // Launch the import/export activity.
+ Intent importExportIntent = new Intent (this, ImportExportActivity.class);
+ startActivity(importExportIntent);
+ break;
+
case R.id.guide:
// Launch `GuideActivity`.
Intent guideIntent = new Intent(this, GuideActivity.class);
break;
case R.id.clearAndExit:
+ // Close the bookmarks cursor and database.
+ bookmarksCursor.close();
+ bookmarksDatabaseHelper.close();
+
// Get a handle for `sharedPreferences`. `this` references the current context.
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
// Reload the ad for the free flavor if we not in full screen mode.
if (BuildConfig.FLAVOR.contentEquals("free") && !inFullScreenBrowsingMode) {
// Reload the ad. The AdView is destroyed and recreated, which changes the ID, every time it is reloaded to handle possible rotations.
- AdHelper.loadAd(findViewById(R.id.adview), getApplicationContext(), getString(R.string.ad_id));
+ AdHelper.loadAd(findViewById(R.id.adview), getApplicationContext(), getString(R.string.ad_unit_id));
}
// `invalidateOptionsMenu` should recalculate the number of action buttons from the menu to display on the app bar, but it doesn't because of the this bug:
// Show a dialog if the user has previously denied the permission.
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) { // Show a dialog explaining the request first.
- // Get a handle for the download location permission alert dialog and set the download type to DOWNLOAD_FILE.
+ // Instantiate the download location permission alert dialog and set the download type to DOWNLOAD_FILE.
DialogFragment downloadLocationPermissionDialogFragment = DownloadLocationPermissionDialog.downloadType(DownloadLocationPermissionDialog.DOWNLOAD_FILE);
// Show the download location permission alert dialog. The permission will be requested when the the dialog is closed.
// Show a dialog if the user has previously denied the permission.
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) { // Show a dialog explaining the request first.
- // Get a handle for the download location permission alert dialog and set the download type to DOWNLOAD_IMAGE.
+ // Instantiate the download location permission alert dialog and set the download type to DOWNLOAD_IMAGE.
DialogFragment downloadLocationPermissionDialogFragment = DownloadLocationPermissionDialog.downloadType(DownloadLocationPermissionDialog.DOWNLOAD_IMAGE);
// Show the download location permission alert dialog. The permission will be requested when the dialog is closed.
// Show a dialog if the user has previously denied the permission.
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) { // Show a dialog explaining the request first.
- // Get a handle for the download location permission alert dialog and set the download type to DOWNLOAD_IMAGE.
+ // Instantiate the download location permission alert dialog and set the download type to DOWNLOAD_IMAGE.
DialogFragment downloadLocationPermissionDialogFragment = DownloadLocationPermissionDialog.downloadType(DownloadLocationPermissionDialog.DOWNLOAD_IMAGE);
// Show the download location permission alert dialog. The permission will be requested when the dialog is closed.
}
@Override
- public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
+ public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode) {
case DOWNLOAD_FILE_REQUEST_CODE:
// Show the download file alert dialog. When the dialog closes, the correct command will be used based on the permission status.
// Check to see if `unformattedUrlString` is a valid URL. Otherwise, convert it into a search.
if ((Patterns.WEB_URL.matcher(unformattedUrlString).matches()) || (unformattedUrlString.startsWith("http://")) || (unformattedUrlString.startsWith("https://"))) {
- // Add `http://` at the beginning if it is missing. Otherwise the app will segfault.
+ // Add `https://` at the beginning if it is missing. Otherwise the app will segfault.
if (!unformattedUrlString.startsWith("http")) {
- unformattedUrlString = "http://" + unformattedUrlString;
+ unformattedUrlString = "https://" + unformattedUrlString;
}
// Initialize `unformattedUrl`.
// Set `waitingForOrbot`.
waitingForOrbot = true;
+ // Disable the wide view port so that the waiting for Orbot text is displayed correctly.
+ mainWebView.getSettings().setUseWideViewPort(false);
+
// Load a waiting page. `null` specifies no encoding, which defaults to ASCII.
mainWebView.loadData(waitingForOrbotHTMLString, "text/html", null);
}
// Show the `BannerAd` in the free flavor.
if (BuildConfig.FLAVOR.contentEquals("free")) {
// Initialize the ad. The AdView is destroyed and recreated, which changes the ID, every time it is reloaded to handle possible rotations.
- AdHelper.initializeAds(findViewById(R.id.adview), getApplicationContext(), getFragmentManager(), getString(R.string.ad_id));
+ AdHelper.initializeAds(findViewById(R.id.adview), getApplicationContext(), getFragmentManager(), getString(R.string.google_app_id), getString(R.string.ad_unit_id));
}
// Remove any `SYSTEM_UI` flags from `rootCoordinatorLayout`.
urlAppBarRelativeLayout.setBackgroundDrawable(getResources().getDrawable(R.color.transparent));
}
- // Close `domainsDatabaseHelper`.
+ // Close the domains database helper.
domainsDatabaseHelper.close();
// Remove the `onTheFlyDisplayImagesSet` flag and set the display webpage images mode. `true` indicates that custom domain settings are applied.