2 * Copyright © 2016-2020 Soren Stoutner <soren@stoutner.com>.
4 * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
6 * Privacy Browser is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * Privacy Browser is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with Privacy Browser. If not, see <http://www.gnu.org/licenses/>.
20 package com.stoutner.privacybrowser.fragments;
22 import android.annotation.SuppressLint;
23 import android.app.Activity;
24 import android.content.Context;
25 import android.content.Intent;
26 import android.content.SharedPreferences;
27 import android.content.res.Resources;
28 import android.os.Build;
29 import android.os.Bundle;
30 import android.os.Handler;
31 import android.view.LayoutInflater;
32 import android.view.View;
33 import android.webkit.WebView;
34 import android.widget.ArrayAdapter;
36 import androidx.preference.Preference;
37 import androidx.preference.PreferenceCategory;
38 import androidx.preference.PreferenceFragmentCompat;
40 import com.stoutner.privacybrowser.R;
41 import com.stoutner.privacybrowser.activities.MainWebViewActivity;
42 import com.stoutner.privacybrowser.helpers.DownloadLocationHelper;
43 import com.stoutner.privacybrowser.helpers.ProxyHelper;
45 public class SettingsFragment extends PreferenceFragmentCompat {
46 // Define the class variables.
47 private SharedPreferences.OnSharedPreferenceChangeListener preferencesListener;
48 private SharedPreferences savedPreferences;
51 public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
52 // Load the preferences from the XML file.
53 setPreferencesFromResource(R.xml.preferences, rootKey);
55 // Get a handle for the activity.
56 Activity activity = getActivity();
58 // Remove the lint warning below that `getApplicationContext()` might produce a null pointer exception.
59 assert activity != null;
61 // Get a handle for the context and the resources.
62 Context context = activity.getApplicationContext();
63 Resources resources = getResources();
65 // Initialize savedPreferences.
66 savedPreferences = getPreferenceScreen().getSharedPreferences();
68 // Get handles for the preferences.
69 Preference javaScriptPreference = findPreference("javascript");
70 Preference firstPartyCookiesPreference = findPreference("first_party_cookies");
71 Preference thirdPartyCookiesPreference = findPreference("third_party_cookies");
72 Preference domStoragePreference = findPreference("dom_storage");
73 Preference formDataPreference = findPreference("save_form_data"); // The form data preference can be removed once the minimum API >= 26.
74 Preference userAgentPreference = findPreference("user_agent");
75 Preference customUserAgentPreference = findPreference("custom_user_agent");
76 Preference incognitoModePreference = findPreference("incognito_mode");
77 Preference doNotTrackPreference = findPreference("do_not_track");
78 Preference allowScreenshotsPreference = findPreference("allow_screenshots");
79 Preference easyListPreference = findPreference("easylist");
80 Preference easyPrivacyPreference = findPreference("easyprivacy");
81 Preference fanboyAnnoyanceListPreference = findPreference("fanboys_annoyance_list");
82 Preference fanboySocialBlockingListPreference = findPreference("fanboys_social_blocking_list");
83 Preference ultraListPreference = findPreference("ultralist");
84 Preference ultraPrivacyPreference = findPreference("ultraprivacy");
85 Preference blockAllThirdPartyRequestsPreference = findPreference("block_all_third_party_requests");
86 Preference googleAnalyticsPreference = findPreference("google_analytics");
87 Preference facebookClickIdsPreference = findPreference("facebook_click_ids");
88 Preference twitterAmpRedirectsPreference = findPreference("twitter_amp_redirects");
89 Preference searchPreference = findPreference("search");
90 Preference searchCustomURLPreference = findPreference("search_custom_url");
91 Preference proxyPreference = findPreference("proxy");
92 Preference proxyCustomUrlPreference = findPreference("proxy_custom_url");
93 Preference fullScreenBrowsingModePreference = findPreference("full_screen_browsing_mode");
94 Preference hideAppBarPreference = findPreference("hide_app_bar");
95 Preference clearEverythingPreference = findPreference("clear_everything");
96 Preference clearCookiesPreference = findPreference("clear_cookies");
97 Preference clearDomStoragePreference = findPreference("clear_dom_storage");
98 Preference clearFormDataPreference = findPreference("clear_form_data"); // The clear form data preference can be removed once the minimum API >= 26.
99 Preference clearCachePreference = findPreference("clear_cache");
100 Preference homepagePreference = findPreference("homepage");
101 Preference downloadLocationPreference = findPreference("download_location");
102 Preference downloadCustomLocationPreference = findPreference("download_custom_location");
103 Preference fontSizePreference = findPreference("font_size");
104 Preference openIntentsInNewTabPreference = findPreference("open_intents_in_new_tab");
105 Preference swipeToRefreshPreference = findPreference("swipe_to_refresh");
106 Preference scrollAppBarPreference = findPreference("scroll_app_bar");
107 Preference displayAdditionalAppBarIconsPreference = findPreference("display_additional_app_bar_icons");
108 Preference darkThemePreference = findPreference("dark_theme");
109 Preference nightModePreference = findPreference("night_mode");
110 Preference wideViewportPreference = findPreference("wide_viewport");
111 Preference displayWebpageImagesPreference = findPreference("display_webpage_images");
113 // Remove the lint warnings below that the preferences might be null.
114 assert javaScriptPreference != null;
115 assert firstPartyCookiesPreference != null;
116 assert thirdPartyCookiesPreference != null;
117 assert domStoragePreference != null;
118 assert formDataPreference != null;
119 assert userAgentPreference != null;
120 assert customUserAgentPreference != null;
121 assert incognitoModePreference != null;
122 assert doNotTrackPreference != null;
123 assert allowScreenshotsPreference != null;
124 assert easyListPreference != null;
125 assert easyPrivacyPreference != null;
126 assert fanboyAnnoyanceListPreference != null;
127 assert fanboySocialBlockingListPreference != null;
128 assert ultraListPreference != null;
129 assert ultraPrivacyPreference != null;
130 assert blockAllThirdPartyRequestsPreference != null;
131 assert googleAnalyticsPreference != null;
132 assert facebookClickIdsPreference != null;
133 assert twitterAmpRedirectsPreference != null;
134 assert searchPreference != null;
135 assert searchCustomURLPreference != null;
136 assert proxyPreference != null;
137 assert proxyCustomUrlPreference != null;
138 assert fullScreenBrowsingModePreference != null;
139 assert hideAppBarPreference != null;
140 assert clearEverythingPreference != null;
141 assert clearCookiesPreference != null;
142 assert clearDomStoragePreference != null;
143 assert clearFormDataPreference != null;
144 assert clearCachePreference != null;
145 assert homepagePreference != null;
146 assert downloadLocationPreference != null;
147 assert downloadCustomLocationPreference != null;
148 assert fontSizePreference != null;
149 assert openIntentsInNewTabPreference != null;
150 assert swipeToRefreshPreference != null;
151 assert scrollAppBarPreference != null;
152 assert displayAdditionalAppBarIconsPreference != null;
153 assert darkThemePreference != null;
154 assert nightModePreference != null;
155 assert wideViewportPreference != null;
156 assert displayWebpageImagesPreference != null;
158 // Set the hide app bar preference dependency.
159 hideAppBarPreference.setDependency("full_screen_browsing_mode");
161 // Get strings from the preferences.
162 String userAgentName = savedPreferences.getString("user_agent", getString(R.string.user_agent_default_value));
163 String searchString = savedPreferences.getString("search", getString(R.string.search_default_value));
164 String proxyString = savedPreferences.getString("proxy", getString(R.string.proxy_default_value));
165 String downloadLocationString = savedPreferences.getString("download_location", getString(R.string.download_location_default_value));
167 // Get booleans that are used in multiple places from the preferences.
168 boolean javaScriptEnabled = savedPreferences.getBoolean("javascript", false);
169 boolean firstPartyCookiesEnabled = savedPreferences.getBoolean("first_party_cookies", false);
170 boolean thirdPartyCookiesEnabled = savedPreferences.getBoolean("third_party_cookies", false);
171 boolean fanboyAnnoyanceListEnabled = savedPreferences.getBoolean("fanboys_annoyance_list", true);
172 boolean fanboySocialBlockingEnabled = savedPreferences.getBoolean("fanboys_social_blocking_list", true);
173 boolean fullScreenBrowsingMode = savedPreferences.getBoolean("full_screen_browsing_mode", false);
174 boolean clearEverything = savedPreferences.getBoolean("clear_everything", true);
175 boolean darkTheme = savedPreferences.getBoolean("dark_theme", false);
176 boolean nightMode = savedPreferences.getBoolean("night_mode", false);
178 // Only enable the third-party cookies preference if first-party cookies are enabled and API >= 21.
179 thirdPartyCookiesPreference.setEnabled(firstPartyCookiesEnabled && (Build.VERSION.SDK_INT >= 21));
181 // Only enable the DOM storage preference if either JavaScript or Night Mode is enabled.
182 domStoragePreference.setEnabled(javaScriptEnabled || nightMode);
184 // Remove the form data preferences if the API is >= 26 as they no longer do anything.
185 if (Build.VERSION.SDK_INT >= 26) {
186 // Get the categories.
187 PreferenceCategory privacyCategory = findPreference("privacy");
188 PreferenceCategory clearAndExitCategory = findPreference("clear_and_exit");
190 // Remove the lint warnings below that the preference categories might be null.
191 assert privacyCategory != null;
192 assert clearAndExitCategory != null;
194 // Remove the form data preferences.
195 privacyCategory.removePreference(formDataPreference);
196 clearAndExitCategory.removePreference(clearFormDataPreference);
199 // Only enable Fanboy's social blocking list preference if Fanboy's annoyance list is disabled.
200 fanboySocialBlockingListPreference.setEnabled(!fanboyAnnoyanceListEnabled);
203 // Inflate a WebView to get the default user agent.
204 LayoutInflater inflater = getActivity().getLayoutInflater();
206 // `@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.
207 @SuppressLint("InflateParams") View bareWebViewLayout = inflater.inflate(R.layout.bare_webview, null, false);
209 // Get a handle for a bare WebView.
210 WebView bareWebView = bareWebViewLayout.findViewById(R.id.bare_webview);
212 // Get the user agent arrays.
213 ArrayAdapter<CharSequence> userAgentNamesArray = ArrayAdapter.createFromResource(context, R.array.user_agent_names, R.layout.spinner_item);
214 String[] translatedUserAgentNamesArray = resources.getStringArray(R.array.translated_user_agent_names);
215 String[] userAgentDataArray = resources.getStringArray(R.array.user_agent_data);
217 // Get the array position of the user agent name.
218 int userAgentArrayPosition = userAgentNamesArray.getPosition(userAgentName);
220 // Populate the user agent summary.
221 switch (userAgentArrayPosition) {
222 case MainWebViewActivity.UNRECOGNIZED_USER_AGENT: // The user agent name is not on the canonical list.
223 // This is probably because it was set in an older version of Privacy Browser before the switch to persistent user agent names. Use the current user agent entry name as the summary.
224 userAgentPreference.setSummary(userAgentName);
227 case MainWebViewActivity.SETTINGS_WEBVIEW_DEFAULT_USER_AGENT:
228 // Get the user agent text from the webview (which changes based on the version of Android and WebView installed).
229 userAgentPreference.setSummary(translatedUserAgentNamesArray[userAgentArrayPosition] + ":\n" + bareWebView.getSettings().getUserAgentString());
232 case MainWebViewActivity.SETTINGS_CUSTOM_USER_AGENT:
233 // Set the summary text.
234 userAgentPreference.setSummary(R.string.custom_user_agent);
238 // Get the user agent summary from the user agent data array.
239 userAgentPreference.setSummary(translatedUserAgentNamesArray[userAgentArrayPosition] + ":\n" + userAgentDataArray[userAgentArrayPosition]);
242 // Set the summary text for the custom user agent preference.
243 customUserAgentPreference.setSummary(savedPreferences.getString("custom_user_agent", getString(R.string.custom_user_agent_default_value)));
245 // Only enable the custom user agent preference if the user agent is set to `Custom`.
246 customUserAgentPreference.setEnabled(userAgentPreference.getSummary().equals(getString(R.string.custom_user_agent)));
249 // Set the search URL as the summary text for the search preference when the preference screen is loaded.
250 if (searchString.equals("Custom URL")) {
251 // Use R.string.custom_url, which will be translated, instead of the array value, which will not.
252 searchPreference.setSummary(R.string.custom_url);
254 // Set the array value as the summary text.
255 searchPreference.setSummary(searchString);
258 // Set the summary text for the search custom URL (the default is `""`).
259 searchCustomURLPreference.setSummary(savedPreferences.getString("search_custom_url", getString(R.string.search_custom_url_default_value)));
261 // Only enable the search custom URL preference if the search is set to `Custom URL`.
262 searchCustomURLPreference.setEnabled(searchString.equals("Custom URL"));
265 // Set the summary text for the proxy preference when the preference screen is loaded.
266 switch (proxyString) {
267 case ProxyHelper.NONE:
268 proxyPreference.setSummary(getString(R.string.no_proxy_enabled));
271 case ProxyHelper.TOR:
272 if (Build.VERSION.SDK_INT == 19) { // Proxying through SOCKS doesn't work on Android KitKat.
273 proxyPreference.setSummary(getString(R.string.tor_enabled_kitkat));
275 proxyPreference.setSummary(getString(R.string.tor_enabled));
279 case ProxyHelper.I2P:
280 proxyPreference.setSummary(getString(R.string.i2p_enabled));
283 case ProxyHelper.CUSTOM:
284 proxyPreference.setSummary(getString(R.string.custom_proxy));
288 // Set the summary text for the custom proxy URL.
289 proxyCustomUrlPreference.setSummary(savedPreferences.getString("proxy_custom_url", getString(R.string.proxy_custom_url_default_value)));
291 // Only enable the custom proxy URL if a custom proxy is selected.
292 proxyCustomUrlPreference.setEnabled(proxyString.equals("Custom"));
295 // Set the status of the Clear and Exit preferences.
296 clearCookiesPreference.setEnabled(!clearEverything);
297 clearDomStoragePreference.setEnabled(!clearEverything);
298 clearFormDataPreference.setEnabled(!clearEverything); // The form data line can be removed once the minimum API is >= 26.
299 clearCachePreference.setEnabled(!clearEverything);
302 // Set the homepage URL as the summary text for the homepage preference.
303 homepagePreference.setSummary(savedPreferences.getString("homepage", getString(R.string.homepage_default_value)));
306 // Get the download location string arrays.
307 String[] downloadLocationEntriesStringArray = resources.getStringArray(R.array.download_location_entries);
308 String[] downloadLocationEntryValuesStringArray = resources.getStringArray(R.array.download_location_entry_values);
310 // Instantiate the download location helper.
311 DownloadLocationHelper downloadLocationHelper = new DownloadLocationHelper();
313 // Check to see if a download custom location is selected.
314 if (downloadLocationString.equals(downloadLocationEntryValuesStringArray[3])) { // A download custom location is selected.
315 // Set the download location summary text to be `Custom`.
316 downloadLocationPreference.setSummary(downloadLocationEntriesStringArray[3]);
317 } else { // A custom download location is not selected.
318 // Set the download location summary text to be the download location.
319 downloadLocationPreference.setSummary(downloadLocationHelper.getDownloadLocation(context));
321 // Disable the download custom location preference.
322 downloadCustomLocationPreference.setEnabled(false);
325 // Set the summary text for the download custom location (the default is `"`).
326 downloadCustomLocationPreference.setSummary(savedPreferences.getString("download_custom_location", getString(R.string.download_custom_location_default_value)));
329 // Set the font size as the summary text for the preference.
330 fontSizePreference.setSummary(savedPreferences.getString("font_size", getString(R.string.font_size_default_value)) + "%");
333 // Disable the JavaScript preference if Night Mode is enabled. JavaScript will be enabled for all web pages.
334 javaScriptPreference.setEnabled(!nightMode);
336 // Set the JavaScript icon.
337 if (javaScriptEnabled || nightMode) {
338 javaScriptPreference.setIcon(R.drawable.javascript_enabled);
340 javaScriptPreference.setIcon(R.drawable.privacy_mode);
343 // Set the first-party cookies icon.
344 if (firstPartyCookiesEnabled) {
345 firstPartyCookiesPreference.setIcon(R.drawable.cookies_enabled);
348 firstPartyCookiesPreference.setIcon(R.drawable.cookies_disabled_dark);
350 firstPartyCookiesPreference.setIcon(R.drawable.cookies_disabled_light);
354 // Set the third party cookies icon.
355 if (firstPartyCookiesEnabled && Build.VERSION.SDK_INT >= 21) {
356 if (thirdPartyCookiesEnabled) {
357 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_warning);
360 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_disabled_dark);
362 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_disabled_light);
367 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_ghosted_dark);
369 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_ghosted_light);
373 // Set the DOM storage icon.
374 if (javaScriptEnabled || nightMode) { // The preference is enabled.
375 if (savedPreferences.getBoolean("dom_storage", false)) { // DOM storage is enabled.
376 domStoragePreference.setIcon(R.drawable.dom_storage_enabled);
377 } else { // DOM storage is disabled.
379 domStoragePreference.setIcon(R.drawable.dom_storage_disabled_dark);
381 domStoragePreference.setIcon(R.drawable.dom_storage_disabled_light);
384 } else { // The preference is disabled. The icon should be ghosted.
386 domStoragePreference.setIcon(R.drawable.dom_storage_ghosted_dark);
388 domStoragePreference.setIcon(R.drawable.dom_storage_ghosted_light);
392 // Set the save form data icon if API < 26. Save form data has no effect on API >= 26.
393 if (Build.VERSION.SDK_INT < 26) {
394 if (savedPreferences.getBoolean("save_form_data", false)) {
395 formDataPreference.setIcon(R.drawable.form_data_enabled);
398 formDataPreference.setIcon(R.drawable.form_data_disabled_dark);
400 formDataPreference.setIcon(R.drawable.form_data_disabled_light);
405 // Set the custom user agent icon.
406 if (customUserAgentPreference.isEnabled()) {
408 customUserAgentPreference.setIcon(R.drawable.custom_user_agent_enabled_dark);
410 customUserAgentPreference.setIcon(R.drawable.custom_user_agent_enabled_light);
414 customUserAgentPreference.setIcon(R.drawable.custom_user_agent_ghosted_dark);
416 customUserAgentPreference.setIcon(R.drawable.custom_user_agent_ghosted_light);
420 // Set the incognito mode icon.
421 if (savedPreferences.getBoolean("incognito_mode", false)) {
423 incognitoModePreference.setIcon(R.drawable.incognito_mode_enabled_dark);
425 incognitoModePreference.setIcon(R.drawable.incognito_mode_enabled_light);
429 incognitoModePreference.setIcon(R.drawable.incognito_mode_disabled_dark);
431 incognitoModePreference.setIcon(R.drawable.incognito_mode_disabled_light);
435 // Set the Do Not Track icon.
436 if (savedPreferences.getBoolean("do_not_track", false)) {
438 doNotTrackPreference.setIcon(R.drawable.block_tracking_enabled_dark);
440 doNotTrackPreference.setIcon(R.drawable.block_tracking_enabled_light);
444 doNotTrackPreference.setIcon(R.drawable.block_tracking_disabled_dark);
446 doNotTrackPreference.setIcon(R.drawable.block_tracking_disabled_light);
450 // Set the allow screenshots icon.
451 if (savedPreferences.getBoolean("allow_screenshots", false)) {
453 allowScreenshotsPreference.setIcon(R.drawable.allow_screenshots_enabled_dark);
455 allowScreenshotsPreference.setIcon(R.drawable.allow_screenshots_enabled_light);
459 allowScreenshotsPreference.setIcon(R.drawable.allow_screenshots_disabled_dark);
461 allowScreenshotsPreference.setIcon(R.drawable.allow_screenshots_disabled_light);
465 // Set the EasyList icon.
466 if (savedPreferences.getBoolean("easylist", true)) {
468 easyListPreference.setIcon(R.drawable.block_ads_enabled_dark);
470 easyListPreference.setIcon(R.drawable.block_ads_enabled_light);
474 easyListPreference.setIcon(R.drawable.block_ads_disabled_dark);
476 easyListPreference.setIcon(R.drawable.block_ads_disabled_light);
480 // Set the EasyPrivacy icon.
481 if (savedPreferences.getBoolean("easyprivacy", true)) {
483 easyPrivacyPreference.setIcon(R.drawable.block_tracking_enabled_dark);
485 easyPrivacyPreference.setIcon(R.drawable.block_tracking_enabled_light);
489 easyPrivacyPreference.setIcon(R.drawable.block_tracking_disabled_dark);
491 easyPrivacyPreference.setIcon(R.drawable.block_tracking_disabled_light);
495 // Set the Fanboy lists icons.
496 if (fanboyAnnoyanceListEnabled) {
498 // Set the Fanboy annoyance list icon.
499 fanboyAnnoyanceListPreference.setIcon(R.drawable.social_media_enabled_dark);
501 // Set the Fanboy social blocking list icon.
502 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_ghosted_dark);
504 // Set the Fanboy annoyance list icon.
505 fanboyAnnoyanceListPreference.setIcon(R.drawable.social_media_enabled_light);
507 // Set the Fanboy social blocking list icon.
508 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_ghosted_light);
512 // Set the Fanboy annoyance list icon.
513 fanboyAnnoyanceListPreference.setIcon(R.drawable.social_media_disabled_dark);
515 // Set the Fanboy social blocking list icon.
516 if (fanboySocialBlockingEnabled) {
517 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_enabled_dark);
519 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_disabled_dark);
522 // Set the Fanboy annoyance list icon.
523 fanboyAnnoyanceListPreference.setIcon(R.drawable.block_ads_disabled_light);
525 // Set the Fanboy social blocking list icon.
526 if (fanboySocialBlockingEnabled) {
527 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_enabled_light);
529 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_disabled_light);
534 // Set the UltraList icon.
535 if (savedPreferences.getBoolean("ultralist", true)){
537 ultraListPreference.setIcon(R.drawable.block_ads_enabled_dark);
539 ultraListPreference.setIcon(R.drawable.block_ads_enabled_light);
543 ultraListPreference.setIcon(R.drawable.block_ads_disabled_dark);
545 ultraListPreference.setIcon(R.drawable.block_ads_disabled_light);
549 // Set the UltraPrivacy icon.
550 if (savedPreferences.getBoolean("ultraprivacy", true)) {
552 ultraPrivacyPreference.setIcon(R.drawable.block_tracking_enabled_dark);
554 ultraPrivacyPreference.setIcon(R.drawable.block_tracking_enabled_light);
558 ultraPrivacyPreference.setIcon(R.drawable.block_tracking_disabled_dark);
560 ultraPrivacyPreference.setIcon(R.drawable.block_tracking_disabled_light);
564 // Set the block all third-party requests icon.
565 if (savedPreferences.getBoolean("block_all_third_party_requests", false)) {
567 blockAllThirdPartyRequestsPreference.setIcon(R.drawable.block_all_third_party_requests_enabled_dark);
569 blockAllThirdPartyRequestsPreference.setIcon(R.drawable.block_all_third_party_requests_enabled_light);
573 blockAllThirdPartyRequestsPreference.setIcon(R.drawable.block_all_third_party_requests_disabled_dark);
575 blockAllThirdPartyRequestsPreference.setIcon(R.drawable.block_all_third_party_requests_disabled_light);
579 // Set the Google Analytics icon according to the theme.
580 if (savedPreferences.getBoolean("google_analytics", true)) {
582 googleAnalyticsPreference.setIcon(R.drawable.modify_url_enabled_dark);
584 googleAnalyticsPreference.setIcon(R.drawable.modify_url_enabled_light);
588 googleAnalyticsPreference.setIcon(R.drawable.modify_url_disabled_dark);
590 googleAnalyticsPreference.setIcon(R.drawable.modify_url_disabled_light);
594 // Set the Facebook Click IDs icon according to the theme.
595 if (savedPreferences.getBoolean("facebook_click_ids", true)) {
597 facebookClickIdsPreference.setIcon(R.drawable.modify_url_enabled_dark);
599 facebookClickIdsPreference.setIcon(R.drawable.modify_url_enabled_light);
603 facebookClickIdsPreference.setIcon(R.drawable.modify_url_disabled_dark);
605 facebookClickIdsPreference.setIcon(R.drawable.modify_url_disabled_light);
609 // Set the Twitter AMP redirects icon according to the theme.
610 if (savedPreferences.getBoolean("twitter_amp_redirects", true)) {
612 twitterAmpRedirectsPreference.setIcon(R.drawable.modify_url_enabled_dark);
614 twitterAmpRedirectsPreference.setIcon(R.drawable.modify_url_enabled_light);
618 twitterAmpRedirectsPreference.setIcon(R.drawable.modify_url_disabled_dark);
620 twitterAmpRedirectsPreference.setIcon(R.drawable.modify_url_disabled_light);
624 // Set the search custom URL icon.
625 if (searchCustomURLPreference.isEnabled()) {
627 searchCustomURLPreference.setIcon(R.drawable.search_custom_url_enabled_dark);
629 searchCustomURLPreference.setIcon(R.drawable.search_custom_url_enabled_light);
633 searchCustomURLPreference.setIcon(R.drawable.search_custom_url_ghosted_dark);
635 searchCustomURLPreference.setIcon(R.drawable.search_custom_url_ghosted_light);
639 // Set the Proxy icons according to the theme and status.
640 if (proxyString.equals("None")) { // Proxying is disabled.
641 if (darkTheme) { // Dark theme.
642 // Set the main proxy icon to be disabled.
643 proxyPreference.setIcon(R.drawable.proxy_disabled_dark);
645 // Set the custom proxy URL icon to be ghosted.
646 proxyCustomUrlPreference.setIcon(R.drawable.proxy_ghosted_dark);
647 } else { // Light theme.
648 // Set the main proxy icon to be disabled.
649 proxyPreference.setIcon(R.drawable.proxy_disabled_light);
651 // Set the custom proxy URL icon to be ghosted.
652 proxyCustomUrlPreference.setIcon(R.drawable.proxy_ghosted_light);
654 } else { // Proxying is enabled.
655 if (darkTheme) { // Dark theme.
656 // Set the main proxy icon to be enabled.
657 proxyPreference.setIcon(R.drawable.proxy_enabled_dark);
659 // Set the custom proxy URL icon according to its status.
660 if (proxyCustomUrlPreference.isEnabled()) { // Custom proxy is enabled.
661 proxyCustomUrlPreference.setIcon(R.drawable.proxy_enabled_dark);
662 } else { // Custom proxy is disabled.
663 proxyCustomUrlPreference.setIcon(R.drawable.proxy_ghosted_dark);
665 } else { // Light theme.
666 // Set the main proxy icon to be enabled.
667 proxyPreference.setIcon(R.drawable.proxy_enabled_light);
669 // Set the custom proxy URL icon according to its status.
670 if (proxyCustomUrlPreference.isEnabled()) { // Custom proxy is enabled.
671 proxyCustomUrlPreference.setIcon(R.drawable.proxy_enabled_light);
672 } else { // Custom proxy is disabled.
673 proxyCustomUrlPreference.setIcon(R.drawable.proxy_ghosted_light);
678 // Set the full screen browsing mode icons.
679 if (fullScreenBrowsingMode) { // Full screen browsing mode is enabled.
680 // Set the `fullScreenBrowsingModePreference` icon according to the theme.
682 fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_enabled_dark);
684 fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_enabled_light);
687 // Set the hide app bar icon.
688 if (savedPreferences.getBoolean("hide_app_bar", true)) { // Hide app bar is enabled.
689 // Set the icon according to the theme.
691 hideAppBarPreference.setIcon(R.drawable.app_bar_enabled_dark);
693 hideAppBarPreference.setIcon(R.drawable.app_bar_enabled_light);
695 } else { // Hide app bar is disabled.
696 // Set the icon according to the theme.
698 hideAppBarPreference.setIcon(R.drawable.app_bar_disabled_dark);
700 hideAppBarPreference.setIcon(R.drawable.app_bar_disabled_light);
703 } else { // Full screen browsing mode is disabled.
704 // Set the icons according to the theme.
706 fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_disabled_dark);
707 hideAppBarPreference.setIcon(R.drawable.app_bar_ghosted_dark);
709 fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_disabled_light);
710 hideAppBarPreference.setIcon(R.drawable.app_bar_ghosted_light);
714 // Set the clear everything preference icon.
715 if (clearEverything) {
717 clearEverythingPreference.setIcon(R.drawable.clear_everything_enabled_dark);
719 clearEverythingPreference.setIcon(R.drawable.clear_everything_enabled_light);
722 clearEverythingPreference.setIcon(R.drawable.clear_everything_disabled);
725 // Set the clear cookies preference icon.
726 if (clearEverything || savedPreferences.getBoolean("clear_cookies", true)) {
728 clearCookiesPreference.setIcon(R.drawable.cookies_cleared_dark);
730 clearCookiesPreference.setIcon(R.drawable.cookies_cleared_light);
733 clearCookiesPreference.setIcon(R.drawable.cookies_warning);
736 // Set the clear DOM storage preference icon.
737 if (clearEverything || savedPreferences.getBoolean("clear_dom_storage", true)) {
739 clearDomStoragePreference.setIcon(R.drawable.dom_storage_cleared_dark);
741 clearDomStoragePreference.setIcon(R.drawable.dom_storage_cleared_light);
744 clearDomStoragePreference.setIcon(R.drawable.dom_storage_warning);
747 // Set the clear form data preference icon if the API < 26. It has no effect on newer versions of Android.
748 if (Build.VERSION.SDK_INT < 26) {
749 if (clearEverything || savedPreferences.getBoolean("clear_form_data", true)) {
751 clearFormDataPreference.setIcon(R.drawable.form_data_cleared_dark);
753 clearFormDataPreference.setIcon(R.drawable.form_data_cleared_light);
756 clearFormDataPreference.setIcon(R.drawable.form_data_warning);
760 // Set the clear cache preference icon.
761 if (clearEverything || savedPreferences.getBoolean("clear_cache", true)) {
763 clearCachePreference.setIcon(R.drawable.cache_cleared_dark);
765 clearCachePreference.setIcon(R.drawable.cache_cleared_light);
768 clearCachePreference.setIcon(R.drawable.cache_warning);
771 // Set the download custom location icon.
772 if (downloadCustomLocationPreference.isEnabled()) {
774 downloadCustomLocationPreference.setIcon(R.drawable.downloads_enabled_dark);
776 downloadCustomLocationPreference.setIcon(R.drawable.downloads_enabled_light);
780 downloadCustomLocationPreference.setIcon(R.drawable.downloads_ghosted_dark);
782 downloadCustomLocationPreference.setIcon(R.drawable.downloads_ghosted_light);
786 // Set the open intents in new tab preference icon.
787 if (savedPreferences.getBoolean("open_intents_in_new_tab", true)) {
789 openIntentsInNewTabPreference.setIcon(R.drawable.tab_enabled_dark);
791 openIntentsInNewTabPreference.setIcon(R.drawable.tab_enabled_light);
795 openIntentsInNewTabPreference.setIcon(R.drawable.tab_disabled_dark);
797 openIntentsInNewTabPreference.setIcon(R.drawable.tab_disabled_light);
801 // Set the swipe to refresh preference icon.
802 if (savedPreferences.getBoolean("swipe_to_refresh", true)) {
804 swipeToRefreshPreference.setIcon(R.drawable.refresh_enabled_dark);
806 swipeToRefreshPreference.setIcon(R.drawable.refresh_enabled_light);
810 swipeToRefreshPreference.setIcon(R.drawable.refresh_disabled_dark);
812 swipeToRefreshPreference.setIcon(R.drawable.refresh_disabled_light);
816 // Set the scroll app bar preference icon.
817 if (savedPreferences.getBoolean("scroll_app_bar", true)) {
819 scrollAppBarPreference.setIcon(R.drawable.app_bar_enabled_dark);
821 scrollAppBarPreference.setIcon(R.drawable.app_bar_enabled_light);
825 scrollAppBarPreference.setIcon(R.drawable.app_bar_disabled_dark);
827 scrollAppBarPreference.setIcon(R.drawable.app_bar_disabled_light);
831 // Set the display additional app bar icons preference icon.
832 if (savedPreferences.getBoolean("display_additional_app_bar_icons", false)) {
834 displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_enabled_dark);
836 displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_enabled_light);
840 displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_disabled_dark);
842 displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_disabled_light);
846 // Set the dark theme preference icon.
847 if (savedPreferences.getBoolean("dark_theme", false)) {
848 darkThemePreference.setIcon(R.drawable.theme_dark);
850 darkThemePreference.setIcon(R.drawable.theme_light);
853 // Set the night mode preference icon.
856 nightModePreference.setIcon(R.drawable.night_mode_enabled_dark);
858 nightModePreference.setIcon(R.drawable.night_mode_enabled_light);
862 nightModePreference.setIcon(R.drawable.night_mode_disabled_dark);
864 nightModePreference.setIcon(R.drawable.night_mode_disabled_light);
868 // Set the wide viewport preference icon.
869 if (savedPreferences.getBoolean("wide_viewport", true)) {
871 wideViewportPreference.setIcon(R.drawable.wide_viewport_enabled_dark);
873 wideViewportPreference.setIcon(R.drawable.wide_viewport_enabled_light);
877 wideViewportPreference.setIcon(R.drawable.wide_viewport_disabled_dark);
879 wideViewportPreference.setIcon(R.drawable.wide_viewport_disabled_light);
883 // Set the display webpage images preference icon.
884 if (savedPreferences.getBoolean("display_webpage_images", true)) {
886 displayWebpageImagesPreference.setIcon(R.drawable.images_enabled_dark);
888 displayWebpageImagesPreference.setIcon(R.drawable.images_enabled_light);
892 displayWebpageImagesPreference.setIcon(R.drawable.images_disabled_dark);
894 displayWebpageImagesPreference.setIcon(R.drawable.images_disabled_light);
899 // Listen for preference changes.
900 preferencesListener = (SharedPreferences sharedPreferences, String key) -> {
903 // Update the icons and the DOM storage preference status.
904 if (sharedPreferences.getBoolean("javascript", false)) { // The JavaScript preference is enabled.
905 // Update the icon for the JavaScript preference.
906 javaScriptPreference.setIcon(R.drawable.javascript_enabled);
908 // Update the status of the DOM storage preference.
909 domStoragePreference.setEnabled(true);
911 // Update the icon for the DOM storage preference.
912 if (sharedPreferences.getBoolean("dom_storage", false)) {
913 domStoragePreference.setIcon(R.drawable.dom_storage_enabled);
916 domStoragePreference.setIcon(R.drawable.dom_storage_disabled_dark);
918 domStoragePreference.setIcon(R.drawable.dom_storage_disabled_light);
921 } else { // The JavaScript preference is disabled.
922 // Update the icon for the JavaScript preference.
923 javaScriptPreference.setIcon(R.drawable.privacy_mode);
925 // Update the status of the DOM storage preference.
926 domStoragePreference.setEnabled(false);
928 // Set the icon for DOM storage preference to be ghosted.
930 domStoragePreference.setIcon(R.drawable.dom_storage_ghosted_dark);
932 domStoragePreference.setIcon(R.drawable.dom_storage_ghosted_light);
937 case "first_party_cookies":
938 // Update the icons for `first_party_cookies` and `third_party_cookies`.
939 if (sharedPreferences.getBoolean("first_party_cookies", false)) {
940 // Set the icon for `first_party_cookies`.
941 firstPartyCookiesPreference.setIcon(R.drawable.cookies_enabled);
943 // Update the icon for `third_party_cookies`.
944 if (Build.VERSION.SDK_INT >= 21) {
945 if (sharedPreferences.getBoolean("third_party_cookies", false)) {
946 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_warning);
949 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_disabled_dark);
951 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_disabled_light);
956 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_ghosted_dark);
958 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_ghosted_light);
961 } else { // `first_party_cookies` is `false`.
962 // Update the icon for `first_party_cookies`.
964 firstPartyCookiesPreference.setIcon(R.drawable.cookies_disabled_dark);
966 firstPartyCookiesPreference.setIcon(R.drawable.cookies_disabled_light);
969 // Set the icon for `third_party_cookies` to be ghosted.
971 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_ghosted_dark);
973 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_ghosted_light);
977 // Enable `third_party_cookies` if `first_party_cookies` is `true` and API >= 21.
978 thirdPartyCookiesPreference.setEnabled(sharedPreferences.getBoolean("first_party_cookies", false) && (Build.VERSION.SDK_INT >= 21));
981 case "third_party_cookies":
983 if (sharedPreferences.getBoolean("third_party_cookies", false)) {
984 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_warning);
987 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_disabled_dark);
989 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_disabled_light);
996 if (sharedPreferences.getBoolean("dom_storage", false)) {
997 domStoragePreference.setIcon(R.drawable.dom_storage_enabled);
1000 domStoragePreference.setIcon(R.drawable.dom_storage_disabled_dark);
1002 domStoragePreference.setIcon(R.drawable.dom_storage_disabled_light);
1007 // Save form data can be removed once the minimum API >= 26.
1008 case "save_form_data":
1010 if (sharedPreferences.getBoolean("save_form_data", false)) {
1011 formDataPreference.setIcon(R.drawable.form_data_enabled);
1014 formDataPreference.setIcon(R.drawable.form_data_disabled_dark);
1016 formDataPreference.setIcon(R.drawable.form_data_disabled_light);
1022 // Get the new user agent name.
1023 String newUserAgentName = sharedPreferences.getString("user_agent", getString(R.string.user_agent_default_value));
1025 // Get the array position for the new user agent name.
1026 int newUserAgentArrayPosition = userAgentNamesArray.getPosition(newUserAgentName);
1028 // Get the translated new user agent name.
1029 String translatedNewUserAgentName = translatedUserAgentNamesArray[newUserAgentArrayPosition];
1031 // Populate the user agent summary.
1032 switch (newUserAgentArrayPosition) {
1033 case MainWebViewActivity.SETTINGS_WEBVIEW_DEFAULT_USER_AGENT:
1034 // Get the user agent text from the webview (which changes based on the version of Android and WebView installed).
1035 userAgentPreference.setSummary(translatedNewUserAgentName + ":\n" + bareWebView.getSettings().getUserAgentString());
1037 // Disable the custom user agent preference.
1038 customUserAgentPreference.setEnabled(false);
1040 // Set the custom user agent preference icon according to the theme.
1042 customUserAgentPreference.setIcon(R.drawable.custom_user_agent_ghosted_dark);
1044 customUserAgentPreference.setIcon(R.drawable.custom_user_agent_ghosted_light);
1048 case MainWebViewActivity.SETTINGS_CUSTOM_USER_AGENT:
1049 // Set the summary text.
1050 userAgentPreference.setSummary(R.string.custom_user_agent);
1052 // Enable the custom user agent preference.
1053 customUserAgentPreference.setEnabled(true);
1055 // Set the custom user agent preference icon according to the theme.
1057 customUserAgentPreference.setIcon(R.drawable.custom_user_agent_enabled_dark);
1059 customUserAgentPreference.setIcon(R.drawable.custom_user_agent_enabled_light);
1064 // Get the user agent summary from the user agent data array.
1065 userAgentPreference.setSummary(translatedNewUserAgentName + ":\n" + userAgentDataArray[newUserAgentArrayPosition]);
1067 // Disable the custom user agent preference.
1068 customUserAgentPreference.setEnabled(false);
1070 // Set the custom user agent preference icon according to the theme.
1072 customUserAgentPreference.setIcon(R.drawable.custom_user_agent_ghosted_dark);
1074 customUserAgentPreference.setIcon(R.drawable.custom_user_agent_ghosted_light);
1079 case "custom_user_agent":
1080 // Set the new custom user agent as the summary text for the preference.
1081 customUserAgentPreference.setSummary(sharedPreferences.getString("custom_user_agent", getString(R.string.custom_user_agent_default_value)));
1084 case "incognito_mode":
1086 if (sharedPreferences.getBoolean("incognito_mode", false)) {
1088 incognitoModePreference.setIcon(R.drawable.incognito_mode_enabled_dark);
1090 incognitoModePreference.setIcon(R.drawable.incognito_mode_enabled_light);
1094 incognitoModePreference.setIcon(R.drawable.incognito_mode_disabled_dark);
1096 incognitoModePreference.setIcon(R.drawable.incognito_mode_disabled_light);
1101 case "do_not_track":
1103 if (sharedPreferences.getBoolean("do_not_track", false)) {
1105 doNotTrackPreference.setIcon(R.drawable.block_tracking_enabled_dark);
1107 doNotTrackPreference.setIcon(R.drawable.block_tracking_enabled_light);
1111 doNotTrackPreference.setIcon(R.drawable.block_tracking_disabled_dark);
1113 doNotTrackPreference.setIcon(R.drawable.block_tracking_disabled_light);
1119 case "allow_screenshots":
1121 if (sharedPreferences.getBoolean("allow_screenshots", false)) {
1123 allowScreenshotsPreference.setIcon(R.drawable.allow_screenshots_enabled_dark);
1125 allowScreenshotsPreference.setIcon(R.drawable.allow_screenshots_enabled_light);
1129 allowScreenshotsPreference.setIcon(R.drawable.allow_screenshots_disabled_dark);
1131 allowScreenshotsPreference.setIcon(R.drawable.allow_screenshots_disabled_light);
1135 // Create an intent to restart Privacy Browser.
1136 Intent allowScreenshotsRestartIntent = getActivity().getParentActivityIntent();
1138 // Assert that the intent is not null to remove the lint error below.
1139 assert allowScreenshotsRestartIntent != null;
1141 // `Intent.FLAG_ACTIVITY_CLEAR_TASK` removes all activities from the stack. It requires `Intent.FLAG_ACTIVITY_NEW_TASK`.
1142 allowScreenshotsRestartIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
1144 // Create a handler to restart the activity.
1145 Handler allowScreenshotsRestartHandler = new Handler();
1147 // Create a runnable to restart the activity.
1148 Runnable allowScreenshotsRestartRunnable = () -> {
1149 // Restart the activity.
1150 startActivity(allowScreenshotsRestartIntent);
1152 // Kill this instance of Privacy Browser. Otherwise, the app exhibits sporadic behavior after the restart.
1156 // Restart the activity after 150 milliseconds, so that the app has enough time to save the change to the preference.
1157 allowScreenshotsRestartHandler.postDelayed(allowScreenshotsRestartRunnable, 150);
1162 if (sharedPreferences.getBoolean("easylist", true)) {
1164 easyListPreference.setIcon(R.drawable.block_ads_enabled_dark);
1166 easyListPreference.setIcon(R.drawable.block_ads_enabled_light);
1170 easyListPreference.setIcon(R.drawable.block_ads_disabled_dark);
1172 easyListPreference.setIcon(R.drawable.block_ads_disabled_light);
1179 if (sharedPreferences.getBoolean("easyprivacy", true)) {
1181 easyPrivacyPreference.setIcon(R.drawable.block_tracking_enabled_dark);
1183 easyPrivacyPreference.setIcon(R.drawable.block_tracking_enabled_light);
1187 easyPrivacyPreference.setIcon(R.drawable.block_tracking_disabled_dark);
1189 easyPrivacyPreference.setIcon(R.drawable.block_tracking_disabled_light);
1194 case "fanboys_annoyance_list":
1195 boolean currentFanboyAnnoyanceList = sharedPreferences.getBoolean("fanboys_annoyance_list", true);
1196 boolean currentFanboySocialBlockingList = sharedPreferences.getBoolean("fanboys_social_blocking_list", true);
1198 // Update the Fanboy icons.
1199 if (currentFanboyAnnoyanceList) { // Fanboy's annoyance list is enabled.
1201 // Update the Fanboy's annoyance list icon.
1202 fanboyAnnoyanceListPreference.setIcon(R.drawable.social_media_enabled_dark);
1204 // Update the Fanboy's social blocking list icon.
1205 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_ghosted_dark);
1207 // Update the Fanboy's annoyance list icon.
1208 fanboyAnnoyanceListPreference.setIcon(R.drawable.social_media_enabled_light);
1210 // Update the Fanboy's social blocking list icon.
1211 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_ghosted_light);
1213 } else { // Fanboy's annoyance list is disabled.
1215 // Update the Fanboy's annoyance list icon.
1216 fanboyAnnoyanceListPreference.setIcon(R.drawable.social_media_disabled_dark);
1218 // Update the Fanboy's social blocking list icon.
1219 if (currentFanboySocialBlockingList) {
1220 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_enabled_dark);
1222 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_disabled_dark);
1225 // Update the Fanboy's annoyance list icon.
1226 fanboyAnnoyanceListPreference.setIcon(R.drawable.social_media_disabled_light);
1228 // Update the Fanboy's social blocking list icon.
1229 if (currentFanboySocialBlockingList) {
1230 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_enabled_light);
1232 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_disabled_light);
1237 // Only enable Fanboy's social blocking list preference if Fanboy's annoyance list preference is disabled.
1238 fanboySocialBlockingListPreference.setEnabled(!currentFanboyAnnoyanceList);
1241 case "fanboys_social_blocking_list":
1243 if (sharedPreferences.getBoolean("fanboys_social_blocking_list", true)) {
1245 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_enabled_dark);
1247 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_enabled_light);
1251 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_disabled_dark);
1253 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_disabled_light);
1260 if (sharedPreferences.getBoolean("ultralist", true)) {
1262 ultraListPreference.setIcon(R.drawable.block_ads_enabled_dark);
1264 ultraListPreference.setIcon(R.drawable.block_ads_enabled_light);
1268 ultraListPreference.setIcon(R.drawable.block_ads_disabled_dark);
1270 ultraListPreference.setIcon(R.drawable.block_ads_disabled_light);
1275 case "ultraprivacy":
1277 if (sharedPreferences.getBoolean("ultraprivacy", true)) {
1279 ultraPrivacyPreference.setIcon(R.drawable.block_tracking_enabled_dark);
1281 ultraPrivacyPreference.setIcon(R.drawable.block_tracking_enabled_light);
1285 ultraPrivacyPreference.setIcon(R.drawable.block_tracking_disabled_dark);
1287 ultraPrivacyPreference.setIcon(R.drawable.block_tracking_disabled_light);
1292 case "block_all_third_party_requests":
1294 if (sharedPreferences.getBoolean("block_all_third_party_requests", false)) {
1296 blockAllThirdPartyRequestsPreference.setIcon(R.drawable.block_all_third_party_requests_enabled_dark);
1298 blockAllThirdPartyRequestsPreference.setIcon(R.drawable.block_all_third_party_requests_enabled_light);
1302 blockAllThirdPartyRequestsPreference.setIcon(R.drawable.block_all_third_party_requests_disabled_dark);
1304 blockAllThirdPartyRequestsPreference.setIcon(R.drawable.block_all_third_party_requests_disabled_light);
1309 case "google_analytics":
1311 if (sharedPreferences.getBoolean("google_analytics", true)) {
1313 googleAnalyticsPreference.setIcon(R.drawable.modify_url_enabled_dark);
1315 googleAnalyticsPreference.setIcon(R.drawable.modify_url_enabled_light);
1319 googleAnalyticsPreference.setIcon(R.drawable.modify_url_disabled_dark);
1321 googleAnalyticsPreference.setIcon(R.drawable.modify_url_disabled_light);
1326 case "facebook_click_ids":
1328 if (sharedPreferences.getBoolean("facebook_click_ids", true)) {
1330 facebookClickIdsPreference.setIcon(R.drawable.modify_url_enabled_dark);
1332 facebookClickIdsPreference.setIcon(R.drawable.modify_url_enabled_light);
1336 facebookClickIdsPreference.setIcon(R.drawable.modify_url_disabled_dark);
1338 facebookClickIdsPreference.setIcon(R.drawable.modify_url_disabled_light);
1343 case "twitter_amp_redirects":
1345 if (sharedPreferences.getBoolean("twitter_amp_redirects", true)) {
1347 twitterAmpRedirectsPreference.setIcon(R.drawable.modify_url_enabled_dark);
1349 twitterAmpRedirectsPreference.setIcon(R.drawable.modify_url_enabled_light);
1353 twitterAmpRedirectsPreference.setIcon(R.drawable.modify_url_disabled_dark);
1355 twitterAmpRedirectsPreference.setIcon(R.drawable.modify_url_disabled_light);
1361 // Store the new search string.
1362 String newSearchString = sharedPreferences.getString("search", getString(R.string.search_default_value));
1364 // Update the search and search custom URL preferences.
1365 if (newSearchString.equals("Custom URL")) { // `Custom URL` is selected.
1366 // Set the summary text to `R.string.custom_url`, which is translated.
1367 searchPreference.setSummary(R.string.custom_url);
1369 // Enable `searchCustomURLPreference`.
1370 searchCustomURLPreference.setEnabled(true);
1372 // Set the `searchCustomURLPreference` according to the theme.
1374 searchCustomURLPreference.setIcon(R.drawable.search_custom_url_enabled_dark);
1376 searchCustomURLPreference.setIcon(R.drawable.search_custom_url_enabled_light);
1378 } else { // `Custom URL` is not selected.
1379 // Set the summary text to `newSearchString`.
1380 searchPreference.setSummary(newSearchString);
1382 // Disable `searchCustomURLPreference`.
1383 searchCustomURLPreference.setEnabled(false);
1385 // Set the `searchCustomURLPreference` according to the theme.
1387 searchCustomURLPreference.setIcon(R.drawable.search_custom_url_ghosted_dark);
1389 searchCustomURLPreference.setIcon(R.drawable.search_custom_url_ghosted_light);
1394 case "search_custom_url":
1395 // Set the new search custom URL as the summary text for the preference.
1396 searchCustomURLPreference.setSummary(sharedPreferences.getString("search_custom_url", getString(R.string.search_custom_url_default_value)));
1400 // Get current proxy string.
1401 String currentProxyString = sharedPreferences.getString("proxy", getString(R.string.proxy_default_value));
1403 // Update the summary text for the proxy preference.
1404 switch (currentProxyString) {
1405 case ProxyHelper.NONE:
1406 proxyPreference.setSummary(getString(R.string.no_proxy_enabled));
1409 case ProxyHelper.TOR:
1410 if (Build.VERSION.SDK_INT == 19) { // Proxying through SOCKS doesn't work on Android KitKat.
1411 proxyPreference.setSummary(getString(R.string.tor_enabled_kitkat));
1413 proxyPreference.setSummary(getString(R.string.tor_enabled));
1417 case ProxyHelper.I2P:
1418 proxyPreference.setSummary(getString(R.string.i2p_enabled));
1421 case ProxyHelper.CUSTOM:
1422 proxyPreference.setSummary(getString(R.string.custom_proxy));
1426 // Update the status of the custom URL preference.
1427 proxyCustomUrlPreference.setEnabled(currentProxyString.equals("Custom"));
1429 // Update the icons.
1430 if (currentProxyString.equals("None")) { // Proxying is disabled.
1431 if (darkTheme) { // Dark theme.
1432 // Set the main proxy icon to be disabled
1433 proxyPreference.setIcon(R.drawable.proxy_disabled_dark);
1435 // Set the custom proxy URL icon to be ghosted.
1436 proxyCustomUrlPreference.setIcon(R.drawable.proxy_ghosted_dark);
1437 } else { // Light theme.
1438 // Set the main proxy icon to be disabled.
1439 proxyPreference.setIcon(R.drawable.proxy_disabled_light);
1441 // Set the custom proxy URL icon to be ghosted.
1442 proxyCustomUrlPreference.setIcon(R.drawable.proxy_ghosted_light);
1444 } else { // Proxying is enabled.
1445 if (darkTheme) { // Dark theme.
1446 // Set the main proxy icon to be enabled.
1447 proxyPreference.setIcon(R.drawable.proxy_enabled_dark);
1449 /// Set the custom proxy URL icon according to its status.
1450 if (proxyCustomUrlPreference.isEnabled()) { // Custom proxy is enabled.
1451 proxyCustomUrlPreference.setIcon(R.drawable.proxy_enabled_dark);
1452 } else { // Custom proxy is disabled.
1453 proxyCustomUrlPreference.setIcon(R.drawable.proxy_ghosted_dark);
1455 } else { // Light theme.
1456 // Set the main proxy icon to be enabled.
1457 proxyPreference.setIcon(R.drawable.proxy_enabled_light);
1459 // Set the custom proxy URL icon according to its status.
1460 if (proxyCustomUrlPreference.isEnabled()) { // Custom proxy is enabled.
1461 proxyCustomUrlPreference.setIcon(R.drawable.proxy_enabled_light);
1462 } else { // Custom proxy is disabled.
1463 proxyCustomUrlPreference.setIcon(R.drawable.proxy_ghosted_light);
1469 case "proxy_custom_url":
1470 // Set the summary text for the proxy custom URL.
1471 proxyCustomUrlPreference.setSummary(sharedPreferences.getString("proxy_custom_url", getString(R.string.proxy_custom_url_default_value)));
1474 case "full_screen_browsing_mode":
1475 if (sharedPreferences.getBoolean("full_screen_browsing_mode", false)) { // Full screen browsing is enabled.
1476 // Set the full screen browsing mode preference icon according to the theme.
1478 fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_enabled_dark);
1480 fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_enabled_light);
1483 // Set the hide app bar preference icon.
1484 if (sharedPreferences.getBoolean("hide_app_bar", true)) { // Hide app bar is enabled.
1485 // Set the icon according to the theme.
1487 hideAppBarPreference.setIcon(R.drawable.app_bar_enabled_dark);
1489 hideAppBarPreference.setIcon(R.drawable.app_bar_enabled_light);
1491 } else { // Hide app bar is disabled.
1492 // Set the icon according to the theme.
1494 hideAppBarPreference.setIcon(R.drawable.app_bar_disabled_dark);
1496 hideAppBarPreference.setIcon(R.drawable.app_bar_disabled_light);
1499 } else { // Full screen browsing is disabled.
1500 // Update the icons according to the theme.
1502 fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_disabled_dark);
1503 hideAppBarPreference.setIcon(R.drawable.app_bar_ghosted_dark);
1505 fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_disabled_light);
1506 hideAppBarPreference.setIcon(R.drawable.app_bar_ghosted_light);
1511 case "hide_app_bar":
1513 if (sharedPreferences.getBoolean("hide_app_bar", true)) { // Hide app bar is enabled.
1514 // Set the icon according to the theme.
1516 hideAppBarPreference.setIcon(R.drawable.app_bar_enabled_dark);
1518 hideAppBarPreference.setIcon(R.drawable.app_bar_enabled_light);
1520 } else { // Hide app bar is disabled.
1521 // Set the icon according to the theme.
1523 hideAppBarPreference.setIcon(R.drawable.app_bar_disabled_dark);
1525 hideAppBarPreference.setIcon(R.drawable.app_bar_disabled_light);
1530 case "clear_everything":
1531 // Store the new `clear_everything` status
1532 boolean newClearEverythingBoolean = sharedPreferences.getBoolean("clear_everything", true);
1534 // Update the status of the `Clear and Exit` preferences.
1535 clearCookiesPreference.setEnabled(!newClearEverythingBoolean);
1536 clearDomStoragePreference.setEnabled(!newClearEverythingBoolean);
1537 clearFormDataPreference.setEnabled(!newClearEverythingBoolean); // This line can be removed once the minimum API >= 26.
1538 clearCachePreference.setEnabled(!newClearEverythingBoolean);
1540 // Update the `clearEverythingPreference` icon.
1541 if (newClearEverythingBoolean) {
1543 clearEverythingPreference.setIcon(R.drawable.clear_everything_enabled_dark);
1545 clearEverythingPreference.setIcon(R.drawable.clear_everything_enabled_light);
1548 clearEverythingPreference.setIcon(R.drawable.clear_everything_disabled);
1551 // Update the `clearCookiesPreference` icon.
1552 if (newClearEverythingBoolean || sharedPreferences.getBoolean("clear_cookies", true)) {
1554 clearCookiesPreference.setIcon(R.drawable.cookies_cleared_dark);
1556 clearCookiesPreference.setIcon(R.drawable.cookies_cleared_light);
1559 clearCookiesPreference.setIcon(R.drawable.cookies_warning);
1562 // Update the `clearDomStoragePreference` icon.
1563 if (newClearEverythingBoolean || sharedPreferences.getBoolean("clear_dom_storage", true)) {
1565 clearDomStoragePreference.setIcon(R.drawable.dom_storage_cleared_dark);
1567 clearDomStoragePreference.setIcon(R.drawable.dom_storage_cleared_light);
1570 clearDomStoragePreference.setIcon(R.drawable.dom_storage_warning);
1573 // Update the clear form data preference icon if the API < 26.
1574 if (Build.VERSION.SDK_INT < 26) {
1575 if (newClearEverythingBoolean || sharedPreferences.getBoolean("clear_form_data", true)) {
1577 clearFormDataPreference.setIcon(R.drawable.form_data_cleared_dark);
1579 clearFormDataPreference.setIcon(R.drawable.form_data_cleared_light);
1582 clearFormDataPreference.setIcon(R.drawable.form_data_warning);
1586 // Update the `clearCachePreference` icon.
1587 if (newClearEverythingBoolean || sharedPreferences.getBoolean("clear_cache", true)) {
1589 clearCachePreference.setIcon(R.drawable.cache_cleared_dark);
1591 clearCachePreference.setIcon(R.drawable.cache_cleared_light);
1594 clearCachePreference.setIcon(R.drawable.cache_warning);
1598 case "clear_cookies":
1600 if (sharedPreferences.getBoolean("clear_cookies", true)) {
1602 clearCookiesPreference.setIcon(R.drawable.cookies_cleared_dark);
1604 clearCookiesPreference.setIcon(R.drawable.cookies_cleared_light);
1607 clearCookiesPreference.setIcon(R.drawable.cookies_warning);
1611 case "clear_dom_storage":
1613 if (sharedPreferences.getBoolean("clear_dom_storage", true)) {
1615 clearDomStoragePreference.setIcon(R.drawable.dom_storage_cleared_dark);
1617 clearDomStoragePreference.setIcon(R.drawable.dom_storage_cleared_light);
1620 clearDomStoragePreference.setIcon(R.drawable.dom_storage_warning);
1624 // This section can be removed once the minimum API >= 26.
1625 case "clear_form_data":
1627 if (sharedPreferences.getBoolean("clear_form_data", true)) {
1629 clearFormDataPreference.setIcon(R.drawable.form_data_cleared_dark);
1631 clearFormDataPreference.setIcon(R.drawable.form_data_cleared_light);
1634 clearFormDataPreference.setIcon(R.drawable.form_data_warning);
1640 if (sharedPreferences.getBoolean("clear_cache", true)) {
1642 clearCachePreference.setIcon(R.drawable.cache_cleared_dark);
1644 clearCachePreference.setIcon(R.drawable.cache_cleared_light);
1647 clearCachePreference.setIcon(R.drawable.cache_warning);
1652 // Set the new homepage URL as the summary text for the Homepage preference.
1653 homepagePreference.setSummary(sharedPreferences.getString("homepage", getString(R.string.homepage_default_value)));
1656 case "download_location":
1657 // Get the new download location.
1658 String newDownloadLocationString = sharedPreferences.getString("download_location", getString(R.string.download_location_default_value));
1660 // Check to see if a download custom location is selected.
1661 if (newDownloadLocationString.equals(downloadLocationEntryValuesStringArray[3])) { // A download custom location is selected.
1662 // Set the download location summary text to be `Custom`.
1663 downloadLocationPreference.setSummary(downloadLocationEntriesStringArray[3]);
1665 // Enable the download custom location preference.
1666 downloadCustomLocationPreference.setEnabled(true);
1667 } else { // A download custom location is not selected.
1668 // Set the download location summary text to be the download location.
1669 downloadLocationPreference.setSummary(downloadLocationHelper.getDownloadLocation(context));
1671 // Disable the download custom location.
1672 downloadCustomLocationPreference.setEnabled(newDownloadLocationString.equals(downloadLocationEntryValuesStringArray[3]));
1675 // Update the download custom location icon.
1676 if (downloadCustomLocationPreference.isEnabled()) {
1678 downloadCustomLocationPreference.setIcon(R.drawable.downloads_enabled_dark);
1680 downloadCustomLocationPreference.setIcon(R.drawable.downloads_enabled_light);
1684 downloadCustomLocationPreference.setIcon(R.drawable.downloads_ghosted_dark);
1686 downloadCustomLocationPreference.setIcon(R.drawable.downloads_ghosted_light);
1691 case "download_custom_location":
1692 // Set the new download custom location as the summary text for the preference.
1693 downloadCustomLocationPreference.setSummary(sharedPreferences.getString("download_custom_location", getString(R.string.download_custom_location_default_value)));
1697 // Update the font size summary text.
1698 fontSizePreference.setSummary(sharedPreferences.getString("font_size", getString(R.string.font_size_default_value)) + "%");
1701 case "open_intents_in_new_tab":
1703 if (sharedPreferences.getBoolean("open_intents_in_new_tab", true)) {
1705 openIntentsInNewTabPreference.setIcon(R.drawable.tab_enabled_dark);
1707 openIntentsInNewTabPreference.setIcon(R.drawable.tab_enabled_light);
1711 openIntentsInNewTabPreference.setIcon(R.drawable.tab_disabled_dark);
1713 openIntentsInNewTabPreference.setIcon(R.drawable.tab_disabled_light);
1718 case "swipe_to_refresh":
1720 if (sharedPreferences.getBoolean("swipe_to_refresh", true)) {
1722 swipeToRefreshPreference.setIcon(R.drawable.refresh_enabled_dark);
1724 swipeToRefreshPreference.setIcon(R.drawable.refresh_enabled_light);
1728 swipeToRefreshPreference.setIcon(R.drawable.refresh_disabled_dark);
1730 swipeToRefreshPreference.setIcon(R.drawable.refresh_disabled_light);
1735 case "scroll_app_bar":
1737 if (sharedPreferences.getBoolean("scroll_app_bar", true)) {
1739 scrollAppBarPreference.setIcon(R.drawable.app_bar_enabled_dark);
1741 scrollAppBarPreference.setIcon(R.drawable.app_bar_enabled_light);
1745 scrollAppBarPreference.setIcon(R.drawable.app_bar_disabled_dark);
1747 scrollAppBarPreference.setIcon(R.drawable.app_bar_disabled_light);
1752 case "display_additional_app_bar_icons":
1754 if (sharedPreferences.getBoolean("display_additional_app_bar_icons", false)) {
1756 displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_enabled_dark);
1758 displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_enabled_light);
1762 displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_disabled_dark);
1764 displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_disabled_light);
1771 if (sharedPreferences.getBoolean("dark_theme", false)) {
1772 darkThemePreference.setIcon(R.drawable.theme_dark);
1774 darkThemePreference.setIcon(R.drawable.theme_light);
1777 // Create an intent to restart Privacy Browser.
1778 Intent changeThemeRestartIntent = getActivity().getParentActivityIntent();
1780 // Assert that the intent is not null to remove the lint error below.
1781 assert changeThemeRestartIntent != null;
1783 // `Intent.FLAG_ACTIVITY_CLEAR_TASK` removes all activities from the stack. It requires `Intent.FLAG_ACTIVITY_NEW_TASK`.
1784 changeThemeRestartIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
1786 // Create a handler to restart the activity.
1787 Handler changeThemeRestartHandler = new Handler();
1789 // Create a runnable to restart the activity.
1790 Runnable changeThemeRestartRunnable = () -> {
1791 // Restart the activity.
1792 startActivity(changeThemeRestartIntent);
1794 // Kill this instance of Privacy Browser. Otherwise, the app exhibits sporadic behavior after the restart.
1798 // Restart the activity after 150 milliseconds, so that the app has enough time to save the change to the preference.
1799 changeThemeRestartHandler.postDelayed(changeThemeRestartRunnable, 150);
1803 // Store the current night mode status.
1804 boolean currentNightModeBoolean = sharedPreferences.getBoolean("night_mode", false);
1805 boolean currentJavaScriptBoolean = sharedPreferences.getBoolean("javascript", false);
1808 if (currentNightModeBoolean) {
1810 nightModePreference.setIcon(R.drawable.night_mode_enabled_dark);
1812 nightModePreference.setIcon(R.drawable.night_mode_enabled_light);
1816 nightModePreference.setIcon(R.drawable.night_mode_disabled_dark);
1818 nightModePreference.setIcon(R.drawable.night_mode_disabled_light);
1822 // Update the status of `javaScriptPreference` and `domStoragePreference`.
1823 javaScriptPreference.setEnabled(!currentNightModeBoolean);
1824 domStoragePreference.setEnabled(currentNightModeBoolean || currentJavaScriptBoolean);
1826 // Update the `javaScriptPreference` icon.
1827 if (currentNightModeBoolean || currentJavaScriptBoolean) {
1828 javaScriptPreference.setIcon(R.drawable.javascript_enabled);
1830 javaScriptPreference.setIcon(R.drawable.privacy_mode);
1833 // Update the DOM storage preference icon.
1834 if (currentNightModeBoolean || currentJavaScriptBoolean) { // The preference is enabled.
1835 if (sharedPreferences.getBoolean("dom_storage", false)) { // DOM storage is enabled.
1836 domStoragePreference.setIcon(R.drawable.dom_storage_enabled);
1837 } else { // DOM storage is disabled.
1839 domStoragePreference.setIcon(R.drawable.dom_storage_disabled_dark);
1841 domStoragePreference.setIcon(R.drawable.dom_storage_disabled_light);
1844 } else { // The preference is disabled. The icon should be ghosted.
1846 domStoragePreference.setIcon(R.drawable.dom_storage_ghosted_dark);
1848 domStoragePreference.setIcon(R.drawable.dom_storage_ghosted_light);
1853 case "wide_viewport":
1855 if (sharedPreferences.getBoolean("wide_viewport", true)) {
1857 wideViewportPreference.setIcon(R.drawable.wide_viewport_enabled_dark);
1859 wideViewportPreference.setIcon(R.drawable.wide_viewport_enabled_light);
1863 wideViewportPreference.setIcon(R.drawable.wide_viewport_disabled_dark);
1865 wideViewportPreference.setIcon(R.drawable.wide_viewport_disabled_light);
1870 case "display_webpage_images":
1872 if (sharedPreferences.getBoolean("display_webpage_images", true)) {
1874 displayWebpageImagesPreference.setIcon(R.drawable.images_enabled_dark);
1876 displayWebpageImagesPreference.setIcon(R.drawable.images_enabled_light);
1880 displayWebpageImagesPreference.setIcon(R.drawable.images_disabled_dark);
1882 displayWebpageImagesPreference.setIcon(R.drawable.images_disabled_light);
1889 // Register the listener.
1890 savedPreferences.registerOnSharedPreferenceChangeListener(preferencesListener);
1893 // It is necessary to re-register the listener on every resume or it will randomly stop working because apps can be paused and resumed at any time, even while running in the foreground.
1895 public void onPause() {
1897 savedPreferences.unregisterOnSharedPreferenceChangeListener(preferencesListener);
1901 public void onResume() {
1903 savedPreferences.registerOnSharedPreferenceChangeListener(preferencesListener);