X-Git-Url: https://gitweb.stoutner.com/?p=PrivacyBrowserAndroid.git;a=blobdiff_plain;f=app%2Fsrc%2Fmain%2Fjava%2Fcom%2Fstoutner%2Fprivacybrowser%2Factivities%2FMainWebViewActivity.java;h=07126c9881fd045ea0aedc4fd826231b8a3c521d;hp=97362dfe9cf5db1dda2d3d25ebecf4fac883d46b;hb=23e147850398e0dd66da4bbef5ca5f2e517c28c6;hpb=80187b7215a5effdbe97ac48e8af34824a05c287 diff --git a/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java b/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java index 97362dfe..07126c98 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java @@ -154,10 +154,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook HttpAuthenticationDialog.HttpAuthenticationListener, NavigationView.OnNavigationItemSelectedListener, PinnedSslCertificateMismatchDialog.PinnedSslCertificateMismatchListener, SslCertificateErrorDialog.SslCertificateErrorListener, UrlHistoryDialog.UrlHistoryListener { - // `darkTheme` is public static so it can be accessed from `AboutActivity`, `GuideActivity`, `AddDomainDialog`, `SettingsActivity`, `DomainsActivity`, `DomainsListFragment`, `BookmarksActivity`, - // `BookmarksDatabaseViewActivity`, `CreateBookmarkDialog`, `CreateBookmarkFolderDialog`, `DownloadFileDialog`, `DownloadImageDialog`, `EditBookmarkDialog`, `EditBookmarkFolderDialog`, - // `EditBookmarkDatabaseViewDialog`, `HttpAuthenticationDialog`, `MoveToFolderDialog`, `SslCertificateErrorDialog`, `UrlHistoryDialog`, `ViewSslCertificateDialog`, `CreateHomeScreenShortcutDialog`, - // and `OrbotProxyHelper`. It is also used in `onCreate()`, `applyAppSettings()`, `applyDomainSettings()`, and `updatePrivacyIcons()`. + // `darkTheme` is public static so it can be accessed from everywhere. public static boolean darkTheme; // `allowScreenshots` is public static so it can be accessed from everywhere. It is also used in `onCreate()`. @@ -200,6 +197,44 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook public static String fanboyAnnoyanceVersion; public static String fanboySocialVersion; + // The request items are public static so they can be accessed by `BlockListHelper`, `RequestsArrayAdapter`, and `ViewRequestsDialog`. They are also used in `onCreate()`. + public static List resourceRequests; + public static String[] whiteListResultStringArray; + public final static int REQUEST_DISPOSITION = 0; + public final static int REQUEST_URL = 1; + public final static int REQUEST_BLOCKLIST = 2; + public final static int REQUEST_SUBLIST = 3; + public final static int REQUEST_BLOCKLIST_ENTRIES = 4; + public final static int REQUEST_BLOCKLIST_ORIGINAL_ENTRY = 5; + + public final static int REQUEST_DEFAULT = 0; + public final static int REQUEST_ALLOWED = 1; + public final static int REQUEST_BLOCKED = 2; + + public final static int MAIN_WHITELIST = 1; + public final static int FINAL_WHITELIST = 2; + public final static int DOMAIN_WHITELIST = 3; + public final static int DOMAIN_INITIAL_WHITELIST = 4; + public final static int DOMAIN_FINAL_WHITELIST = 5; + public final static int THIRD_PARTY_WHITELIST = 6; + public final static int THIRD_PARTY_DOMAIN_WHITELIST = 7; + public final static int THIRD_PARTY_DOMAIN_INITIAL_WHITELIST = 8; + + public final static int MAIN_BLACKLIST = 9; + public final static int INITIAL_BLACKLIST = 10; + public final static int FINAL_BLACKLIST = 11; + public final static int DOMAIN_BLACKLIST = 12; + public final static int DOMAIN_INITIAL_BLACKLIST = 13; + public final static int DOMAIN_FINAL_BLACKLIST = 14; + public final static int DOMAIN_REGULAR_EXPRESSION_BLACKLIST = 15; + public final static int THIRD_PARTY_BLACKLIST = 16; + public final static int THIRD_PARTY_INITIAL_BLACKLIST = 17; + public final static int THIRD_PARTY_DOMAIN_BLACKLIST = 18; + public final static int THIRD_PARTY_DOMAIN_INITIAL_BLACKLIST = 19; + public final static int THIRD_PARTY_REGULAR_EXPRESSION_BLACKLIST = 20; + public final static int THIRD_PARTY_DOMAIN_REGULAR_EXPRESSION_BLACKLIST = 21; + public final static int REGULAR_EXPRESSION_BLACKLIST = 22; + // `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; @@ -248,7 +283,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // `fullScreenVideoFrameLayout` is used in `onCreate()` and `onConfigurationChanged()`. private FrameLayout fullScreenVideoFrameLayout; - // `swipeRefreshLayout` is used in `onCreate()`, `onPrepareOptionsMenu()`, `onOptionsMenuSelected()`, and `onRestart()`. + // `swipeRefreshLayout` is used in `onCreate()`, `onPrepareOptionsMenu()`, `onOptionsItemSelected()`, and `onRestart()`. private SwipeRefreshLayout swipeRefreshLayout; // `urlAppBarRelativeLayout` is used in `onCreate()` and `applyDomainSettings()`. @@ -290,7 +325,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // `searchURL` is used in `loadURLFromTextBox()` and `applyAppSettings()`. private String searchURL; - // The block list variables are used in `onCreate()` and `applyAppSettings()`. + // The block list variables are used in `onCreate()`, `onPrepareOptionsMenu()`, `onOptionsItemSelected()`, and `applyAppSettings()`. private boolean easyListEnabled; private boolean easyPrivacyEnabled; private boolean fanboysAnnoyanceListEnabled; @@ -754,6 +789,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook final MenuItem navigationBackMenuItem = navigationMenu.getItem(1); final MenuItem navigationForwardMenuItem = navigationMenu.getItem(2); final MenuItem navigationHistoryMenuItem = navigationMenu.getItem(3); + final MenuItem navigationRequestsMenuItem = navigationMenu.getItem(4); // Initialize the bookmarks database helper. `this` specifies the context. The two `nulls` do not specify the database name or a `CursorFactory`. // The `0` specifies a database version, but that is ignored and set instead using a constant in `BookmarksDatabaseHelper`. @@ -816,7 +852,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook return true; }); - // The `DrawerListener` allows us to update the Navigation Menu. + // The `DrawerListener` is used to update the Navigation Menu. drawerLayout.addDrawerListener(new DrawerLayout.DrawerListener() { @Override public void onDrawerSlide(@NonNull View drawerView, float slideOffset) { @@ -833,10 +869,21 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook @Override public void onDrawerStateChanged(int newState) { if ((newState == DrawerLayout.STATE_SETTLING) || (newState == DrawerLayout.STATE_DRAGGING)) { // The drawer is opening or closing. - // Update the `Back`, `Forward`, and `History` menu items. + // Initialize a the blocked requests counter. + int blockedRequests = 0; + + // Count the number of blocked requests. + for (int i = 0; i < resourceRequests.size(); i++) { + if (Integer.valueOf(resourceRequests.get(i)[REQUEST_DISPOSITION]) == REQUEST_BLOCKED) { + blockedRequests++; + } + } + + // Update the back, forward, history, and requests menu items. navigationBackMenuItem.setEnabled(mainWebView.canGoBack()); navigationForwardMenuItem.setEnabled(mainWebView.canGoForward()); navigationHistoryMenuItem.setEnabled((mainWebView.canGoBack() || mainWebView.canGoForward())); + navigationRequestsMenuItem.setTitle(getResources().getString(R.string.requests) + " - " + blockedRequests); // Hide the keyboard (if displayed) so we can see the navigation menu. `0` indicates no additional flags. inputMethodManager.hideSoftInputFromWindow(mainWebView.getWindowToken(), 0); @@ -949,6 +996,9 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Set `rootCoordinatorLayout` to fill the entire screen. rootCoordinatorLayout.setFitsSystemWindows(false); + // Disable the sliding drawers. + drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED); + // Add `view` to `fullScreenVideoFrameLayout` and display it on the screen. fullScreenVideoFrameLayout.addView(view); fullScreenVideoFrameLayout.setVisibility(View.VISIBLE); @@ -961,6 +1011,9 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook fullScreenVideoFrameLayout.removeAllViews(); fullScreenVideoFrameLayout.setVisibility(View.GONE); + // Enable the sliding drawers. + drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED); + // Add the translucent status flag. This also resets `drawerLayout's` `View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN`. getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); @@ -1103,6 +1156,9 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Instantiate the block list helper. BlockListHelper blockListHelper = new BlockListHelper(); + // Initialize the list of resource requests. + resourceRequests = new ArrayList<>(); + // Parse the block lists. final ArrayList> easyList = blockListHelper.parseBlockList(getAssets(), "blocklists/easylist.txt"); final ArrayList> easyPrivacy = blockListHelper.parseBlockList(getAssets(), "blocklists/easyprivacy.txt"); @@ -1122,15 +1178,9 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { if (url.startsWith("http")) { // Load the URL in Privacy Browser. - // Hide the WebView while applying domain settings so changes to things like JavaScript aren't rendered on the current URL, which otherwise will reload automatically. - mainWebView.setVisibility(View.INVISIBLE); - - // Apply the domain settings for the new URL. + // Apply the domain settings for the new URL. `applyDomainSettings` doesn't do anything if the domain has not changed. applyDomainSettings(url, true, false); - // Display the WebView again so that the new URL can be loaded. - mainWebView.setVisibility(View.VISIBLE); - // Returning false causes the current WebView to handle the URL and prevents it from adding redirects to the history list. return false; } else if (url.startsWith("mailto:")) { // Load the email address in an external email program. @@ -1188,13 +1238,16 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook } } - // Check requests against the block lists. The deprecated `shouldInterceptRequest` must be used until minimum API >= 21. + // Check requests against the block lists. The deprecated `shouldInterceptRequest()` must be used until minimum API >= 21. @SuppressWarnings("deprecation") @Override public WebResourceResponse shouldInterceptRequest(WebView view, String url){ // 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())); + // Reset `whiteListResultStringArray`. + whiteListResultStringArray = null; + // Check EasyList if it is enabled. if (easyListEnabled) { if (blockListHelper.isBlocked(formattedUrlString, url, easyList)) { @@ -1224,6 +1277,13 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook } } + // Add the request to the log. + if (whiteListResultStringArray != null ) { // The request was processed by a whitelist. + resourceRequests.add(whiteListResultStringArray); + } else { // The request didn't match any blocklist entry. Log it as a defult request. + resourceRequests.add(new String[]{String.valueOf(REQUEST_DEFAULT), url}); + } + // The resource request has not been blocked. `return null` loads the requested resource. return null; } @@ -1241,7 +1301,11 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Update the URL in urlTextBox when the page starts to load. @Override - public void onPageStarted(WebView view, String url, Bitmap favicon) {// If night mode is enabled, hide `mainWebView` until after the night mode CSS is applied. + public void onPageStarted(WebView view, String url, Bitmap favicon) { + // Reset the list of resource requests. + resourceRequests.clear(); + + // If night mode is enabled, hide `mainWebView` until after the night mode CSS is applied. if (nightMode) { mainWebView.setVisibility(View.INVISIBLE); } @@ -1249,7 +1313,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Hide the keyboard. `0` indicates no additional flags. inputMethodManager.hideSoftInputFromWindow(mainWebView.getWindowToken(), 0); - // Check to see if we are waiting on Orbot. + // Check to see if Privacy Browser is waiting on Orbot. if (!waitingForOrbot) { // We are not waiting on Orbot, so we need to process the URL. // We need to update `formattedUrlString` at the beginning of the load, so that if the user toggles JavaScript during the load the new website is reloaded. formattedUrlString = url; @@ -1633,6 +1697,10 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook MenuItem clearCookiesMenuItem = menu.findItem(R.id.clear_cookies); MenuItem clearDOMStorageMenuItem = menu.findItem(R.id.clear_dom_storage); MenuItem clearFormDataMenuItem = menu.findItem(R.id.clear_form_data); // Form data can be removed once the minimum API >= 26. + MenuItem easyListMenuItem = menu.findItem(R.id.easylist); + MenuItem easyPrivacyMenuItem = menu.findItem(R.id.easyprivacy); + MenuItem fanboysAnnoyanceListMenuItem = menu.findItem(R.id.fanboys_annoyance_list); + MenuItem fanboysSocialBlockingListMenuItem = menu.findItem(R.id.fanboys_social_blocking_list); MenuItem fontSizeMenuItem = menu.findItem(R.id.font_size); MenuItem swipeToRefreshMenuItem = menu.findItem(R.id.swipe_to_refresh); MenuItem displayImagesMenuItem = menu.findItem(R.id.display_images); @@ -1649,44 +1717,51 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook 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); swipeToRefreshMenuItem.setChecked(swipeRefreshLayout.isEnabled()); displayImagesMenuItem.setChecked(mainWebView.getSettings().getLoadsImagesAutomatically()); // Enable third-party cookies if first-party cookies are enabled. toggleThirdPartyCookiesMenuItem.setEnabled(firstPartyCookiesEnabled); - // Enable `DOM Storage` if JavaScript is enabled. + // Enable DOM Storage if JavaScript is enabled. toggleDomStorageMenuItem.setEnabled(javaScriptEnabled); - // Enable `Clear Cookies` if there are any. + // Enable Clear Cookies if there are any. clearCookiesMenuItem.setEnabled(cookieManager.hasCookies()); - // Get a count of the number of files in the `Local Storage` directory. + // Get a count of the number of files in the Local Storage directory. File localStorageDirectory = new File (privateDataDirectoryString + "/app_webview/Local Storage/"); int localStorageDirectoryNumberOfFiles = 0; if (localStorageDirectory.exists()) { localStorageDirectoryNumberOfFiles = localStorageDirectory.list().length; } - // Get a count of the number of files in the `IndexedDB` directory. + // Get a count of the number of files in the IndexedDB directory. File indexedDBDirectory = new File (privateDataDirectoryString + "/app_webview/IndexedDB"); int indexedDBDirectoryNumberOfFiles = 0; if (indexedDBDirectory.exists()) { indexedDBDirectoryNumberOfFiles = indexedDBDirectory.list().length; } - // Enable `Clear DOM Storage` if there is any. + // Enable Clear DOM Storage if there is any. clearDOMStorageMenuItem.setEnabled(localStorageDirectoryNumberOfFiles > 0 || indexedDBDirectoryNumberOfFiles > 0); - // Enable `Clear Form Data` is there is any. This can be removed once the minimum API >= 26. + // Enable Clear Form Data is there is any. This can be removed once the minimum API >= 26. if (Build.VERSION.SDK_INT < 26) { WebViewDatabase mainWebViewDatabase = WebViewDatabase.getInstance(this); clearFormDataMenuItem.setEnabled(mainWebViewDatabase.hasFormData()); } - // Enable `Clear Data` if any of the submenu items are enabled. + // 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); + // Initialize font size variables. int fontSize = mainWebView.getSettings().getTextZoom(); String fontSizeTitle; @@ -2074,6 +2149,54 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook startActivity(viewSourceIntent); return true; + case R.id.easylist: + // Toggle the EasyList status. + easyListEnabled = !easyListEnabled; + + // Update the menu checkbox. + menuItem.setChecked(easyListEnabled); + + // Reload the main WebView. + mainWebView.reload(); + return true; + + case R.id.easyprivacy: + // Toggle the EasyPrivacy status. + easyPrivacyEnabled = !easyPrivacyEnabled; + + // Update the menu checkbox. + menuItem.setChecked(easyPrivacyEnabled); + + // Reload the main WebView. + mainWebView.reload(); + return true; + + case R.id.fanboys_annoyance_list: + // Toggle Fanboy's Annoyance List status. + fanboysAnnoyanceListEnabled = !fanboysAnnoyanceListEnabled; + + // Update the menu checkbox. + menuItem.setChecked(fanboysAnnoyanceListEnabled); + + // Update the staus of Fanboy's Social Blocking List. + MenuItem fanboysSocialBlockingListMenuItem = mainMenu.findItem(R.id.fanboys_social_blocking_list); + fanboysSocialBlockingListMenuItem.setEnabled(!fanboysAnnoyanceListEnabled); + + // Reload the main WebView. + mainWebView.reload(); + return true; + + case R.id.fanboys_social_blocking_list: + // Toggle Fanboy's Social Blocking List status. + fanboysSocialBlockingListEnabled = !fanboysSocialBlockingListEnabled; + + // Update teh menu checkbox. + menuItem.setChecked(fanboysSocialBlockingListEnabled); + + // Reload the main WebView. + mainWebView.reload(); + return true; + case R.id.share: // Setup the share string. String shareString = webViewTitle + " – " + urlTextBox.getText().toString(); @@ -2184,6 +2307,12 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook urlHistoryDialogFragment.show(getSupportFragmentManager(), getString(R.string.history)); break; + case R.id.requests: + // Launch the requests activity. + Intent requestsIntent = new Intent(this, RequestsActivity.class); + startActivity(requestsIntent); + break; + case R.id.downloads: // Launch the system Download Manager. Intent downloadManagerIntent = new Intent(DownloadManager.ACTION_VIEW_DOWNLOADS); @@ -2199,7 +2328,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook reapplyDomainSettingsOnRestart = true; currentDomainName = ""; - // Launch `DomainsActivity`. + // Launch the domains activity. Intent domainsIntent = new Intent(this, DomainsActivity.class); startActivity(domainsIntent); break; @@ -2212,7 +2341,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook reapplyDomainSettingsOnRestart = true; currentDomainName = ""; - // Launch `SettingsActivity`. + // Launch the settings activity. Intent settingsIntent = new Intent(this, SettingsActivity.class); startActivity(settingsIntent); break; @@ -3118,16 +3247,14 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook loadUrl(formattedUrlString); } - - private void loadUrl(String url) { - // Apply any custom domain settings. + private void loadUrl(String url) {// Apply any custom domain settings. applyDomainSettings(url, true, false); - // Load the URL. - mainWebView.loadUrl(url, customHeaders); - // Set `urlIsLoading` to prevent changes in the user agent on websites with redirects from reloading the current website. urlIsLoading = true; + + // Load the URL. + mainWebView.loadUrl(url, customHeaders); } public void findPreviousOnPage(View view) { @@ -3571,7 +3698,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook } else { urlAppBarRelativeLayout.setBackground(getResources().getDrawable(R.drawable.url_bar_background_light_green)); } - } else { // The URL we are loading does not have custom domain settings. Load the defaults. + } else { // The new URL does not have custom domain settings. Load the defaults. // Store the values from `sharedPreferences` in variables. javaScriptEnabled = sharedPreferences.getBoolean("javascript_enabled", false); firstPartyCookiesEnabled = sharedPreferences.getBoolean("first_party_cookies_enabled", false); @@ -3664,11 +3791,11 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook if (mainMenu != null) { updatePrivacyIcons(true); } + } - // Reload the website if returning from the Domains activity. - if (reloadWebsite) { - mainWebView.reload(); - } + // Reload the website if returning from the Domains activity. + if (reloadWebsite) { + mainWebView.reload(); } }