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.
62 Context context = activity.getApplicationContext();
64 // Initialize savedPreferences.
65 savedPreferences = getPreferenceScreen().getSharedPreferences();
67 // Get handles for the preferences.
68 Preference javaScriptPreference = findPreference("javascript");
69 Preference firstPartyCookiesPreference = findPreference("first_party_cookies");
70 Preference thirdPartyCookiesPreference = findPreference("third_party_cookies");
71 Preference domStoragePreference = findPreference("dom_storage");
72 Preference formDataPreference = findPreference("save_form_data"); // The form data preference can be removed once the minimum API >= 26.
73 Preference userAgentPreference = findPreference("user_agent");
74 Preference customUserAgentPreference = findPreference("custom_user_agent");
75 Preference incognitoModePreference = findPreference("incognito_mode");
76 Preference doNotTrackPreference = findPreference("do_not_track");
77 Preference allowScreenshotsPreference = findPreference("allow_screenshots");
78 Preference easyListPreference = findPreference("easylist");
79 Preference easyPrivacyPreference = findPreference("easyprivacy");
80 Preference fanboyAnnoyanceListPreference = findPreference("fanboys_annoyance_list");
81 Preference fanboySocialBlockingListPreference = findPreference("fanboys_social_blocking_list");
82 Preference ultraListPreference = findPreference("ultralist");
83 Preference ultraPrivacyPreference = findPreference("ultraprivacy");
84 Preference blockAllThirdPartyRequestsPreference = findPreference("block_all_third_party_requests");
85 Preference googleAnalyticsPreference = findPreference("google_analytics");
86 Preference facebookClickIdsPreference = findPreference("facebook_click_ids");
87 Preference twitterAmpRedirectsPreference = findPreference("twitter_amp_redirects");
88 Preference searchPreference = findPreference("search");
89 Preference searchCustomURLPreference = findPreference("search_custom_url");
90 Preference proxyPreference = findPreference("proxy");
91 Preference proxyCustomUrlPreference = findPreference("proxy_custom_url");
92 Preference fullScreenBrowsingModePreference = findPreference("full_screen_browsing_mode");
93 Preference hideAppBarPreference = findPreference("hide_app_bar");
94 Preference clearEverythingPreference = findPreference("clear_everything");
95 Preference clearCookiesPreference = findPreference("clear_cookies");
96 Preference clearDomStoragePreference = findPreference("clear_dom_storage");
97 Preference clearFormDataPreference = findPreference("clear_form_data"); // The clear form data preference can be removed once the minimum API >= 26.
98 Preference clearCachePreference = findPreference("clear_cache");
99 Preference homepagePreference = findPreference("homepage");
100 Preference downloadLocationPreference = findPreference("download_location");
101 Preference downloadCustomLocationPreference = findPreference("download_custom_location");
102 Preference fontSizePreference = findPreference("font_size");
103 Preference openIntentsInNewTabPreference = findPreference("open_intents_in_new_tab");
104 Preference swipeToRefreshPreference = findPreference("swipe_to_refresh");
105 Preference scrollAppBarPreference = findPreference("scroll_app_bar");
106 Preference displayAdditionalAppBarIconsPreference = findPreference("display_additional_app_bar_icons");
107 Preference darkThemePreference = findPreference("dark_theme");
108 Preference nightModePreference = findPreference("night_mode");
109 Preference wideViewportPreference = findPreference("wide_viewport");
110 Preference displayWebpageImagesPreference = findPreference("display_webpage_images");
112 // Remove the lint warnings below that the preferences might be null.
113 assert javaScriptPreference != null;
114 assert firstPartyCookiesPreference != null;
115 assert thirdPartyCookiesPreference != null;
116 assert domStoragePreference != null;
117 assert formDataPreference != null;
118 assert userAgentPreference != null;
119 assert customUserAgentPreference != null;
120 assert incognitoModePreference != null;
121 assert doNotTrackPreference != null;
122 assert allowScreenshotsPreference != null;
123 assert easyListPreference != null;
124 assert easyPrivacyPreference != null;
125 assert fanboyAnnoyanceListPreference != null;
126 assert fanboySocialBlockingListPreference != null;
127 assert ultraListPreference != null;
128 assert ultraPrivacyPreference != null;
129 assert blockAllThirdPartyRequestsPreference != null;
130 assert googleAnalyticsPreference != null;
131 assert facebookClickIdsPreference != null;
132 assert twitterAmpRedirectsPreference != null;
133 assert searchPreference != null;
134 assert searchCustomURLPreference != null;
135 assert proxyPreference != null;
136 assert proxyCustomUrlPreference != null;
137 assert fullScreenBrowsingModePreference != null;
138 assert hideAppBarPreference != null;
139 assert clearEverythingPreference != null;
140 assert clearCookiesPreference != null;
141 assert clearDomStoragePreference != null;
142 assert clearFormDataPreference != null;
143 assert clearCachePreference != null;
144 assert homepagePreference != null;
145 assert downloadLocationPreference != null;
146 assert downloadCustomLocationPreference != null;
147 assert fontSizePreference != null;
148 assert openIntentsInNewTabPreference != null;
149 assert swipeToRefreshPreference != null;
150 assert scrollAppBarPreference != null;
151 assert displayAdditionalAppBarIconsPreference != null;
152 assert darkThemePreference != null;
153 assert nightModePreference != null;
154 assert wideViewportPreference != null;
155 assert displayWebpageImagesPreference != null;
157 // Set the hide app bar preference dependency.
158 hideAppBarPreference.setDependency("full_screen_browsing_mode");
160 // Get strings from the preferences.
161 String userAgentName = savedPreferences.getString("user_agent", getString(R.string.user_agent_default_value));
162 String searchString = savedPreferences.getString("search", getString(R.string.search_default_value));
163 String proxyString = savedPreferences.getString("proxy", getString(R.string.proxy_default_value));
164 String downloadLocationString = savedPreferences.getString("download_location", getString(R.string.download_location_default_value));
166 // Get booleans that are used in multiple places from the preferences.
167 boolean javaScriptEnabled = savedPreferences.getBoolean("javascript", false);
168 boolean firstPartyCookiesEnabled = savedPreferences.getBoolean("first_party_cookies", false);
169 boolean thirdPartyCookiesEnabled = savedPreferences.getBoolean("third_party_cookies", false);
170 boolean fanboyAnnoyanceListEnabled = savedPreferences.getBoolean("fanboys_annoyance_list", true);
171 boolean fanboySocialBlockingEnabled = savedPreferences.getBoolean("fanboys_social_blocking_list", true);
172 boolean fullScreenBrowsingMode = savedPreferences.getBoolean("full_screen_browsing_mode", false);
173 boolean clearEverything = savedPreferences.getBoolean("clear_everything", true);
174 boolean darkTheme = savedPreferences.getBoolean("dark_theme", false);
175 boolean nightMode = savedPreferences.getBoolean("night_mode", false);
177 // Only enable the third-party cookies preference if first-party cookies are enabled and API >= 21.
178 thirdPartyCookiesPreference.setEnabled(firstPartyCookiesEnabled && (Build.VERSION.SDK_INT >= 21));
180 // Only enable the DOM storage preference if either JavaScript or Night Mode is enabled.
181 domStoragePreference.setEnabled(javaScriptEnabled || nightMode);
183 // Remove the form data preferences if the API is >= 26 as they no longer do anything.
184 if (Build.VERSION.SDK_INT >= 26) {
185 // Get the categories.
186 PreferenceCategory privacyCategory = findPreference("privacy");
187 PreferenceCategory clearAndExitCategory = findPreference("clear_and_exit");
189 // Remove the lint warnings below that the preference categories might be null.
190 assert privacyCategory != null;
191 assert clearAndExitCategory != null;
193 // Remove the form data preferences.
194 privacyCategory.removePreference(formDataPreference);
195 clearAndExitCategory.removePreference(clearFormDataPreference);
198 // Only enable Fanboy's social blocking list preference if Fanboy's annoyance list is disabled.
199 fanboySocialBlockingListPreference.setEnabled(!fanboyAnnoyanceListEnabled);
202 // Inflate a WebView to get the default user agent.
203 LayoutInflater inflater = getActivity().getLayoutInflater();
205 // `@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.
206 @SuppressLint("InflateParams") View bareWebViewLayout = inflater.inflate(R.layout.bare_webview, null, false);
208 // Get a handle for a bare WebView.
209 WebView bareWebView = bareWebViewLayout.findViewById(R.id.bare_webview);
211 // Get the user agent arrays.
212 ArrayAdapter<CharSequence> userAgentNamesArray = ArrayAdapter.createFromResource(context, R.array.user_agent_names, R.layout.spinner_item);
213 String[] translatedUserAgentNamesArray = getResources().getStringArray(R.array.translated_user_agent_names);
214 String[] userAgentDataArray = getResources().getStringArray(R.array.user_agent_data);
216 // Get the array position of the user agent name.
217 int userAgentArrayPosition = userAgentNamesArray.getPosition(userAgentName);
219 // Populate the user agent summary.
220 switch (userAgentArrayPosition) {
221 case MainWebViewActivity.UNRECOGNIZED_USER_AGENT: // The user agent name is not on the canonical list.
222 // 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.
223 userAgentPreference.setSummary(userAgentName);
226 case MainWebViewActivity.SETTINGS_WEBVIEW_DEFAULT_USER_AGENT:
227 // Get the user agent text from the webview (which changes based on the version of Android and WebView installed).
228 userAgentPreference.setSummary(translatedUserAgentNamesArray[userAgentArrayPosition] + ":\n" + bareWebView.getSettings().getUserAgentString());
231 case MainWebViewActivity.SETTINGS_CUSTOM_USER_AGENT:
232 // Set the summary text.
233 userAgentPreference.setSummary(R.string.custom_user_agent);
237 // Get the user agent summary from the user agent data array.
238 userAgentPreference.setSummary(translatedUserAgentNamesArray[userAgentArrayPosition] + ":\n" + userAgentDataArray[userAgentArrayPosition]);
241 // Set the summary text for the custom user agent preference.
242 customUserAgentPreference.setSummary(savedPreferences.getString("custom_user_agent", getString(R.string.custom_user_agent_default_value)));
244 // Only enable the custom user agent preference if the user agent is set to `Custom`.
245 customUserAgentPreference.setEnabled(userAgentPreference.getSummary().equals(getString(R.string.custom_user_agent)));
248 // Set the search URL as the summary text for the search preference when the preference screen is loaded.
249 if (searchString.equals("Custom URL")) {
250 // Use R.string.custom_url, which will be translated, instead of the array value, which will not.
251 searchPreference.setSummary(R.string.custom_url);
253 // Set the array value as the summary text.
254 searchPreference.setSummary(searchString);
257 // Set the summary text for the search custom URL (the default is `""`).
258 searchCustomURLPreference.setSummary(savedPreferences.getString("search_custom_url", getString(R.string.search_custom_url_default_value)));
260 // Only enable the search custom URL preference if the search is set to `Custom URL`.
261 searchCustomURLPreference.setEnabled(searchString.equals("Custom URL"));
264 // Set the summary text for the proxy preference when the preference screen is loaded.
265 switch (proxyString) {
266 case ProxyHelper.NONE:
267 proxyPreference.setSummary(getString(R.string.no_proxy_enabled));
270 case ProxyHelper.TOR:
271 if (Build.VERSION.SDK_INT == 19) { // Proxying through SOCKS doesn't work on Android KitKat.
272 proxyPreference.setSummary(getString(R.string.tor_enabled_kitkat));
274 proxyPreference.setSummary(getString(R.string.tor_enabled));
278 case ProxyHelper.I2P:
279 proxyPreference.setSummary(getString(R.string.i2p_enabled));
282 case ProxyHelper.CUSTOM:
283 proxyPreference.setSummary(getString(R.string.custom_proxy));
287 // Set the summary text for the custom proxy URL.
288 proxyCustomUrlPreference.setSummary(savedPreferences.getString("proxy_custom_url", getString(R.string.proxy_custom_url_default_value)));
290 // Only enable the custom proxy URL if a custom proxy is selected.
291 proxyCustomUrlPreference.setEnabled(proxyString.equals("Custom"));
294 // Set the status of the Clear and Exit preferences.
295 clearCookiesPreference.setEnabled(!clearEverything);
296 clearDomStoragePreference.setEnabled(!clearEverything);
297 clearFormDataPreference.setEnabled(!clearEverything); // The form data line can be removed once the minimum API is >= 26.
298 clearCachePreference.setEnabled(!clearEverything);
301 // Set the homepage URL as the summary text for the homepage preference.
302 homepagePreference.setSummary(savedPreferences.getString("homepage", getString(R.string.homepage_default_value)));
305 // Instantiate the download location helper.
306 DownloadLocationHelper downloadLocationHelper = new DownloadLocationHelper();
308 // Set the download location summary text.
309 downloadLocationPreference.setSummary(downloadLocationHelper.getDownloadLocation(context));
311 // Set the summary text for the download custom location (the default is `"`).
312 downloadCustomLocationPreference.setSummary(savedPreferences.getString("download_custom_location", getString(R.string.download_custom_location_default_value)));
314 // Get the download location entry values string array.
315 String[] downloadLocationEntryValuesStringArray = context.getResources().getStringArray(R.array.download_location_entry_values);
317 // Only enable the download custom location preference if the download location is set to `Custom`.
318 downloadCustomLocationPreference.setEnabled(downloadLocationString.equals(downloadLocationEntryValuesStringArray[3]));
321 // Set the font size as the summary text for the preference.
322 fontSizePreference.setSummary(savedPreferences.getString("font_size", getString(R.string.font_size_default_value)) + "%");
325 // Disable the JavaScript preference if Night Mode is enabled. JavaScript will be enabled for all web pages.
326 javaScriptPreference.setEnabled(!nightMode);
328 // Set the JavaScript icon.
329 if (javaScriptEnabled || nightMode) {
330 javaScriptPreference.setIcon(R.drawable.javascript_enabled);
332 javaScriptPreference.setIcon(R.drawable.privacy_mode);
335 // Set the first-party cookies icon.
336 if (firstPartyCookiesEnabled) {
337 firstPartyCookiesPreference.setIcon(R.drawable.cookies_enabled);
340 firstPartyCookiesPreference.setIcon(R.drawable.cookies_disabled_dark);
342 firstPartyCookiesPreference.setIcon(R.drawable.cookies_disabled_light);
346 // Set the third party cookies icon.
347 if (firstPartyCookiesEnabled && Build.VERSION.SDK_INT >= 21) {
348 if (thirdPartyCookiesEnabled) {
349 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_warning);
352 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_disabled_dark);
354 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_disabled_light);
359 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_ghosted_dark);
361 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_ghosted_light);
365 // Set the DOM storage icon.
366 if (javaScriptEnabled || nightMode) { // The preference is enabled.
367 if (savedPreferences.getBoolean("dom_storage", false)) { // DOM storage is enabled.
368 domStoragePreference.setIcon(R.drawable.dom_storage_enabled);
369 } else { // DOM storage is disabled.
371 domStoragePreference.setIcon(R.drawable.dom_storage_disabled_dark);
373 domStoragePreference.setIcon(R.drawable.dom_storage_disabled_light);
376 } else { // The preference is disabled. The icon should be ghosted.
378 domStoragePreference.setIcon(R.drawable.dom_storage_ghosted_dark);
380 domStoragePreference.setIcon(R.drawable.dom_storage_ghosted_light);
384 // Set the save form data icon if API < 26. Save form data has no effect on API >= 26.
385 if (Build.VERSION.SDK_INT < 26) {
386 if (savedPreferences.getBoolean("save_form_data", false)) {
387 formDataPreference.setIcon(R.drawable.form_data_enabled);
390 formDataPreference.setIcon(R.drawable.form_data_disabled_dark);
392 formDataPreference.setIcon(R.drawable.form_data_disabled_light);
397 // Set the custom user agent icon.
398 if (customUserAgentPreference.isEnabled()) {
400 customUserAgentPreference.setIcon(R.drawable.custom_user_agent_enabled_dark);
402 customUserAgentPreference.setIcon(R.drawable.custom_user_agent_enabled_light);
406 customUserAgentPreference.setIcon(R.drawable.custom_user_agent_ghosted_dark);
408 customUserAgentPreference.setIcon(R.drawable.custom_user_agent_ghosted_light);
412 // Set the incognito mode icon.
413 if (savedPreferences.getBoolean("incognito_mode", false)) {
415 incognitoModePreference.setIcon(R.drawable.incognito_mode_enabled_dark);
417 incognitoModePreference.setIcon(R.drawable.incognito_mode_enabled_light);
421 incognitoModePreference.setIcon(R.drawable.incognito_mode_disabled_dark);
423 incognitoModePreference.setIcon(R.drawable.incognito_mode_disabled_light);
427 // Set the Do Not Track icon.
428 if (savedPreferences.getBoolean("do_not_track", false)) {
430 doNotTrackPreference.setIcon(R.drawable.block_tracking_enabled_dark);
432 doNotTrackPreference.setIcon(R.drawable.block_tracking_enabled_light);
436 doNotTrackPreference.setIcon(R.drawable.block_tracking_disabled_dark);
438 doNotTrackPreference.setIcon(R.drawable.block_tracking_disabled_light);
442 // Set the allow screenshots icon.
443 if (savedPreferences.getBoolean("allow_screenshots", false)) {
445 allowScreenshotsPreference.setIcon(R.drawable.allow_screenshots_enabled_dark);
447 allowScreenshotsPreference.setIcon(R.drawable.allow_screenshots_enabled_light);
451 allowScreenshotsPreference.setIcon(R.drawable.allow_screenshots_disabled_dark);
453 allowScreenshotsPreference.setIcon(R.drawable.allow_screenshots_disabled_light);
457 // Set the EasyList icon.
458 if (savedPreferences.getBoolean("easylist", true)) {
460 easyListPreference.setIcon(R.drawable.block_ads_enabled_dark);
462 easyListPreference.setIcon(R.drawable.block_ads_enabled_light);
466 easyListPreference.setIcon(R.drawable.block_ads_disabled_dark);
468 easyListPreference.setIcon(R.drawable.block_ads_disabled_light);
472 // Set the EasyPrivacy icon.
473 if (savedPreferences.getBoolean("easyprivacy", true)) {
475 easyPrivacyPreference.setIcon(R.drawable.block_tracking_enabled_dark);
477 easyPrivacyPreference.setIcon(R.drawable.block_tracking_enabled_light);
481 easyPrivacyPreference.setIcon(R.drawable.block_tracking_disabled_dark);
483 easyPrivacyPreference.setIcon(R.drawable.block_tracking_disabled_light);
487 // Set the Fanboy lists icons.
488 if (fanboyAnnoyanceListEnabled) {
490 // Set the Fanboy annoyance list icon.
491 fanboyAnnoyanceListPreference.setIcon(R.drawable.social_media_enabled_dark);
493 // Set the Fanboy social blocking list icon.
494 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_ghosted_dark);
496 // Set the Fanboy annoyance list icon.
497 fanboyAnnoyanceListPreference.setIcon(R.drawable.social_media_enabled_light);
499 // Set the Fanboy social blocking list icon.
500 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_ghosted_light);
504 // Set the Fanboy annoyance list icon.
505 fanboyAnnoyanceListPreference.setIcon(R.drawable.social_media_disabled_dark);
507 // Set the Fanboy social blocking list icon.
508 if (fanboySocialBlockingEnabled) {
509 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_enabled_dark);
511 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_disabled_dark);
514 // Set the Fanboy annoyance list icon.
515 fanboyAnnoyanceListPreference.setIcon(R.drawable.block_ads_disabled_light);
517 // Set the Fanboy social blocking list icon.
518 if (fanboySocialBlockingEnabled) {
519 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_enabled_light);
521 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_disabled_light);
526 // Set the UltraList icon.
527 if (savedPreferences.getBoolean("ultralist", true)){
529 ultraListPreference.setIcon(R.drawable.block_ads_enabled_dark);
531 ultraListPreference.setIcon(R.drawable.block_ads_enabled_light);
535 ultraListPreference.setIcon(R.drawable.block_ads_disabled_dark);
537 ultraListPreference.setIcon(R.drawable.block_ads_disabled_light);
541 // Set the UltraPrivacy icon.
542 if (savedPreferences.getBoolean("ultraprivacy", true)) {
544 ultraPrivacyPreference.setIcon(R.drawable.block_tracking_enabled_dark);
546 ultraPrivacyPreference.setIcon(R.drawable.block_tracking_enabled_light);
550 ultraPrivacyPreference.setIcon(R.drawable.block_tracking_disabled_dark);
552 ultraPrivacyPreference.setIcon(R.drawable.block_tracking_disabled_light);
556 // Set the block all third-party requests icon.
557 if (savedPreferences.getBoolean("block_all_third_party_requests", false)) {
559 blockAllThirdPartyRequestsPreference.setIcon(R.drawable.block_all_third_party_requests_enabled_dark);
561 blockAllThirdPartyRequestsPreference.setIcon(R.drawable.block_all_third_party_requests_enabled_light);
565 blockAllThirdPartyRequestsPreference.setIcon(R.drawable.block_all_third_party_requests_disabled_dark);
567 blockAllThirdPartyRequestsPreference.setIcon(R.drawable.block_all_third_party_requests_disabled_light);
571 // Set the Google Analytics icon according to the theme.
572 if (savedPreferences.getBoolean("google_analytics", true)) {
574 googleAnalyticsPreference.setIcon(R.drawable.modify_url_enabled_dark);
576 googleAnalyticsPreference.setIcon(R.drawable.modify_url_enabled_light);
580 googleAnalyticsPreference.setIcon(R.drawable.modify_url_disabled_dark);
582 googleAnalyticsPreference.setIcon(R.drawable.modify_url_disabled_light);
586 // Set the Facebook Click IDs icon according to the theme.
587 if (savedPreferences.getBoolean("facebook_click_ids", true)) {
589 facebookClickIdsPreference.setIcon(R.drawable.modify_url_enabled_dark);
591 facebookClickIdsPreference.setIcon(R.drawable.modify_url_enabled_light);
595 facebookClickIdsPreference.setIcon(R.drawable.modify_url_disabled_dark);
597 facebookClickIdsPreference.setIcon(R.drawable.modify_url_disabled_light);
601 // Set the Twitter AMP redirects icon according to the theme.
602 if (savedPreferences.getBoolean("twitter_amp_redirects", true)) {
604 twitterAmpRedirectsPreference.setIcon(R.drawable.modify_url_enabled_dark);
606 twitterAmpRedirectsPreference.setIcon(R.drawable.modify_url_enabled_light);
610 twitterAmpRedirectsPreference.setIcon(R.drawable.modify_url_disabled_dark);
612 twitterAmpRedirectsPreference.setIcon(R.drawable.modify_url_disabled_light);
616 // Set the search custom URL icon.
617 if (searchCustomURLPreference.isEnabled()) {
619 searchCustomURLPreference.setIcon(R.drawable.search_custom_url_enabled_dark);
621 searchCustomURLPreference.setIcon(R.drawable.search_custom_url_enabled_light);
625 searchCustomURLPreference.setIcon(R.drawable.search_custom_url_ghosted_dark);
627 searchCustomURLPreference.setIcon(R.drawable.search_custom_url_ghosted_light);
631 // Set the Proxy icons according to the theme and status.
632 if (proxyString.equals("None")) { // Proxying is disabled.
633 if (darkTheme) { // Dark theme.
634 // Set the main proxy icon to be disabled.
635 proxyPreference.setIcon(R.drawable.proxy_disabled_dark);
637 // Set the custom proxy URL icon to be ghosted.
638 proxyCustomUrlPreference.setIcon(R.drawable.proxy_ghosted_dark);
639 } else { // Light theme.
640 // Set the main proxy icon to be disabled.
641 proxyPreference.setIcon(R.drawable.proxy_disabled_light);
643 // Set the custom proxy URL icon to be ghosted.
644 proxyCustomUrlPreference.setIcon(R.drawable.proxy_ghosted_light);
646 } else { // Proxying is enabled.
647 if (darkTheme) { // Dark theme.
648 // Set the main proxy icon to be enabled.
649 proxyPreference.setIcon(R.drawable.proxy_enabled_dark);
651 // Set the custom proxy URL icon according to its status.
652 if (proxyCustomUrlPreference.isEnabled()) { // Custom proxy is enabled.
653 proxyCustomUrlPreference.setIcon(R.drawable.proxy_enabled_dark);
654 } else { // Custom proxy is disabled.
655 proxyCustomUrlPreference.setIcon(R.drawable.proxy_ghosted_dark);
657 } else { // Light theme.
658 // Set the main proxy icon to be enabled.
659 proxyPreference.setIcon(R.drawable.proxy_enabled_light);
661 // Set the custom proxy URL icon according to its status.
662 if (proxyCustomUrlPreference.isEnabled()) { // Custom proxy is enabled.
663 proxyCustomUrlPreference.setIcon(R.drawable.proxy_enabled_light);
664 } else { // Custom proxy is disabled.
665 proxyCustomUrlPreference.setIcon(R.drawable.proxy_ghosted_light);
670 // Set the full screen browsing mode icons.
671 if (fullScreenBrowsingMode) { // Full screen browsing mode is enabled.
672 // Set the `fullScreenBrowsingModePreference` icon according to the theme.
674 fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_enabled_dark);
676 fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_enabled_light);
679 // Set the hide app bar icon.
680 if (savedPreferences.getBoolean("hide_app_bar", true)) { // Hide app bar is enabled.
681 // Set the icon according to the theme.
683 hideAppBarPreference.setIcon(R.drawable.app_bar_enabled_dark);
685 hideAppBarPreference.setIcon(R.drawable.app_bar_enabled_light);
687 } else { // Hide app bar is disabled.
688 // Set the icon according to the theme.
690 hideAppBarPreference.setIcon(R.drawable.app_bar_disabled_dark);
692 hideAppBarPreference.setIcon(R.drawable.app_bar_disabled_light);
695 } else { // Full screen browsing mode is disabled.
696 // Set the icons according to the theme.
698 fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_disabled_dark);
699 hideAppBarPreference.setIcon(R.drawable.app_bar_ghosted_dark);
701 fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_disabled_light);
702 hideAppBarPreference.setIcon(R.drawable.app_bar_ghosted_light);
706 // Set the clear everything preference icon.
707 if (clearEverything) {
709 clearEverythingPreference.setIcon(R.drawable.clear_everything_enabled_dark);
711 clearEverythingPreference.setIcon(R.drawable.clear_everything_enabled_light);
714 clearEverythingPreference.setIcon(R.drawable.clear_everything_disabled);
717 // Set the clear cookies preference icon.
718 if (clearEverything || savedPreferences.getBoolean("clear_cookies", true)) {
720 clearCookiesPreference.setIcon(R.drawable.cookies_cleared_dark);
722 clearCookiesPreference.setIcon(R.drawable.cookies_cleared_light);
725 clearCookiesPreference.setIcon(R.drawable.cookies_warning);
728 // Set the clear DOM storage preference icon.
729 if (clearEverything || savedPreferences.getBoolean("clear_dom_storage", true)) {
731 clearDomStoragePreference.setIcon(R.drawable.dom_storage_cleared_dark);
733 clearDomStoragePreference.setIcon(R.drawable.dom_storage_cleared_light);
736 clearDomStoragePreference.setIcon(R.drawable.dom_storage_warning);
739 // Set the clear form data preference icon if the API < 26. It has no effect on newer versions of Android.
740 if (Build.VERSION.SDK_INT < 26) {
741 if (clearEverything || savedPreferences.getBoolean("clear_form_data", true)) {
743 clearFormDataPreference.setIcon(R.drawable.form_data_cleared_dark);
745 clearFormDataPreference.setIcon(R.drawable.form_data_cleared_light);
748 clearFormDataPreference.setIcon(R.drawable.form_data_warning);
752 // Set the clear cache preference icon.
753 if (clearEverything || savedPreferences.getBoolean("clear_cache", true)) {
755 clearCachePreference.setIcon(R.drawable.cache_cleared_dark);
757 clearCachePreference.setIcon(R.drawable.cache_cleared_light);
760 clearCachePreference.setIcon(R.drawable.cache_warning);
763 // Set the download custom location icon.
764 if (downloadCustomLocationPreference.isEnabled()) {
766 downloadCustomLocationPreference.setIcon(R.drawable.downloads_enabled_dark);
768 downloadCustomLocationPreference.setIcon(R.drawable.downloads_enabled_light);
772 downloadCustomLocationPreference.setIcon(R.drawable.downloads_ghosted_dark);
774 downloadCustomLocationPreference.setIcon(R.drawable.downloads_ghosted_light);
778 // Set the open intents in new tab preference icon.
779 if (savedPreferences.getBoolean("open_intents_in_new_tab", true)) {
781 openIntentsInNewTabPreference.setIcon(R.drawable.tab_enabled_dark);
783 openIntentsInNewTabPreference.setIcon(R.drawable.tab_enabled_light);
787 openIntentsInNewTabPreference.setIcon(R.drawable.tab_disabled_dark);
789 openIntentsInNewTabPreference.setIcon(R.drawable.tab_disabled_light);
793 // Set the swipe to refresh preference icon.
794 if (savedPreferences.getBoolean("swipe_to_refresh", true)) {
796 swipeToRefreshPreference.setIcon(R.drawable.refresh_enabled_dark);
798 swipeToRefreshPreference.setIcon(R.drawable.refresh_enabled_light);
802 swipeToRefreshPreference.setIcon(R.drawable.refresh_disabled_dark);
804 swipeToRefreshPreference.setIcon(R.drawable.refresh_disabled_light);
808 // Set the scroll app bar preference icon.
809 if (savedPreferences.getBoolean("scroll_app_bar", true)) {
811 scrollAppBarPreference.setIcon(R.drawable.app_bar_enabled_dark);
813 scrollAppBarPreference.setIcon(R.drawable.app_bar_enabled_light);
817 scrollAppBarPreference.setIcon(R.drawable.app_bar_disabled_dark);
819 scrollAppBarPreference.setIcon(R.drawable.app_bar_disabled_light);
823 // Set the display additional app bar icons preference icon.
824 if (savedPreferences.getBoolean("display_additional_app_bar_icons", false)) {
826 displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_enabled_dark);
828 displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_enabled_light);
832 displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_disabled_dark);
834 displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_disabled_light);
838 // Set the dark theme preference icon.
839 if (savedPreferences.getBoolean("dark_theme", false)) {
840 darkThemePreference.setIcon(R.drawable.theme_dark);
842 darkThemePreference.setIcon(R.drawable.theme_light);
845 // Set the night mode preference icon.
848 nightModePreference.setIcon(R.drawable.night_mode_enabled_dark);
850 nightModePreference.setIcon(R.drawable.night_mode_enabled_light);
854 nightModePreference.setIcon(R.drawable.night_mode_disabled_dark);
856 nightModePreference.setIcon(R.drawable.night_mode_disabled_light);
860 // Set the wide viewport preference icon.
861 if (savedPreferences.getBoolean("wide_viewport", true)) {
863 wideViewportPreference.setIcon(R.drawable.wide_viewport_enabled_dark);
865 wideViewportPreference.setIcon(R.drawable.wide_viewport_enabled_light);
869 wideViewportPreference.setIcon(R.drawable.wide_viewport_disabled_dark);
871 wideViewportPreference.setIcon(R.drawable.wide_viewport_disabled_light);
875 // Set the display webpage images preference icon.
876 if (savedPreferences.getBoolean("display_webpage_images", true)) {
878 displayWebpageImagesPreference.setIcon(R.drawable.images_enabled_dark);
880 displayWebpageImagesPreference.setIcon(R.drawable.images_enabled_light);
884 displayWebpageImagesPreference.setIcon(R.drawable.images_disabled_dark);
886 displayWebpageImagesPreference.setIcon(R.drawable.images_disabled_light);
891 // Listen for preference changes.
892 preferencesListener = (SharedPreferences sharedPreferences, String key) -> {
895 // Update the icons and the DOM storage preference status.
896 if (sharedPreferences.getBoolean("javascript", false)) { // The JavaScript preference is enabled.
897 // Update the icon for the JavaScript preference.
898 javaScriptPreference.setIcon(R.drawable.javascript_enabled);
900 // Update the status of the DOM storage preference.
901 domStoragePreference.setEnabled(true);
903 // Update the icon for the DOM storage preference.
904 if (sharedPreferences.getBoolean("dom_storage", false)) {
905 domStoragePreference.setIcon(R.drawable.dom_storage_enabled);
908 domStoragePreference.setIcon(R.drawable.dom_storage_disabled_dark);
910 domStoragePreference.setIcon(R.drawable.dom_storage_disabled_light);
913 } else { // The JavaScript preference is disabled.
914 // Update the icon for the JavaScript preference.
915 javaScriptPreference.setIcon(R.drawable.privacy_mode);
917 // Update the status of the DOM storage preference.
918 domStoragePreference.setEnabled(false);
920 // Set the icon for DOM storage preference to be ghosted.
922 domStoragePreference.setIcon(R.drawable.dom_storage_ghosted_dark);
924 domStoragePreference.setIcon(R.drawable.dom_storage_ghosted_light);
929 case "first_party_cookies":
930 // Update the icons for `first_party_cookies` and `third_party_cookies`.
931 if (sharedPreferences.getBoolean("first_party_cookies", false)) {
932 // Set the icon for `first_party_cookies`.
933 firstPartyCookiesPreference.setIcon(R.drawable.cookies_enabled);
935 // Update the icon for `third_party_cookies`.
936 if (Build.VERSION.SDK_INT >= 21) {
937 if (sharedPreferences.getBoolean("third_party_cookies", false)) {
938 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_warning);
941 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_disabled_dark);
943 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_disabled_light);
948 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_ghosted_dark);
950 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_ghosted_light);
953 } else { // `first_party_cookies` is `false`.
954 // Update the icon for `first_party_cookies`.
956 firstPartyCookiesPreference.setIcon(R.drawable.cookies_disabled_dark);
958 firstPartyCookiesPreference.setIcon(R.drawable.cookies_disabled_light);
961 // Set the icon for `third_party_cookies` to be ghosted.
963 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_ghosted_dark);
965 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_ghosted_light);
969 // Enable `third_party_cookies` if `first_party_cookies` is `true` and API >= 21.
970 thirdPartyCookiesPreference.setEnabled(sharedPreferences.getBoolean("first_party_cookies", false) && (Build.VERSION.SDK_INT >= 21));
973 case "third_party_cookies":
975 if (sharedPreferences.getBoolean("third_party_cookies", false)) {
976 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_warning);
979 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_disabled_dark);
981 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_disabled_light);
988 if (sharedPreferences.getBoolean("dom_storage", false)) {
989 domStoragePreference.setIcon(R.drawable.dom_storage_enabled);
992 domStoragePreference.setIcon(R.drawable.dom_storage_disabled_dark);
994 domStoragePreference.setIcon(R.drawable.dom_storage_disabled_light);
999 // Save form data can be removed once the minimum API >= 26.
1000 case "save_form_data":
1002 if (sharedPreferences.getBoolean("save_form_data", false)) {
1003 formDataPreference.setIcon(R.drawable.form_data_enabled);
1006 formDataPreference.setIcon(R.drawable.form_data_disabled_dark);
1008 formDataPreference.setIcon(R.drawable.form_data_disabled_light);
1014 // Get the new user agent name.
1015 String newUserAgentName = sharedPreferences.getString("user_agent", getString(R.string.user_agent_default_value));
1017 // Get the array position for the new user agent name.
1018 int newUserAgentArrayPosition = userAgentNamesArray.getPosition(newUserAgentName);
1020 // Get the translated new user agent name.
1021 String translatedNewUserAgentName = translatedUserAgentNamesArray[newUserAgentArrayPosition];
1023 // Populate the user agent summary.
1024 switch (newUserAgentArrayPosition) {
1025 case MainWebViewActivity.SETTINGS_WEBVIEW_DEFAULT_USER_AGENT:
1026 // Get the user agent text from the webview (which changes based on the version of Android and WebView installed).
1027 userAgentPreference.setSummary(translatedNewUserAgentName + ":\n" + bareWebView.getSettings().getUserAgentString());
1029 // Disable the custom user agent preference.
1030 customUserAgentPreference.setEnabled(false);
1032 // Set the custom user agent preference icon according to the theme.
1034 customUserAgentPreference.setIcon(R.drawable.custom_user_agent_ghosted_dark);
1036 customUserAgentPreference.setIcon(R.drawable.custom_user_agent_ghosted_light);
1040 case MainWebViewActivity.SETTINGS_CUSTOM_USER_AGENT:
1041 // Set the summary text.
1042 userAgentPreference.setSummary(R.string.custom_user_agent);
1044 // Enable the custom user agent preference.
1045 customUserAgentPreference.setEnabled(true);
1047 // Set the custom user agent preference icon according to the theme.
1049 customUserAgentPreference.setIcon(R.drawable.custom_user_agent_enabled_dark);
1051 customUserAgentPreference.setIcon(R.drawable.custom_user_agent_enabled_light);
1056 // Get the user agent summary from the user agent data array.
1057 userAgentPreference.setSummary(translatedNewUserAgentName + ":\n" + userAgentDataArray[newUserAgentArrayPosition]);
1059 // Disable the custom user agent preference.
1060 customUserAgentPreference.setEnabled(false);
1062 // Set the custom user agent preference icon according to the theme.
1064 customUserAgentPreference.setIcon(R.drawable.custom_user_agent_ghosted_dark);
1066 customUserAgentPreference.setIcon(R.drawable.custom_user_agent_ghosted_light);
1071 case "custom_user_agent":
1072 // Set the new custom user agent as the summary text for the preference.
1073 customUserAgentPreference.setSummary(sharedPreferences.getString("custom_user_agent", getString(R.string.custom_user_agent_default_value)));
1076 case "incognito_mode":
1078 if (sharedPreferences.getBoolean("incognito_mode", false)) {
1080 incognitoModePreference.setIcon(R.drawable.incognito_mode_enabled_dark);
1082 incognitoModePreference.setIcon(R.drawable.incognito_mode_enabled_light);
1086 incognitoModePreference.setIcon(R.drawable.incognito_mode_disabled_dark);
1088 incognitoModePreference.setIcon(R.drawable.incognito_mode_disabled_light);
1093 case "do_not_track":
1095 if (sharedPreferences.getBoolean("do_not_track", false)) {
1097 doNotTrackPreference.setIcon(R.drawable.block_tracking_enabled_dark);
1099 doNotTrackPreference.setIcon(R.drawable.block_tracking_enabled_light);
1103 doNotTrackPreference.setIcon(R.drawable.block_tracking_disabled_dark);
1105 doNotTrackPreference.setIcon(R.drawable.block_tracking_disabled_light);
1111 case "allow_screenshots":
1113 if (sharedPreferences.getBoolean("allow_screenshots", false)) {
1115 allowScreenshotsPreference.setIcon(R.drawable.allow_screenshots_enabled_dark);
1117 allowScreenshotsPreference.setIcon(R.drawable.allow_screenshots_enabled_light);
1121 allowScreenshotsPreference.setIcon(R.drawable.allow_screenshots_disabled_dark);
1123 allowScreenshotsPreference.setIcon(R.drawable.allow_screenshots_disabled_light);
1127 // Create an intent to restart Privacy Browser.
1128 Intent allowScreenshotsRestartIntent = getActivity().getParentActivityIntent();
1130 // Assert that the intent is not null to remove the lint error below.
1131 assert allowScreenshotsRestartIntent != null;
1133 // `Intent.FLAG_ACTIVITY_CLEAR_TASK` removes all activities from the stack. It requires `Intent.FLAG_ACTIVITY_NEW_TASK`.
1134 allowScreenshotsRestartIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
1136 // Create a handler to restart the activity.
1137 Handler allowScreenshotsRestartHandler = new Handler();
1139 // Create a runnable to restart the activity.
1140 Runnable allowScreenshotsRestartRunnable = () -> {
1141 // Restart the activity.
1142 startActivity(allowScreenshotsRestartIntent);
1144 // Kill this instance of Privacy Browser. Otherwise, the app exhibits sporadic behavior after the restart.
1148 // Restart the activity after 150 milliseconds, so that the app has enough time to save the change to the preference.
1149 allowScreenshotsRestartHandler.postDelayed(allowScreenshotsRestartRunnable, 150);
1154 if (sharedPreferences.getBoolean("easylist", true)) {
1156 easyListPreference.setIcon(R.drawable.block_ads_enabled_dark);
1158 easyListPreference.setIcon(R.drawable.block_ads_enabled_light);
1162 easyListPreference.setIcon(R.drawable.block_ads_disabled_dark);
1164 easyListPreference.setIcon(R.drawable.block_ads_disabled_light);
1171 if (sharedPreferences.getBoolean("easyprivacy", true)) {
1173 easyPrivacyPreference.setIcon(R.drawable.block_tracking_enabled_dark);
1175 easyPrivacyPreference.setIcon(R.drawable.block_tracking_enabled_light);
1179 easyPrivacyPreference.setIcon(R.drawable.block_tracking_disabled_dark);
1181 easyPrivacyPreference.setIcon(R.drawable.block_tracking_disabled_light);
1186 case "fanboys_annoyance_list":
1187 boolean currentFanboyAnnoyanceList = sharedPreferences.getBoolean("fanboys_annoyance_list", true);
1188 boolean currentFanboySocialBlockingList = sharedPreferences.getBoolean("fanboys_social_blocking_list", true);
1190 // Update the Fanboy icons.
1191 if (currentFanboyAnnoyanceList) { // Fanboy's annoyance list is enabled.
1193 // Update the Fanboy's annoyance list icon.
1194 fanboyAnnoyanceListPreference.setIcon(R.drawable.social_media_enabled_dark);
1196 // Update the Fanboy's social blocking list icon.
1197 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_ghosted_dark);
1199 // Update the Fanboy's annoyance list icon.
1200 fanboyAnnoyanceListPreference.setIcon(R.drawable.social_media_enabled_light);
1202 // Update the Fanboy's social blocking list icon.
1203 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_ghosted_light);
1205 } else { // Fanboy's annoyance list is disabled.
1207 // Update the Fanboy's annoyance list icon.
1208 fanboyAnnoyanceListPreference.setIcon(R.drawable.social_media_disabled_dark);
1210 // Update the Fanboy's social blocking list icon.
1211 if (currentFanboySocialBlockingList) {
1212 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_enabled_dark);
1214 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_disabled_dark);
1217 // Update the Fanboy's annoyance list icon.
1218 fanboyAnnoyanceListPreference.setIcon(R.drawable.social_media_disabled_light);
1220 // Update the Fanboy's social blocking list icon.
1221 if (currentFanboySocialBlockingList) {
1222 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_enabled_light);
1224 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_disabled_light);
1229 // Only enable Fanboy's social blocking list preference if Fanboy's annoyance list preference is disabled.
1230 fanboySocialBlockingListPreference.setEnabled(!currentFanboyAnnoyanceList);
1233 case "fanboys_social_blocking_list":
1235 if (sharedPreferences.getBoolean("fanboys_social_blocking_list", true)) {
1237 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_enabled_dark);
1239 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_enabled_light);
1243 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_disabled_dark);
1245 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_disabled_light);
1252 if (sharedPreferences.getBoolean("ultralist", true)) {
1254 ultraListPreference.setIcon(R.drawable.block_ads_enabled_dark);
1256 ultraListPreference.setIcon(R.drawable.block_ads_enabled_light);
1260 ultraListPreference.setIcon(R.drawable.block_ads_disabled_dark);
1262 ultraListPreference.setIcon(R.drawable.block_ads_disabled_light);
1267 case "ultraprivacy":
1269 if (sharedPreferences.getBoolean("ultraprivacy", true)) {
1271 ultraPrivacyPreference.setIcon(R.drawable.block_tracking_enabled_dark);
1273 ultraPrivacyPreference.setIcon(R.drawable.block_tracking_enabled_light);
1277 ultraPrivacyPreference.setIcon(R.drawable.block_tracking_disabled_dark);
1279 ultraPrivacyPreference.setIcon(R.drawable.block_tracking_disabled_light);
1284 case "block_all_third_party_requests":
1286 if (sharedPreferences.getBoolean("block_all_third_party_requests", false)) {
1288 blockAllThirdPartyRequestsPreference.setIcon(R.drawable.block_all_third_party_requests_enabled_dark);
1290 blockAllThirdPartyRequestsPreference.setIcon(R.drawable.block_all_third_party_requests_enabled_light);
1294 blockAllThirdPartyRequestsPreference.setIcon(R.drawable.block_all_third_party_requests_disabled_dark);
1296 blockAllThirdPartyRequestsPreference.setIcon(R.drawable.block_all_third_party_requests_disabled_light);
1301 case "google_analytics":
1303 if (sharedPreferences.getBoolean("google_analytics", true)) {
1305 googleAnalyticsPreference.setIcon(R.drawable.modify_url_enabled_dark);
1307 googleAnalyticsPreference.setIcon(R.drawable.modify_url_enabled_light);
1311 googleAnalyticsPreference.setIcon(R.drawable.modify_url_disabled_dark);
1313 googleAnalyticsPreference.setIcon(R.drawable.modify_url_disabled_light);
1318 case "facebook_click_ids":
1320 if (sharedPreferences.getBoolean("facebook_click_ids", true)) {
1322 facebookClickIdsPreference.setIcon(R.drawable.modify_url_enabled_dark);
1324 facebookClickIdsPreference.setIcon(R.drawable.modify_url_enabled_light);
1328 facebookClickIdsPreference.setIcon(R.drawable.modify_url_disabled_dark);
1330 facebookClickIdsPreference.setIcon(R.drawable.modify_url_disabled_light);
1335 case "twitter_amp_redirects":
1337 if (sharedPreferences.getBoolean("twitter_amp_redirects", true)) {
1339 twitterAmpRedirectsPreference.setIcon(R.drawable.modify_url_enabled_dark);
1341 twitterAmpRedirectsPreference.setIcon(R.drawable.modify_url_enabled_light);
1345 twitterAmpRedirectsPreference.setIcon(R.drawable.modify_url_disabled_dark);
1347 twitterAmpRedirectsPreference.setIcon(R.drawable.modify_url_disabled_light);
1353 // Store the new search string.
1354 String newSearchString = sharedPreferences.getString("search", getString(R.string.search_default_value));
1356 // Update the search and search custom URL preferences.
1357 if (newSearchString.equals("Custom URL")) { // `Custom URL` is selected.
1358 // Set the summary text to `R.string.custom_url`, which is translated.
1359 searchPreference.setSummary(R.string.custom_url);
1361 // Enable `searchCustomURLPreference`.
1362 searchCustomURLPreference.setEnabled(true);
1364 // Set the `searchCustomURLPreference` according to the theme.
1366 searchCustomURLPreference.setIcon(R.drawable.search_custom_url_enabled_dark);
1368 searchCustomURLPreference.setIcon(R.drawable.search_custom_url_enabled_light);
1370 } else { // `Custom URL` is not selected.
1371 // Set the summary text to `newSearchString`.
1372 searchPreference.setSummary(newSearchString);
1374 // Disable `searchCustomURLPreference`.
1375 searchCustomURLPreference.setEnabled(false);
1377 // Set the `searchCustomURLPreference` according to the theme.
1379 searchCustomURLPreference.setIcon(R.drawable.search_custom_url_ghosted_dark);
1381 searchCustomURLPreference.setIcon(R.drawable.search_custom_url_ghosted_light);
1386 case "search_custom_url":
1387 // Set the new search custom URL as the summary text for the preference.
1388 searchCustomURLPreference.setSummary(sharedPreferences.getString("search_custom_url", getString(R.string.search_custom_url_default_value)));
1392 // Get current proxy string.
1393 String currentProxyString = sharedPreferences.getString("proxy", getString(R.string.proxy_default_value));
1395 // Update the summary text for the proxy preference.
1396 switch (currentProxyString) {
1397 case ProxyHelper.NONE:
1398 proxyPreference.setSummary(getString(R.string.no_proxy_enabled));
1401 case ProxyHelper.TOR:
1402 if (Build.VERSION.SDK_INT == 19) { // Proxying through SOCKS doesn't work on Android KitKat.
1403 proxyPreference.setSummary(getString(R.string.tor_enabled_kitkat));
1405 proxyPreference.setSummary(getString(R.string.tor_enabled));
1409 case ProxyHelper.I2P:
1410 proxyPreference.setSummary(getString(R.string.i2p_enabled));
1413 case ProxyHelper.CUSTOM:
1414 proxyPreference.setSummary(getString(R.string.custom_proxy));
1418 // Update the status of the custom URL preference.
1419 proxyCustomUrlPreference.setEnabled(currentProxyString.equals("Custom"));
1421 // Update the icons.
1422 if (currentProxyString.equals("None")) { // Proxying is disabled.
1423 if (darkTheme) { // Dark theme.
1424 // Set the main proxy icon to be disabled
1425 proxyPreference.setIcon(R.drawable.proxy_disabled_dark);
1427 // Set the custom proxy URL icon to be ghosted.
1428 proxyCustomUrlPreference.setIcon(R.drawable.proxy_ghosted_dark);
1429 } else { // Light theme.
1430 // Set the main proxy icon to be disabled.
1431 proxyPreference.setIcon(R.drawable.proxy_disabled_light);
1433 // Set the custom proxy URL icon to be ghosted.
1434 proxyCustomUrlPreference.setIcon(R.drawable.proxy_ghosted_light);
1436 } else { // Proxying is enabled.
1437 if (darkTheme) { // Dark theme.
1438 // Set the main proxy icon to be enabled.
1439 proxyPreference.setIcon(R.drawable.proxy_enabled_dark);
1441 /// Set the custom proxy URL icon according to its status.
1442 if (proxyCustomUrlPreference.isEnabled()) { // Custom proxy is enabled.
1443 proxyCustomUrlPreference.setIcon(R.drawable.proxy_enabled_dark);
1444 } else { // Custom proxy is disabled.
1445 proxyCustomUrlPreference.setIcon(R.drawable.proxy_ghosted_dark);
1447 } else { // Light theme.
1448 // Set the main proxy icon to be enabled.
1449 proxyPreference.setIcon(R.drawable.proxy_enabled_light);
1451 // Set the custom proxy URL icon according to its status.
1452 if (proxyCustomUrlPreference.isEnabled()) { // Custom proxy is enabled.
1453 proxyCustomUrlPreference.setIcon(R.drawable.proxy_enabled_light);
1454 } else { // Custom proxy is disabled.
1455 proxyCustomUrlPreference.setIcon(R.drawable.proxy_ghosted_light);
1461 case "proxy_custom_url":
1462 // Set the summary text for the proxy custom URL.
1463 proxyCustomUrlPreference.setSummary(sharedPreferences.getString("proxy_custom_url", getString(R.string.proxy_custom_url_default_value)));
1466 case "full_screen_browsing_mode":
1467 if (sharedPreferences.getBoolean("full_screen_browsing_mode", false)) { // Full screen browsing is enabled.
1468 // Set the full screen browsing mode preference icon according to the theme.
1470 fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_enabled_dark);
1472 fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_enabled_light);
1475 // Set the hide app bar preference icon.
1476 if (sharedPreferences.getBoolean("hide_app_bar", true)) { // Hide app bar is enabled.
1477 // Set the icon according to the theme.
1479 hideAppBarPreference.setIcon(R.drawable.app_bar_enabled_dark);
1481 hideAppBarPreference.setIcon(R.drawable.app_bar_enabled_light);
1483 } else { // Hide app bar is disabled.
1484 // Set the icon according to the theme.
1486 hideAppBarPreference.setIcon(R.drawable.app_bar_disabled_dark);
1488 hideAppBarPreference.setIcon(R.drawable.app_bar_disabled_light);
1491 } else { // Full screen browsing is disabled.
1492 // Update the icons according to the theme.
1494 fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_disabled_dark);
1495 hideAppBarPreference.setIcon(R.drawable.app_bar_ghosted_dark);
1497 fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_disabled_light);
1498 hideAppBarPreference.setIcon(R.drawable.app_bar_ghosted_light);
1503 case "hide_app_bar":
1505 if (sharedPreferences.getBoolean("hide_app_bar", true)) { // Hide app bar is enabled.
1506 // Set the icon according to the theme.
1508 hideAppBarPreference.setIcon(R.drawable.app_bar_enabled_dark);
1510 hideAppBarPreference.setIcon(R.drawable.app_bar_enabled_light);
1512 } else { // Hide app bar is disabled.
1513 // Set the icon according to the theme.
1515 hideAppBarPreference.setIcon(R.drawable.app_bar_disabled_dark);
1517 hideAppBarPreference.setIcon(R.drawable.app_bar_disabled_light);
1522 case "clear_everything":
1523 // Store the new `clear_everything` status
1524 boolean newClearEverythingBoolean = sharedPreferences.getBoolean("clear_everything", true);
1526 // Update the status of the `Clear and Exit` preferences.
1527 clearCookiesPreference.setEnabled(!newClearEverythingBoolean);
1528 clearDomStoragePreference.setEnabled(!newClearEverythingBoolean);
1529 clearFormDataPreference.setEnabled(!newClearEverythingBoolean); // This line can be removed once the minimum API >= 26.
1530 clearCachePreference.setEnabled(!newClearEverythingBoolean);
1532 // Update the `clearEverythingPreference` icon.
1533 if (newClearEverythingBoolean) {
1535 clearEverythingPreference.setIcon(R.drawable.clear_everything_enabled_dark);
1537 clearEverythingPreference.setIcon(R.drawable.clear_everything_enabled_light);
1540 clearEverythingPreference.setIcon(R.drawable.clear_everything_disabled);
1543 // Update the `clearCookiesPreference` icon.
1544 if (newClearEverythingBoolean || sharedPreferences.getBoolean("clear_cookies", true)) {
1546 clearCookiesPreference.setIcon(R.drawable.cookies_cleared_dark);
1548 clearCookiesPreference.setIcon(R.drawable.cookies_cleared_light);
1551 clearCookiesPreference.setIcon(R.drawable.cookies_warning);
1554 // Update the `clearDomStoragePreference` icon.
1555 if (newClearEverythingBoolean || sharedPreferences.getBoolean("clear_dom_storage", true)) {
1557 clearDomStoragePreference.setIcon(R.drawable.dom_storage_cleared_dark);
1559 clearDomStoragePreference.setIcon(R.drawable.dom_storage_cleared_light);
1562 clearDomStoragePreference.setIcon(R.drawable.dom_storage_warning);
1565 // Update the clear form data preference icon if the API < 26.
1566 if (Build.VERSION.SDK_INT < 26) {
1567 if (newClearEverythingBoolean || sharedPreferences.getBoolean("clear_form_data", true)) {
1569 clearFormDataPreference.setIcon(R.drawable.form_data_cleared_dark);
1571 clearFormDataPreference.setIcon(R.drawable.form_data_cleared_light);
1574 clearFormDataPreference.setIcon(R.drawable.form_data_warning);
1578 // Update the `clearCachePreference` icon.
1579 if (newClearEverythingBoolean || sharedPreferences.getBoolean("clear_cache", true)) {
1581 clearCachePreference.setIcon(R.drawable.cache_cleared_dark);
1583 clearCachePreference.setIcon(R.drawable.cache_cleared_light);
1586 clearCachePreference.setIcon(R.drawable.cache_warning);
1590 case "clear_cookies":
1592 if (sharedPreferences.getBoolean("clear_cookies", true)) {
1594 clearCookiesPreference.setIcon(R.drawable.cookies_cleared_dark);
1596 clearCookiesPreference.setIcon(R.drawable.cookies_cleared_light);
1599 clearCookiesPreference.setIcon(R.drawable.cookies_warning);
1603 case "clear_dom_storage":
1605 if (sharedPreferences.getBoolean("clear_dom_storage", true)) {
1607 clearDomStoragePreference.setIcon(R.drawable.dom_storage_cleared_dark);
1609 clearDomStoragePreference.setIcon(R.drawable.dom_storage_cleared_light);
1612 clearDomStoragePreference.setIcon(R.drawable.dom_storage_warning);
1616 // This section can be removed once the minimum API >= 26.
1617 case "clear_form_data":
1619 if (sharedPreferences.getBoolean("clear_form_data", true)) {
1621 clearFormDataPreference.setIcon(R.drawable.form_data_cleared_dark);
1623 clearFormDataPreference.setIcon(R.drawable.form_data_cleared_light);
1626 clearFormDataPreference.setIcon(R.drawable.form_data_warning);
1632 if (sharedPreferences.getBoolean("clear_cache", true)) {
1634 clearCachePreference.setIcon(R.drawable.cache_cleared_dark);
1636 clearCachePreference.setIcon(R.drawable.cache_cleared_light);
1639 clearCachePreference.setIcon(R.drawable.cache_warning);
1644 // Set the new homepage URL as the summary text for the Homepage preference.
1645 homepagePreference.setSummary(sharedPreferences.getString("homepage", getString(R.string.homepage_default_value)));
1648 case "download_location":
1649 // Get the new download location.
1650 String newDownloadLocationString = sharedPreferences.getString("download_location", getString(R.string.download_location_default_value));
1652 // Update the download location summary text.
1653 downloadLocationPreference.setSummary(downloadLocationHelper.getDownloadLocation(context));
1655 // Update the status of the download custom location preference.
1656 downloadCustomLocationPreference.setEnabled(newDownloadLocationString.equals(downloadLocationEntryValuesStringArray[3]));
1658 // Update the download custom location icon.
1659 if (downloadCustomLocationPreference.isEnabled()) {
1661 downloadCustomLocationPreference.setIcon(R.drawable.downloads_enabled_dark);
1663 downloadCustomLocationPreference.setIcon(R.drawable.downloads_enabled_light);
1667 downloadCustomLocationPreference.setIcon(R.drawable.downloads_ghosted_dark);
1669 downloadCustomLocationPreference.setIcon(R.drawable.downloads_ghosted_light);
1674 case "download_custom_location":
1675 // Set the new download custom location as the summary text for the preference.
1676 downloadCustomLocationPreference.setSummary(sharedPreferences.getString("download_custom_location", getString(R.string.download_custom_location_default_value)));
1680 // Update the font size summary text.
1681 fontSizePreference.setSummary(sharedPreferences.getString("font_size", getString(R.string.font_size_default_value)) + "%");
1684 case "open_intents_in_new_tab":
1686 if (sharedPreferences.getBoolean("open_intents_in_new_tab", true)) {
1688 openIntentsInNewTabPreference.setIcon(R.drawable.tab_enabled_dark);
1690 openIntentsInNewTabPreference.setIcon(R.drawable.tab_enabled_light);
1694 openIntentsInNewTabPreference.setIcon(R.drawable.tab_disabled_dark);
1696 openIntentsInNewTabPreference.setIcon(R.drawable.tab_disabled_light);
1701 case "swipe_to_refresh":
1703 if (sharedPreferences.getBoolean("swipe_to_refresh", true)) {
1705 swipeToRefreshPreference.setIcon(R.drawable.refresh_enabled_dark);
1707 swipeToRefreshPreference.setIcon(R.drawable.refresh_enabled_light);
1711 swipeToRefreshPreference.setIcon(R.drawable.refresh_disabled_dark);
1713 swipeToRefreshPreference.setIcon(R.drawable.refresh_disabled_light);
1718 case "scroll_app_bar":
1720 if (sharedPreferences.getBoolean("scroll_app_bar", true)) {
1722 scrollAppBarPreference.setIcon(R.drawable.app_bar_enabled_dark);
1724 scrollAppBarPreference.setIcon(R.drawable.app_bar_enabled_light);
1728 scrollAppBarPreference.setIcon(R.drawable.app_bar_disabled_dark);
1730 scrollAppBarPreference.setIcon(R.drawable.app_bar_disabled_light);
1735 case "display_additional_app_bar_icons":
1737 if (sharedPreferences.getBoolean("display_additional_app_bar_icons", false)) {
1739 displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_enabled_dark);
1741 displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_enabled_light);
1745 displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_disabled_dark);
1747 displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_disabled_light);
1754 if (sharedPreferences.getBoolean("dark_theme", false)) {
1755 darkThemePreference.setIcon(R.drawable.theme_dark);
1757 darkThemePreference.setIcon(R.drawable.theme_light);
1760 // Create an intent to restart Privacy Browser.
1761 Intent changeThemeRestartIntent = getActivity().getParentActivityIntent();
1763 // Assert that the intent is not null to remove the lint error below.
1764 assert changeThemeRestartIntent != null;
1766 // `Intent.FLAG_ACTIVITY_CLEAR_TASK` removes all activities from the stack. It requires `Intent.FLAG_ACTIVITY_NEW_TASK`.
1767 changeThemeRestartIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
1769 // Create a handler to restart the activity.
1770 Handler changeThemeRestartHandler = new Handler();
1772 // Create a runnable to restart the activity.
1773 Runnable changeThemeRestartRunnable = () -> {
1774 // Restart the activity.
1775 startActivity(changeThemeRestartIntent);
1777 // Kill this instance of Privacy Browser. Otherwise, the app exhibits sporadic behavior after the restart.
1781 // Restart the activity after 150 milliseconds, so that the app has enough time to save the change to the preference.
1782 changeThemeRestartHandler.postDelayed(changeThemeRestartRunnable, 150);
1786 // Store the current night mode status.
1787 boolean currentNightModeBoolean = sharedPreferences.getBoolean("night_mode", false);
1788 boolean currentJavaScriptBoolean = sharedPreferences.getBoolean("javascript", false);
1791 if (currentNightModeBoolean) {
1793 nightModePreference.setIcon(R.drawable.night_mode_enabled_dark);
1795 nightModePreference.setIcon(R.drawable.night_mode_enabled_light);
1799 nightModePreference.setIcon(R.drawable.night_mode_disabled_dark);
1801 nightModePreference.setIcon(R.drawable.night_mode_disabled_light);
1805 // Update the status of `javaScriptPreference` and `domStoragePreference`.
1806 javaScriptPreference.setEnabled(!currentNightModeBoolean);
1807 domStoragePreference.setEnabled(currentNightModeBoolean || currentJavaScriptBoolean);
1809 // Update the `javaScriptPreference` icon.
1810 if (currentNightModeBoolean || currentJavaScriptBoolean) {
1811 javaScriptPreference.setIcon(R.drawable.javascript_enabled);
1813 javaScriptPreference.setIcon(R.drawable.privacy_mode);
1816 // Update the DOM storage preference icon.
1817 if (currentNightModeBoolean || currentJavaScriptBoolean) { // The preference is enabled.
1818 if (sharedPreferences.getBoolean("dom_storage", false)) { // DOM storage is enabled.
1819 domStoragePreference.setIcon(R.drawable.dom_storage_enabled);
1820 } else { // DOM storage is disabled.
1822 domStoragePreference.setIcon(R.drawable.dom_storage_disabled_dark);
1824 domStoragePreference.setIcon(R.drawable.dom_storage_disabled_light);
1827 } else { // The preference is disabled. The icon should be ghosted.
1829 domStoragePreference.setIcon(R.drawable.dom_storage_ghosted_dark);
1831 domStoragePreference.setIcon(R.drawable.dom_storage_ghosted_light);
1836 case "wide_viewport":
1838 if (sharedPreferences.getBoolean("wide_viewport", true)) {
1840 wideViewportPreference.setIcon(R.drawable.wide_viewport_enabled_dark);
1842 wideViewportPreference.setIcon(R.drawable.wide_viewport_enabled_light);
1846 wideViewportPreference.setIcon(R.drawable.wide_viewport_disabled_dark);
1848 wideViewportPreference.setIcon(R.drawable.wide_viewport_disabled_light);
1853 case "display_webpage_images":
1855 if (sharedPreferences.getBoolean("display_webpage_images", true)) {
1857 displayWebpageImagesPreference.setIcon(R.drawable.images_enabled_dark);
1859 displayWebpageImagesPreference.setIcon(R.drawable.images_enabled_light);
1863 displayWebpageImagesPreference.setIcon(R.drawable.images_disabled_dark);
1865 displayWebpageImagesPreference.setIcon(R.drawable.images_disabled_light);
1872 // Register the listener.
1873 savedPreferences.registerOnSharedPreferenceChangeListener(preferencesListener);
1876 // 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.
1878 public void onPause() {
1880 savedPreferences.unregisterOnSharedPreferenceChangeListener(preferencesListener);
1884 public void onResume() {
1886 savedPreferences.registerOnSharedPreferenceChangeListener(preferencesListener);