// `allowScreenshots` is public static so it can be accessed from everywhere. It is also used in `onCreate()`.
public static boolean allowScreenshots;
- // `favoriteIconBitmap` is public static so it can be accessed from `BookmarksActivity`, `BookmarksDatabaseViewActivity`, `CreateBookmarkFolderDialog`,
- // `EditBookmarkDialog`, `EditBookmarkFolderDialog`, `EditBookmarkDatabaseViewDialog`, and `ViewSslCertificateDialog`. It is also used in `onCreate()`, `onCreateBookmark()`, `onCreateBookmarkFolder()`,
- // `onCreateHomeScreenShortcut()`, `onSaveEditBookmark()`, `onSaveEditBookmarkFolder()`, and `applyDomainSettings()`.
- public static Bitmap favoriteIconBitmap;
-
- // `favoriteIconDefaultBitmap` public static so it can be accessed from `PinnedMismatchDialog`. It is also used in `onCreate()` and `applyDomainSettings`.
- public static Bitmap favoriteIconDefaultBitmap;
-
// TODO Remove.
// `formattedUrlString` is public static so it can be accessed from `AddDomainDialog`, `BookmarksActivity`, `DomainSettingsFragment`, and `PinnedMismatchDialog`.
// It is also used in `onCreate()`, `onOptionsItemSelected()`, `onNavigationItemSelected()`, `onCreateHomeScreenShortcutCreate()`, `loadUrlFromTextBox()`, and `applyProxyThroughOrbot()`.
public static String formattedUrlString;
- // TODO. We are going to have to move this to the NestedScrollWebView.
- // The URL loading tracker is public static so it can be accessed from `GetHostIpAddresses`.
- // It is also used in `onCreate()`, `onCreateOptionsMenu()`, `loadUrl()`, `applyDomainSettings()`, and `GetHostIpAddresses`.
- public static boolean urlIsLoading;
-
// `orbotStatus` is public static so it can be accessed from `OrbotProxyHelper`. It is also used in `onCreate()`, `onResume()`, and `applyProxyThroughOrbot()`.
public static String orbotStatus;
- // TODO.
- // `appliedUserAgentString` is public static so it can be accessed from `ViewSourceActivity`. It is also used in `applyDomainSettings()`.
- public static String appliedUserAgentString;
-
// The WebView pager adapter is accessed from `PinnedMismatchDialog`. It is also used in `onCreate()`, `onResume()`, and `addTab()`.
public static WebViewPagerAdapter webViewPagerAdapter;
public static String fanboysSocialVersion;
public static String ultraPrivacyVersion;
- // `blockAllThirdPartyRequests` is public static so it can be accessed from `RequestsActivity`.
- // It is also used in `onCreate()`, `onPrepareOptionsMenu()`, `onOptionsItemSelected()`, and `applyAppSettings()`
- public static boolean blockAllThirdPartyRequests;
-
// `currentBookmarksFolder` is public static so it can be accessed from `BookmarksActivity`. It is also used in `onCreate()`, `onBackPressed()`, `onCreateBookmark()`, `onCreateBookmarkFolder()`,
// `onSaveEditBookmark()`, `onSaveEditBookmarkFolder()`, and `loadBookmarksFolder()`.
public static String currentBookmarksFolder;
// `navigatingHistory` is used in `onCreate()`, `onNavigationItemSelected()`, `onSslMismatchBack()`, and `applyDomainSettings()`.
- private boolean navigatingHistory;
+ private boolean navigatingHistory; // TODO.
// The current WebView is used in `onCreate()`, `onPrepareOptionsMenu()`, `onOptionsItemSelected()`, `onNavigationItemSelected()`, `onRestart()`, `onCreateContextMenu()`, `findPreviousOnPage()`,
// `findNextOnPage()`, `closeFindOnPage()`, `loadUrlFromTextBox()`, `onSslMismatchBack()`, `applyProxyThroughOrbot()`, and `applyDomainSettings()`.
private NestedScrollWebView currentWebView;
- // `fullScreenVideoFrameLayout` is used in `onCreate()` and `onConfigurationChanged()`.
- private FrameLayout fullScreenVideoFrameLayout;
-
- // `cookieManager` is used in `onCreate()`, `onOptionsItemSelected()`, and `onNavigationItemSelected()`, `loadUrlFromTextBox()`, `onDownloadImage()`, `onDownloadFile()`, and `onRestart()`.
- private CookieManager cookieManager;
-
// `customHeader` is used in `onCreate()`, `onOptionsItemSelected()`, `onCreateContextMenu()`, and `loadUrl()`.
private final Map<String, String> customHeaders = new HashMap<>();
- // `javaScriptEnabled` is also used in `onCreate()`, `onPrepareOptionsMenu()`, `onOptionsItemSelected()`, `applyDomainSettings()`, and `updatePrivacyIcons()`.
- private boolean javaScriptEnabled;
-
// `firstPartyCookiesEnabled` is used in `onCreate()`, `onPrepareOptionsMenu()`, `onOptionsItemSelected()`, `onDownloadImage()`, `onDownloadFile()`, and `applyDomainSettings()`.
private boolean firstPartyCookiesEnabled;
- // `thirdPartyCookiesEnabled` used in `onCreate()`, `onPrepareOptionsMenu()`, `onPrepareOptionsMenu()`, `onOptionsItemSelected()`, and `applyDomainSettings()`.
- private boolean thirdPartyCookiesEnabled;
-
- // `domStorageEnabled` is used in `onCreate()`, `onPrepareOptionsMenu()`, `onOptionsItemSelected()`, and `applyDomainSettings()`.
- private boolean domStorageEnabled;
-
// `saveFormDataEnabled` is used in `onCreate()`, `onPrepareOptionsMenu()`, `onOptionsItemSelected()`, and `applyDomainSettings()`. It can be removed once the minimum API >= 26.
private boolean saveFormDataEnabled;
private boolean nightMode;
// 'homepage' is used in `onCreate()`, `onNavigationItemSelected()`, and `applyProxyThroughOrbot()`.
- private String homepage;
+ private String homepage; // TODO ?
// `searchURL` is used in `loadURLFromTextBox()` and `applyProxyThroughOrbot()`.
- private String searchURL;
-
- // `mainMenu` is used in `onCreateOptionsMenu()` and `updatePrivacyIcons()`.
- private Menu mainMenu;
+ private String searchURL; // TODO ?
- // `refreshMenuItem` is used in `onCreate()` and `onCreateOptionsMenu()`.
- private MenuItem refreshMenuItem;
+ // The options menu is set in `onCreateOptionsMenu()` and used in `onOptionsItemSelected()` and `updatePrivacyIcons()`.
+ private Menu optionsMenu;
- // The navigation requests menu item is used in `onCreate()` and accessed from `WebViewPagerAdapter`.
- private MenuItem navigationRequestsMenuItem;
+ // The refresh menu item is set in `onCreateOptionsMenu()` and accessed from `initializeWebView()`.
+ // It must be this way because `initializeWebView()` runs before the menu is created but doesn't actually modify the menu until later.
+ private MenuItem refreshMenuItem; // TODO. Create it from `optionsMenu`.
// TODO. This could probably be removed.
// The blocklist helper is used in `onCreate()` and `WebViewPagerAdapter`.
private ArrayList<List<String[]>> fanboysSocialList;
private ArrayList<List<String[]>> ultraPrivacy;
- // The blocklist menu items are used in `onCreate()`, `onCreateOptionsMenu()`, and `onPrepareOptionsMenu()`.
+ // The blocklist menu items are used in `onCreateOptionsMenu()`, `onPrepareOptionsMenu()`, and `initializeWebView()`. // TODO.
private MenuItem blocklistsMenuItem;
private MenuItem easyListMenuItem;
private MenuItem easyPrivacyMenuItem;
private MenuItem ultraPrivacyMenuItem;
private MenuItem blockAllThirdPartyRequestsMenuItem;
- // The blocklist variables are used in `onCreate()`, `onPrepareOptionsMenu()`, `onOptionsItemSelected()`, and `applyAppSettings()`.
- private boolean easyListEnabled;
- private boolean easyPrivacyEnabled;
- private boolean fanboysAnnoyanceListEnabled;
- private boolean fanboysSocialBlockingListEnabled;
- private boolean ultraPrivacyEnabled;
-
// `webViewDefaultUserAgent` is used in `onCreate()` and `onPrepareOptionsMenu()`.
private String webViewDefaultUserAgent;
- // `defaultCustomUserAgentString` is used in `onPrepareOptionsMenu()` and `applyDomainSettings()`.
- private String defaultCustomUserAgentString;
-
- // `privacyBrowserRuntime` is used in `onCreate()`, `onOptionsItemSelected()`, and `applyAppSettings()`.
- private Runtime privacyBrowserRuntime;
-
// `proxyThroughOrbot` is used in `onRestart()`, `onOptionsItemSelected()`, `applyAppSettings()`, and `applyProxyThroughOrbot()`.
private boolean proxyThroughOrbot;
// `incognitoModeEnabled` is used in `onCreate()` and `applyAppSettings()`.
- private boolean incognitoModeEnabled;
+ private boolean incognitoModeEnabled; // TODO.
// `fullScreenBrowsingModeEnabled` is used in `onCreate()` and `applyAppSettings()`.
- private boolean fullScreenBrowsingModeEnabled;
+ private boolean fullScreenBrowsingModeEnabled; // TODO.
// `inFullScreenBrowsingMode` is used in `onCreate()`, `onConfigurationChanged()`, and `applyAppSettings()`.
private boolean inFullScreenBrowsingMode;
// Hide app bar is used in `onCreate()` and `applyAppSettings()`.
- private boolean hideAppBar;
+ private boolean hideAppBar; // TODO.
// `reapplyDomainSettingsOnRestart` is used in `onCreate()`, `onOptionsItemSelected()`, `onNavigationItemSelected()`, `onRestart()`, and `onAddDomain()`, .
private boolean reapplyDomainSettingsOnRestart;
private boolean displayingFullScreenVideo;
// `downloadWithExternalApp` is used in `onCreate()`, `onCreateContextMenu()`, and `applyDomainSettings()`.
- private boolean downloadWithExternalApp;
-
- // `currentDomainName` is used in `onCreate()`, `onOptionsItemSelected()`, `onNavigationItemSelected()`, `onAddDomain()`, and `applyDomainSettings()`.
- private String currentDomainName;
+ private boolean downloadWithExternalApp; // TODO.
// `orbotStatusBroadcastReceiver` is used in `onCreate()` and `onDestroy()`.
private BroadcastReceiver orbotStatusBroadcastReceiver;
private boolean waitingForOrbot;
// `domainSettingsJavaScriptEnabled` is used in `onOptionsItemSelected()` and `applyDomainSettings()`.
- private Boolean domainSettingsJavaScriptEnabled;
+ private Boolean domainSettingsJavaScriptEnabled; // TODO.
// `waitingForOrbotHtmlString` is used in `onCreate()` and `applyProxyThroughOrbot()`.
- private String waitingForOrbotHtmlString;
+ private String waitingForOrbotHtmlString; // TODO.
// `privateDataDirectoryString` is used in `onCreate()`, `onOptionsItemSelected()`, and `onNavigationItemSelected()`.
- private String privateDataDirectoryString;
+ private String privateDataDirectoryString; // TODO.
// `findOnPageEditText` is used in `onCreate()`, `onOptionsItemSelected()`, and `closeFindOnPage()`.
- private EditText findOnPageEditText;
+ private EditText findOnPageEditText; // TODO.
// `displayAdditionalAppBarIcons` is used in `onCreate()` and `onCreateOptionsMenu()`.
- private boolean displayAdditionalAppBarIcons;
+ private boolean displayAdditionalAppBarIcons; // TODO.
// The action bar drawer toggle is initialized in `onCreate()` and used in `onResume()`.
- private ActionBarDrawerToggle actionBarDrawerToggle;
+ private ActionBarDrawerToggle actionBarDrawerToggle; // TODO.
// The color spans are used in `onCreate()` and `highlightUrlText()`.
private ForegroundColorSpan redColorSpan;
private int drawerHeaderPaddingBottom;
// `sslErrorHandler` is used in `onCreate()`, `onSslErrorCancel()`, and `onSslErrorProceed`.
- private SslErrorHandler sslErrorHandler;
+ private SslErrorHandler sslErrorHandler; // TODO.
// `httpAuthHandler` is used in `onCreate()`, `onHttpAuthenticationCancel()`, and `onHttpAuthenticationProceed()`.
- private static HttpAuthHandler httpAuthHandler;
+ private static HttpAuthHandler httpAuthHandler; // TODO.
// `inputMethodManager` is used in `onOptionsItemSelected()`, `loadUrlFromTextBox()`, and `closeFindOnPage()`.
- private InputMethodManager inputMethodManager;
+ private InputMethodManager inputMethodManager; // TODO.
// `bookmarksDatabaseHelper` is used in `onCreate()`, `onDestroy`, `onOptionsItemSelected()`, `onCreateBookmark()`, `onCreateBookmarkFolder()`, `onSaveEditBookmark()`, `onSaveEditBookmarkFolder()`,
// and `loadBookmarksFolder()`.
- private BookmarksDatabaseHelper bookmarksDatabaseHelper;
+ private BookmarksDatabaseHelper bookmarksDatabaseHelper; // TODO.
// `bookmarksListView` is used in `onCreate()`, `onCreateBookmark()`, `onCreateBookmarkFolder()`, and `loadBookmarksFolder()`.
- private ListView bookmarksListView;
+ private ListView bookmarksListView; // TODO.
// `bookmarksTitleTextView` is used in `onCreate()` and `loadBookmarksFolder()`.
- private TextView bookmarksTitleTextView;
+ private TextView bookmarksTitleTextView; // TODO.
// `bookmarksCursor` is used in `onDestroy()`, `onOptionsItemSelected()`, `onCreateBookmark()`, `onCreateBookmarkFolder()`, `onSaveEditBookmark()`, `onSaveEditBookmarkFolder()`, and `loadBookmarksFolder()`.
private Cursor bookmarksCursor;
private final int DOWNLOAD_IMAGE_REQUEST_CODE = 2;
@Override
- // Remove Android Studio's warning about the dangers of using SetJavaScriptEnabled. The whole premise of Privacy Browser is built around an understanding of these dangers.
- // Also, remove the warning about needing to override `performClick()` when using an `OnTouchListener` with `WebView`.
- @SuppressLint({"SetJavaScriptEnabled", "ClickableViewAccessibility"})
- // Remove Android Studio's warning about deprecations. The deprecated `getColor()` must be used until API >= 23.
- @SuppressWarnings("deprecation")
+ // Remove the warning about needing to override `performClick()` when using an `OnTouchListener` with `WebView`.
+ @SuppressLint("ClickableViewAccessibility")
protected void onCreate(Bundle savedInstanceState) {
// Get a handle for the shared preferences.
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
initialGrayColorSpan = new ForegroundColorSpan(getResources().getColor(R.color.gray_500));
finalGrayColorSpan = new ForegroundColorSpan(getResources().getColor(R.color.gray_500));
- // Get a handle for `urlTextBox`.
+ // Get handles for the URL views.
EditText urlEditText = findViewById(R.id.url_edittext);
// Remove the formatting from `urlTextBar` when the user is editing the text.
// Set `waitingForOrbotHTMLString`.
waitingForOrbotHtmlString = "<html><body><br/><center><h1>" + getString(R.string.waiting_for_orbot) + "</h1></center></body></html>";
- // Initialize `currentDomainName`, `orbotStatus`, and `waitingForOrbot`.
- currentDomainName = "";
+ // Initialize the Orbot status and the waiting for Orbot trackers.
orbotStatus = "unknown";
waitingForOrbot = false;
// Get handles for views that need to be modified.
DrawerLayout drawerLayout = findViewById(R.id.drawerlayout);
- final NavigationView navigationView = findViewById(R.id.navigationview);
+ NavigationView navigationView = findViewById(R.id.navigationview);
TabLayout tabLayout = findViewById(R.id.tablayout);
SwipeRefreshLayout swipeRefreshLayout = findViewById(R.id.swiperefreshlayout);
ViewPager webViewPager = findViewById(R.id.webviewpager);
FloatingActionButton createBookmarkFolderFab = findViewById(R.id.create_bookmark_folder_fab);
FloatingActionButton createBookmarkFab = findViewById(R.id.create_bookmark_fab);
findOnPageEditText = findViewById(R.id.find_on_page_edittext);
- fullScreenVideoFrameLayout = findViewById(R.id.full_screen_video_framelayout);
// Listen for touches on the navigation menu.
navigationView.setNavigationItemSelectedListener(this);
// Get handles for the navigation menu and the back and forward menu items. The menu is zero-based.
- final Menu navigationMenu = navigationView.getMenu();
- final MenuItem navigationCloseTabMenuItem = navigationMenu.getItem(0);
- final MenuItem navigationBackMenuItem = navigationMenu.getItem(3);
- final MenuItem navigationForwardMenuItem = navigationMenu.getItem(4);
- final MenuItem navigationHistoryMenuItem = navigationMenu.getItem(5);
- navigationRequestsMenuItem = navigationMenu.getItem(6);
+ Menu navigationMenu = navigationView.getMenu();
+ MenuItem navigationCloseTabMenuItem = navigationMenu.getItem(0);
+ MenuItem navigationBackMenuItem = navigationMenu.getItem(3);
+ MenuItem navigationForwardMenuItem = navigationMenu.getItem(4);
+ MenuItem navigationHistoryMenuItem = navigationMenu.getItem(5);
+ MenuItem navigationRequestsMenuItem = navigationMenu.getItem(6);
// Initialize the web view pager adapter.
webViewPagerAdapter = new WebViewPagerAdapter(getSupportFragmentManager());
@Override
public void onPageSelected(int position) {
- // Get the WebView tab fragment.
- WebViewTabFragment webViewTabFragment = webViewPagerAdapter.getPageFragment(position);
-
- // Get the fragment view.
- View fragmentView = webViewTabFragment.getView();
-
- // Remove the incorrect lint warning below that the fragment view might be null.
- assert fragmentView != null;
-
- // Store the current WebView.
- currentWebView = fragmentView.findViewById(R.id.nestedscroll_webview);
-
- // Store the current formatted URL string.
- formattedUrlString = currentWebView.getUrl();
-
- // Clear the focus from the URL text box.
- urlEditText.clearFocus();
-
- // Hide the soft keyboard.
- inputMethodManager.hideSoftInputFromWindow(currentWebView.getWindowToken(), 0);
-
- // Display the current URL in the URL text box.
- urlEditText.setText(formattedUrlString);
-
- // Highlight the URL text.
- highlightUrlText();
-
- // Set the background to indicate the domain settings status.
- if (currentWebView.getDomainSettingsApplied()) {
- // Set a green background on `urlTextBox` to indicate that custom domain settings are being used. The deprecated `.getDrawable()` must be used until the minimum API >= 21.
- if (darkTheme) {
- urlEditText.setBackground(getResources().getDrawable(R.drawable.url_bar_background_dark_blue));
- } else {
- urlEditText.setBackground(getResources().getDrawable(R.drawable.url_bar_background_light_green));
- }
- } else {
- urlEditText.setBackgroundDrawable(getResources().getDrawable(R.color.transparent));
- }
+ // Set the current WebView.
+ setCurrentWebView(position);
// Select the corresponding tab if it does not match the currently selected page. This will happen if the page was scrolled via swiping in the view pager.
if (tabLayout.getSelectedTabPosition() != position) {
@Override
public void onTabReselected(TabLayout.Tab tab) {
// Instantiate the View SSL Certificate dialog.
- DialogFragment viewSslCertificateDialogFragment = ViewSslCertificateDialog.displayDialog(currentWebView.getWebViewFragmentId());
+ DialogFragment viewSslCertificateDialogFragment = ViewSslCertificateDialog.displayDialog(currentWebView.getWebViewFragmentId(), currentWebView.getFavoriteOrDefaultIcon());
// Display the View SSL Certificate dialog.
viewSslCertificateDialogFragment.show(getSupportFragmentManager(), getString(R.string.view_ssl_certificate));
}
});
- // Add the first tab. (It doesn't matter what view is passed. That is just required as part of the ImageView `onClick()` syntax).
- addTab(webViewPager);
+ // Add the first tab.
+ addTab(null);
// Set the bookmarks drawer resources according to the theme. This can't be done in the layout due to compatibility issues with the `DrawerLayout` support widget.
// The deprecated `getResources().getDrawable()` must be used until the minimum API >= 21 and and `getResources().getColor()` must be used until the minimum API >= 23.
// Set the launch bookmarks activity FAB to launch the bookmarks activity.
launchBookmarksActivityFab.setOnClickListener(v -> {
- // Store the current WebView url and title in the bookmarks activity.
+ // Store the current WebView url and title in the bookmarks activity. // TODO.
BookmarksActivity.currentWebViewUrl = currentWebView.getUrl();
BookmarksActivity.currentWebViewTitle = currentWebView.getTitle();
+ // Get a copy of the favorite icon bitmap.
+ Bitmap favoriteIconBitmap = currentWebView.getFavoriteOrDefaultIcon();
+
+ // Create a favorite icon byte array output stream.
+ ByteArrayOutputStream favoriteIconByteArrayOutputStream = new ByteArrayOutputStream();
+
+ // Convert the favorite icon bitmap to a byte array. `0` is for lossless compression (the only option for a PNG).
+ favoriteIconBitmap.compress(Bitmap.CompressFormat.PNG, 0, favoriteIconByteArrayOutputStream);
+
+ // Convert the favorite icon byte array stream to a byte array.
+ byte[] favoriteIconByteArray = favoriteIconByteArrayOutputStream.toByteArray();
+
// Create an intent to launch the bookmarks activity.
Intent bookmarksIntent = new Intent(getApplicationContext(), BookmarksActivity.class);
- // Include the current folder with the `Intent`.
- bookmarksIntent.putExtra("Current Folder", currentBookmarksFolder);
+ // Add the extra information to the intent.
+ bookmarksIntent.putExtra("current_folder", currentBookmarksFolder);
+ bookmarksIntent.putExtra("favorite_icon_byte_array", favoriteIconByteArray);
// Make it so.
startActivity(bookmarksIntent);
// Set the create new bookmark folder FAB to display an alert dialog.
createBookmarkFolderFab.setOnClickListener(v -> {
- // Show the create bookmark folder dialog and name the instance `@string/create_folder`.
- DialogFragment createBookmarkFolderDialog = new CreateBookmarkFolderDialog();
+ // Create a create bookmark folder dialog.
+ DialogFragment createBookmarkFolderDialog = CreateBookmarkFolderDialog.createBookmarkFolder(currentWebView.getFavoriteOrDefaultIcon());
+
+ // 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(), favoriteIconBitmap);
+ DialogFragment createBookmarkDialog = CreateBookmarkDialog.createBookmark(currentWebView.getUrl(), currentWebView.getTitle(), currentWebView.getFavoriteOrDefaultIcon());
// Display the create bookmark dialog.
createBookmarkDialog.show(getSupportFragmentManager(), getString(R.string.create_bookmark));
oldFolderNameString = bookmarksCursor.getString(bookmarksCursor.getColumnIndex(BookmarksDatabaseHelper.BOOKMARK_NAME));
// Show the edit bookmark folder `AlertDialog` and name the instance `@string/edit_folder`.
- DialogFragment editBookmarkFolderDialog = EditBookmarkFolderDialog.folderDatabaseId(databaseId);
+ DialogFragment editBookmarkFolderDialog = EditBookmarkFolderDialog.folderDatabaseId(databaseId, currentWebView.getFavoriteOrDefaultIcon());
editBookmarkFolderDialog.show(getSupportFragmentManager(), getString(R.string.edit_folder));
} else {
// Show the edit bookmark `AlertDialog` and name the instance `@string/edit_bookmark`.
- DialogFragment editBookmarkDialog = EditBookmarkDialog.bookmarkDatabaseId(databaseId);
+ DialogFragment editBookmarkDialog = EditBookmarkDialog.bookmarkDatabaseId(databaseId, currentWebView.getFavoriteOrDefaultIcon());
editBookmarkDialog.show(getSupportFragmentManager(), getString(R.string.edit_bookmark));
}
// Create the hamburger icon at the start of the AppBar.
actionBarDrawerToggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar, R.string.open_navigation_drawer, R.string.close_navigation_drawer);
- // Initialize cookieManager.
- cookieManager = CookieManager.getInstance();
-
// Replace the header that `WebView` creates for `X-Requested-With` with a null value. The default value is the application ID (com.stoutner.privacybrowser.standard).
customHeaders.put("X-Requested-With", "");
// Initialize the default preference values the first time the program is run. `false` keeps this command from resetting any current preferences back to default.
PreferenceManager.setDefaultValues(this, R.xml.preferences, false);
- // Get a handle for the `Runtime`.
- privacyBrowserRuntime = Runtime.getRuntime();
-
// Store the application's private data directory.
privateDataDirectoryString = getApplicationInfo().dataDir;
// `dataDir` will vary, but will be something like `/data/user/0/com.stoutner.privacybrowser.standard`, which links to `/data/data/com.stoutner.privacybrowser.standard`.
inFullScreenBrowsingMode = false;
// Initialize the privacy settings variables.
- javaScriptEnabled = false;
firstPartyCookiesEnabled = false;
- thirdPartyCookiesEnabled = false;
- domStorageEnabled = false;
saveFormDataEnabled = false; // Form data can be removed once the minimum API >= 26.
nightMode = false;
// Destroy the bare WebView.
bareWebView.destroy();
- // Initialize the favorite icon bitmap. `ContextCompat` must be used until API >= 21.
- Drawable favoriteIconDrawable = ContextCompat.getDrawable(getApplicationContext(), R.drawable.world);
- BitmapDrawable favoriteIconBitmapDrawable = (BitmapDrawable) favoriteIconDrawable;
- assert favoriteIconBitmapDrawable != null;
- favoriteIconDefaultBitmap = favoriteIconBitmapDrawable.getBitmap();
-
- // If the favorite icon is null, load the default.
- if (favoriteIconBitmap == null) {
- favoriteIconBitmap = favoriteIconDefaultBitmap;
- }
-
// Initialize the user agent array adapter and string array.
userAgentNamesArray = ArrayAdapter.createFromResource(this, R.array.user_agent_names, R.layout.spinner_item);
userAgentDataArray = getResources().getStringArray(R.array.user_agent_data);
@Override
protected void onNewIntent(Intent intent) {
- // Sets the new intent as the activity intent, so that any future `getIntent()`s pick up this one instead of creating a new activity.
- setIntent(intent);
-
// Get the information from the intent.
String intentAction = intent.getAction();
Uri intentUriData = intent.getData();
- // If the intent action is a web search, perform the search.
- if ((intentAction != null) && intentAction.equals(Intent.ACTION_WEB_SEARCH)) {
- // Create an encoded URL string.
- String encodedUrlString;
+ // Only process the URI if it contains data. If the user pressed the desktop icon after the app was already running the URI will be null.
+ if (intentUriData != null) {
+ // Sets the new intent as the activity intent, which replaces the one that originally started the app.
+ setIntent(intent);
- // Sanitize the search input and convert it to a search.
- try {
- encodedUrlString = URLEncoder.encode(intent.getStringExtra(SearchManager.QUERY), "UTF-8");
- } catch (UnsupportedEncodingException exception) {
- encodedUrlString = "";
+ // Add a new tab.
+ addTab(null);
+
+ // If the intent action is a web search, perform the search.
+ if ((intentAction != null) && intentAction.equals(Intent.ACTION_WEB_SEARCH)) {
+ // Create an encoded URL string.
+ String encodedUrlString;
+
+ // Sanitize the search input and convert it to a search.
+ try {
+ encodedUrlString = URLEncoder.encode(intent.getStringExtra(SearchManager.QUERY), "UTF-8");
+ } catch (UnsupportedEncodingException exception) {
+ encodedUrlString = "";
+ }
+
+ // Add the base search URL.
+ formattedUrlString = searchURL + encodedUrlString;
+ } else { // The intent should contain a URL.
+ // Set the formatted URL string.
+ formattedUrlString = intentUriData.toString();
}
- // Add the base search URL.
- formattedUrlString = searchURL + encodedUrlString;
- } else if (intentUriData != null){ // Check to see if the intent contains a new URL.
- // Set the formatted URL string.
- formattedUrlString = intentUriData.toString();
- }
+ // Load the URL.
+ loadUrl(formattedUrlString);
- // Load the URL.
- loadUrl(formattedUrlString);
+ // Get a handle for the drawer layout.
+ DrawerLayout drawerLayout = findViewById(R.id.drawerlayout);
- // Get a handle for the drawer layout.
- DrawerLayout drawerLayout = findViewById(R.id.drawerlayout);
+ // Close the navigation drawer if it is open.
+ if (drawerLayout.isDrawerVisible(GravityCompat.START)) {
+ drawerLayout.closeDrawer(GravityCompat.START);
+ }
- // Close the navigation drawer if it is open.
- if (drawerLayout.isDrawerVisible(GravityCompat.START)) {
- drawerLayout.closeDrawer(GravityCompat.START);
- }
+ // Close the bookmarks drawer if it is open.
+ if (drawerLayout.isDrawerVisible(GravityCompat.END)) {
+ drawerLayout.closeDrawer(GravityCompat.END);
+ }
- // Close the bookmarks drawer if it is open.
- if (drawerLayout.isDrawerVisible(GravityCompat.END)) {
- drawerLayout.closeDrawer(GravityCompat.END);
+ // Clear the keyboard if displayed and remove the focus on the urlTextBar if it has it.
+ currentWebView.requestFocus();
}
-
- // Clear the keyboard if displayed and remove the focus on the urlTextBar if it has it.
- currentWebView.requestFocus();
}
@Override
// Inflate the menu. This adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.webview_options_menu, menu);
- // Set mainMenu so it can be used by `onOptionsItemSelected()` and `updatePrivacyIcons`.
- mainMenu = menu;
+ // Store a handle for the options menu so it can be used by `onOptionsItemSelected()` and `updatePrivacyIcons`.
+ optionsMenu = menu;
// Set the initial status of the privacy icons. `false` does not call `invalidateOptionsMenu` as the last step.
updatePrivacyIcons(false);
}
// Replace Refresh with Stop if a URL is already loading.
- if (urlIsLoading) {
+ if (currentWebView != null && currentWebView.getProgress() != 100) {
// Set the title.
refreshMenuItem.setTitle(R.string.stop);
MenuItem nightModeMenuItem = menu.findItem(R.id.night_mode);
MenuItem proxyThroughOrbotMenuItem = menu.findItem(R.id.proxy_through_orbot);
+ // Get a handle for the cookie manager.
+ CookieManager cookieManager = CookieManager.getInstance();
+
// Initialize the current user agent string and the font size.
String currentUserAgent = getString(R.string.user_agent_privacy_browser);
int fontSize = 100;
// Get the current font size from the
fontSize = currentWebView.getSettings().getTextZoom();
- // Set the status of the display images menu item.
+ // Set the status of the menu item checkboxes.
+ toggleDomStorageMenuItem.setChecked(currentWebView.getSettings().getDomStorageEnabled());
+ easyListMenuItem.setChecked(currentWebView.isBlocklistEnabled(NestedScrollWebView.EASY_LIST));
+ easyPrivacyMenuItem.setChecked(currentWebView.isBlocklistEnabled(NestedScrollWebView.EASY_PRIVACY));
+ fanboysAnnoyanceListMenuItem.setChecked(currentWebView.isBlocklistEnabled(NestedScrollWebView.FANBOYS_ANNOYANCE_LIST));
+ fanboysSocialBlockingListMenuItem.setChecked(currentWebView.isBlocklistEnabled(NestedScrollWebView.FANBOYS_SOCIAL_BLOCKING_LIST));
+ ultraPrivacyMenuItem.setChecked(currentWebView.isBlocklistEnabled(NestedScrollWebView.ULTRA_PRIVACY));
+ blockAllThirdPartyRequestsMenuItem.setChecked(currentWebView.isBlocklistEnabled(NestedScrollWebView.THIRD_PARTY_REQUESTS));
displayImagesMenuItem.setChecked(currentWebView.getSettings().getLoadsImagesAutomatically());
// Initialize the display names for the blocklists with the number of blocked requests.
blocklistsMenuItem.setTitle(getString(R.string.blocklists) + " - " + currentWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS));
- easyListMenuItem.setTitle(currentWebView.getRequestsCount(NestedScrollWebView.EASY_LIST_BLOCKED_REQUESTS) + " - " + getString(R.string.easylist));
- easyPrivacyMenuItem.setTitle(currentWebView.getRequestsCount(NestedScrollWebView.EASY_PRIVACY_BLOCKED_REQUESTS) + " - " + getString(R.string.easyprivacy));
- fanboysAnnoyanceListMenuItem.setTitle(currentWebView.getRequestsCount(NestedScrollWebView.FANBOYS_ANNOYANCE_LIST_BLOCKED_REQUESTS) + " - " + getString(R.string.fanboys_annoyance_list));
- fanboysSocialBlockingListMenuItem.setTitle(currentWebView.getRequestsCount(NestedScrollWebView.FANBOYS_SOCIAL_BLOCKING_LIST_BLOCKED_REQUESTS) + " - " +
- getString(R.string.fanboys_social_blocking_list));
- ultraPrivacyMenuItem.setTitle(currentWebView.getRequestsCount(NestedScrollWebView.ULTRA_PRIVACY_BLOCKED_REQUESTS) + " - " + getString(R.string.ultraprivacy));
- blockAllThirdPartyRequestsMenuItem.setTitle(currentWebView.getRequestsCount(NestedScrollWebView.THIRD_PARTY_BLOCKED_REQUESTS) + " - " + getString(R.string.block_all_third_party_requests));
+ easyListMenuItem.setTitle(currentWebView.getRequestsCount(NestedScrollWebView.EASY_LIST) + " - " + getString(R.string.easylist));
+ easyPrivacyMenuItem.setTitle(currentWebView.getRequestsCount(NestedScrollWebView.EASY_PRIVACY) + " - " + getString(R.string.easyprivacy));
+ fanboysAnnoyanceListMenuItem.setTitle(currentWebView.getRequestsCount(NestedScrollWebView.FANBOYS_ANNOYANCE_LIST) + " - " + getString(R.string.fanboys_annoyance_list));
+ fanboysSocialBlockingListMenuItem.setTitle(currentWebView.getRequestsCount(NestedScrollWebView.FANBOYS_SOCIAL_BLOCKING_LIST) + " - " + getString(R.string.fanboys_social_blocking_list));
+ ultraPrivacyMenuItem.setTitle(currentWebView.getRequestsCount(NestedScrollWebView.ULTRA_PRIVACY) + " - " + getString(R.string.ultraprivacy));
+ blockAllThirdPartyRequestsMenuItem.setTitle(currentWebView.getRequestsCount(NestedScrollWebView.THIRD_PARTY_REQUESTS) + " - " + getString(R.string.block_all_third_party_requests));
}
// Set the status of the menu item checkboxes.
toggleFirstPartyCookiesMenuItem.setChecked(firstPartyCookiesEnabled);
- toggleThirdPartyCookiesMenuItem.setChecked(thirdPartyCookiesEnabled);
- toggleDomStorageMenuItem.setChecked(domStorageEnabled);
toggleSaveFormDataMenuItem.setChecked(saveFormDataEnabled); // Form data can be removed once the minimum API >= 26.
- easyListMenuItem.setChecked(easyListEnabled);
- easyPrivacyMenuItem.setChecked(easyPrivacyEnabled);
- fanboysAnnoyanceListMenuItem.setChecked(fanboysAnnoyanceListEnabled);
- fanboysSocialBlockingListMenuItem.setChecked(fanboysSocialBlockingListEnabled);
- ultraPrivacyMenuItem.setChecked(ultraPrivacyEnabled);
- blockAllThirdPartyRequestsMenuItem.setChecked(blockAllThirdPartyRequests);
swipeToRefreshMenuItem.setChecked(swipeRefreshLayout.isEnabled());
nightModeMenuItem.setChecked(nightMode);
proxyThroughOrbotMenuItem.setChecked(proxyThroughOrbot);
- // Enable third-party cookies if first-party cookies are enabled.
- toggleThirdPartyCookiesMenuItem.setEnabled(firstPartyCookiesEnabled);
+ // Only modify third-party cookies if the API >= 21.
+ if (Build.VERSION.SDK_INT >= 21) {
+ // Set the status of the third-party cookies checkbox.
+ toggleThirdPartyCookiesMenuItem.setChecked(cookieManager.acceptThirdPartyCookies(currentWebView));
+
+ // Enable third-party cookies if first-party cookies are enabled.
+ toggleThirdPartyCookiesMenuItem.setEnabled(firstPartyCookiesEnabled);
+ }
// Enable DOM Storage if JavaScript is enabled.
- toggleDomStorageMenuItem.setEnabled(javaScriptEnabled);
+ toggleDomStorageMenuItem.setEnabled(currentWebView.getSettings().getJavaScriptEnabled());
// Enable Clear Cookies if there are any.
clearCookiesMenuItem.setEnabled(cookieManager.hasCookies());
// Enable Clear Data if any of the submenu items are enabled.
clearDataMenuItem.setEnabled(clearCookiesMenuItem.isEnabled() || clearDOMStorageMenuItem.isEnabled() || clearFormDataMenuItem.isEnabled());
- // Disable Fanboy's Social Blocking List if Fanboy's Annoyance List is checked.
- fanboysSocialBlockingListMenuItem.setEnabled(!fanboysAnnoyanceListEnabled);
+ // Disable Fanboy's Social Blocking List menu item if Fanboy's Annoyance List is checked.
+ fanboysSocialBlockingListMenuItem.setEnabled(!fanboysAnnoyanceListMenuItem.isChecked());
// Select the current user agent menu item. A switch statement cannot be used because the user agents are not compile time constants.
if (currentUserAgent.equals(getResources().getStringArray(R.array.user_agent_data)[0])) { // Privacy Browser.
// Get the selected menu item ID.
int menuItemId = menuItem.getItemId();
+ // Get a handle for the shared preferences.
+ SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
+
+ // Get a handle for the cookie manager.
+ CookieManager cookieManager = CookieManager.getInstance();
+
// Run the commands that correlate to the selected menu item.
switch (menuItemId) {
case R.id.toggle_javascript:
- // Switch the status of javaScriptEnabled.
- javaScriptEnabled = !javaScriptEnabled;
-
- // Apply the new JavaScript status.
- currentWebView.getSettings().setJavaScriptEnabled(javaScriptEnabled);
+ // Toggle the JavaScript status.
+ currentWebView.getSettings().setJavaScriptEnabled(!currentWebView.getSettings().getJavaScriptEnabled());
// Update the privacy icon. `true` runs `invalidateOptionsMenu` as the last step.
updatePrivacyIcons(true);
// Display a `Snackbar`.
- if (javaScriptEnabled) { // JavaScrip is enabled.
+ if (currentWebView.getSettings().getJavaScriptEnabled()) { // JavaScrip is enabled.
Snackbar.make(findViewById(R.id.webviewpager), R.string.javascript_enabled, Snackbar.LENGTH_SHORT).show();
} else if (firstPartyCookiesEnabled) { // JavaScript is disabled, but first-party cookies are enabled.
Snackbar.make(findViewById(R.id.webviewpager), R.string.javascript_disabled, Snackbar.LENGTH_SHORT).show();
if (currentWebView.getDomainSettingsApplied()) { // Edit the current domain settings.
// Reapply the domain settings on returning to `MainWebViewActivity`.
reapplyDomainSettingsOnRestart = true;
- currentDomainName = "";
+ currentWebView.resetCurrentDomainName();
// TODO. Move these to `putExtra`. The certificate can be stored as strings.
// Store the current SSL certificate and IP addresses in the domains activity.
Intent domainsIntent = new Intent(this, DomainsActivity.class);
// Put extra information instructing the domains activity to directly load the current domain and close on back instead of returning to the domains list.
- domainsIntent.putExtra("loadDomain", currentWebView.getDomainSettingsDatabaseId());
- domainsIntent.putExtra("closeOnBack", true);
+ domainsIntent.putExtra("load_domain", currentWebView.getDomainSettingsDatabaseId());
+ domainsIntent.putExtra("close_on_back", true);
// Make it so.
startActivity(domainsIntent);
} else { // Add a new domain.
// Apply the new domain settings on returning to `MainWebViewActivity`.
reapplyDomainSettingsOnRestart = true;
- currentDomainName = "";
+ currentWebView.resetCurrentDomainName();
// Get the current domain
Uri currentUri = Uri.parse(formattedUrlString);
Intent domainsIntent = new Intent(this, DomainsActivity.class);
// Put extra information instructing the domains activity to directly load the new domain and close on back instead of returning to the domains list.
- domainsIntent.putExtra("loadDomain", newDomainDatabaseId);
- domainsIntent.putExtra("closeOnBack", true);
+ domainsIntent.putExtra("load_domain", newDomainDatabaseId);
+ domainsIntent.putExtra("close_on_back", true);
// Make it so.
startActivity(domainsIntent);
// Display a `Snackbar`.
if (firstPartyCookiesEnabled) { // First-party cookies are enabled.
Snackbar.make(findViewById(R.id.webviewpager), R.string.first_party_cookies_enabled, Snackbar.LENGTH_SHORT).show();
- } else if (javaScriptEnabled) { // JavaScript is still enabled.
+ } else if (currentWebView.getSettings().getJavaScriptEnabled()) { // JavaScript is still enabled.
Snackbar.make(findViewById(R.id.webviewpager), R.string.first_party_cookies_disabled, Snackbar.LENGTH_SHORT).show();
} else { // Privacy mode.
Snackbar.make(findViewById(R.id.webviewpager), R.string.privacy_mode, Snackbar.LENGTH_SHORT).show();
case R.id.toggle_third_party_cookies:
if (Build.VERSION.SDK_INT >= 21) {
// Switch the status of thirdPartyCookiesEnabled.
- thirdPartyCookiesEnabled = !thirdPartyCookiesEnabled;
+ cookieManager.setAcceptThirdPartyCookies(currentWebView, !cookieManager.acceptThirdPartyCookies(currentWebView));
// Update the menu checkbox.
- menuItem.setChecked(thirdPartyCookiesEnabled);
-
- // Apply the new cookie status.
- cookieManager.setAcceptThirdPartyCookies(currentWebView, thirdPartyCookiesEnabled);
+ menuItem.setChecked(cookieManager.acceptThirdPartyCookies(currentWebView));
- // Display a `Snackbar`.
- if (thirdPartyCookiesEnabled) {
+ // Display a snackbar.
+ if (cookieManager.acceptThirdPartyCookies(currentWebView)) {
Snackbar.make(findViewById(R.id.webviewpager), R.string.third_party_cookies_enabled, Snackbar.LENGTH_SHORT).show();
} else {
Snackbar.make(findViewById(R.id.webviewpager), R.string.third_party_cookies_disabled, Snackbar.LENGTH_SHORT).show();
return true;
case R.id.toggle_dom_storage:
- // Switch the status of domStorageEnabled.
- domStorageEnabled = !domStorageEnabled;
+ // Toggle the status of domStorageEnabled.
+ currentWebView.getSettings().setDomStorageEnabled(!currentWebView.getSettings().getDomStorageEnabled());
// Update the menu checkbox.
- menuItem.setChecked(domStorageEnabled);
-
- // Apply the new DOM Storage status.
- currentWebView.getSettings().setDomStorageEnabled(domStorageEnabled);
+ menuItem.setChecked(currentWebView.getSettings().getDomStorageEnabled());
- // Update the privacy icon. `true` runs `invalidateOptionsMenu` as the last step.
+ // Update the privacy icon. `true` refreshes the app bar icons.
updatePrivacyIcons(true);
- // Display a `Snackbar`.
- if (domStorageEnabled) {
+ // Display a snackbar.
+ if (currentWebView.getSettings().getDomStorageEnabled()) {
Snackbar.make(findViewById(R.id.webviewpager), R.string.dom_storage_enabled, Snackbar.LENGTH_SHORT).show();
} else {
Snackbar.make(findViewById(R.id.webviewpager), R.string.dom_storage_disabled, Snackbar.LENGTH_SHORT).show();
// Setup a runnable to manually delete the DOM storage files and directories.
Runnable deleteDomStorageRunnable = () -> {
try {
+ // Get a handle for the runtime.
+ Runtime runtime = Runtime.getRuntime();
+
// A string array must be used because the directory contains a space and `Runtime.exec` will otherwise not escape the string correctly.
- Process deleteLocalStorageProcess = privacyBrowserRuntime.exec(new String[]{"rm", "-rf", privateDataDirectoryString + "/app_webview/Local Storage/"});
+ Process deleteLocalStorageProcess = runtime.exec(new String[]{"rm", "-rf", privateDataDirectoryString + "/app_webview/Local Storage/"});
// Multiple commands must be used because `Runtime.exec()` does not like `*`.
- Process deleteIndexProcess = privacyBrowserRuntime.exec("rm -rf " + privateDataDirectoryString + "/app_webview/IndexedDB");
- Process deleteQuotaManagerProcess = privacyBrowserRuntime.exec("rm -f " + privateDataDirectoryString + "/app_webview/QuotaManager");
- Process deleteQuotaManagerJournalProcess = privacyBrowserRuntime.exec("rm -f " + privateDataDirectoryString + "/app_webview/QuotaManager-journal");
- Process deleteDatabasesProcess = privacyBrowserRuntime.exec("rm -rf " + privateDataDirectoryString + "/app_webview/databases");
+ Process deleteIndexProcess = runtime.exec("rm -rf " + privateDataDirectoryString + "/app_webview/IndexedDB");
+ Process deleteQuotaManagerProcess = runtime.exec("rm -f " + privateDataDirectoryString + "/app_webview/QuotaManager");
+ Process deleteQuotaManagerJournalProcess = runtime.exec("rm -f " + privateDataDirectoryString + "/app_webview/QuotaManager-journal");
+ Process deleteDatabasesProcess = runtime.exec("rm -rf " + privateDataDirectoryString + "/app_webview/databases");
// Wait for the processes to finish.
deleteLocalStorageProcess.waitFor();
case R.id.easylist:
// Toggle the EasyList status.
- easyListEnabled = !easyListEnabled;
+ currentWebView.enableBlocklist(NestedScrollWebView.EASY_LIST, !currentWebView.isBlocklistEnabled(NestedScrollWebView.EASY_LIST));
// Update the menu checkbox.
- menuItem.setChecked(easyListEnabled);
+ menuItem.setChecked(currentWebView.isBlocklistEnabled(NestedScrollWebView.EASY_LIST));
// Reload the current WebView.
currentWebView.reload();
case R.id.easyprivacy:
// Toggle the EasyPrivacy status.
- easyPrivacyEnabled = !easyPrivacyEnabled;
+ currentWebView.enableBlocklist(NestedScrollWebView.EASY_PRIVACY, !currentWebView.isBlocklistEnabled(NestedScrollWebView.EASY_PRIVACY));
// Update the menu checkbox.
- menuItem.setChecked(easyPrivacyEnabled);
+ menuItem.setChecked(currentWebView.isBlocklistEnabled(NestedScrollWebView.EASY_PRIVACY));
// Reload the current WebView.
currentWebView.reload();
case R.id.fanboys_annoyance_list:
// Toggle Fanboy's Annoyance List status.
- fanboysAnnoyanceListEnabled = !fanboysAnnoyanceListEnabled;
+ currentWebView.enableBlocklist(NestedScrollWebView.FANBOYS_ANNOYANCE_LIST, !currentWebView.isBlocklistEnabled(NestedScrollWebView.FANBOYS_ANNOYANCE_LIST));
// Update the menu checkbox.
- menuItem.setChecked(fanboysAnnoyanceListEnabled);
+ menuItem.setChecked(currentWebView.isBlocklistEnabled(NestedScrollWebView.FANBOYS_ANNOYANCE_LIST));
// Update the staus of Fanboy's Social Blocking List.
- MenuItem fanboysSocialBlockingListMenuItem = mainMenu.findItem(R.id.fanboys_social_blocking_list);
- fanboysSocialBlockingListMenuItem.setEnabled(!fanboysAnnoyanceListEnabled);
+ MenuItem fanboysSocialBlockingListMenuItem = optionsMenu.findItem(R.id.fanboys_social_blocking_list);
+ fanboysSocialBlockingListMenuItem.setEnabled(!currentWebView.isBlocklistEnabled(NestedScrollWebView.FANBOYS_ANNOYANCE_LIST));
// Reload the current WebView.
currentWebView.reload();
case R.id.fanboys_social_blocking_list:
// Toggle Fanboy's Social Blocking List status.
- fanboysSocialBlockingListEnabled = !fanboysSocialBlockingListEnabled;
+ currentWebView.enableBlocklist(NestedScrollWebView.FANBOYS_SOCIAL_BLOCKING_LIST, !currentWebView.isBlocklistEnabled(NestedScrollWebView.FANBOYS_SOCIAL_BLOCKING_LIST));
// Update the menu checkbox.
- menuItem.setChecked(fanboysSocialBlockingListEnabled);
+ menuItem.setChecked(currentWebView.isBlocklistEnabled(NestedScrollWebView.FANBOYS_SOCIAL_BLOCKING_LIST));
// Reload the current WebView.
currentWebView.reload();
case R.id.ultraprivacy:
// Toggle the UltraPrivacy status.
- ultraPrivacyEnabled = !ultraPrivacyEnabled;
+ currentWebView.enableBlocklist(NestedScrollWebView.ULTRA_PRIVACY, !currentWebView.isBlocklistEnabled(NestedScrollWebView.ULTRA_PRIVACY));
// Update the menu checkbox.
- menuItem.setChecked(ultraPrivacyEnabled);
+ menuItem.setChecked(currentWebView.isBlocklistEnabled(NestedScrollWebView.ULTRA_PRIVACY));
// Reload the current WebView.
currentWebView.reload();
case R.id.block_all_third_party_requests:
//Toggle the third-party requests blocker status.
- blockAllThirdPartyRequests = !blockAllThirdPartyRequests;
+ currentWebView.enableBlocklist(NestedScrollWebView.THIRD_PARTY_REQUESTS, !currentWebView.isBlocklistEnabled(NestedScrollWebView.THIRD_PARTY_REQUESTS));
// Update the menu checkbox.
- menuItem.setChecked(blockAllThirdPartyRequests);
+ menuItem.setChecked(currentWebView.isBlocklistEnabled(NestedScrollWebView.THIRD_PARTY_REQUESTS));
// Reload the current WebView.
currentWebView.reload();
case R.id.user_agent_custom:
// Update the user agent.
- currentWebView.getSettings().setUserAgentString(defaultCustomUserAgentString);
+ currentWebView.getSettings().setUserAgentString(sharedPreferences.getString("custom_user_agent", getString(R.string.custom_user_agent_default_value)));
// Reload the current WebView.
currentWebView.reload();
nightMode = !nightMode;
// Enable or disable JavaScript according to night mode, the global preference, and any domain settings.
- if (nightMode) { // Night mode is enabled. Enable JavaScript.
- // Update the global variable.
- javaScriptEnabled = true;
+ if (nightMode) { // Night mode is enabled, which requires JavaScript.
+ // Enable JavaScript.
+ currentWebView.getSettings().setJavaScriptEnabled(true);
} else if (currentWebView.getDomainSettingsApplied()) { // Night mode is disabled and domain settings are applied. Set JavaScript according to the domain settings.
- // Get the JavaScript preference that was stored the last time domain settings were loaded.
- javaScriptEnabled = domainSettingsJavaScriptEnabled;
+ // Apply the JavaScript preference that was stored the last time domain settings were loaded.
+ currentWebView.getSettings().setJavaScriptEnabled(domainSettingsJavaScriptEnabled);
} else { // Night mode is disabled and domain settings are not applied. Set JavaScript according to the global preference.
- // Get a handle for the shared preference.
- SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
-
- // Get the JavaScript preference.
- javaScriptEnabled = sharedPreferences.getBoolean("javascript", false);
+ // Apply the JavaScript preference.
+ currentWebView.getSettings().setJavaScriptEnabled(sharedPreferences.getBoolean("javascript", false));
}
- // Apply the JavaScript setting to the WebView.
- currentWebView.getSettings().setJavaScriptEnabled(javaScriptEnabled);
-
// Update the privacy icons.
updatePrivacyIcons(false);
return true;
case R.id.view_source:
- // Launch the View Source activity.
+ // Create an intent to launch the view source activity.
Intent viewSourceIntent = new Intent(this, ViewSourceActivity.class);
+
+ // Add the user agent as an extra to the intent.
+ viewSourceIntent.putExtra("user_agent", currentWebView.getSettings().getUserAgentString());
+
+ // Make it so.
startActivity(viewSourceIntent);
return true;
case R.id.add_to_homescreen:
// Instantiate the create home screen shortcut dialog.
- DialogFragment createHomeScreenShortcutDialogFragment = CreateHomeScreenShortcutDialog.createDialog(currentWebView.getTitle(), formattedUrlString, favoriteIconBitmap);
+ DialogFragment createHomeScreenShortcutDialogFragment = CreateHomeScreenShortcutDialog.createDialog(currentWebView.getTitle(), formattedUrlString, currentWebView.getFavoriteOrDefaultIcon());
// Show the create home screen shortcut dialog.
createHomeScreenShortcutDialogFragment.show(getSupportFragmentManager(), getString(R.string.create_shortcut));
// Run the commands that correspond to the selected menu item.
switch (menuItemId) {
case R.id.close_tab:
- // Get a handle for the tab layout.
+ // Get a handle for the tab layout and the view pager.
TabLayout tabLayout = findViewById(R.id.tablayout);
+ ViewPager webViewPager = findViewById(R.id.webviewpager);
// Get the current tab number.
int currentTabNumber = tabLayout.getSelectedTabPosition();
// Delete the current tab.
tabLayout.removeTabAt(currentTabNumber);
- // Delete the current page.
- webViewPagerAdapter.deletePage(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.
+ if (webViewPagerAdapter.deletePage(currentTabNumber, webViewPager)) {
+ setCurrentWebView(currentTabNumber);
+ }
break;
case R.id.clear_and_exit:
// Get the status of the clear everything preference.
boolean clearEverything = sharedPreferences.getBoolean("clear_everything", true);
+ // Get a handle for the runtime.
+ Runtime runtime = Runtime.getRuntime();
+
// Clear cookies.
if (clearEverything || sharedPreferences.getBoolean("clear_cookies", true)) {
// The command to remove cookies changed slightly in API 21.
if (Build.VERSION.SDK_INT >= 21) {
- cookieManager.removeAllCookies(null);
+ CookieManager.getInstance().removeAllCookies(null);
} else {
- cookieManager.removeAllCookie();
+ CookieManager.getInstance().removeAllCookie();
}
// Manually delete the cookies database, as `CookieManager` sometimes will not flush its changes to disk before `System.exit(0)` is run.
try {
// Two commands must be used because `Runtime.exec()` does not like `*`.
- Process deleteCookiesProcess = privacyBrowserRuntime.exec("rm -f " + privateDataDirectoryString + "/app_webview/Cookies");
- Process deleteCookiesJournalProcess = privacyBrowserRuntime.exec("rm -f " + privateDataDirectoryString + "/app_webview/Cookies-journal");
+ Process deleteCookiesProcess = runtime.exec("rm -f " + privateDataDirectoryString + "/app_webview/Cookies");
+ Process deleteCookiesJournalProcess = runtime.exec("rm -f " + privateDataDirectoryString + "/app_webview/Cookies-journal");
// Wait until the processes have finished.
deleteCookiesProcess.waitFor();
// Manually delete the DOM storage files and directories, as `WebStorage` sometimes will not flush its changes to disk before `System.exit(0)` is run.
try {
// A `String[]` must be used because the directory contains a space and `Runtime.exec` will otherwise not escape the string correctly.
- Process deleteLocalStorageProcess = privacyBrowserRuntime.exec(new String[] {"rm", "-rf", privateDataDirectoryString + "/app_webview/Local Storage/"});
+ Process deleteLocalStorageProcess = runtime.exec(new String[] {"rm", "-rf", privateDataDirectoryString + "/app_webview/Local Storage/"});
// Multiple commands must be used because `Runtime.exec()` does not like `*`.
- Process deleteIndexProcess = privacyBrowserRuntime.exec("rm -rf " + privateDataDirectoryString + "/app_webview/IndexedDB");
- Process deleteQuotaManagerProcess = privacyBrowserRuntime.exec("rm -f " + privateDataDirectoryString + "/app_webview/QuotaManager");
- Process deleteQuotaManagerJournalProcess = privacyBrowserRuntime.exec("rm -f " + privateDataDirectoryString + "/app_webview/QuotaManager-journal");
- Process deleteDatabaseProcess = privacyBrowserRuntime.exec("rm -rf " + privateDataDirectoryString + "/app_webview/databases");
+ Process deleteIndexProcess = runtime.exec("rm -rf " + privateDataDirectoryString + "/app_webview/IndexedDB");
+ Process deleteQuotaManagerProcess = runtime.exec("rm -f " + privateDataDirectoryString + "/app_webview/QuotaManager");
+ Process deleteQuotaManagerJournalProcess = runtime.exec("rm -f " + privateDataDirectoryString + "/app_webview/QuotaManager-journal");
+ Process deleteDatabaseProcess = runtime.exec("rm -rf " + privateDataDirectoryString + "/app_webview/databases");
// Wait until the processes have finished.
deleteLocalStorageProcess.waitFor();
// Manually delete the form data database, as `WebViewDatabase` sometimes will not flush its changes to disk before `System.exit(0)` is run.
try {
// A string array must be used because the database contains a space and `Runtime.exec` will not otherwise escape the string correctly.
- Process deleteWebDataProcess = privacyBrowserRuntime.exec(new String[] {"rm", "-f", privateDataDirectoryString + "/app_webview/Web Data"});
- Process deleteWebDataJournalProcess = privacyBrowserRuntime.exec(new String[] {"rm", "-f", privateDataDirectoryString + "/app_webview/Web Data-journal"});
+ Process deleteWebDataProcess = runtime.exec(new String[] {"rm", "-f", privateDataDirectoryString + "/app_webview/Web Data"});
+ Process deleteWebDataJournalProcess = runtime.exec(new String[] {"rm", "-f", privateDataDirectoryString + "/app_webview/Web Data-journal"});
// Wait until the processes have finished.
deleteWebDataProcess.waitFor();
// Manually delete the cache directories.
try {
// Delete the main cache directory.
- Process deleteCacheProcess = privacyBrowserRuntime.exec("rm -rf " + privateDataDirectoryString + "/cache");
+ Process deleteCacheProcess = runtime.exec("rm -rf " + privateDataDirectoryString + "/cache");
// Delete the secondary `Service Worker` cache directory.
// A string array must be used because the directory contains a space and `Runtime.exec` will otherwise not escape the string correctly.
- Process deleteServiceWorkerProcess = privacyBrowserRuntime.exec(new String[] {"rm", "-rf", privateDataDirectoryString + "/app_webview/Service Worker/"});
+ Process deleteServiceWorkerProcess = runtime.exec(new String[] {"rm", "-rf", privateDataDirectoryString + "/app_webview/Service Worker/"});
// Wait until the processes have finished.
deleteCacheProcess.waitFor();
if (clearEverything) {
try {
// Delete the folder.
- Process deleteAppWebviewProcess = privacyBrowserRuntime.exec("rm -rf " + privateDataDirectoryString + "/app_webview");
+ Process deleteAppWebviewProcess = runtime.exec("rm -rf " + privateDataDirectoryString + "/app_webview");
// Wait until the process has finished.
deleteAppWebviewProcess.waitFor();
// Create an intent to launch the Requests activity.
Intent requestsIntent = new Intent(this, RequestsActivity.class);
+ // Add the block third-party requests status to the intent.
+ requestsIntent.putExtra("block_all_third_party_requests", currentWebView.isBlocklistEnabled(NestedScrollWebView.THIRD_PARTY_REQUESTS));
+
// Make it so.
startActivity(requestsIntent);
break;
case R.id.domains:
// Set the flag to reapply the domain settings on restart when returning from Domain Settings.
reapplyDomainSettingsOnRestart = true;
- currentDomainName = "";
+ currentWebView.resetCurrentDomainName(); // TODO. Do this for all tabs.
// TODO. Move these to `putExtra`. The certificate can be stored as strings.
// Store the current SSL certificate and IP addresses in the domains activity.
// Set the flag to reapply the domain settings on restart when returning from Settings.
reapplyDomainSettingsOnRestart = true;
- currentDomainName = "";
+ currentWebView.resetCurrentDomainName(); // TODO. Do this for all tabs.
// Launch the settings activity.
Intent settingsIntent = new Intent(this, SettingsActivity.class);
}
@Override
- public void onCreateBookmark(DialogFragment dialogFragment) {
+ public void onCreateBookmark(DialogFragment dialogFragment, Bitmap favoriteIconBitmap) {
// Get the views from the dialog fragment.
EditText createBookmarkNameEditText = dialogFragment.getDialog().findViewById(R.id.create_bookmark_name_edittext);
EditText createBookmarkUrlEditText = dialogFragment.getDialog().findViewById(R.id.create_bookmark_url_edittext);
String bookmarkNameString = createBookmarkNameEditText.getText().toString();
String bookmarkUrlString = createBookmarkUrlEditText.getText().toString();
- // Get a copy of the favorite icon bitmap.
- Bitmap favoriteIcon = favoriteIconBitmap;
-
- // Scale the favorite icon bitmap down if it is larger than 256 x 256. Filtering uses bilinear interpolation.
- if ((favoriteIcon.getHeight() > 256) || (favoriteIcon.getWidth() > 256)) {
- favoriteIcon = Bitmap.createScaledBitmap(favoriteIcon, 256, 256, true);
- }
-
// Create a favorite icon byte array output stream.
ByteArrayOutputStream favoriteIconByteArrayOutputStream = new ByteArrayOutputStream();
// Convert the favorite icon bitmap to a byte array. `0` is for lossless compression (the only option for a PNG).
- favoriteIcon.compress(Bitmap.CompressFormat.PNG, 0, favoriteIconByteArrayOutputStream);
+ favoriteIconBitmap.compress(Bitmap.CompressFormat.PNG, 0, favoriteIconByteArrayOutputStream);
// Convert the favorite icon byte array stream to a byte array.
byte[] favoriteIconByteArray = favoriteIconByteArrayOutputStream.toByteArray();
}
@Override
- public void onCreateBookmarkFolder(DialogFragment dialogFragment) {
+ public void onCreateBookmarkFolder(DialogFragment dialogFragment, Bitmap favoriteIconBitmap) {
// Get handles for the views in the dialog fragment.
EditText createFolderNameEditText = dialogFragment.getDialog().findViewById(R.id.create_folder_name_edittext);
RadioButton defaultFolderIconRadioButton = dialogFragment.getDialog().findViewById(R.id.create_folder_default_icon_radiobutton);
// Convert the folder icon bitmap drawable to a bitmap.
folderIconBitmap = folderIconBitmapDrawable.getBitmap();
} else { // Use the WebView favorite icon.
- // Get a copy of the favorite icon bitmap.
+ // Copy the favorite icon bitmap to the folder icon bitmap.
folderIconBitmap = favoriteIconBitmap;
-
- // Scale the folder icon bitmap down if it is larger than 256 x 256. Filtering uses bilinear interpolation.
- if ((folderIconBitmap.getHeight() > 256) || (folderIconBitmap.getWidth() > 256)) {
- folderIconBitmap = Bitmap.createScaledBitmap(folderIconBitmap, 256, 256, true);
- }
}
// Create a folder icon byte array output stream.
}
@Override
- public void onSaveBookmark(DialogFragment dialogFragment, int selectedBookmarkDatabaseId) {
+ public void onSaveBookmark(DialogFragment dialogFragment, int selectedBookmarkDatabaseId, Bitmap favoriteIconBitmap) {
// Get handles for the views from `dialogFragment`.
EditText editBookmarkNameEditText = dialogFragment.getDialog().findViewById(R.id.edit_bookmark_name_edittext);
EditText editBookmarkUrlEditText = dialogFragment.getDialog().findViewById(R.id.edit_bookmark_url_edittext);
if (currentBookmarkIconRadioButton.isChecked()) { // Update the bookmark without changing the favorite icon.
bookmarksDatabaseHelper.updateBookmark(selectedBookmarkDatabaseId, bookmarkNameString, bookmarkUrlString);
} else { // Update the bookmark using the `WebView` favorite icon.
- // Get a copy of the favorite icon bitmap.
- Bitmap favoriteIcon = favoriteIconBitmap;
-
- // Scale the favorite icon bitmap down if it is larger than 256 x 256. Filtering uses bilinear interpolation.
- if ((favoriteIcon.getHeight() > 256) || (favoriteIcon.getWidth() > 256)) {
- favoriteIcon = Bitmap.createScaledBitmap(favoriteIcon, 256, 256, true);
- }
-
// Create a favorite icon byte array output stream.
ByteArrayOutputStream newFavoriteIconByteArrayOutputStream = new ByteArrayOutputStream();
// Convert the favorite icon bitmap to a byte array. `0` is for lossless compression (the only option for a PNG).
- favoriteIcon.compress(Bitmap.CompressFormat.PNG, 0, newFavoriteIconByteArrayOutputStream);
+ favoriteIconBitmap.compress(Bitmap.CompressFormat.PNG, 0, newFavoriteIconByteArrayOutputStream);
// Convert the favorite icon byte array stream to a byte array.
byte[] newFavoriteIconByteArray = newFavoriteIconByteArrayOutputStream.toByteArray();
}
@Override
- public void onSaveBookmarkFolder(DialogFragment dialogFragment, int selectedFolderDatabaseId) {
+ public void onSaveBookmarkFolder(DialogFragment dialogFragment, int selectedFolderDatabaseId, Bitmap favoriteIconBitmap) {
// Get handles for the views from `dialogFragment`.
EditText editFolderNameEditText = dialogFragment.getDialog().findViewById(R.id.edit_folder_name_edittext);
RadioButton currentFolderIconRadioButton = dialogFragment.getDialog().findViewById(R.id.edit_folder_current_icon_radiobutton);
// Convert the folder icon bitmap drawable to a bitmap.
folderIconBitmap = folderIconBitmapDrawable.getBitmap();
} else { // Use the `WebView` favorite icon.
- // Get a copy of the favorite icon bitmap.
- folderIconBitmap = MainWebViewActivity.favoriteIconBitmap;
-
- // Scale the folder icon bitmap down if it is larger than 256 x 256. Filtering uses bilinear interpolation.
- if ((folderIconBitmap.getHeight() > 256) || (folderIconBitmap.getWidth() > 256)) {
- folderIconBitmap = Bitmap.createScaledBitmap(folderIconBitmap, 256, 256, true);
- }
+ // Copy the favorite icon bitmap to the folder icon bitmap.
+ folderIconBitmap = favoriteIconBitmap;
}
// Create a folder icon byte array output stream.
// Convert the folder icon bitmap drawable to a bitmap.
folderIconBitmap = folderIconBitmapDrawable.getBitmap();
} else { // Use the `WebView` favorite icon.
- // Get a copy of the favorite icon bitmap.
- folderIconBitmap = MainWebViewActivity.favoriteIconBitmap;
-
- // Scale the folder icon bitmap down if it is larger than 256 x 256. Filtering uses bilinear interpolation.
- if ((folderIconBitmap.getHeight() > 256) || (folderIconBitmap.getWidth() > 256)) {
- folderIconBitmap = Bitmap.createScaledBitmap(folderIconBitmap, 256, 256, true);
- }
+ // Copy the favorite icon bitmap to the folder icon bitmap.
+ folderIconBitmap = favoriteIconBitmap;
}
// Create a folder icon byte array output stream.
// Code contributed 2017 Hendrik Knackstedt. Copyright assigned to Soren Stoutner <soren@stoutner.com>.
if (firstPartyCookiesEnabled) {
// Get the cookies for `imageUrl`.
- String cookies = cookieManager.getCookie(imageUrl);
+ String cookies = CookieManager.getInstance().getCookie(imageUrl);
// Add the cookies to `downloadRequest`. In the HTTP request header, cookies are named `Cookie`.
downloadRequest.addRequestHeader("Cookie", cookies);
// Code contributed 2017 Hendrik Knackstedt. Copyright assigned to Soren Stoutner <soren@stoutner.com>.
if (firstPartyCookiesEnabled) {
// Get the cookies for `downloadUrl`.
- String cookies = cookieManager.getCookie(downloadUrl);
+ String cookies = CookieManager.getInstance().getCookie(downloadUrl);
// Add the cookies to `downloadRequest`. In the HTTP request header, cookies are named `Cookie`.
downloadRequest.addRequestHeader("Cookie", cookies);
}
@Override
- public void onSslErrorCancel() {
+ public void onSslErrorCancel() { // TODO. How to handle this with multiple tabs? There could be multiple errors at once.
sslErrorHandler.cancel();
}
@Override
- public void onSslErrorProceed() {
+ public void onSslErrorProceed() { // TODO. How to handle this with multiple tabs? There could be multiple errors at once.
sslErrorHandler.proceed();
}
// Apply the domain settings.
applyDomainSettings(currentWebView, url, true, false);
- // If loading a website, set `urlIsLoading` to prevent changes in the user agent on websites with redirects from reloading the current website.
- urlIsLoading = !url.equals("");
-
// Load the URL.
currentWebView.loadUrl(url, customHeaders);
}
// `reloadWebsite` is used if returning from the Domains activity. Otherwise JavaScript might not function correctly if it is newly enabled.
- // The deprecated `.getDrawable()` must be used until the minimum API >= 21.
- @SuppressWarnings("deprecation")
+ @SuppressLint("SetJavaScriptEnabled")
private boolean applyDomainSettings(NestedScrollWebView nestedScrollWebView, String url, boolean resetFavoriteIcon, boolean reloadWebsite) {
- // Get a handle for the URL edit text.
- EditText urlEditText = findViewById(R.id.url_edittext);
+ // Get a handle for the URL relative layout.
+ RelativeLayout urlRelativeLayout = findViewById(R.id.url_relativelayout);
- // Get the current user agent.
+ // Store a copy of the current user agent to track changes for the return boolean.
String initialUserAgent = nestedScrollWebView.getSettings().getUserAgentString();
- // Initialize a variable to track if the user agent changes.
- boolean userAgentChanged = false;
-
// Parse the URL into a URI.
Uri uri = Uri.parse(url);
// Extract the domain from `uri`.
- String hostName = uri.getHost();
-
- // Initialize `loadingNewDomainName`.
- boolean loadingNewDomainName;
-
- // If either `hostName` or `currentDomainName` are `null`, run the options for loading a new domain name.
- // The lint suggestion to simplify the `if` statement is incorrect, because `hostName.equals(currentDomainName)` can produce a `null object reference.`
- //noinspection SimplifiableIfStatement
- if ((hostName == null) || (currentDomainName == null)) { // TODO.
- loadingNewDomainName = true;
- } else { // Determine if `hostName` equals `currentDomainName`.
- loadingNewDomainName = !hostName.equals(currentDomainName); // TODO.
- }
+ String newHostName = uri.getHost();
// Strings don't like to be null.
- if (hostName == null) {
- hostName = "";
+ if (newHostName == null) {
+ newHostName = "";
}
// Only apply the domain settings if a new domain is being loaded. This allows the user to set temporary settings for JavaScript, cookies, DOM storage, etc.
- if (loadingNewDomainName) {
- // Set the new `hostname` as the `currentDomainName`.
- currentDomainName = hostName; // TODO.
+ if (!nestedScrollWebView.getCurrentDomainName().equals(newHostName)) {
+ // Set the new host name as the current domain name.
+ nestedScrollWebView.setCurrentDomainName(newHostName);
// Reset the ignoring of pinned domain information.
nestedScrollWebView.setIgnorePinnedDomainInformation(false);
// Reset the favorite icon if specified.
if (resetFavoriteIcon) {
- // Store the favorite icon bitmap.
- favoriteIconBitmap = favoriteIconDefaultBitmap; // TODO.
+ // Initialize the favorite icon.
+ currentWebView.initializeFavoriteIcon();
// Get a handle for the tab layout.
TabLayout tabLayout = findViewById(R.id.tablayout);
ImageView currentTabFavoriteIconImageView = currentTabCustomView.findViewById(R.id.favorite_icon_imageview);
// Set the default favorite icon as the favorite icon for this tab.
- currentTabFavoriteIconImageView.setImageBitmap(Bitmap.createScaledBitmap(favoriteIconBitmap, 64, 64, true));
+ currentTabFavoriteIconImageView.setImageBitmap(Bitmap.createScaledBitmap(nestedScrollWebView.getFavoriteOrDefaultIcon(), 64, 64, true));
}
// Get a handle for the swipe refresh layout.
String domainNameInDatabase = null;
// Check the hostname against the domain settings set.
- if (domainSettingsSet.contains(hostName)) { // The hostname is contained in the domain settings set.
+ if (domainSettingsSet.contains(newHostName)) { // The hostname is contained in the domain settings set.
// Record the domain name in the database.
- domainNameInDatabase = hostName;
+ domainNameInDatabase = newHostName;
// Set the domain settings applied tracker to true.
nestedScrollWebView.setDomainSettingsApplied(true);
}
// Check all the subdomains of the host name against wildcard domains in the domain cursor.
- while (!nestedScrollWebView.getDomainSettingsApplied() && hostName.contains(".")) { // Stop checking if domain settings are already applied or there are no more `.` in the host name.
- if (domainSettingsSet.contains("*." + hostName)) { // Check the host name prepended by `*.`.
+ while (!nestedScrollWebView.getDomainSettingsApplied() && newHostName.contains(".")) { // Stop checking if domain settings are already applied or there are no more `.` in the host name.
+ if (domainSettingsSet.contains("*." + newHostName)) { // Check the host name prepended by `*.`.
// Set the domain settings applied tracker to true.
nestedScrollWebView.setDomainSettingsApplied(true);
// Store the applied domain names as it appears in the database.
- domainNameInDatabase = "*." + hostName;
+ domainNameInDatabase = "*." + newHostName;
}
// Strip out the lowest subdomain of of the host name.
- hostName = hostName.substring(hostName.indexOf(".") + 1);
+ newHostName = newHostName.substring(newHostName.indexOf(".") + 1);
}
- // Get a handle for the shared preference.
+ // Get a handle for the shared preferences.
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
// Store the general preference information.
String defaultFontSizeString = sharedPreferences.getString("font_size", getString(R.string.font_size_default_value));
String defaultUserAgentName = sharedPreferences.getString("user_agent", getString(R.string.user_agent_default_value));
- defaultCustomUserAgentString = sharedPreferences.getString("custom_user_agent", getString(R.string.custom_user_agent_default_value)); // TODO.
boolean defaultSwipeToRefresh = sharedPreferences.getBoolean("swipe_to_refresh", true);
nightMode = sharedPreferences.getBoolean("night_mode", false); // TODO.
boolean displayWebpageImages = sharedPreferences.getBoolean("display_webpage_images", true);
+ // Get a handle for the cookie manager.
+ CookieManager cookieManager = CookieManager.getInstance();
+
if (nestedScrollWebView.getDomainSettingsApplied()) { // The url has custom domain settings.
// Get a cursor for the current host and move it to the first position.
- Cursor currentHostDomainSettingsCursor = domainsDatabaseHelper.getCursorForDomainName(domainNameInDatabase);
- currentHostDomainSettingsCursor.moveToFirst();
+ Cursor currentDomainSettingsCursor = domainsDatabaseHelper.getCursorForDomainName(domainNameInDatabase);
+ currentDomainSettingsCursor.moveToFirst();
// Get the settings from the cursor.
- nestedScrollWebView.setDomainSettingsDatabaseId(currentHostDomainSettingsCursor.getInt(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper._ID)));
- javaScriptEnabled = (currentHostDomainSettingsCursor.getInt(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_JAVASCRIPT)) == 1); // TODO.
- firstPartyCookiesEnabled = (currentHostDomainSettingsCursor.getInt(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_FIRST_PARTY_COOKIES)) == 1); // TODO.
- thirdPartyCookiesEnabled = (currentHostDomainSettingsCursor.getInt(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_THIRD_PARTY_COOKIES)) == 1); // TODO.
- domStorageEnabled = (currentHostDomainSettingsCursor.getInt(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_DOM_STORAGE)) == 1); // TODO.
+ nestedScrollWebView.setDomainSettingsDatabaseId(currentDomainSettingsCursor.getInt(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper._ID)));
+ boolean domainJavaScriptEnabled = (currentDomainSettingsCursor.getInt(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_JAVASCRIPT)) == 1);
+ firstPartyCookiesEnabled = (currentDomainSettingsCursor.getInt(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_FIRST_PARTY_COOKIES)) == 1); // TODO.
+ boolean domainThirdPartyCookiesEnabled = (currentDomainSettingsCursor.getInt(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_THIRD_PARTY_COOKIES)) == 1);
+ boolean domainDomStorageEnabled = (currentDomainSettingsCursor.getInt(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_DOM_STORAGE)) == 1);
// Form data can be removed once the minimum API >= 26.
- saveFormDataEnabled = (currentHostDomainSettingsCursor.getInt(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_FORM_DATA)) == 1); // TODO.
- easyListEnabled = (currentHostDomainSettingsCursor.getInt(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_EASYLIST)) == 1); // TODO.
- easyPrivacyEnabled = (currentHostDomainSettingsCursor.getInt(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_EASYPRIVACY)) == 1); // TODO.
- fanboysAnnoyanceListEnabled = (currentHostDomainSettingsCursor.getInt(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_FANBOYS_ANNOYANCE_LIST)) == 1); // TODO.
- fanboysSocialBlockingListEnabled = (currentHostDomainSettingsCursor.getInt(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_FANBOYS_SOCIAL_BLOCKING_LIST)) == 1); // TODO.
- ultraPrivacyEnabled = (currentHostDomainSettingsCursor.getInt(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_ULTRAPRIVACY)) == 1); // TODO.
- blockAllThirdPartyRequests = (currentHostDomainSettingsCursor.getInt(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.BLOCK_ALL_THIRD_PARTY_REQUESTS)) == 1); // TODO.
- String userAgentName = currentHostDomainSettingsCursor.getString(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.USER_AGENT));
- int fontSize = currentHostDomainSettingsCursor.getInt(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.FONT_SIZE));
- int swipeToRefreshInt = currentHostDomainSettingsCursor.getInt(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.SWIPE_TO_REFRESH));
- int nightModeInt = currentHostDomainSettingsCursor.getInt(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.NIGHT_MODE));
- int displayWebpageImagesInt = currentHostDomainSettingsCursor.getInt(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.DISPLAY_IMAGES));
- boolean pinnedSslCertificate = (currentHostDomainSettingsCursor.getInt(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.PINNED_SSL_CERTIFICATE)) == 1);
- String pinnedSslIssuedToCName = currentHostDomainSettingsCursor.getString(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.SSL_ISSUED_TO_COMMON_NAME));
- String pinnedSslIssuedToOName = currentHostDomainSettingsCursor.getString(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.SSL_ISSUED_TO_ORGANIZATION));
- String pinnedSslIssuedToUName = currentHostDomainSettingsCursor.getString(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.SSL_ISSUED_TO_ORGANIZATIONAL_UNIT));
- String pinnedSslIssuedByCName = currentHostDomainSettingsCursor.getString(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.SSL_ISSUED_BY_COMMON_NAME));
- String pinnedSslIssuedByOName = currentHostDomainSettingsCursor.getString(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.SSL_ISSUED_BY_ORGANIZATION));
- String pinnedSslIssuedByUName = currentHostDomainSettingsCursor.getString(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.SSL_ISSUED_BY_ORGANIZATIONAL_UNIT));
- boolean pinnedIpAddresses = (currentHostDomainSettingsCursor.getInt(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.PINNED_IP_ADDRESSES)) == 1);
- String pinnedHostIpAddresses = currentHostDomainSettingsCursor.getString(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.IP_ADDRESSES));
+ saveFormDataEnabled = (currentDomainSettingsCursor.getInt(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_FORM_DATA)) == 1); // TODO.
+ nestedScrollWebView.enableBlocklist(NestedScrollWebView.EASY_LIST,
+ currentDomainSettingsCursor.getInt(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_EASYLIST)) == 1);
+ nestedScrollWebView.enableBlocklist(NestedScrollWebView.EASY_PRIVACY,
+ currentDomainSettingsCursor.getInt(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_EASYPRIVACY)) == 1);
+ nestedScrollWebView.enableBlocklist(NestedScrollWebView.FANBOYS_ANNOYANCE_LIST,
+ currentDomainSettingsCursor.getInt(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_FANBOYS_ANNOYANCE_LIST)) == 1);
+ nestedScrollWebView.enableBlocklist(NestedScrollWebView.FANBOYS_SOCIAL_BLOCKING_LIST,
+ currentDomainSettingsCursor.getInt(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_FANBOYS_SOCIAL_BLOCKING_LIST)) == 1);
+ nestedScrollWebView.enableBlocklist(NestedScrollWebView.ULTRA_PRIVACY,
+ currentDomainSettingsCursor.getInt(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_ULTRAPRIVACY)) == 1);
+ nestedScrollWebView.enableBlocklist(NestedScrollWebView.THIRD_PARTY_REQUESTS,
+ currentDomainSettingsCursor.getInt(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.BLOCK_ALL_THIRD_PARTY_REQUESTS)) == 1);
+ String userAgentName = currentDomainSettingsCursor.getString(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.USER_AGENT));
+ int fontSize = currentDomainSettingsCursor.getInt(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.FONT_SIZE));
+ int swipeToRefreshInt = currentDomainSettingsCursor.getInt(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.SWIPE_TO_REFRESH));
+ int nightModeInt = currentDomainSettingsCursor.getInt(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.NIGHT_MODE));
+ int displayWebpageImagesInt = currentDomainSettingsCursor.getInt(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.DISPLAY_IMAGES));
+ boolean pinnedSslCertificate = (currentDomainSettingsCursor.getInt(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.PINNED_SSL_CERTIFICATE)) == 1);
+ String pinnedSslIssuedToCName = currentDomainSettingsCursor.getString(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.SSL_ISSUED_TO_COMMON_NAME));
+ String pinnedSslIssuedToOName = currentDomainSettingsCursor.getString(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.SSL_ISSUED_TO_ORGANIZATION));
+ String pinnedSslIssuedToUName = currentDomainSettingsCursor.getString(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.SSL_ISSUED_TO_ORGANIZATIONAL_UNIT));
+ String pinnedSslIssuedByCName = currentDomainSettingsCursor.getString(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.SSL_ISSUED_BY_COMMON_NAME));
+ String pinnedSslIssuedByOName = currentDomainSettingsCursor.getString(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.SSL_ISSUED_BY_ORGANIZATION));
+ String pinnedSslIssuedByUName = currentDomainSettingsCursor.getString(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.SSL_ISSUED_BY_ORGANIZATIONAL_UNIT));
+ boolean pinnedIpAddresses = (currentDomainSettingsCursor.getInt(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.PINNED_IP_ADDRESSES)) == 1);
+ String pinnedHostIpAddresses = currentDomainSettingsCursor.getString(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.IP_ADDRESSES));
// Create the pinned SSL date variables.
Date pinnedSslStartDate;
Date pinnedSslEndDate;
// Set the pinned SSL certificate start date to `null` if the saved date `long` is 0 because creating a new Date results in an error if the input is 0.
- if (currentHostDomainSettingsCursor.getLong(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.SSL_START_DATE)) == 0) {
+ if (currentDomainSettingsCursor.getLong(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.SSL_START_DATE)) == 0) {
pinnedSslStartDate = null;
} else {
- pinnedSslStartDate = new Date(currentHostDomainSettingsCursor.getLong(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.SSL_START_DATE)));
+ pinnedSslStartDate = new Date(currentDomainSettingsCursor.getLong(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.SSL_START_DATE)));
}
// Set the pinned SSL certificate end date to `null` if the saved date `long` is 0 because creating a new Date results in an error if the input is 0.
- if (currentHostDomainSettingsCursor.getLong(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.SSL_END_DATE)) == 0) {
+ if (currentDomainSettingsCursor.getLong(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.SSL_END_DATE)) == 0) {
pinnedSslEndDate = null;
} else {
- pinnedSslEndDate = new Date(currentHostDomainSettingsCursor.getLong(currentHostDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.SSL_END_DATE)));
+ pinnedSslEndDate = new Date(currentDomainSettingsCursor.getLong(currentDomainSettingsCursor.getColumnIndex(DomainsDatabaseHelper.SSL_END_DATE)));
}
// If there is a pinned SSL certificate, store it in the WebView.
// TODO.
// Store the domain JavaScript status. This is used by the options menu night mode toggle.
- domainSettingsJavaScriptEnabled = javaScriptEnabled;
+ domainSettingsJavaScriptEnabled = domainJavaScriptEnabled;
// Enable JavaScript if night mode is enabled.
if (nightMode) {
- javaScriptEnabled = true; // TODO.
+ // Enable JavaScript.
+ nestedScrollWebView.getSettings().setJavaScriptEnabled(true);
+ } else {
+ // Set JavaScript according to the domain settings.
+ nestedScrollWebView.getSettings().setJavaScriptEnabled(domainJavaScriptEnabled);
}
// Close `currentHostDomainSettingsCursor`.
- currentHostDomainSettingsCursor.close();
+ currentDomainSettingsCursor.close();
// Apply the domain settings.
- nestedScrollWebView.getSettings().setJavaScriptEnabled(javaScriptEnabled); // TODO.
cookieManager.setAcceptCookie(firstPartyCookiesEnabled); //TODO This could be bad.
- nestedScrollWebView.getSettings().setDomStorageEnabled(domStorageEnabled); // TODO.
+ nestedScrollWebView.getSettings().setDomStorageEnabled(domainDomStorageEnabled); // TODO. Move up.
// Apply the form data setting if the API < 26.
if (Build.VERSION.SDK_INT < 26) {
// Set third-party cookies status if API >= 21.
if (Build.VERSION.SDK_INT >= 21) {
- cookieManager.setAcceptThirdPartyCookies(nestedScrollWebView, thirdPartyCookiesEnabled); // TODO.
+ cookieManager.setAcceptThirdPartyCookies(nestedScrollWebView, domainThirdPartyCookiesEnabled);
}
// Only set the user agent if the webpage is not currently loading. Otherwise, changing the user agent on redirects can cause the original website to reload.
// <https://redmine.stoutner.com/issues/160>
- if (!urlIsLoading) { // TODO. We need to track this by WebView.
+ if (nestedScrollWebView.getProgress() == 100) { // A URL is not loading.
// Set the user agent.
if (userAgentName.equals(getString(R.string.system_default_user_agent))) { // Use the system default user agent.
// Get the array position of the default user agent name.
break;
case SETTINGS_CUSTOM_USER_AGENT:
- // Set the custom user agent.
- nestedScrollWebView.getSettings().setUserAgentString(defaultCustomUserAgentString);
+ // Set the default custom user agent.
+ nestedScrollWebView.getSettings().setUserAgentString(sharedPreferences.getString("custom_user_agent", getString(R.string.custom_user_agent_default_value)));
break;
default:
nestedScrollWebView.getSettings().setUserAgentString(userAgentDataArray[userAgentArrayPosition]);
}
}
-
- // Store the applied user agent string, which is used in the View Source activity.
- appliedUserAgentString = nestedScrollWebView.getSettings().getUserAgentString(); // TODO.
-
- // Update the user agent change tracker.
- userAgentChanged = !appliedUserAgentString.equals(initialUserAgent); // TODO.
}
// Set swipe to refresh.
break;
}
- // Set a green background on URL edit text to indicate that custom domain settings are being used. The deprecated `.getDrawable()` must be used until the minimum API >= 21.
+ // Set a green background on the URL relative layout to indicate that custom domain settings are being used. The deprecated `.getDrawable()` must be used until the minimum API >= 21.
if (darkTheme) {
- urlEditText.setBackground(getResources().getDrawable(R.drawable.url_bar_background_dark_blue));
+ urlRelativeLayout.setBackground(getResources().getDrawable(R.drawable.url_bar_background_dark_blue));
} else {
- urlEditText.setBackground(getResources().getDrawable(R.drawable.url_bar_background_light_green));
+ urlRelativeLayout.setBackground(getResources().getDrawable(R.drawable.url_bar_background_light_green));
}
} else { // The new URL does not have custom domain settings. Load the defaults.
- // Store the values from `sharedPreferences` in variables.
- javaScriptEnabled = sharedPreferences.getBoolean("javascript", false); // TODO.
+ // Store the values from the shared preferences.
+ boolean defaultJavaScriptEnabled = sharedPreferences.getBoolean("javascript", false);
firstPartyCookiesEnabled = sharedPreferences.getBoolean("first_party_cookies", false); // TODO.
- thirdPartyCookiesEnabled = sharedPreferences.getBoolean("third_party_cookies", false); // TODO.
- domStorageEnabled = sharedPreferences.getBoolean("dom_storage", false); // TODO.
+ boolean defaultThirdPartyCookiesEnabled = sharedPreferences.getBoolean("third_party_cookies", false);
+ nestedScrollWebView.getSettings().setDomStorageEnabled(sharedPreferences.getBoolean("dom_storage", false));
saveFormDataEnabled = sharedPreferences.getBoolean("save_form_data", false); // Form data can be removed once the minimum API >= 26. // TODO.
- easyListEnabled = sharedPreferences.getBoolean("easylist", true); // TODO.
- easyPrivacyEnabled = sharedPreferences.getBoolean("easyprivacy", true); // TODO.
- fanboysAnnoyanceListEnabled = sharedPreferences.getBoolean("fanboys_annoyance_list", true); // TODO.
- fanboysSocialBlockingListEnabled = sharedPreferences.getBoolean("fanboys_social_blocking_list", true); // TODO.
- ultraPrivacyEnabled = sharedPreferences.getBoolean("ultraprivacy", true); // TODO.
- blockAllThirdPartyRequests = sharedPreferences.getBoolean("block_all_third_party_requests", false); // TODO.
-
- // Set `javaScriptEnabled` to be `true` if `night_mode` is `true`.
+ nestedScrollWebView.enableBlocklist(NestedScrollWebView.EASY_LIST, sharedPreferences.getBoolean("easylist", true));
+ nestedScrollWebView.enableBlocklist(NestedScrollWebView.EASY_PRIVACY, sharedPreferences.getBoolean("easyprivacy", true));
+ nestedScrollWebView.enableBlocklist(NestedScrollWebView.FANBOYS_ANNOYANCE_LIST, sharedPreferences.getBoolean("fanboys_annoyance_list", true));
+ nestedScrollWebView.enableBlocklist(NestedScrollWebView.FANBOYS_SOCIAL_BLOCKING_LIST, sharedPreferences.getBoolean("fanboys_social_blocking_list", true));
+ nestedScrollWebView.enableBlocklist(NestedScrollWebView.ULTRA_PRIVACY, sharedPreferences.getBoolean("ultraprivacy", true));
+ nestedScrollWebView.enableBlocklist(NestedScrollWebView.THIRD_PARTY_REQUESTS, sharedPreferences.getBoolean("block_all_third_party_requests", false));
+
+ // Enable JavaScript if night mode is enabled.
if (nightMode) {
- javaScriptEnabled = true; // TODO.
+ // Enable JavaScript.
+ nestedScrollWebView.getSettings().setJavaScriptEnabled(true);
+ } else {
+ // Set JavaScript according to the domain settings.
+ nestedScrollWebView.getSettings().setJavaScriptEnabled(defaultJavaScriptEnabled);
}
// Apply the default settings.
- nestedScrollWebView.getSettings().setJavaScriptEnabled(javaScriptEnabled); // TODO.
cookieManager.setAcceptCookie(firstPartyCookiesEnabled); // TODO.
- nestedScrollWebView.getSettings().setDomStorageEnabled(domStorageEnabled); // TODO.
nestedScrollWebView.getSettings().setTextZoom(Integer.valueOf(defaultFontSizeString));
swipeRefreshLayout.setEnabled(defaultSwipeToRefresh);
// Set third-party cookies status if API >= 21.
if (Build.VERSION.SDK_INT >= 21) {
- cookieManager.setAcceptThirdPartyCookies(nestedScrollWebView, thirdPartyCookiesEnabled);
+ cookieManager.setAcceptThirdPartyCookies(nestedScrollWebView, defaultThirdPartyCookiesEnabled);
}
// Only set the user agent if the webpage is not currently loading. Otherwise, changing the user agent on redirects can cause the original website to reload.
// <https://redmine.stoutner.com/issues/160>
- if (!urlIsLoading) { // TODO.
+ if (nestedScrollWebView.getProgress() == 100) { // A URL is not loading.
// Get the array position of the user agent name.
int userAgentArrayPosition = userAgentNamesArray.getPosition(defaultUserAgentName);
break;
case SETTINGS_CUSTOM_USER_AGENT:
- // Set the custom user agent.
- nestedScrollWebView.getSettings().setUserAgentString(defaultCustomUserAgentString); // TODO.
+ // Set the default custom user agent.
+ nestedScrollWebView.getSettings().setUserAgentString(sharedPreferences.getString("custom_user_agent", getString(R.string.custom_user_agent_default_value)));
break;
default:
// Get the user agent string from the user agent data array
nestedScrollWebView.getSettings().setUserAgentString(userAgentDataArray[userAgentArrayPosition]);
}
-
- // Store the applied user agent string, which is used in the View Source activity.
- appliedUserAgentString = nestedScrollWebView.getSettings().getUserAgentString(); // TODO.
-
- // Update the user agent change tracker.
- userAgentChanged = !appliedUserAgentString.equals(initialUserAgent); // TODO.
}
// Set the loading of webpage images.
nestedScrollWebView.getSettings().setLoadsImagesAutomatically(displayWebpageImages);
- // Set a transparent background on URL edit text. The deprecated `.getDrawable()` must be used until the minimum API >= 21.
- urlEditText.setBackgroundDrawable(getResources().getDrawable(R.color.transparent));
+ // Set a transparent background on URL edit text. The deprecated `getResources().getDrawable()` must be used until the minimum API >= 21.
+ urlRelativeLayout.setBackground(getResources().getDrawable(R.color.transparent));
}
// Close the domains database helper.
domainsDatabaseHelper.close();
- // Update the privacy icons, but only if the options menu has already been populated.
- if (mainMenu != null) { // TODO. Consider renaming this to optionsMenu.
- updatePrivacyIcons(true);
- }
+ // Update the privacy icons.
+ updatePrivacyIcons(true);
}
// Reload the website if returning from the Domains activity.
}
// Return the user agent changed status.
- return userAgentChanged;
+ return !nestedScrollWebView.getSettings().getUserAgentString().equals(initialUserAgent);
}
private void applyProxyThroughOrbot(boolean reloadWebsite) {
}
private void updatePrivacyIcons(boolean runInvalidateOptionsMenu) {
- // Get handles for the menu items.
- MenuItem privacyMenuItem = mainMenu.findItem(R.id.toggle_javascript);
- MenuItem firstPartyCookiesMenuItem = mainMenu.findItem(R.id.toggle_first_party_cookies);
- MenuItem domStorageMenuItem = mainMenu.findItem(R.id.toggle_dom_storage);
- MenuItem refreshMenuItem = mainMenu.findItem(R.id.refresh);
-
- // Update the privacy icon.
- if (javaScriptEnabled) { // JavaScript is enabled.
- privacyMenuItem.setIcon(R.drawable.javascript_enabled);
- } else if (firstPartyCookiesEnabled) { // JavaScript is disabled but cookies are enabled.
- privacyMenuItem.setIcon(R.drawable.warning);
- } else { // All the dangerous features are disabled.
- privacyMenuItem.setIcon(R.drawable.privacy_mode);
- }
+ // Only update the privacy icons if the options menu has already been populated.
+ if (optionsMenu != null) {
+ // Get handles for the menu items.
+ MenuItem privacyMenuItem = optionsMenu.findItem(R.id.toggle_javascript);
+ MenuItem firstPartyCookiesMenuItem = optionsMenu.findItem(R.id.toggle_first_party_cookies);
+ MenuItem domStorageMenuItem = optionsMenu.findItem(R.id.toggle_dom_storage);
+ MenuItem refreshMenuItem = optionsMenu.findItem(R.id.refresh);
+
+ // Update the privacy icon.
+ if (currentWebView.getSettings().getJavaScriptEnabled()) { // JavaScript is enabled.
+ privacyMenuItem.setIcon(R.drawable.javascript_enabled);
+ } else if (firstPartyCookiesEnabled) { // JavaScript is disabled but cookies are enabled.
+ privacyMenuItem.setIcon(R.drawable.warning);
+ } else { // All the dangerous features are disabled.
+ privacyMenuItem.setIcon(R.drawable.privacy_mode);
+ }
- // Update the first-party cookies icon.
- if (firstPartyCookiesEnabled) { // First-party cookies are enabled.
- firstPartyCookiesMenuItem.setIcon(R.drawable.cookies_enabled);
- } else { // First-party cookies are disabled.
- if (darkTheme) {
- firstPartyCookiesMenuItem.setIcon(R.drawable.cookies_disabled_dark);
- } else {
- firstPartyCookiesMenuItem.setIcon(R.drawable.cookies_disabled_light);
+ // Update the first-party cookies icon.
+ if (firstPartyCookiesEnabled) { // First-party cookies are enabled.
+ firstPartyCookiesMenuItem.setIcon(R.drawable.cookies_enabled);
+ } else { // First-party cookies are disabled.
+ if (darkTheme) {
+ firstPartyCookiesMenuItem.setIcon(R.drawable.cookies_disabled_dark);
+ } else {
+ firstPartyCookiesMenuItem.setIcon(R.drawable.cookies_disabled_light);
+ }
}
- }
- // Update the DOM storage icon.
- if (javaScriptEnabled && domStorageEnabled) { // Both JavaScript and DOM storage are enabled.
- domStorageMenuItem.setIcon(R.drawable.dom_storage_enabled);
- } else if (javaScriptEnabled) { // JavaScript is enabled but DOM storage is disabled.
- if (darkTheme) {
- domStorageMenuItem.setIcon(R.drawable.dom_storage_disabled_dark);
- } else {
- domStorageMenuItem.setIcon(R.drawable.dom_storage_disabled_light);
+ // Update the DOM storage icon.
+ if (currentWebView.getSettings().getJavaScriptEnabled() && currentWebView.getSettings().getDomStorageEnabled()) { // Both JavaScript and DOM storage are enabled.
+ domStorageMenuItem.setIcon(R.drawable.dom_storage_enabled);
+ } else if (currentWebView.getSettings().getJavaScriptEnabled()) { // JavaScript is enabled but DOM storage is disabled.
+ if (darkTheme) {
+ domStorageMenuItem.setIcon(R.drawable.dom_storage_disabled_dark);
+ } else {
+ domStorageMenuItem.setIcon(R.drawable.dom_storage_disabled_light);
+ }
+ } else { // JavaScript is disabled, so DOM storage is ghosted.
+ if (darkTheme) {
+ domStorageMenuItem.setIcon(R.drawable.dom_storage_ghosted_dark);
+ } else {
+ domStorageMenuItem.setIcon(R.drawable.dom_storage_ghosted_light);
+ }
}
- } else { // JavaScript is disabled, so DOM storage is ghosted.
+
+ // Update the refresh icon.
if (darkTheme) {
- domStorageMenuItem.setIcon(R.drawable.dom_storage_ghosted_dark);
+ refreshMenuItem.setIcon(R.drawable.refresh_enabled_dark);
} else {
- domStorageMenuItem.setIcon(R.drawable.dom_storage_ghosted_light);
+ refreshMenuItem.setIcon(R.drawable.refresh_enabled_light);
}
- }
-
- // Update the refresh icon.
- if (darkTheme) {
- refreshMenuItem.setIcon(R.drawable.refresh_enabled_dark);
- } else {
- refreshMenuItem.setIcon(R.drawable.refresh_enabled_light);
- }
- // `invalidateOptionsMenu` calls `onPrepareOptionsMenu()` and redraws the icons in the `AppBar`.
- if (runInvalidateOptionsMenu) {
- invalidateOptionsMenu();
+ // `invalidateOptionsMenu` calls `onPrepareOptionsMenu()` and redraws the icons in the `AppBar`.
+ if (runInvalidateOptionsMenu) {
+ invalidateOptionsMenu();
+ }
}
}
}
public void addTab(View view) {
- // Get a handle for the tab layout.
+ // Get a handle for the tab layout and the view pager.
TabLayout tabLayout = findViewById(R.id.tablayout);
+ ViewPager webViewPager = findViewById(R.id.webviewpager);
// 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();
// Remove the lint warning below that the current tab might be null.
assert newTab != null;
- // Set a custom view on the current tab.
+ // Set a custom view on the new tab.
newTab.setCustomView(R.layout.custom_tab_view);
// Add the new WebView page.
- webViewPagerAdapter.addPage(newTabNumber);
+ webViewPagerAdapter.addPage(newTabNumber, webViewPager);
+ }
+
+ private void setCurrentWebView(int pageNumber) {
+ // Get handles for the URL views.
+ RelativeLayout urlRelativeLayout = findViewById(R.id.url_relativelayout);
+ EditText urlEditText = findViewById(R.id.url_edittext);
+
+ // Get the WebView tab fragment.
+ WebViewTabFragment webViewTabFragment = webViewPagerAdapter.getPageFragment(pageNumber);
+
+ // Get the fragment view.
+ View fragmentView = webViewTabFragment.getView();
- if (newTabNumber > 0) {
- // Move to the new tab.
- newTab.select();
+ // Remove the incorrect lint warning below that the fragment view might be null.
+ assert fragmentView != null;
+
+ // Store the current WebView.
+ currentWebView = fragmentView.findViewById(R.id.nestedscroll_webview);
+
+ // Update the privacy icons. `true` redraws the icons in the app bar.
+ updatePrivacyIcons(true);
+
+ // Store the current formatted URL string.
+ formattedUrlString = currentWebView.getUrl();
+
+ // Clear the focus from the URL text box.
+ urlEditText.clearFocus();
+
+ // Hide the soft keyboard.
+ inputMethodManager.hideSoftInputFromWindow(currentWebView.getWindowToken(), 0);
+
+ // Display the current URL in the URL text box.
+ urlEditText.setText(formattedUrlString);
+
+ // Highlight the URL text.
+ highlightUrlText();
+
+ // Set the background to indicate the domain settings status.
+ if (currentWebView.getDomainSettingsApplied()) {
+ // Set a green background on the URL relative layout to indicate that custom domain settings are being used. The deprecated `.getDrawable()` must be used until the minimum API >= 21.
+ if (darkTheme) {
+ urlRelativeLayout.setBackground(getResources().getDrawable(R.drawable.url_bar_background_dark_blue));
+ } else {
+ urlRelativeLayout.setBackground(getResources().getDrawable(R.drawable.url_bar_background_light_green));
+ }
+ } else {
+ urlRelativeLayout.setBackground(getResources().getDrawable(R.color.transparent));
}
}
// Get the relevant preferences.
boolean downloadWithExternalApp = sharedPreferences.getBoolean("download_with_external_app", false);
+ // Initialize the favorite icon.
+ nestedScrollWebView.initializeFavoriteIcon();
+
// Set the app bar scrolling.
nestedScrollWebView.setNestedScrollingEnabled(sharedPreferences.getBoolean("scroll_app_bar", true));
public void onReceivedIcon(WebView view, Bitmap icon) {
// Only update the favorite icon if the website has finished loading.
if (progressBar.getVisibility() == View.GONE) {
- // Save a copy of the favorite icon.
- favoriteIconBitmap = icon;
+ // Store the new favorite icon.
+ nestedScrollWebView.setFavoriteOrDefaultIcon(icon);
// Get the current page position.
int currentPosition = webViewPagerAdapter.getPositionForId(nestedScrollWebView.getWebViewFragmentId());
// Get the current tab.
TabLayout.Tab tab = tabLayout.getTabAt(currentPosition);
- // Remove the lint warning below that the current tab might be null.
- assert tab != null;
-
- // Get the custom view from the tab.
- View tabView = tab.getCustomView();
+ // Only populate the title text view if the tab has been fully created.
+ if (tab != null) {
+ // Get the custom view from the tab.
+ View tabView = tab.getCustomView();
- // Remove the incorrect warning below that the current tab view might be null.
- assert tabView != null;
+ // Remove the incorrect warning below that the current tab view might be null.
+ assert tabView != null;
- // Get the title text view from the tab.
- TextView tabTitleTextView = tabView.findViewById(R.id.title_textview);
+ // Get the title text view from the tab.
+ TextView tabTitleTextView = tabView.findViewById(R.id.title_textview);
- // Set the title as the tab text.
- tabTitleTextView.setText(title);
+ // Set the title as the tab text.
+ tabTitleTextView.setText(title);
+ }
}
// Enter full screen video.
@Override
public void onShowCustomView(View video, CustomViewCallback callback) {
+ // Get a handle for the full screen video frame layout.
+ FrameLayout fullScreenVideoFrameLayout = findViewById(R.id.full_screen_video_framelayout);
+
// Set the full screen video flag.
displayingFullScreenVideo = true;
// Exit full screen video.
@Override
public void onHideCustomView() {
+ // Get a handle for the full screen video frame layout.
+ FrameLayout fullScreenVideoFrameLayout = findViewById(R.id.full_screen_video_framelayout);
+
// Unset the full screen video flag.
displayingFullScreenVideo = false;
@SuppressWarnings("deprecation")
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
+ // Get a handle for the navigation view.
+ NavigationView navigationView = findViewById(R.id.navigationview);
+
+ // Get a handle for the navigation menu.
+ Menu navigationMenu = navigationView.getMenu();
+
+ // Get a handle for the navigation requests menu item. The menu is 0 based.
+ MenuItem navigationRequestsMenuItem = navigationMenu.getItem(6);
+
// Create an empty web resource response to be used if the resource request is blocked.
WebResourceResponse emptyWebResourceResponse = new WebResourceResponse("text/plain", "utf8", new ByteArrayInputStream("".getBytes()));
boolean webViewDisplayed = (webViewPagePosition == tabLayout.getSelectedTabPosition());
// Block third-party requests if enabled.
- if (isThirdPartyRequest && blockAllThirdPartyRequests) {
+ if (isThirdPartyRequest && nestedScrollWebView.isBlocklistEnabled(NestedScrollWebView.THIRD_PARTY_REQUESTS)) {
// Add the result to the resource requests.
nestedScrollWebView.addResourceRequest(new String[]{BlockListHelper.REQUEST_THIRD_PARTY, url});
// Increment the blocked requests counters.
nestedScrollWebView.incrementRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS);
- nestedScrollWebView.incrementRequestsCount(NestedScrollWebView.THIRD_PARTY_BLOCKED_REQUESTS);
+ nestedScrollWebView.incrementRequestsCount(NestedScrollWebView.THIRD_PARTY_REQUESTS);
// Update the titles of the blocklist menu items if the WebView is currently displayed.
if (webViewDisplayed) {
// Update the menu item titles.
navigationRequestsMenuItem.setTitle(getString(R.string.requests) + " - " + nestedScrollWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS));
blocklistsMenuItem.setTitle(getString(R.string.blocklists) + " - " + nestedScrollWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS));
- blockAllThirdPartyRequestsMenuItem.setTitle(nestedScrollWebView.getRequestsCount(NestedScrollWebView.THIRD_PARTY_BLOCKED_REQUESTS) + " - " +
+ blockAllThirdPartyRequestsMenuItem.setTitle(nestedScrollWebView.getRequestsCount(NestedScrollWebView.THIRD_PARTY_REQUESTS) + " - " +
getString(R.string.block_all_third_party_requests));
});
}
}
// Check UltraPrivacy if it is enabled.
- if (ultraPrivacyEnabled) {
+ if (nestedScrollWebView.isBlocklistEnabled(NestedScrollWebView.ULTRA_PRIVACY)) {
// Check the URL against UltraPrivacy.
String[] ultraPrivacyResults = blockListHelper.checkBlocklist(currentDomain, url, isThirdPartyRequest, ultraPrivacy);
// Increment the blocked requests counters.
nestedScrollWebView.incrementRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS);
- nestedScrollWebView.incrementRequestsCount(NestedScrollWebView.ULTRA_PRIVACY_BLOCKED_REQUESTS);
+ nestedScrollWebView.incrementRequestsCount(NestedScrollWebView.ULTRA_PRIVACY);
// Update the titles of the blocklist menu items if the WebView is currently displayed.
if (webViewDisplayed) {
// Update the menu item titles.
navigationRequestsMenuItem.setTitle(getString(R.string.requests) + " - " + nestedScrollWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS));
blocklistsMenuItem.setTitle(getString(R.string.blocklists) + " - " + nestedScrollWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS));
- ultraPrivacyMenuItem.setTitle(nestedScrollWebView.getRequestsCount(NestedScrollWebView.ULTRA_PRIVACY_BLOCKED_REQUESTS) + " - " + getString(R.string.ultraprivacy));
+ ultraPrivacyMenuItem.setTitle(nestedScrollWebView.getRequestsCount(NestedScrollWebView.ULTRA_PRIVACY) + " - " + getString(R.string.ultraprivacy));
});
}
}
// Check EasyList if it is enabled.
- if (easyListEnabled) {
+ if (nestedScrollWebView.isBlocklistEnabled(NestedScrollWebView.EASY_LIST)) {
// Check the URL against EasyList.
String[] easyListResults = blockListHelper.checkBlocklist(currentDomain, url, isThirdPartyRequest, easyList);
// Increment the blocked requests counters.
nestedScrollWebView.incrementRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS);
- nestedScrollWebView.incrementRequestsCount(NestedScrollWebView.EASY_LIST_BLOCKED_REQUESTS);
+ nestedScrollWebView.incrementRequestsCount(NestedScrollWebView.EASY_LIST);
// Update the titles of the blocklist menu items if the WebView is currently displayed.
if (webViewDisplayed) {
// Update the menu item titles.
navigationRequestsMenuItem.setTitle(getString(R.string.requests) + " - " + nestedScrollWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS));
blocklistsMenuItem.setTitle(getString(R.string.blocklists) + " - " + nestedScrollWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS));
- easyListMenuItem.setTitle(nestedScrollWebView.getRequestsCount(NestedScrollWebView.EASY_LIST_BLOCKED_REQUESTS) + " - " + getString(R.string.easylist));
+ easyListMenuItem.setTitle(nestedScrollWebView.getRequestsCount(NestedScrollWebView.EASY_LIST) + " - " + getString(R.string.easylist));
});
}
}
// Check EasyPrivacy if it is enabled.
- if (easyPrivacyEnabled) {
+ if (nestedScrollWebView.isBlocklistEnabled(NestedScrollWebView.EASY_PRIVACY)) {
// Check the URL against EasyPrivacy.
String[] easyPrivacyResults = blockListHelper.checkBlocklist(currentDomain, url, isThirdPartyRequest, easyPrivacy);
// Process the EasyPrivacy results.
if (easyPrivacyResults[0].equals(BlockListHelper.REQUEST_BLOCKED)) { // The resource request matched EasyPrivacy's blacklist.
// Add the result to the resource requests.
- nestedScrollWebView.addResourceRequest(new String[] {easyPrivacyResults[0], easyPrivacyResults[1], easyPrivacyResults[2], easyPrivacyResults[3], easyPrivacyResults[5],
+ nestedScrollWebView.addResourceRequest(new String[] {easyPrivacyResults[0], easyPrivacyResults[1], easyPrivacyResults[2], easyPrivacyResults[3], easyPrivacyResults[4],
easyPrivacyResults[5]});
// Increment the blocked requests counters.
nestedScrollWebView.incrementRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS);
- nestedScrollWebView.incrementRequestsCount(NestedScrollWebView.EASY_PRIVACY_BLOCKED_REQUESTS);
+ nestedScrollWebView.incrementRequestsCount(NestedScrollWebView.EASY_PRIVACY);
// Update the titles of the blocklist menu items if the WebView is currently displayed.
if (webViewDisplayed) {
// Update the menu item titles.
navigationRequestsMenuItem.setTitle(getString(R.string.requests) + " - " + nestedScrollWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS));
blocklistsMenuItem.setTitle(getString(R.string.blocklists) + " - " + nestedScrollWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS));
- easyPrivacyMenuItem.setTitle(nestedScrollWebView.getRequestsCount(NestedScrollWebView.EASY_PRIVACY_BLOCKED_REQUESTS) + " - " + getString(R.string.easyprivacy));
+ easyPrivacyMenuItem.setTitle(nestedScrollWebView.getRequestsCount(NestedScrollWebView.EASY_PRIVACY) + " - " + getString(R.string.easyprivacy));
});
}
}
// Check Fanboy’s Annoyance List if it is enabled.
- if (fanboysAnnoyanceListEnabled) {
+ if (nestedScrollWebView.isBlocklistEnabled(NestedScrollWebView.FANBOYS_ANNOYANCE_LIST)) {
// Check the URL against Fanboy's Annoyance List.
String[] fanboysAnnoyanceListResults = blockListHelper.checkBlocklist(currentDomain, url, isThirdPartyRequest, fanboysAnnoyanceList);
// Increment the blocked requests counters.
nestedScrollWebView.incrementRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS);
- nestedScrollWebView.incrementRequestsCount(NestedScrollWebView.FANBOYS_ANNOYANCE_LIST_BLOCKED_REQUESTS);
+ nestedScrollWebView.incrementRequestsCount(NestedScrollWebView.FANBOYS_ANNOYANCE_LIST);
// Update the titles of the blocklist menu items if the WebView is currently displayed.
if (webViewDisplayed) {
// Update the menu item titles.
navigationRequestsMenuItem.setTitle(getString(R.string.requests) + " - " + nestedScrollWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS));
blocklistsMenuItem.setTitle(getString(R.string.blocklists) + " - " + nestedScrollWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS));
- fanboysAnnoyanceListMenuItem.setTitle(nestedScrollWebView.getRequestsCount(NestedScrollWebView.FANBOYS_ANNOYANCE_LIST_BLOCKED_REQUESTS) + " - " +
+ fanboysAnnoyanceListMenuItem.setTitle(nestedScrollWebView.getRequestsCount(NestedScrollWebView.FANBOYS_ANNOYANCE_LIST) + " - " +
getString(R.string.fanboys_annoyance_list));
});
}
whitelistResultStringArray = new String[] {fanboysAnnoyanceListResults[0], fanboysAnnoyanceListResults[1], fanboysAnnoyanceListResults[2], fanboysAnnoyanceListResults[3],
fanboysAnnoyanceListResults[4], fanboysAnnoyanceListResults[5]};
}
- } else if (fanboysSocialBlockingListEnabled) { // Only check Fanboy’s Social Blocking List if Fanboy’s Annoyance List is disabled.
+ } else if (nestedScrollWebView.isBlocklistEnabled(NestedScrollWebView.FANBOYS_SOCIAL_BLOCKING_LIST)) { // Only check Fanboy’s Social Blocking List if Fanboy’s Annoyance List is disabled.
// Check the URL against Fanboy's Annoyance List.
String[] fanboysSocialListResults = blockListHelper.checkBlocklist(currentDomain, url, isThirdPartyRequest, fanboysSocialList);
// Increment the blocked requests counters.
nestedScrollWebView.incrementRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS);
- nestedScrollWebView.incrementRequestsCount(NestedScrollWebView.FANBOYS_SOCIAL_BLOCKING_LIST_BLOCKED_REQUESTS);
+ nestedScrollWebView.incrementRequestsCount(NestedScrollWebView.FANBOYS_SOCIAL_BLOCKING_LIST);
// Update the titles of the blocklist menu items if the WebView is currently displayed.
if (webViewDisplayed) {
// Update the menu item titles.
navigationRequestsMenuItem.setTitle(getString(R.string.requests) + " - " + nestedScrollWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS));
blocklistsMenuItem.setTitle(getString(R.string.blocklists) + " - " + nestedScrollWebView.getRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS));
- fanboysSocialBlockingListMenuItem.setTitle(nestedScrollWebView.getRequestsCount(NestedScrollWebView.FANBOYS_SOCIAL_BLOCKING_LIST_BLOCKED_REQUESTS) + " - " +
+ fanboysSocialBlockingListMenuItem.setTitle(nestedScrollWebView.getRequestsCount(NestedScrollWebView.FANBOYS_SOCIAL_BLOCKING_LIST) + " - " +
getString(R.string.fanboys_social_blocking_list));
});
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
- // Set `urlIsLoading` to `true`, so that redirects while loading do not trigger changes in the user agent, which forces another reload of the existing page.
- // This is also used to determine when to check for pinned mismatches.
- urlIsLoading = true;
-
// Reset the list of resource requests.
nestedScrollWebView.clearResourceRequests();
- // Initialize the counters for requests blocked by each blocklist.
- nestedScrollWebView.resetRequestsCount(NestedScrollWebView.BLOCKED_REQUESTS);
- nestedScrollWebView.resetRequestsCount(NestedScrollWebView.EASY_LIST_BLOCKED_REQUESTS);
- nestedScrollWebView.resetRequestsCount(NestedScrollWebView.EASY_PRIVACY_BLOCKED_REQUESTS);
- nestedScrollWebView.resetRequestsCount(NestedScrollWebView.FANBOYS_ANNOYANCE_LIST_BLOCKED_REQUESTS);
- nestedScrollWebView.resetRequestsCount(NestedScrollWebView.FANBOYS_SOCIAL_BLOCKING_LIST_BLOCKED_REQUESTS);
- nestedScrollWebView.resetRequestsCount(NestedScrollWebView.ULTRA_PRIVACY_BLOCKED_REQUESTS);
- nestedScrollWebView.resetRequestsCount(NestedScrollWebView.THIRD_PARTY_BLOCKED_REQUESTS);
+ // Reset the requests counters.
+ nestedScrollWebView.resetRequestsCounters();
// If night mode is enabled, hide `mainWebView` until after the night mode CSS is applied.
if (nightMode) {
// 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();
+ CookieManager.getInstance().flush();
}
// Update the Refresh menu item if it has been created.
// Manually delete cache folders.
try {
// Delete the main cache directory.
- privacyBrowserRuntime.exec("rm -rf " + privateDataDirectoryString + "/cache");
+ Runtime.getRuntime().exec("rm -rf " + privateDataDirectoryString + "/cache");
// Delete the secondary `Service Worker` cache directory.
// A `String[]` must be used because the directory contains a space and `Runtime.exec` will not escape the string correctly otherwise.
- privacyBrowserRuntime.exec(new String[]{"rm", "-rf", privateDataDirectoryString + "/app_webview/Service Worker/"});
+ Runtime.getRuntime().exec(new String[]{"rm", "-rf", privateDataDirectoryString + "/app_webview/Service Worker/"});
} catch (IOException e) {
// Do nothing if an error is thrown.
}
CheckPinnedMismatchHelper.checkPinnedMismatch(getSupportFragmentManager(), nestedScrollWebView);
}
}
-
- // Reset `urlIsLoading`, which is used to prevent reloads on redirect if the user agent changes. It is also used to determine when to check for pinned mismatches.
- urlIsLoading = false;
}
// Handle SSL Certificate errors.