X-Git-Url: https://gitweb.stoutner.com/?a=blobdiff_plain;f=app%2Fsrc%2Fmain%2Fjava%2Fcom%2Fstoutner%2Fprivacybrowser%2Factivities%2FMainWebView.java;h=cf7cbdad3fb7f817f4e9d172b9699fabcee0b71e;hb=4474c3d7c1c831fa46a3bfc17056bbd87ecacb9f;hp=b9c2746a828aa923e24178784fc8a16afa786345;hpb=c3c399fcc6ada5f970e3d75102ad8e61303903a0;p=PrivacyBrowserAndroid.git 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 b9c2746a..cf7cbdad 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebView.java +++ b/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebView.java @@ -1,5 +1,7 @@ /** - * Copyright 2015-2016 Soren Stoutner . + * Copyright 2015-2017 Soren Stoutner . + * + * Download cookie code contributed 2017 Hendrik Knackstedt. Copyright assigned to Soren Stoutner . * * This file is part of Privacy Browser . * @@ -55,6 +57,7 @@ import android.support.v7.app.AppCompatDialogFragment; import android.support.v7.widget.Toolbar; import android.text.Editable; import android.text.TextWatcher; +import android.util.Log; import android.util.Patterns; import android.view.ContextMenu; import android.view.GestureDetector; @@ -127,7 +130,6 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN public static SslCertificate sslCertificate; - // `drawerLayout` is used in `onCreate()`, `onNewIntent()`, and `onBackPressed()`. private DrawerLayout drawerLayout; @@ -143,7 +145,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()`. @@ -153,7 +155,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()`. @@ -529,14 +531,16 @@ 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`. - while (requestHost.contains(".")) { - if (adServersSet.contains(requestHost)) { - requestHostIsAdServer = true; - } + // Check all the subdomains of `requestHost` if it is not `null`. + if (requestHost != null) { + while (requestHost.contains(".")) { + if (adServersSet.contains(requestHost)) { + requestHostIsAdServer = true; + } - // Strip out the lowest subdomain of `requestHost`. - requestHost = requestHost.substring(requestHost.indexOf(".") + 1); + // Strip out the lowest subdomain of `requestHost`. + requestHost = requestHost.substring(requestHost.indexOf(".") + 1); + } } if (requestHostIsAdServer) { // It is an ad server. @@ -1226,6 +1230,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(); @@ -1475,66 +1488,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); + } + + // 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(imageUrl); + // Add the URL as the description for the download. + downloadRequest.setDescription(imageUrl); - // 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 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 save in the the `DIRECTORY_DOWNLOADS` using `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(); - // 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 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); + } - // Add the URL as the description for the download. - downloadRequest.setDescription(downloadUrl); + // 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(downloadUrl); - // 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 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) { @@ -1716,7 +1758,7 @@ public class MainWebView extends AppCompatActivity implements NavigationView.OnN String defaultFontSizeString = sharedPreferences.getString("default_font_size", "100"); swipeToRefreshEnabled = sharedPreferences.getBoolean("swipe_to_refresh_enabled", false); adBlockerEnabled = sharedPreferences.getBoolean("block_ads", true); - boolean doNotTrackEnabled = sharedPreferences.getBoolean("do_not_track", true); + boolean doNotTrackEnabled = sharedPreferences.getBoolean("do_not_track", false); boolean proxyThroughOrbot = sharedPreferences.getBoolean("proxy_through_orbot", false); fullScreenBrowsingModeEnabled = sharedPreferences.getBoolean("enable_full_screen_browsing_mode", false); hideSystemBarsOnFullscreen = sharedPreferences.getBoolean("hide_system_bars", false);