implementation 'com.google.android.material:material:1.1.0'
// Only compile Firebase ads for the free flavor.
- freeImplementation 'com.google.firebase:firebase-ads:19.0.0'
+ freeImplementation 'com.google.firebase:firebase-ads:19.0.1'
}
\ No newline at end of file
import com.stoutner.privacybrowser.R;
import com.stoutner.privacybrowser.dialogs.StoragePermissionDialog;
+import com.stoutner.privacybrowser.helpers.DownloadLocationHelper;
import com.stoutner.privacybrowser.helpers.FileNameHelper;
import com.stoutner.privacybrowser.helpers.ImportExportDatabaseHelper;
openKeychainImportInstructionsTextView.setVisibility(View.GONE);
importExportButton.setVisibility(View.GONE);
- // Create strings for the default file paths.
- String defaultFilePath;
- String defaultPasswordEncryptionFilePath;
- String defaultPgpFilePath;
+ // Instantiate the download location helper.
+ DownloadLocationHelper downloadLocationHelper = new DownloadLocationHelper();
- // Set the default file paths according to the storage permission status.
- if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { // The storage permission has been granted.
- // Set the default file paths to use the external public directory.
- defaultFilePath = Environment.getExternalStorageDirectory() + "/" + getString(R.string.settings_pbs);
- defaultPasswordEncryptionFilePath = defaultFilePath + ".aes";
- defaultPgpFilePath = defaultFilePath + ".pgp";
+ // Get the default file path.
+ String defaultFilePath = downloadLocationHelper.getDownloadLocation(this) + "/" + getString(R.string.settings_pbs);
- // Hide the storage permission text view.
- storagePermissionTextView.setVisibility(View.GONE);
- } else { // The storage permission has not been granted.
- // Set the default file paths to use the external private directory.
- defaultFilePath = getApplicationContext().getExternalFilesDir(null) + "/" + getString(R.string.settings_pbs);
- defaultPasswordEncryptionFilePath = defaultFilePath + ".aes";
- defaultPgpFilePath = defaultFilePath + ".pgp";
- }
+ // Set the other default file paths.
+ String defaultPasswordEncryptionFilePath = defaultFilePath + ".aes";
+ String defaultPgpFilePath = defaultFilePath + ".pgp";
// Set the default file path.
fileNameEditText.setText(defaultFilePath);
+ // Hide the storage permission text view if the permission has already been granted.
+ if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
+ storagePermissionTextView.setVisibility(View.GONE);
+ }
+
// Update the UI when the spinner changes.
encryptionSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
// Launch as a new task so that Download Manager and Privacy Browser show as separate windows in the recent tasks list.
downloadManagerIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ // Make it so.
startActivity(downloadManagerIntent);
break;
// Disconnect HTTP URL connection.
httpUrlConnection.disconnect();
}
- } catch (IOException exception) {
- exception.printStackTrace();
+ } catch (Exception exception) {
+ // Do nothing.
}
// Return the response body string as the result.
import com.stoutner.privacybrowser.R;
import com.stoutner.privacybrowser.helpers.ProxyHelper;
-import java.io.IOException;
import java.lang.ref.WeakReference;
import java.net.HttpURLConnection;
import java.net.Proxy;
Proxy proxy = proxyHelper.getCurrentProxy(context);
// Open a connection to the URL. No data is actually sent at this point.
- HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection(proxy);
+ HttpURLConnection httpUrlConnection = (HttpURLConnection) url.openConnection(proxy);
// Add the user agent to the header property.
- httpURLConnection.setRequestProperty("User-Agent", userAgent);
+ httpUrlConnection.setRequestProperty("User-Agent", userAgent);
// Add the cookies if they are enabled.
if (cookiesEnabled) {
// Only add the cookies if they are not null.
if (cookiesString != null) {
// Add the cookies to the header property.
- httpURLConnection.setRequestProperty("Cookie", cookiesString);
+ httpUrlConnection.setRequestProperty("Cookie", cookiesString);
}
}
// Exit if the task has been cancelled.
if (isCancelled()) {
// Disconnect the HTTP URL connection.
- httpURLConnection.disconnect();
+ httpUrlConnection.disconnect();
// Return the formatted file size string.
return formattedFileSize;
}
// Get the status code.
- int responseCode = httpURLConnection.getResponseCode();
+ int responseCode = httpUrlConnection.getResponseCode();
// Exit if the task has been cancelled.
if (isCancelled()) {
// Disconnect the HTTP URL connection.
- httpURLConnection.disconnect();
+ httpUrlConnection.disconnect();
// Return the formatted file size string.
return formattedFileSize;
formattedFileSize = context.getString(R.string.invalid_url);
} else { // The response code is not an error message.
// Get the content length header.
- String contentLengthString = httpURLConnection.getHeaderField("Content-Length");
+ String contentLengthString = httpUrlConnection.getHeaderField("Content-Length");
// Define the file size long.
long fileSize;
}
} finally {
// Disconnect the HTTP URL connection.
- httpURLConnection.disconnect();
+ httpUrlConnection.disconnect();
}
- } catch (IOException exception) {
+ } catch (Exception exception) {
// Set the formatted file size to indicate a bad URL.
formattedFileSize = context.getString(R.string.invalid_url);
}
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
-import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.ref.WeakReference;
// Close the output stream.
outputStream.close();
- // Define a media scanner intent, which adds items like pictures to Android's recent file list.
+ // Create a media scanner intent, which adds items like pictures to Android's recent file list.
Intent mediaScannerIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
// Add the URI to the media scanner intent.
// Disconnect the HTTP URL connection.
httpUrlConnection.disconnect();
}
- } catch (IOException exception) {
+ } catch (Exception exception) {
// Store the error in the save disposition string.
saveDisposition = exception.toString();
}
import com.stoutner.privacybrowser.R;
import com.stoutner.privacybrowser.activities.MainWebViewActivity;
+import com.stoutner.privacybrowser.helpers.DownloadLocationHelper;
import java.io.File;
TextView storagePermissionTextView = alertDialog.findViewById(R.id.storage_permission_textview);
Button openButton = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
- // Create a string for the default file path.
- String defaultFilePath;
-
// Update the status of the open button when the file name changes.
fileNameEditText.addTextChangedListener(new TextWatcher() {
@Override
}
});
- // Set the default file path according to the storage permission state.
- if (ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { // The storage permission has been granted.
- // Set the default file path to use the external public directory.
- defaultFilePath = Environment.getExternalStorageDirectory() + "/";
+ // Instantiate the download location helper.
+ DownloadLocationHelper downloadLocationHelper = new DownloadLocationHelper();
- // Hide the storage permission text view.
- storagePermissionTextView.setVisibility(View.GONE);
- } else { // The storage permission has not been granted.
- // Set the default file path to use the external private directory.
- defaultFilePath = context.getExternalFilesDir(null) + "/";
- }
+ // Get the default file path.
+ String defaultFilePath = downloadLocationHelper.getDownloadLocation(context) + "/";
// Display the default file path.
fileNameEditText.setText(defaultFilePath);
// Move the cursor to the end of the default file path.
fileNameEditText.setSelection(defaultFilePath.length());
+ // Hide the storage permission text view if the permission has already been granted.
+ if (ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
+ storagePermissionTextView.setVisibility(View.GONE);
+ }
+
// Handle clicks on the browse button.
browseButton.setOnClickListener((View view) -> {
// Create the file picker intent.
import com.stoutner.privacybrowser.R;
import com.stoutner.privacybrowser.activities.MainWebViewActivity;
import com.stoutner.privacybrowser.asynctasks.GetUrlSize;
+import com.stoutner.privacybrowser.helpers.DownloadLocationHelper;
import java.io.File;
// Save the file name as the default file name. This must be final to be used in the lambda below.
final String defaultFileName = fileName;
- // Create a string for the default file path.
- String defaultFilePath;
+ // Instantiate the download location helper.
+ DownloadLocationHelper downloadLocationHelper = new DownloadLocationHelper();
- // Set the default file path according to the storage permission state.
- if (ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { // The storage permission has been granted.
- // Set the default file path to use the external public directory.
- defaultFilePath = Environment.getExternalStorageDirectory() + "/" + defaultFileName;
+ // Get the default file path.
+ String defaultFilePath = downloadLocationHelper.getDownloadLocation(context) + "/" + defaultFileName;
- // Hide the storage permission text view.
+ // Hide the storage permission text view if the permission has already been granted.
+ if (ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
storagePermissionTextView.setVisibility(View.GONE);
- } else { // The storage permission has not been granted.
- // Set the default file path to use the external private directory.
- defaultFilePath = context.getExternalFilesDir(null) + "/" + defaultFileName;
}
// Populate the edit texts.
import androidx.fragment.app.DialogFragment; // The AndroidX dialog fragment is required or an error is produced on API <=22. It is also required for the browse button to work correctly.
import com.stoutner.privacybrowser.R;
+import com.stoutner.privacybrowser.helpers.DownloadLocationHelper;
import java.io.File;
// Use an alert dialog builder to create the alert dialog.
AlertDialog.Builder dialogBuilder;
- // Get a handle for the activity.
+ // Get a handle for the activity and the context.
Activity activity = getActivity();
+ Context context = getContext();
- // Remove the incorrect lint warning below that the activity might be null.
+ // Remove the incorrect lint warnings.
assert activity != null;
+ assert context != null;
// Set the style according to the theme.
if (darkTheme) {
}
});
- // Create a string for the default file path.
- String defaultFilePath;
+ // Instantiate the download location helper.
+ DownloadLocationHelper downloadLocationHelper = new DownloadLocationHelper();
- // Get a handle for the context.
- Context context = getContext();
-
- // Remove the incorrect lint warning below that context might be null.
- assert context != null;
+ // Get the default file path.
+ String defaultFilePath = downloadLocationHelper.getDownloadLocation(context) + "/" + getString(R.string.privacy_browser_logcat_txt);
- // Set the default file path according to the storage permission state.
- if (ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { // The storage permission has been granted.
- // Set the default file path to use the external public directory.
- defaultFilePath = Environment.getExternalStorageDirectory() + "/" + getString(R.string.privacy_browser_logcat_txt);
+ // Display the default file path.
+ fileNameEditText.setText(defaultFilePath);
- // Hide the storage permission text view.
+ // Hide the storage permission text view if the permission has already been granted.
+ if (ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
storagePermissionTextView.setVisibility(View.GONE);
- } else { // The storage permission has not been granted.
- // Set the default file path to use the external private directory.
- defaultFilePath = context.getExternalFilesDir(null) + "/" + getString(R.string.privacy_browser_logcat_txt);
}
- // Display the default file path.
- fileNameEditText.setText(defaultFilePath);
-
// Handle clicks on the browse button.
browseButton.setOnClickListener((View view) -> {
// Create the file picker intent.
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
+import android.content.res.Resources;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import com.stoutner.privacybrowser.R;
import com.stoutner.privacybrowser.activities.MainWebViewActivity;
+import com.stoutner.privacybrowser.helpers.DownloadLocationHelper;
import com.stoutner.privacybrowser.helpers.ProxyHelper;
public class SettingsFragment extends PreferenceFragmentCompat {
Preference clearFormDataPreference = findPreference("clear_form_data"); // The clear form data preference can be removed once the minimum API >= 26.
Preference clearCachePreference = findPreference("clear_cache");
Preference homepagePreference = findPreference("homepage");
+ Preference downloadLocationPreference = findPreference("download_location");
+ Preference downloadCustomLocationPreference = findPreference("download_custom_location");
Preference fontSizePreference = findPreference("font_size");
Preference openIntentsInNewTabPreference = findPreference("open_intents_in_new_tab");
Preference swipeToRefreshPreference = findPreference("swipe_to_refresh");
assert clearFormDataPreference != null;
assert clearCachePreference != null;
assert homepagePreference != null;
+ assert downloadLocationPreference != null;
+ assert downloadCustomLocationPreference != null;
assert fontSizePreference != null;
assert openIntentsInNewTabPreference != null;
assert swipeToRefreshPreference != null;
hideAppBarPreference.setDependency("full_screen_browsing_mode");
// Get strings from the preferences.
+ String userAgentName = savedPreferences.getString("user_agent", getString(R.string.user_agent_default_value));
String searchString = savedPreferences.getString("search", getString(R.string.search_default_value));
String proxyString = savedPreferences.getString("proxy", getString(R.string.proxy_default_value));
+ String downloadLocationString = savedPreferences.getString("download_location", getString(R.string.download_location_default_value));
// Get booleans that are used in multiple places from the preferences.
boolean javaScriptEnabled = savedPreferences.getBoolean("javascript", false);
// Only enable Fanboy's social blocking list preference if Fanboy's annoyance list is disabled.
fanboySocialBlockingListPreference.setEnabled(!fanboyAnnoyanceListEnabled);
+
// Inflate a WebView to get the default user agent.
LayoutInflater inflater = getActivity().getLayoutInflater();
+
// `@SuppressLint("InflateParams")` removes the warning about using `null` as the `ViewGroup`, which in this case makes sense because the `bare_webview` will not be displayed.
@SuppressLint("InflateParams") View bareWebViewLayout = inflater.inflate(R.layout.bare_webview, null, false);
+
+ // Get a handle for a bare WebView.
WebView bareWebView = bareWebViewLayout.findViewById(R.id.bare_webview);
// Get the user agent arrays.
String[] translatedUserAgentNamesArray = getResources().getStringArray(R.array.translated_user_agent_names);
String[] userAgentDataArray = getResources().getStringArray(R.array.user_agent_data);
- // Get the current user agent name from the preference.
- String userAgentName = savedPreferences.getString("user_agent", getString(R.string.user_agent_default_value));
-
// Get the array position of the user agent name.
int userAgentArrayPosition = userAgentNamesArray.getPosition(userAgentName);
userAgentPreference.setSummary(translatedUserAgentNamesArray[userAgentArrayPosition] + ":\n" + userAgentDataArray[userAgentArrayPosition]);
}
- // Set the summary text for the custom user agent preference and enable it if user agent preference is set to custom.
+ // Set the summary text for the custom user agent preference.
customUserAgentPreference.setSummary(savedPreferences.getString("custom_user_agent", getString(R.string.custom_user_agent_default_value)));
+
+ // Only enable the custom user agent preference if the user agent is set to `Custom`.
customUserAgentPreference.setEnabled(userAgentPreference.getSummary().equals(getString(R.string.custom_user_agent)));
+
// Set the search URL as the summary text for the search preference when the preference screen is loaded.
if (searchString.equals("Custom URL")) {
// Use R.string.custom_url, which will be translated, instead of the array value, which will not.
searchPreference.setSummary(searchString);
}
- // Set the summary text for `search_custom_url` (the default is `""`) and enable it if `search` is set to `Custom URL`.
+ // Set the summary text for the search custom URL (the default is `""`).
searchCustomURLPreference.setSummary(savedPreferences.getString("search_custom_url", getString(R.string.search_custom_url_default_value)));
+
+ // Only enable the search custom URL preference if the search is set to `Custom URL`.
searchCustomURLPreference.setEnabled(searchString.equals("Custom URL"));
+
// Set the summary text for the proxy preference when the preference screen is loaded.
switch (proxyString) {
case ProxyHelper.NONE:
break;
}
+ // Set the summary text for the custom proxy URL.
+ proxyCustomUrlPreference.setSummary(savedPreferences.getString("proxy_custom_url", getString(R.string.proxy_custom_url_default_value)));
+
// Only enable the custom proxy URL if a custom proxy is selected.
proxyCustomUrlPreference.setEnabled(proxyString.equals("Custom"));
- // Set the summary text for the custom proxy URL.
- proxyCustomUrlPreference.setSummary(savedPreferences.getString("proxy_custom_url", getString(R.string.proxy_custom_url_default_value)));
// Set the status of the Clear and Exit preferences.
clearCookiesPreference.setEnabled(!clearEverything);
clearFormDataPreference.setEnabled(!clearEverything); // The form data line can be removed once the minimum API is >= 26.
clearCachePreference.setEnabled(!clearEverything);
+
// Set the homepage URL as the summary text for the homepage preference.
homepagePreference.setSummary(savedPreferences.getString("homepage", getString(R.string.homepage_default_value)));
+
+ // Instantiate the download location helper.
+ DownloadLocationHelper downloadLocationHelper = new DownloadLocationHelper();
+
+ // Set the download location summary text.
+ downloadLocationPreference.setSummary(downloadLocationHelper.getDownloadLocation(context));
+
+ // Set the summary text for the download custom location (the default is `"`).
+ downloadCustomLocationPreference.setSummary(savedPreferences.getString("download_custom_location", getString(R.string.download_custom_location_default_value)));
+
+ // Get the download location entry values string array.
+ String[] downloadLocationEntryValuesStringArray = context.getResources().getStringArray(R.array.download_location_entry_values);
+
+ // Only enable the download custom location preference if the download location is set to `Custom`.
+ downloadCustomLocationPreference.setEnabled(downloadLocationString.equals(downloadLocationEntryValuesStringArray[3]));
+
+
// Set the font size as the summary text for the preference.
fontSizePreference.setSummary(savedPreferences.getString("font_size", getString(R.string.font_size_default_value)) + "%");
+
// Disable the JavaScript preference if Night Mode is enabled. JavaScript will be enabled for all web pages.
javaScriptPreference.setEnabled(!nightMode);
clearCachePreference.setIcon(R.drawable.cache_warning);
}
+ // Set the download custom location icon.
+ if (downloadCustomLocationPreference.isEnabled()) {
+ if (darkTheme) {
+ downloadCustomLocationPreference.setIcon(R.drawable.downloads_enabled_dark);
+ } else {
+ downloadCustomLocationPreference.setIcon(R.drawable.downloads_enabled_light);
+ }
+ } else {
+ if (darkTheme) {
+ downloadCustomLocationPreference.setIcon(R.drawable.downloads_ghosted_dark);
+ } else {
+ downloadCustomLocationPreference.setIcon(R.drawable.downloads_ghosted_light);
+ }
+ }
+
// Set the open intents in new tab preference icon.
if (savedPreferences.getBoolean("open_intents_in_new_tab", true)) {
if (darkTheme) {
// Store the new search string.
String newSearchString = sharedPreferences.getString("search", getString(R.string.search_default_value));
- // Update `searchPreference` and `searchCustomURLPreference`.
+ // Update the search and search custom URL preferences.
if (newSearchString.equals("Custom URL")) { // `Custom URL` is selected.
// Set the summary text to `R.string.custom_url`, which is translated.
searchPreference.setSummary(R.string.custom_url);
break;
case "search_custom_url":
- // Set the new custom search URL as the summary text for `search_custom_url`. The default is `""`.
+ // Set the new search custom URL as the summary text for the preference.
searchCustomURLPreference.setSummary(sharedPreferences.getString("search_custom_url", getString(R.string.search_custom_url_default_value)));
break;
homepagePreference.setSummary(sharedPreferences.getString("homepage", getString(R.string.homepage_default_value)));
break;
+ case "download_location":
+ // Get the new download location.
+ String newDownloadLocationString = sharedPreferences.getString("download_location", getString(R.string.download_location_default_value));
+
+ // Update the download location summary text.
+ downloadLocationPreference.setSummary(downloadLocationHelper.getDownloadLocation(context));
+
+ // Update the status of the download custom location preference.
+ downloadCustomLocationPreference.setEnabled(newDownloadLocationString.equals(downloadLocationEntryValuesStringArray[3]));
+
+ // Update the download custom location icon.
+ if (downloadCustomLocationPreference.isEnabled()) {
+ if (darkTheme) {
+ downloadCustomLocationPreference.setIcon(R.drawable.downloads_enabled_dark);
+ } else {
+ downloadCustomLocationPreference.setIcon(R.drawable.downloads_enabled_light);
+ }
+ } else {
+ if (darkTheme) {
+ downloadCustomLocationPreference.setIcon(R.drawable.downloads_ghosted_dark);
+ } else {
+ downloadCustomLocationPreference.setIcon(R.drawable.downloads_ghosted_light);
+ }
+ }
+ break;
+
+ case "download_custom_location":
+ // Set the new download custom location as the summary text for the preference.
+ downloadCustomLocationPreference.setSummary(sharedPreferences.getString("download_custom_location", getString(R.string.download_custom_location_default_value)));
+ break;
+
case "font_size":
// Update the font size summary text.
fontSizePreference.setSummary(sharedPreferences.getString("font_size", getString(R.string.font_size_default_value)) + "%");
--- /dev/null
+/*
+ * Copyright © 2020 Soren Stoutner <soren@stoutner.com>.
+ *
+ * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
+ *
+ * Privacy Browser is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Privacy Browser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Privacy Browser. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.stoutner.privacybrowser.helpers;
+
+import android.Manifest;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.pm.PackageManager;
+import android.os.Environment;
+
+import androidx.core.content.ContextCompat;
+import androidx.preference.PreferenceManager;
+
+import com.stoutner.privacybrowser.R;
+
+import java.io.File;
+
+public class DownloadLocationHelper {
+ public String getDownloadLocation(Context context) {
+ // Get the download location entry values string array.
+ String[] downloadLocationEntryValuesStringArray = context.getResources().getStringArray(R.array.download_location_entry_values);
+
+ // Get the two standard download directories.
+ File publicDownloadDirectory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
+ File publicAppFilesDirectory = context.getExternalFilesDir(null);
+
+ // Remove the incorrect lint warning below that the public app files directory might be null.
+ assert publicAppFilesDirectory != null;
+
+ // Convert the download directories to strings.
+ String publicDownloadDirectoryString = publicDownloadDirectory.toString();
+ String publicAppFilesDirectoryString = publicAppFilesDirectory.toString();
+
+ // Get a handle for the shared preferences.
+ SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
+
+ // Get the download location strings from the preferences.
+ String downloadLocationString = sharedPreferences.getString("download_location", context.getString(R.string.download_location_default_value));
+ String downloadCustomLocationString = sharedPreferences.getString("download_custom_location", context.getString(R.string.download_custom_location_default_value));
+
+ // Define a string for the default file path.
+ String defaultFilePath;
+
+ // Set the default file path according to the download location.
+ if (downloadLocationString.equals(downloadLocationEntryValuesStringArray[0])) { // the download location is set to auto.
+ // Set the download location summary text according to the storage permission status.
+ if (ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { // The storage permission has been granted.
+ // Use the public download directory.
+ defaultFilePath = publicDownloadDirectoryString;
+ } else { // The storage permission has not been granted.
+ // Use the public app files directory.
+ defaultFilePath = publicAppFilesDirectoryString;
+ }
+ } else if (downloadLocationString.equals(downloadLocationEntryValuesStringArray[1])) { // The download location is set to the app directory.
+ // Use the public app files directory.
+ defaultFilePath = publicAppFilesDirectoryString;
+ } else if (downloadLocationString.equals(downloadLocationEntryValuesStringArray[2])) { // The download location is set to the public directory.
+ // Use the public download directory.
+ defaultFilePath = publicDownloadDirectoryString;
+ } else { // The download location is set to custom.
+ // Use the download custom location.
+ defaultFilePath = downloadCustomLocationString;
+ }
+
+ // Return the default file path.
+ return defaultFilePath;
+ }
+}
\ No newline at end of file
private static final String CLEAR_FORM_DATA = "clear_form_data";
private static final String CLEAR_CACHE = "clear_cache";
private static final String HOMEPAGE = "homepage";
+ private static final String DOWNLOAD_LOCATION = "download_location";
+ private static final String DOWNLOAD_CUSTOM_LOCATION = "download_custom_location";
private static final String FONT_SIZE = "font_size";
private static final String OPEN_INTENTS_IN_NEW_TAB = "open_intents_in_new_tab";
private static final String SWIPE_TO_REFRESH = "swipe_to_refresh";
CLEAR_FORM_DATA + " BOOLEAN, " +
CLEAR_CACHE + " BOOLEAN, " +
HOMEPAGE + " TEXT, " +
+ DOWNLOAD_LOCATION + " TEXT, " +
+ DOWNLOAD_CUSTOM_LOCATION + " TEXT, " +
FONT_SIZE + " TEXT, " +
OPEN_INTENTS_IN_NEW_TAB + " BOOLEAN, " +
SWIPE_TO_REFRESH + " BOOLEAN, " +
preferencesContentValues.put(CLEAR_FORM_DATA, sharedPreferences.getBoolean(CLEAR_FORM_DATA, true)); // Clear form data can be removed once the minimum API >= 26.
preferencesContentValues.put(CLEAR_CACHE, sharedPreferences.getBoolean(CLEAR_CACHE, true));
preferencesContentValues.put(HOMEPAGE, sharedPreferences.getString(HOMEPAGE, context.getString(R.string.homepage_default_value)));
+ preferencesContentValues.put(DOWNLOAD_LOCATION, sharedPreferences.getString(DOWNLOAD_LOCATION, context.getString(R.string.download_location_default_value)));
+ preferencesContentValues.put(DOWNLOAD_CUSTOM_LOCATION, sharedPreferences.getString(DOWNLOAD_CUSTOM_LOCATION, context.getString(R.string.download_custom_location_default_value)));
preferencesContentValues.put(FONT_SIZE, sharedPreferences.getString(FONT_SIZE, context.getString(R.string.font_size_default_value)));
preferencesContentValues.put(OPEN_INTENTS_IN_NEW_TAB, sharedPreferences.getBoolean(OPEN_INTENTS_IN_NEW_TAB, true));
preferencesContentValues.put(SWIPE_TO_REFRESH, sharedPreferences.getBoolean(SWIPE_TO_REFRESH, true));
// Create the new font size column.
importDatabase.execSQL("ALTER TABLE " + PREFERENCES_TABLE + " ADD COLUMN " + FONT_SIZE + " TEXT");
- // Place the font size string in the new column.
+ // Populate the preferences table with the current font size value.
importDatabase.execSQL("UPDATE " + PREFERENCES_TABLE + " SET " + FONT_SIZE + " = '" + fontSize + "'");
// Upgrade from schema version 3.
boolean hideAppBar = sharedPreferences.getBoolean(HIDE_APP_BAR, true);
boolean scrollAppBar = sharedPreferences.getBoolean(SCROLL_APP_BAR, true);
- // Populate the database with the current values.
+ // Populate the preferences table with the current app bar values.
if (hideAppBar) {
importDatabase.execSQL("UPDATE " + PREFERENCES_TABLE + " SET " + HIDE_APP_BAR + " = " + 1);
} else {
// Get the current open intents in new tab preference.
boolean openIntentsInNewTab = sharedPreferences.getBoolean(OPEN_INTENTS_IN_NEW_TAB, true);
- // Populate the database with the current value.
+ // Populate the preferences table with the current open intents value.
if (openIntentsInNewTab) {
importDatabase.execSQL("UPDATE " + PREFERENCES_TABLE + " SET " + OPEN_INTENTS_IN_NEW_TAB + " = " + 1);
} else {
boolean twitterAmpRedirects = sharedPreferences.getBoolean(TWITTER_AMP_REDIRECTS, true);
boolean wideViewport = sharedPreferences.getBoolean(WIDE_VIEWPORT, true);
- // Populate the database with the current Google Analytics value.
+ // Populate the preferences with the current Google Analytics value.
if (googleAnalytics) {
importDatabase.execSQL("UPDATE " + PREFERENCES_TABLE + " SET " + GOOGLE_ANALYTICS + " = " + 1);
} else {
importDatabase.execSQL("UPDATE " + PREFERENCES_TABLE + " SET " + GOOGLE_ANALYTICS + " = " + 0);
}
- // Populate the database with the current Facebook Click IDs value.
+ // Populate the preferences with the current Facebook Click IDs value.
if (facebookClickIds) {
importDatabase.execSQL("UPDATE " + PREFERENCES_TABLE + " SET " + FACEBOOK_CLICK_IDS + " = " + 1);
} else {
importDatabase.execSQL("UPDATE " + PREFERENCES_TABLE + " SET " + FACEBOOK_CLICK_IDS + " = " + 0);
}
- // Populate the database with the current Twitter AMP redirects value.
+ // Populate the preferences table with the current Twitter AMP redirects value.
if (twitterAmpRedirects) {
importDatabase.execSQL("UPDATE " + PREFERENCES_TABLE + " SET " + TWITTER_AMP_REDIRECTS + " = " + 1);
} else {
importDatabase.execSQL("UPDATE " + PREFERENCES_TABLE + " SET " + TWITTER_AMP_REDIRECTS + " = " + 0);
}
- // Populate the database with the current wide viewport value.
+ // Populate the preferences table with the current wide viewport value.
if (wideViewport) {
importDatabase.execSQL("UPDATE " + PREFERENCES_TABLE + " SET " + WIDE_VIEWPORT + " = " + 1);
} else {
// Get the current preference values.
boolean ultraList = sharedPreferences.getBoolean(ULTRALIST, true);
- // Populate the tables with the current UltraList value.
+ // Populate the preferences tables with the current UltraList value.
if (ultraList) {
importDatabase.execSQL("UPDATE " + DomainsDatabaseHelper.DOMAINS_TABLE + " SET " + DomainsDatabaseHelper.ULTRALIST + " = " + 1);
importDatabase.execSQL("UPDATE " + PREFERENCES_TABLE + " SET " + ULTRALIST + " = " + 1);
// SQL escape the proxy custom URL string.
proxyCustomUrl = DatabaseUtils.sqlEscapeString(proxyCustomUrl);
- // Populate the table with the current proxy values.
+ // Populate the preferences table with the current proxy values.
importDatabase.execSQL("UPDATE " + PREFERENCES_TABLE + " SET " + PROXY + " = '" + proxy + "'");
importDatabase.execSQL("UPDATE " + PREFERENCES_TABLE + " SET " + PROXY_CUSTOM_URL + " = '" + proxyCustomUrl + "'");
// Upgrade from schema version 9.
case 9:
- // `download_with_external_app` was removed the the Preferences table in schema version 10, but there is no need to make any modifications to the database.
+ // Add the download location columns to the preferences table.
+ importDatabase.execSQL("ALTER TABLE " + PREFERENCES_TABLE + " ADD COLUMN " + DOWNLOAD_LOCATION + " TEXT");
+ importDatabase.execSQL("ALTER TABLE " + PREFERENCES_TABLE + " ADD COLUMN " + DOWNLOAD_CUSTOM_LOCATION + " TEXT");
+
+ // Get the current download location values.
+ String downloadLocation = sharedPreferences.getString(DOWNLOAD_LOCATION, context.getString(R.string.download_location_default_value));
+ String downloadCustomLocation = sharedPreferences.getString(DOWNLOAD_CUSTOM_LOCATION, context.getString(R.string.download_custom_location_default_value));
+
+ // Populate the preferences table with the current download location values.
+ importDatabase.execSQL("UPDATE " + PREFERENCES_TABLE + " SET " + DOWNLOAD_LOCATION + " = '" + downloadLocation + "'");
+ importDatabase.execSQL("UPDATE " + PREFERENCES_TABLE + " SET " + DOWNLOAD_CUSTOM_LOCATION + " = '" + downloadCustomLocation + "'");
}
}
.putBoolean(CLEAR_FORM_DATA, importPreferencesCursor.getInt(importPreferencesCursor.getColumnIndex(CLEAR_FORM_DATA)) == 1)
.putBoolean(CLEAR_CACHE, importPreferencesCursor.getInt(importPreferencesCursor.getColumnIndex(CLEAR_CACHE)) == 1)
.putString(HOMEPAGE, importPreferencesCursor.getString(importPreferencesCursor.getColumnIndex(HOMEPAGE)))
+ .putString(DOWNLOAD_LOCATION, importPreferencesCursor.getString(importPreferencesCursor.getColumnIndex(DOWNLOAD_LOCATION)))
+ .putString(DOWNLOAD_CUSTOM_LOCATION, importPreferencesCursor.getString(importPreferencesCursor.getColumnIndex(DOWNLOAD_CUSTOM_LOCATION)))
.putString(FONT_SIZE, importPreferencesCursor.getString(importPreferencesCursor.getColumnIndex(FONT_SIZE)))
.putBoolean(OPEN_INTENTS_IN_NEW_TAB, importPreferencesCursor.getInt(importPreferencesCursor.getColumnIndex(OPEN_INTENTS_IN_NEW_TAB)) == 1)
.putBoolean(SWIPE_TO_REFRESH, importPreferencesCursor.getInt(importPreferencesCursor.getColumnIndex(SWIPE_TO_REFRESH)) == 1)
+++ /dev/null
-<!-- This file comes from the Android Material icon set, where it is called `file_download`. It is released under the Apache License 2.0. -->
-<vector
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:height="24dp"
- android:width="24dp"
- android:viewportHeight="24.0"
- android:viewportWidth="24.0" >
-
- <!-- The hard coded color must be used until API >= 21. Then `@color` may be used. -->
- <path
- android:fillColor="#FF000000"
- android:pathData="M19,9h-4V3H9v6H5l7,7 7,-7zM5,18v2h14v-2H5z" />
-</vector>
\ No newline at end of file
--- /dev/null
+<!-- This file comes from the Android Material icon set, where it is called `file_download`. It is released under the Apache License 2.0. -->
+<vector
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="24dp"
+ android:width="24dp"
+ android:viewportHeight="24.0"
+ android:viewportWidth="24.0" >
+
+ <!-- The hard coded color must be used until API >= 21. Then `@color` may be used. -->
+ <path
+ android:fillColor="#FF1E88E5"
+ android:pathData="M19,9h-4V3H9v6H5l7,7 7,-7zM5,18v2h14v-2H5z" />
+</vector>
\ No newline at end of file
--- /dev/null
+<!-- This file comes from the Android Material icon set, where it is called `file_download`. It is released under the Apache License 2.0. -->
+<vector
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="24dp"
+ android:width="24dp"
+ android:viewportHeight="24.0"
+ android:viewportWidth="24.0" >
+
+ <!-- The hard coded color must be used until API >= 21. Then `@color` may be used. -->
+ <path
+ android:fillColor="#FF1565C0"
+ android:pathData="M19,9h-4V3H9v6H5l7,7 7,-7zM5,18v2h14v-2H5z" />
+</vector>
\ No newline at end of file
--- /dev/null
+<!-- This file comes from the Android Material icon set, where it is called `file_download`. It is released under the Apache License 2.0. -->
+<vector
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="24dp"
+ android:width="24dp"
+ android:viewportHeight="24.0"
+ android:viewportWidth="24.0" >
+
+ <!-- The hard coded color must be used until API >= 21. Then `@color` may be used. -->
+ <path
+ android:fillColor="#FF616161"
+ android:pathData="M19,9h-4V3H9v6H5l7,7 7,-7zM5,18v2h14v-2H5z" />
+</vector>
\ No newline at end of file
--- /dev/null
+<!-- This file comes from the Android Material icon set, where it is called `file_download`. It is released under the Apache License 2.0. -->
+<vector
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="24dp"
+ android:width="24dp"
+ android:viewportHeight="24.0"
+ android:viewportWidth="24.0" >
+
+ <!-- The hard coded color must be used until API >= 21. Then `@color` may be used. -->
+ <path
+ android:fillColor="#FFB7B7B7"
+ android:pathData="M19,9h-4V3H9v6H5l7,7 7,-7zM5,18v2h14v-2H5z" />
+</vector>
\ No newline at end of file
-<!-- `full_screen_disabled_dark.xml` comes from the Android Material icon set, where it is called `smartphone`. It is released under the Apache License 2.0. -->
+<!-- This file comes from the Android Material icon set, where it is called `smartphone`. It is released under the Apache License 2.0. -->
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
-<!-- `full_screen_disabled_light.xml` comes from the Android Material icon set, where it is called `smartphone`. It is released under the Apache License 2.0. -->
+<!-- This file comes from the Android Material icon set, where it is called `smartphone`. It is released under the Apache License 2.0. -->
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
-<!-- `full_screen_enabled_dark.xml` comes from the Android Material icon set, where it is called `smartphone`. It is released under the Apache License 2.0. -->
+<!-- This file comes from the Android Material icon set, where it is called `smartphone`. It is released under the Apache License 2.0. -->
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
-<!-- `full_screen_enabled_light.xml` comes from the Android Material icon set, where it is called `smartphone`. It is released under the Apache License 2.0. -->
+<!-- This file comes from the Android Material icon set, where it is called `smartphone`. It is released under the Apache License 2.0. -->
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
-<!-- `search_custom_url_enabled_dark.xml` comes from the Android Material icon set, where it is called `find_in_page`. It is released under the Apache License 2.0. -->
+<!-- This file comes from the Android Material icon set, where it is called `find_in_page`. It is released under the Apache License 2.0. -->
<!-- `tools:ignore="VectorRaster"` removes the lint warning about `android:autoMirrored="true"` not applying to API < 21. -->
<vector
-<!-- `search_custom_url_enabled_light.xml` comes from the Android Material icon set, where it is called `find_in_page`. It is released under the Apache License 2.0. -->
+<!-- This file comes from the Android Material icon set, where it is called `find_in_page`. It is released under the Apache License 2.0. -->
<!-- `tools:ignore="VectorRaster"` removes the lint warning about `android:autoMirrored="true"` not applying to API < 21. -->
<vector
-<!-- `search_custom_url_ghosted_dark.xml` comes from the Android Material icon set, where it is called `find_in_page`. It is released under the Apache License 2.0. -->
+<!-- This file comes from the Android Material icon set, where it is called `find_in_page`. It is released under the Apache License 2.0. -->
<!-- `tools:ignore="VectorRaster"` removes the lint warning about `android:autoMirrored="true"` not applying to API < 21. -->
<vector
-<!-- `search_custom_url_ghosted_light.xml` comes from the Android Material icon set, where it is called `find_in_page`. It is released under the Apache License 2.0. -->
+<!-- This file comes from the Android Material icon set, where it is called `find_in_page`. It is released under the Apache License 2.0. -->
<!-- `tools:ignore="VectorRaster"` removes the lint warning about `android:autoMirrored="true"` not applying to API < 21. -->
<vector
<item
android:id="@+id/downloads"
android:title="@string/downloads"
- android:icon="@drawable/downloads"
+ android:icon="@drawable/downloads_enabled_light"
android:orderInCategory="80" />
</group>
<string name="previous">Vorheriges</string>
<string name="next">Nächstes</string>
- <!-- Save Webpage. -->
+ <!-- Save. -->
<string name="file_name">Dateiname</string>
<string name="save_archive">Archiv speichern</string>
<string name="save_image">Grafik speichern</string>
<item>Yahoo - JavaScript aktiviert</item>
<item>Eigene</item>
</string-array>
- <string name="search_custom_url">Suchmaschinen-URL</string>
<string name="custom_url">Eigene URL</string>
+ <string name="search_custom_url">Suchmaschinen-URL</string>
<string name="proxy">Proxy</string>
<string name="proxy_none">Keiner</string>
<string name="proxy_tor">Tor</string>
<string name="previous">Anterior</string>
<string name="next">Siguiente</string>
- <!-- Save Webpage. -->
+ <!-- Save. -->
<string name="file_name">Nombre de archivo</string>
<string name="save_archive">Guardar archivo</string>
<string name="save_image">Guardar imagen</string>
<item>Yahoo - Javascript habilitado</item>
<item>Personalizado</item>
</string-array>
- <string name="no_proxy_enabled">Ninguno - conectar directamente a Internet.</string>
- <string name="tor_enabled">Tor - conectar a través de socks://localhost:9050.</string>
- <string name="tor_enabled_kitkat">Tor - conectar a través de http://localhost:8118.</string>
- <string name="i2p_enabled">I2P - conectar a través de http://localhost:4444.</string>
- <string name="search_custom_url">URL personalizado de búsqueda</string>
<string name="custom_url">URL personalizado</string>
- <string name="proxy_custom_url">URL personalizada del proxy</string>
+ <string name="search_custom_url">URL personalizado de búsqueda</string>
<string name="proxy">Proxy</string>
<string name="proxy_none">Ninguno</string>
<string name="proxy_tor">Tor</string>
<item>I2P</item>
<item>Personalizado</item>
</string-array>
+ <string name="no_proxy_enabled">Ninguno - conectar directamente a Internet.</string>
+ <string name="tor_enabled">Tor - conectar a través de socks://localhost:9050.</string>
+ <string name="tor_enabled_kitkat">Tor - conectar a través de http://localhost:8118.</string>
+ <string name="i2p_enabled">I2P - conectar a través de http://localhost:4444.</string>
<string name="custom_proxy">Proxy personalizado</string>
+ <string name="proxy_custom_url">URL personalizada del proxy</string>
<string name="full_screen">Pantalla completa</string>
<string name="full_screen_browsing_mode">Navegación de pantalla completa</string>
<string name="full_screen_browsing_mode_summary">Doble toque para alternar a modo de navegación de pantalla completa.</string>
<string name="previous">Précédent</string>
<string name="next">Suivant</string>
- <!-- Save Webpage. -->
+ <!-- Save. -->
<string name="file_name">Nom du fichier</string>
<string name="save_archive">Enregistrer l\'archive</string>
<string name="save_image">Sauvegarder en tant qu\'image</string>
<item>Yahoo - JavaScript activé</item>
<item>Personnalisée</item>
</string-array>
- <string name="search_custom_url">URL de recherche personnalisée</string>
<string name="custom_url">URL personnalisée</string>
+ <string name="search_custom_url">URL de recherche personnalisée</string>
<string name="proxy">Proxy</string>
<string name="proxy_none">Aucun</string>
<string name="proxy_tor">Tor</string>
<string name="previous">Precedente</string>
<string name="next">Successivo</string>
- <!-- Save Webpage. -->
+ <!-- Save. -->
<string name="file_name">Nome File</string>
<string name="save_archive">Salva Archivio</string>
<string name="save_image">Salva Immagine</string>
<item>Yahoo - JavaScript abilitato</item>
<item>Personalizzata</item>
</string-array>
- <string name="search_custom_url">Ricerca personalizzata</string>
<string name="custom_url">URL Personalizzata</string>
+ <string name="search_custom_url">Ricerca personalizzata</string>
<string name="proxy">Proxy</string>
<string name="proxy_none">Nessuno</string>
<string name="proxy_tor">Tor</string>
<string name="previous">Предыдущий</string>
<string name="next">Следующий</string>
- <!-- Save Webpage. -->
+ <!-- Save. -->
<string name="file_name">Имя файла</string>
<string name="save_archive">Сохранить архив</string>
<string name="save_image">Сохранить изображение</string>
<item>Yahoo - JavaScript включен</item>
<item>Настраиваемый</item>
</string-array>
- <string name="search_custom_url">Настраиваемый URL поиска</string>
<string name="custom_url">Настраиваемый URL</string>
+ <string name="search_custom_url">Настраиваемый URL поиска</string>
<string name="proxy">Прокси</string>
<string name="proxy_none">Нет</string>
<string name="proxy_tor">Tor</string>
<string name="previous">Önceki</string>
<string name="next">Sonraki</string>
- <!-- Save Webpage. -->
+ <!-- Save. -->
<string name="file_name">Dosya adı</string>
<string name="save_image">Resmi kaydet</string>
<string name="webpage_png">Websayfası.png</string>
<item>Yahoo - JavaScript etkin</item>
<item>Özel sayfa</item>
</string-array>
- <string name="search_custom_url">Özel sayfa ara</string>
<string name="custom_url">Özel sayfa</string>
+ <string name="search_custom_url">Özel sayfa ara</string>
<string name="full_screen">Tam Ekran</string>
<string name="full_screen_browsing_mode">Tam ekran modu</string>
<string name="full_screen_browsing_mode_summary">Tam ekran moduna geçmek için çift dokun.</string>
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright © 2017-2019 Soren Stoutner <soren@stoutner.com>.
+ Copyright © 2017-2020 Soren Stoutner <soren@stoutner.com>.
This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
<attr name="clearIcon" format="reference" />
<attr name="copyIcon" format="reference" />
<attr name="deleteIcon" format="reference" />
+ <attr name="downloadIcon" format="reference" />
<attr name="editIcon" format="reference" />
<attr name="fontSizeIcon" format="reference" />
<attr name="homepageIcon" format="reference" />
<string name="loading_ultralist">Loading UltraList</string>
<string name="loading_ultraprivacy">Loading UltraPrivacy</string>
- <!-- Save As. -->
-
<!-- Custom App Bar. -->
<string name="favorite_icon">Favorite Icon</string>
<string name="url_or_search_terms">URL or Search Terms</string>
<string name="previous">Previous</string>
<string name="next">Next</string>
- <!-- Save Webpage. -->
+ <!-- Save. -->
<string name="save_dialog" translatable="false">Save Dialog</string> <!-- This string is used to tag the save dialog. It is never displayed to the user. -->
<string name="file_name">File name</string>
<string name="save_archive">Save Archive</string>
<item>https://search.yahoo.com/mobile/s?p=</item>
<item>Custom URL</item> <!-- This item must not be translated into other languages because it is referenced in code. It is never displayed on the screen. -->
</string-array>
- <string name="search_custom_url">Search custom URL</string>
<string name="custom_url">Custom URL</string>
+ <string name="search_custom_url">Search custom URL</string>
<string name="proxy">Proxy</string>
<string name="proxy_none">None</string>
<string name="proxy_tor">Tor</string>
<string name="clear_cache_summary">Clears WebView’s cache.</string>
<string name="general">General</string>
<string name="homepage">Homepage</string>
+ <string name="download_location">Download location</string>
+ <string-array name="download_location_entries">
+ <item>Auto</item>
+ <item>App directory</item>
+ <item>Public directory</item>
+ <item>Custom</item>
+ </string-array>
+ <string-array name="download_location_entry_values" translatable="false"> <!-- None of the items in this string array should be translated. -->
+ <item>Auto</item>
+ <item>App</item>
+ <item>Public</item>
+ <item>Custom</item>
+ </string-array>
+ <string name="download_custom_location">Download custom location</string>
<string name="font_size_preference">Font size</string>
<string name="open_intents_in_new_tab">Open intents in new tab</string>
<string name="open_intents_in_new_tab_summary">Intents are links sent from other apps.</string>
<string name="proxy_default_value" translatable="false">None</string>
<string name="proxy_custom_url_default_value" translatable="false">http://localhost:8118</string>
<string name="homepage_default_value" translatable="false">https://www.startpage.com/</string>
+ <string name="download_location_default_value" translatable="false">Auto</string>
+ <string name="download_custom_location_default_value" translatable="false" />
<string name="font_size_default_value" translatable="false">100</string>
<!-- Ad Control. There are no ads in the standard flavor, but these strings must exist because they are referenced in the code. -->
<item name="colorPrimary">@color/blue_700</item>
<item name="colorPrimaryDark">@color/blue_900</item>
<item name="colorAccent">@color/blue_700</item>
- <item name="userAgentIcon">@drawable/user_agent_light</item>
- <item name="searchIcon">@drawable/search_enabled_light</item>
- <item name="homepageIcon">@drawable/home_enabled_light</item>
+ <item name="downloadIcon">@drawable/downloads_enabled_light</item>
<item name="fontSizeIcon">@drawable/font_size_light</item>
+ <item name="homepageIcon">@drawable/home_enabled_light</item>
+ <item name="searchIcon">@drawable/search_enabled_light</item>
+ <item name="userAgentIcon">@drawable/user_agent_light</item>
</style>
<!-- `ThemeOverlay.AppCompat.ActionBar` makes the hamburger icons dark. -->
</style>
<style name="PrivacyBrowserSettingsDark" parent="Theme.AppCompat" >
+ <item name="android:textColorPrimary">@color/primary_text_color_selector_dark</item>
<item name="colorPrimary">@color/blue_800</item>
<item name="colorPrimaryDark">@color/blue_900</item>
- <item name="android:textColorPrimary">@color/primary_text_color_selector_dark</item>
<item name="colorAccent">@color/blue_600</item>
- <item name="userAgentIcon">@drawable/user_agent_dark</item>
- <item name="searchIcon">@drawable/search_enabled_dark</item>
- <item name="homepageIcon">@drawable/home_enabled_dark</item>
+ <item name="downloadIcon">@drawable/downloads_enabled_dark</item>
<item name="fontSizeIcon">@drawable/font_size_dark</item>
+ <item name="homepageIcon">@drawable/home_enabled_dark</item>
+ <item name="searchIcon">@drawable/search_enabled_dark</item>
+ <item name="userAgentIcon">@drawable/user_agent_dark</item>
</style>
<!-- `ThemeOverlay.AppCompat.Dark.ActionBar` makes the text and the icons in the AppBar white. -->
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright © 2016-2019 Soren Stoutner <soren@stoutner.com>.
+ Copyright © 2016-2020 Soren Stoutner <soren@stoutner.com>.
This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
android:inputType="textUri"
android:icon="?attr/homepageIcon" />
+ <ListPreference
+ android:key="download_location"
+ android:title="@string/download_location"
+ android:entries="@array/download_location_entries"
+ android:entryValues="@array/download_location_entry_values"
+ android:defaultValue="@string/download_location_default_value"
+ android:inputType="textUri"
+ android:icon="?attr/downloadIcon" />
+
+ <EditTextPreference
+ android:key="download_custom_location"
+ android:title="@string/download_custom_location"
+ android:defaultValue="@string/download_custom_location_default_value"
+ android:inputType="textUri" />
+
<!-- `android:inputType="number"` currently doesn't work with AndroidX. -->
<EditTextPreference
android:key="font_size"