X-Git-Url: https://gitweb.stoutner.com/?p=PrivacyBrowserAndroid.git;a=blobdiff_plain;f=app%2Fsrc%2Fmain%2Fjava%2Fcom%2Fstoutner%2Fprivacybrowser%2Factivities%2FMainWebView.java;h=3ee406ce8abe77c648230ca9c827766c2e69b0a7;hp=2e5503b639c752084ff3d11305defe99fd0b1613;hb=acae0260d295ddab13d47bf6e011ae4ebe8b5e44;hpb=e59f99e8ba2f66916186c13dabea9686e1b6f70f diff --git a/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebView.java b/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebView.java index 2e5503b6..3ee406ce 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebView.java +++ b/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebView.java @@ -1,6 +1,8 @@ /** * Copyright 2015-2017 Soren Stoutner . * + * Download cookie code contributed 2017 Hendrik Knackstedt. Copyright assigned to Soren Stoutner . + * * This file is part of Privacy Browser . * * Privacy Browser is free software: you can redistribute it and/or modify @@ -142,7 +144,7 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN // `swipeRefreshLayout` is used in `onCreate()`, `onPrepareOptionsMenu`, and `onRestart()`. private SwipeRefreshLayout swipeRefreshLayout; - // `cookieManager` is used in `onCreate()`, `onOptionsItemSelected()`, and `onNavigationItemSelected()`, and `onRestart()`. + // `cookieManager` is used in `onCreate()`, `onOptionsItemSelected()`, and `onNavigationItemSelected()`, `onDownloadImage()`, `onDownloadFile()`, and `onRestart()`. private CookieManager cookieManager; // `customHeader` is used in `onCreate()`, `onOptionsItemSelected()`, `onCreateContextMenu()`, and `loadUrlFromTextBox()`. @@ -152,7 +154,7 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN // It is `Boolean` instead of `boolean` because `applySettings()` needs to know if it is `null`. private Boolean javaScriptEnabled; - // `firstPartyCookiesEnabled` is used in `onCreate()`, `onCreateOptionsMenu()`, `onPrepareOptionsMenu()`, `onOptionsItemSelected()`, and `applySettings()`. + // `firstPartyCookiesEnabled` is used in `onCreate()`, `onCreateOptionsMenu()`, `onPrepareOptionsMenu()`, `onOptionsItemSelected()`, `onDownloadImage()`, `onDownloadFile()`, and `applySettings()`. private boolean firstPartyCookiesEnabled; // `thirdPartyCookiesEnabled` used in `onCreate()`, `onCreateOptionsMenu()`, `onPrepareOptionsMenu()`, `onOptionsItemSelected()`, and `applySettings()`. @@ -528,7 +530,7 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN // Create a variable to track if this is an ad server. boolean requestHostIsAdServer = false; - // Check all the subdomains of `requestHost` if it is not null. + // Check all the subdomains of `requestHost` if it is not `null`. if (requestHost != null) { while (requestHost.contains(".")) { if (adServersSet.contains(requestHost)) { @@ -1178,6 +1180,14 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN startActivity(settingsIntent); break; + /* + case R.id.domains: + // Launch `DomainsList`. + Intent domainsIntent = new Intent(this, DomainsList.class); + startActivity(domainsIntent); + break; + */ + case R.id.guide: // Launch `Guide`. Intent guideIntent = new Intent(this, Guide.class); @@ -1227,6 +1237,15 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN // Destroy the internal state of `mainWebView`. mainWebView.destroy(); + // Manually delete the `app_webview` folder, which contains an additional `WebView` cache. See `https://code.google.com/p/android/issues/detail?id=233826&thanks=233826&ts=1486670530`. + Runtime runtime = Runtime.getRuntime(); + String dataDirString = 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`. + try { + runtime.exec("rm -rf " + dataDirString + "/app_webview"); + } catch (IOException e) { + // Do nothing if the files do not exist. + } + // Close Privacy Browser. `finishAndRemoveTask` also removes Privacy Browser from the recent app list. if (Build.VERSION.SDK_INT >= 21) { finishAndRemoveTask(); @@ -1476,66 +1495,95 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN @Override public void onDownloadImage(AppCompatDialogFragment dialogFragment, String imageUrl) { - // Get a handle for the system `DOWNLOAD_SERVICE`. - DownloadManager downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE); + // Download the image if it has an HTTP or HTTPS URI. + if (imageUrl.startsWith("http")) { + // Get a handle for the system `DOWNLOAD_SERVICE`. + DownloadManager downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE); - // Parse `imageUrl`. - DownloadManager.Request downloadRequest = new DownloadManager.Request(Uri.parse(imageUrl)); + // Parse `imageUrl`. + DownloadManager.Request downloadRequest = new DownloadManager.Request(Uri.parse(imageUrl)); - // Get the file name from `dialogFragment`. - EditText downloadImageNameEditText = (EditText) dialogFragment.getDialog().findViewById(R.id.download_image_name); - String imageName = downloadImageNameEditText.getText().toString(); + // Pass cookies to download manager if cookies are enabled. This is required to download images from websites that require a login. + if (firstPartyCookiesEnabled) { + // Get the cookies for `imageUrl`. + String cookies = cookieManager.getCookie(imageUrl); - // Once we have `WRITE_EXTERNAL_STORAGE` permissions we can use `setDestinationInExternalPublicDir`. - if (Build.VERSION.SDK_INT >= 23) { // If API >= 23, set the download save in the the `DIRECTORY_DOWNLOADS` using `imageName`. - downloadRequest.setDestinationInExternalFilesDir(this, "/", imageName); - } else { // Only set the title using `imageName`. - downloadRequest.setTitle(imageName); - } + // Add the cookies to `downloadRequest`. In the HTTP request header, cookies are named `Cookie`. + downloadRequest.addRequestHeader("Cookie", cookies); + } + + // Get the file name from `dialogFragment`. + EditText downloadImageNameEditText = (EditText) dialogFragment.getDialog().findViewById(R.id.download_image_name); + String imageName = downloadImageNameEditText.getText().toString(); - // Allow `MediaScanner` to index the download if it is a media file. - downloadRequest.allowScanningByMediaScanner(); + // Once we have `WRITE_EXTERNAL_STORAGE` permissions we can use `setDestinationInExternalPublicDir`. + if (Build.VERSION.SDK_INT >= 23) { // If API >= 23, set the download save in the the `DIRECTORY_DOWNLOADS` using `imageName`. + downloadRequest.setDestinationInExternalFilesDir(this, "/", imageName); + } else { // Only set the title using `imageName`. + downloadRequest.setTitle(imageName); + } - // Add the URL as the description for the download. - downloadRequest.setDescription(imageUrl); + // Allow `MediaScanner` to index the download if it is a media file. + downloadRequest.allowScanningByMediaScanner(); - // Show the download notification after the download is completed. - downloadRequest.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); + // Add the URL as the description for the download. + downloadRequest.setDescription(imageUrl); - // Initiate the download. - downloadManager.enqueue(downloadRequest); + // Show the download notification after the download is completed. + downloadRequest.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); + + // Initiate the download. + downloadManager.enqueue(downloadRequest); + } else { // The image is not an HTTP or HTTPS URI. + Snackbar.make(mainWebView, R.string.cannot_download_image, Snackbar.LENGTH_INDEFINITE).show(); + } } @Override public void onDownloadFile(AppCompatDialogFragment dialogFragment, String downloadUrl) { - // Get a handle for the system `DOWNLOAD_SERVICE`. - DownloadManager downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE); + // Download the file if it has an HTTP or HTTPS URI. + if (downloadUrl.startsWith("http")) { - // Parse `downloadUrl`. - DownloadManager.Request downloadRequest = new DownloadManager.Request(Uri.parse(downloadUrl)); + // Get a handle for the system `DOWNLOAD_SERVICE`. + DownloadManager downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE); - // Get the file name from `dialogFragment`. - EditText downloadFileNameEditText = (EditText) dialogFragment.getDialog().findViewById(R.id.download_file_name); - String fileName = downloadFileNameEditText.getText().toString(); + // Parse `downloadUrl`. + DownloadManager.Request downloadRequest = new DownloadManager.Request(Uri.parse(downloadUrl)); - // Once we have `WRITE_EXTERNAL_STORAGE` permissions we can use `setDestinationInExternalPublicDir`. - if (Build.VERSION.SDK_INT >= 23) { // If API >= 23, set the download location to `/sdcard/Android/data/com.stoutner.privacybrowser.standard/files` named `fileName`. - downloadRequest.setDestinationInExternalFilesDir(this, "/", fileName); - } else { // Only set the title using `fileName`. - downloadRequest.setTitle(fileName); - } + // Pass cookies to download manager if cookies are enabled. This is required to download files from websites that require a login. + if (firstPartyCookiesEnabled) { + // Get the cookies for `downloadUrl`. + String cookies = cookieManager.getCookie(downloadUrl); + + // Add the cookies to `downloadRequest`. In the HTTP request header, cookies are named `Cookie`. + downloadRequest.addRequestHeader("Cookie", cookies); + } + + // Get the file name from `dialogFragment`. + EditText downloadFileNameEditText = (EditText) dialogFragment.getDialog().findViewById(R.id.download_file_name); + String fileName = downloadFileNameEditText.getText().toString(); + + // Once we have `WRITE_EXTERNAL_STORAGE` permissions we can use `setDestinationInExternalPublicDir`. + if (Build.VERSION.SDK_INT >= 23) { // If API >= 23, set the download location to `/sdcard/Android/data/com.stoutner.privacybrowser.standard/files` named `fileName`. + downloadRequest.setDestinationInExternalFilesDir(this, "/", fileName); + } else { // Only set the title using `fileName`. + downloadRequest.setTitle(fileName); + } - // Allow `MediaScanner` to index the download if it is a media file. - downloadRequest.allowScanningByMediaScanner(); + // Allow `MediaScanner` to index the download if it is a media file. + downloadRequest.allowScanningByMediaScanner(); - // Add the URL as the description for the download. - downloadRequest.setDescription(downloadUrl); + // Add the URL as the description for the download. + downloadRequest.setDescription(downloadUrl); - // Show the download notification after the download is completed. - downloadRequest.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); + // Show the download notification after the download is completed. + downloadRequest.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); - // Initiate the download. - downloadManager.enqueue(downloadRequest); + // Initiate the download. + downloadManager.enqueue(downloadRequest); + } else { // The download is not an HTTP or HTTPS URI. + Snackbar.make(mainWebView, R.string.cannot_download_file, Snackbar.LENGTH_INDEFINITE).show(); + } } public void viewSslCertificate(View view) { @@ -1710,10 +1758,15 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN String userAgentString = sharedPreferences.getString("user_agent", "PrivacyBrowser/1.0"); String customUserAgentString = sharedPreferences.getString("custom_user_agent", "PrivacyBrowser/1.0"); String javaScriptDisabledSearchString = sharedPreferences.getString("javascript_disabled_search", "https://duckduckgo.com/html/?q="); - String javaScriptDisabledCustomSearchString = sharedPreferences.getString("javascript_disabled_search_custom_url", ""); + String javaScriptDisabledSearchCustomURLString = sharedPreferences.getString("javascript_disabled_search_custom_url", ""); String javaScriptEnabledSearchString = sharedPreferences.getString("javascript_enabled_search", "https://duckduckgo.com/?q="); - String javaScriptEnabledCustomSearchString = sharedPreferences.getString("javascript_enabled_search_custom_url", ""); + String javaScriptEnabledSearchCustomURLString = sharedPreferences.getString("javascript_enabled_search_custom_url", ""); String homepageString = sharedPreferences.getString("homepage", "https://www.duckduckgo.com"); + String torHomepageString = sharedPreferences.getString("tor_homepage", "https://3g2upl4pq6kufc4m.onion"); + String torJavaScriptDisabledSearchString = sharedPreferences.getString("tor_javascript_disabled_search", "https://3g2upl4pq6kufc4m.onion/html/?q="); + String torJavaScriptDisabledSearchCustomURLString = sharedPreferences.getString("tor_javascript_disabled_search_custom_url", ""); + String torJavaScriptEnabledSearchString = sharedPreferences.getString("tor_javascript_enabled_search", "https://3g2upl4pq6kufc4m.onion/?q="); + String torJavaScriptEnabledSearchCustomURLString = sharedPreferences.getString("tor_javascript_enabled_search_custom_url", ""); String defaultFontSizeString = sharedPreferences.getString("default_font_size", "100"); swipeToRefreshEnabled = sharedPreferences.getBoolean("swipe_to_refresh_enabled", false); adBlockerEnabled = sharedPreferences.getBoolean("block_ads", true); @@ -1745,8 +1798,50 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN } } - // Apply the other settings from `sharedPreferences`. - homepage = homepageString; + // Set the homepage, search, and proxy options. + if (proxyThroughOrbot) { // Set the Tor options. + // Set `torHomepageString` as `homepage`. + homepage = torHomepageString; + + // Set JavaScript disabled search. + if (torJavaScriptDisabledSearchString.equals("Custom URL")) { // Get the custom URL string. + javaScriptDisabledSearchURL = torJavaScriptDisabledSearchCustomURLString; + } else { // Use the string from the pre-built list. + javaScriptDisabledSearchURL = torJavaScriptDisabledSearchString; + } + + // Set JavaScript enabled search. + if (torJavaScriptEnabledSearchString.equals("Custom URL")) { // Get the custom URL string. + javaScriptEnabledSearchURL = torJavaScriptEnabledSearchCustomURLString; + } else { // Use the string from the pre-built list. + javaScriptEnabledSearchURL = torJavaScriptEnabledSearchString; + } + + // Set the proxy. `this` refers to the current activity where an `AlertDialog` might be displayed. + OrbotProxyHelper.setProxy(getApplicationContext(), this, "localhost", "8118"); + } else { // Set the non-Tor options. + // Set `homepageString` as `homepage`. + homepage = homepageString; + + // Set JavaScript disabled search. + if (javaScriptDisabledSearchString.equals("Custom URL")) { // Get the custom URL string. + javaScriptDisabledSearchURL = javaScriptDisabledSearchCustomURLString; + } else { // Use the string from the pre-built list. + javaScriptDisabledSearchURL = javaScriptDisabledSearchString; + } + + // Set JavaScript enabled search. + if (javaScriptEnabledSearchString.equals("Custom URL")) { // Get the custom URL string. + javaScriptEnabledSearchURL = javaScriptEnabledSearchCustomURLString; + } else { // Use the string from the pre-built list. + javaScriptEnabledSearchURL = javaScriptEnabledSearchString; + } + + // Reset the proxy to default. The host is `""` and the port is `"0"`. + OrbotProxyHelper.setProxy(getApplicationContext(), this, "", "0"); + } + + // Set swipe to refresh. swipeRefreshLayout.setEnabled(swipeToRefreshEnabled); // Set the user agent initial status. @@ -1767,20 +1862,6 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN break; } - // Set JavaScript disabled search. - if (javaScriptDisabledSearchString.equals("Custom URL")) { // Get the custom URL string. - javaScriptDisabledSearchURL = javaScriptDisabledCustomSearchString; - } else { // Use the string from the pre-built list. - javaScriptDisabledSearchURL = javaScriptDisabledSearchString; - } - - // Set JavaScript enabled search. - if (javaScriptEnabledSearchString.equals("Custom URL")) { // Get the custom URL string. - javaScriptEnabledSearchURL = javaScriptEnabledCustomSearchString; - } else { // Use the string from the pre-built list. - javaScriptEnabledSearchURL = javaScriptEnabledSearchString; - } - // Set Do Not Track status. if (doNotTrackEnabled) { customHeaders.put("DNT", "1"); @@ -1788,14 +1869,6 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN customHeaders.remove("DNT"); } - // Set Orbot proxy status. - if (proxyThroughOrbot) { - // Set the proxy. `this` refers to the current activity where an `AlertDialog` might be displayed. - OrbotProxyHelper.setProxy(getApplicationContext(), this, "localhost", "8118"); - } else { // Reset the proxy to default. The host is `""` and the port is `"0"`. - OrbotProxyHelper.setProxy(getApplicationContext(), this, "", "0"); - } - // If we are in full screen mode update the `SYSTEM_UI` flags. if (inFullScreenBrowsingMode) { if (hideSystemBarsOnFullscreen) { // Hide everything.