2 * Copyright © 2016-2019 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.content.Context;
24 import android.content.Intent;
25 import android.content.SharedPreferences;
26 import android.os.Build;
27 import android.os.Bundle;
28 import android.os.Handler;
29 import android.preference.Preference;
30 import android.preference.PreferenceCategory;
31 import android.preference.PreferenceFragment;
32 import android.view.LayoutInflater;
33 import android.view.View;
34 import android.webkit.WebView;
35 import android.widget.ArrayAdapter;
37 import com.stoutner.privacybrowser.R;
38 import com.stoutner.privacybrowser.activities.MainWebViewActivity;
40 public class SettingsFragment extends PreferenceFragment {
41 private SharedPreferences.OnSharedPreferenceChangeListener preferencesListener;
42 private SharedPreferences savedPreferences;
45 public void onCreate(Bundle savedInstanceState) {
46 // Run the default commands.
47 super.onCreate(savedInstanceState);
49 // Load the preferences from the XML file.
50 addPreferencesFromResource(R.xml.preferences);
52 // Get a handle for the context.
53 Context context = getActivity().getApplicationContext();
55 // Initialize savedPreferences.
56 savedPreferences = getPreferenceScreen().getSharedPreferences();
58 // Get handles for the preferences.
59 final Preference javaScriptPreference = findPreference("javascript");
60 final Preference firstPartyCookiesPreference = findPreference("first_party_cookies");
61 final Preference thirdPartyCookiesPreference = findPreference("third_party_cookies");
62 final Preference domStoragePreference = findPreference("dom_storage");
63 final Preference saveFormDataPreference = findPreference("save_form_data"); // The form data preference can be removed once the minimum API >= 26.
64 final Preference userAgentPreference = findPreference("user_agent");
65 final Preference customUserAgentPreference = findPreference("custom_user_agent");
66 final Preference incognitoModePreference = findPreference("incognito_mode");
67 final Preference doNotTrackPreference = findPreference("do_not_track");
68 final Preference allowScreenshotsPreference = findPreference("allow_screenshots");
69 final Preference easyListPreference = findPreference("easylist");
70 final Preference easyPrivacyPreference = findPreference("easyprivacy");
71 final Preference fanboyAnnoyanceListPreference = findPreference("fanboys_annoyance_list");
72 final Preference fanboySocialBlockingListPreference = findPreference("fanboys_social_blocking_list");
73 final Preference ultraPrivacyPreference = findPreference("ultraprivacy");
74 final Preference blockAllThirdPartyRequestsPreference = findPreference("block_all_third_party_requests");
75 final Preference proxyThroughOrbotPreference = findPreference("proxy_through_orbot");
76 final Preference torHomepagePreference = findPreference("tor_homepage");
77 final Preference torSearchPreference = findPreference("tor_search");
78 final Preference torSearchCustomURLPreference = findPreference("tor_search_custom_url");
79 final Preference searchPreference = findPreference("search");
80 final Preference searchCustomURLPreference = findPreference("search_custom_url");
81 final Preference fullScreenBrowsingModePreference = findPreference("full_screen_browsing_mode");
82 final Preference hideAppBarPreference = findPreference("hide_app_bar");
83 final Preference clearEverythingPreference = findPreference("clear_everything");
84 final Preference clearCookiesPreference = findPreference("clear_cookies");
85 final Preference clearDomStoragePreference = findPreference("clear_dom_storage");
86 final Preference clearFormDataPreference = findPreference("clear_form_data"); // The clear form data preference can be removed once the minimum API >= 26.
87 final Preference clearCachePreference = findPreference("clear_cache");
88 final Preference homepagePreference = findPreference("homepage");
89 final Preference fontSizePreference = findPreference("font_size");
90 final Preference swipeToRefreshPreference = findPreference("swipe_to_refresh");
91 final Preference scrollAppBarPreference = findPreference("scroll_app_bar");
92 final Preference displayAdditionalAppBarIconsPreference = findPreference("display_additional_app_bar_icons");
93 final Preference downloadWithExternalAppPreference = findPreference("download_with_external_app");
94 final Preference darkThemePreference = findPreference("dark_theme");
95 final Preference nightModePreference = findPreference("night_mode");
96 final Preference displayWebpageImagesPreference = findPreference("display_webpage_images");
99 torHomepagePreference.setDependency("proxy_through_orbot");
100 torSearchPreference.setDependency("proxy_through_orbot");
101 hideAppBarPreference.setDependency("full_screen_browsing_mode");
103 // Get strings from the preferences.
104 String torSearchString = savedPreferences.getString("tor_search", getString(R.string.tor_search_default_value));
105 String searchString = savedPreferences.getString("search", getString(R.string.search_default_value));
107 // Get booleans that are used in multiple places from the preferences.
108 final boolean javaScriptEnabled = savedPreferences.getBoolean("javascript", false);
109 boolean firstPartyCookiesEnabled = savedPreferences.getBoolean("first_party_cookies", false);
110 boolean thirdPartyCookiesEnabled = savedPreferences.getBoolean("third_party_cookies", false);
111 boolean fanboyAnnoyanceListEnabled = savedPreferences.getBoolean("fanboys_annoyance_list", true);
112 boolean fanboySocialBlockingEnabled = savedPreferences.getBoolean("fanboys_social_blocking_list", true);
113 boolean proxyThroughOrbot = savedPreferences.getBoolean("proxy_through_orbot", false);
114 boolean fullScreenBrowsingMode = savedPreferences.getBoolean("full_screen_browsing_mode", false);
115 boolean clearEverything = savedPreferences.getBoolean("clear_everything", true);
116 boolean darkTheme = savedPreferences.getBoolean("dark_theme", false);
117 final boolean nightMode = savedPreferences.getBoolean("night_mode", false);
119 // Only enable the third-party cookies preference if first-party cookies are enabled and API >= 21.
120 thirdPartyCookiesPreference.setEnabled(firstPartyCookiesEnabled && (Build.VERSION.SDK_INT >= 21));
122 // Only enable the DOM storage preference if either JavaScript or Night Mode is enabled.
123 domStoragePreference.setEnabled(javaScriptEnabled || nightMode);
125 // Remove the form data preferences if the API is >= 26 as they no longer do anything.
126 if (Build.VERSION.SDK_INT >= 26) {
127 // Get the categories.
128 PreferenceCategory privacyCategory = (PreferenceCategory) findPreference("privacy");
129 PreferenceCategory clearAndExitCategory = (PreferenceCategory) findPreference("clear_and_exit");
131 // Remove the form data preferences.
132 privacyCategory.removePreference(saveFormDataPreference);
133 clearAndExitCategory.removePreference(clearFormDataPreference);
136 // Only enable Fanboy's social blocking list preference if Fanboy's annoyance list is disabled.
137 fanboySocialBlockingListPreference.setEnabled(!fanboyAnnoyanceListEnabled);
139 // Inflate a WebView to get the default user agent.
140 LayoutInflater inflater = getActivity().getLayoutInflater();
141 // `@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.
142 @SuppressLint("InflateParams") View bareWebViewLayout = inflater.inflate(R.layout.bare_webview, null, false);
143 final WebView bareWebView = bareWebViewLayout.findViewById(R.id.bare_webview);
145 // Get the user agent arrays.
146 ArrayAdapter<CharSequence> userAgentNamesArray = ArrayAdapter.createFromResource(context, R.array.user_agent_names, R.layout.spinner_item);
147 String[] translatedUserAgentNamesArray = getResources().getStringArray(R.array.translated_user_agent_names);
148 String[] userAgentDataArray = getResources().getStringArray(R.array.user_agent_data);
150 // Get the current user agent name from the preference.
151 String userAgentName = savedPreferences.getString("user_agent", getString(R.string.user_agent_default_value));
153 // Get the array position of the user agent name.
154 int userAgentArrayPosition = userAgentNamesArray.getPosition(userAgentName);
156 // Populate the user agent summary.
157 switch (userAgentArrayPosition) {
158 case MainWebViewActivity.UNRECOGNIZED_USER_AGENT: // The user agent name is not on the canonical list.
159 // 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.
160 userAgentPreference.setSummary(userAgentName);
163 case MainWebViewActivity.SETTINGS_WEBVIEW_DEFAULT_USER_AGENT:
164 // Get the user agent text from the webview (which changes based on the version of Android and WebView installed).
165 userAgentPreference.setSummary(translatedUserAgentNamesArray[userAgentArrayPosition] + ":\n" + bareWebView.getSettings().getUserAgentString());
168 case MainWebViewActivity.SETTINGS_CUSTOM_USER_AGENT:
169 // Set the summary text.
170 userAgentPreference.setSummary(R.string.custom_user_agent);
174 // Get the user agent summary from the user agent data array.
175 userAgentPreference.setSummary(translatedUserAgentNamesArray[userAgentArrayPosition] + ":\n" + userAgentDataArray[userAgentArrayPosition]);
178 // Set the summary text for the custom user agent preference and enable it if user agent preference is set to custom.
179 customUserAgentPreference.setSummary(savedPreferences.getString("custom_user_agent", getString(R.string.custom_user_agent_default_value)));
180 customUserAgentPreference.setEnabled(userAgentPreference.getSummary().equals(getString(R.string.custom_user_agent)));
183 // Set the Tor homepage URL as the summary text for the `tor_homepage` preference when the preference screen is loaded. The default is Searx: `http://ulrn6sryqaifefld.onion/`.
184 torHomepagePreference.setSummary(savedPreferences.getString("tor_homepage", getString(R.string.tor_homepage_default_value)));
187 // Set the Tor search URL as the summary text for the Tor preference when the preference screen is loaded.
188 if (torSearchString.equals("Custom URL")) {
189 // Use R.string.custom_url, which will be translated, instead of the array value, which will not.
190 torSearchPreference.setSummary(R.string.custom_url);
192 // Set the array value as the summary text.
193 torSearchPreference.setSummary(torSearchString);
196 // Set the summary text for `tor_search_custom_url`. The default is `""`.
197 torSearchCustomURLPreference.setSummary(savedPreferences.getString("tor_search_custom_url", getString(R.string.tor_search_custom_url_default_value)));
199 // Enable the Tor custom URL search options only if proxying through Orbot and the search is set to `Custom URL`.
200 torSearchCustomURLPreference.setEnabled(proxyThroughOrbot && torSearchString.equals("Custom URL"));
203 // Set the search URL as the summary text for the search preference when the preference screen is loaded.
204 if (searchString.equals("Custom URL")) {
205 // Use R.string.custom_url, which will be translated, instead of the array value, which will not.
206 searchPreference.setSummary(R.string.custom_url);
208 // Set the array value as the summary text.
209 searchPreference.setSummary(searchString);
212 // Set the summary text for `search_custom_url` (the default is `""`) and enable it if `search` is set to `Custom URL`.
213 searchCustomURLPreference.setSummary(savedPreferences.getString("search_custom_url", getString(R.string.search_custom_url_default_value)));
214 searchCustomURLPreference.setEnabled(searchString.equals("Custom URL"));
216 // Set the status of the Clear and Exit preferences.
217 clearCookiesPreference.setEnabled(!clearEverything);
218 clearDomStoragePreference.setEnabled(!clearEverything);
219 clearFormDataPreference.setEnabled(!clearEverything); // The form data line can be removed once the minimum API is >= 26.
220 clearCachePreference.setEnabled(!clearEverything);
222 // Set the homepage URL as the summary text for the homepage preference.
223 homepagePreference.setSummary(savedPreferences.getString("homepage", getString(R.string.homepage_default_value)));
225 // Set the font size as the summary text for the preference.
226 fontSizePreference.setSummary(savedPreferences.getString("font_size", getString(R.string.font_size_default_value)) + "%%");
228 // Disable the JavaScript preference if Night Mode is enabled. JavaScript will be enabled for all web pages.
229 javaScriptPreference.setEnabled(!nightMode);
231 // Set the JavaScript icon.
232 if (javaScriptEnabled || nightMode) {
233 javaScriptPreference.setIcon(R.drawable.javascript_enabled);
235 javaScriptPreference.setIcon(R.drawable.privacy_mode);
238 // Set the first-party cookies icon.
239 if (firstPartyCookiesEnabled) {
240 firstPartyCookiesPreference.setIcon(R.drawable.cookies_enabled);
243 firstPartyCookiesPreference.setIcon(R.drawable.cookies_disabled_dark);
245 firstPartyCookiesPreference.setIcon(R.drawable.cookies_disabled_light);
249 // Set the third party cookies icon.
250 if (firstPartyCookiesEnabled && Build.VERSION.SDK_INT >= 21) {
251 if (thirdPartyCookiesEnabled) {
252 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_warning);
255 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_disabled_dark);
257 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_disabled_light);
262 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_ghosted_dark);
264 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_ghosted_light);
268 // Set the DOM storage icon.
269 if (javaScriptEnabled || nightMode) { // The preference is enabled.
270 if (savedPreferences.getBoolean("dom_storage", false)) { // DOM storage is enabled.
271 domStoragePreference.setIcon(R.drawable.dom_storage_enabled);
272 } else { // DOM storage is disabled.
274 domStoragePreference.setIcon(R.drawable.dom_storage_disabled_dark);
276 domStoragePreference.setIcon(R.drawable.dom_storage_disabled_light);
279 } else { // The preference is disabled. The icon should be ghosted.
281 domStoragePreference.setIcon(R.drawable.dom_storage_ghosted_dark);
283 domStoragePreference.setIcon(R.drawable.dom_storage_ghosted_light);
287 // Set the save form data icon if API < 26. Save form data has no effect on API >= 26.
288 if (Build.VERSION.SDK_INT < 26) {
289 if (savedPreferences.getBoolean("save_form_data", false)) {
290 saveFormDataPreference.setIcon(R.drawable.form_data_enabled);
293 saveFormDataPreference.setIcon(R.drawable.form_data_disabled_dark);
295 saveFormDataPreference.setIcon(R.drawable.form_data_disabled_light);
300 // Set the custom user agent icon.
301 if (customUserAgentPreference.isEnabled()) {
303 customUserAgentPreference.setIcon(R.drawable.custom_user_agent_enabled_dark);
305 customUserAgentPreference.setIcon(R.drawable.custom_user_agent_enabled_light);
309 customUserAgentPreference.setIcon(R.drawable.custom_user_agent_ghosted_dark);
311 customUserAgentPreference.setIcon(R.drawable.custom_user_agent_ghosted_light);
315 // Set the incognito mode icon.
316 if (savedPreferences.getBoolean("incognito_mode", false)) {
318 incognitoModePreference.setIcon(R.drawable.incognito_mode_enabled_dark);
320 incognitoModePreference.setIcon(R.drawable.incognito_mode_enabled_light);
324 incognitoModePreference.setIcon(R.drawable.incognito_mode_disabled_dark);
326 incognitoModePreference.setIcon(R.drawable.incognito_mode_disabled_light);
330 // Set the Do Not Track icon.
331 if (savedPreferences.getBoolean("do_not_track", false)) {
333 doNotTrackPreference.setIcon(R.drawable.block_tracking_enabled_dark);
335 doNotTrackPreference.setIcon(R.drawable.block_tracking_enabled_light);
339 doNotTrackPreference.setIcon(R.drawable.block_tracking_disabled_dark);
341 doNotTrackPreference.setIcon(R.drawable.block_tracking_disabled_light);
345 // Set the allow screenshots icon.
346 if (savedPreferences.getBoolean("allow_screenshots", false)) {
348 allowScreenshotsPreference.setIcon(R.drawable.allow_screenshots_enabled_dark);
350 allowScreenshotsPreference.setIcon(R.drawable.allow_screenshots_enabled_light);
354 allowScreenshotsPreference.setIcon(R.drawable.allow_screenshots_disabled_dark);
356 allowScreenshotsPreference.setIcon(R.drawable.allow_screenshots_disabled_light);
360 // Set the EasyList icon.
361 if (savedPreferences.getBoolean("easylist", true)) {
363 easyListPreference.setIcon(R.drawable.block_ads_enabled_dark);
365 easyListPreference.setIcon(R.drawable.block_ads_enabled_light);
369 easyListPreference.setIcon(R.drawable.block_ads_disabled_dark);
371 easyListPreference.setIcon(R.drawable.block_ads_disabled_light);
375 // Set the EasyPrivacy icon.
376 if (savedPreferences.getBoolean("easyprivacy", true)) {
378 easyPrivacyPreference.setIcon(R.drawable.block_tracking_enabled_dark);
380 easyPrivacyPreference.setIcon(R.drawable.block_tracking_enabled_light);
384 easyPrivacyPreference.setIcon(R.drawable.block_tracking_disabled_dark);
386 easyPrivacyPreference.setIcon(R.drawable.block_tracking_disabled_light);
390 // Set the Fanboy lists icons.
391 if (fanboyAnnoyanceListEnabled) {
393 // Set the Fanboy annoyance list icon.
394 fanboyAnnoyanceListPreference.setIcon(R.drawable.social_media_enabled_dark);
396 // Set the Fanboy social blocking list icon.
397 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_ghosted_dark);
399 // Set the Fanboy annoyance list icon.
400 fanboyAnnoyanceListPreference.setIcon(R.drawable.social_media_enabled_light);
402 // Set the Fanboy social blocking list icon.
403 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_ghosted_light);
407 // Set the Fanboy annoyance list icon.
408 fanboyAnnoyanceListPreference.setIcon(R.drawable.social_media_disabled_dark);
410 // Set the Fanboy social blocking list icon.
411 if (fanboySocialBlockingEnabled) {
412 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_enabled_dark);
414 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_disabled_dark);
417 // Set the Fanboy annoyance list icon.
418 fanboyAnnoyanceListPreference.setIcon(R.drawable.block_ads_disabled_light);
420 // Set the Fanboy social blocking list icon.
421 if (fanboySocialBlockingEnabled) {
422 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_enabled_light);
424 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_disabled_light);
429 // Set the UltraPrivacy icon.
430 if (savedPreferences.getBoolean("ultraprivacy", true)) {
432 ultraPrivacyPreference.setIcon(R.drawable.block_tracking_enabled_dark);
434 ultraPrivacyPreference.setIcon(R.drawable.block_tracking_enabled_light);
438 ultraPrivacyPreference.setIcon(R.drawable.block_tracking_disabled_dark);
440 ultraPrivacyPreference.setIcon(R.drawable.block_tracking_disabled_light);
444 // Set the block all third-party requests icon.
445 if (savedPreferences.getBoolean("block_all_third_party_requests", false)) {
447 blockAllThirdPartyRequestsPreference.setIcon(R.drawable.block_all_third_party_requests_enabled_dark);
449 blockAllThirdPartyRequestsPreference.setIcon(R.drawable.block_all_third_party_requests_enabled_light);
453 blockAllThirdPartyRequestsPreference.setIcon(R.drawable.block_all_third_party_requests_disabled_dark);
455 blockAllThirdPartyRequestsPreference.setIcon(R.drawable.block_all_third_party_requests_disabled_light);
459 // Set the Tor icons according to the theme.
460 if (proxyThroughOrbot) { // Proxying is enabled.
462 proxyThroughOrbotPreference.setIcon(R.drawable.orbot_enabled_dark);
463 torHomepagePreference.setIcon(R.drawable.home_enabled_dark);
464 torSearchPreference.setIcon(R.drawable.search_enabled_dark);
466 // Set the custom search icon.
467 if (torSearchCustomURLPreference.isEnabled()) {
468 torSearchCustomURLPreference.setIcon(R.drawable.search_custom_url_enabled_dark);
470 torSearchCustomURLPreference.setIcon(R.drawable.search_custom_url_ghosted_dark);
473 proxyThroughOrbotPreference.setIcon(R.drawable.orbot_enabled_light);
474 torHomepagePreference.setIcon(R.drawable.home_enabled_light);
475 torSearchPreference.setIcon(R.drawable.search_enabled_light);
477 // Set the custom search icon.
478 if (torSearchCustomURLPreference.isEnabled()) {
479 torSearchCustomURLPreference.setIcon(R.drawable.search_custom_url_enabled_light);
481 torSearchCustomURLPreference.setIcon(R.drawable.search_custom_url_ghosted_light);
484 } else { // Proxying is disabled.
486 proxyThroughOrbotPreference.setIcon(R.drawable.orbot_disabled_dark);
487 torHomepagePreference.setIcon(R.drawable.home_ghosted_dark);
488 torSearchPreference.setIcon(R.drawable.search_ghosted_dark);
489 torSearchCustomURLPreference.setIcon(R.drawable.search_custom_url_ghosted_dark);
491 proxyThroughOrbotPreference.setIcon(R.drawable.orbot_disabled_light);
492 torHomepagePreference.setIcon(R.drawable.home_ghosted_light);
493 torSearchPreference.setIcon(R.drawable.search_ghosted_light);
494 torSearchCustomURLPreference.setIcon(R.drawable.search_custom_url_ghosted_light);
498 // Set the search custom URL icon.
499 if (searchCustomURLPreference.isEnabled()) {
501 searchCustomURLPreference.setIcon(R.drawable.search_custom_url_enabled_dark);
503 searchCustomURLPreference.setIcon(R.drawable.search_custom_url_enabled_light);
507 searchCustomURLPreference.setIcon(R.drawable.search_custom_url_ghosted_dark);
509 searchCustomURLPreference.setIcon(R.drawable.search_custom_url_ghosted_light);
513 // Set the full screen browsing mode icons.
514 if (fullScreenBrowsingMode) { // Full screen browsing mode is enabled.
515 // Set the `fullScreenBrowsingModePreference` icon according to the theme.
517 fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_enabled_dark);
519 fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_enabled_light);
522 // Set the hide app bar icon.
523 if (savedPreferences.getBoolean("hide_app_bar", true)) { // Hide app bar is enabled.
524 // Set the icon according to the theme.
526 hideAppBarPreference.setIcon(R.drawable.app_bar_enabled_dark);
528 hideAppBarPreference.setIcon(R.drawable.app_bar_enabled_light);
530 } else { // Hide app bar is disabled.
531 // Set the icon according to the theme.
533 hideAppBarPreference.setIcon(R.drawable.app_bar_disabled_dark);
535 hideAppBarPreference.setIcon(R.drawable.app_bar_disabled_light);
538 } else { // Full screen browsing mode is disabled.
539 // Set the icons according to the theme.
541 fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_disabled_dark);
542 hideAppBarPreference.setIcon(R.drawable.app_bar_ghosted_dark);
544 fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_disabled_light);
545 hideAppBarPreference.setIcon(R.drawable.app_bar_ghosted_light);
549 // Set the clear everything preference icon.
550 if (clearEverything) {
552 clearEverythingPreference.setIcon(R.drawable.clear_everything_enabled_dark);
554 clearEverythingPreference.setIcon(R.drawable.clear_everything_enabled_light);
557 clearEverythingPreference.setIcon(R.drawable.clear_everything_disabled);
560 // Set the clear cookies preference icon.
561 if (clearEverything || savedPreferences.getBoolean("clear_cookies", true)) {
563 clearCookiesPreference.setIcon(R.drawable.cookies_cleared_dark);
565 clearCookiesPreference.setIcon(R.drawable.cookies_cleared_light);
568 clearCookiesPreference.setIcon(R.drawable.cookies_warning);
571 // Set the clear DOM storage preference icon.
572 if (clearEverything || savedPreferences.getBoolean("clear_dom_storage", true)) {
574 clearDomStoragePreference.setIcon(R.drawable.dom_storage_cleared_dark);
576 clearDomStoragePreference.setIcon(R.drawable.dom_storage_cleared_light);
579 clearDomStoragePreference.setIcon(R.drawable.dom_storage_warning);
582 // Set the clear form data preference icon if the API < 26. It has no effect on newer versions of Android.
583 if (Build.VERSION.SDK_INT < 26) {
584 if (clearEverything || savedPreferences.getBoolean("clear_form_data", true)) {
586 clearFormDataPreference.setIcon(R.drawable.form_data_cleared_dark);
588 clearFormDataPreference.setIcon(R.drawable.form_data_cleared_light);
591 clearFormDataPreference.setIcon(R.drawable.form_data_warning);
595 // Set the clear cache preference icon.
596 if (clearEverything || savedPreferences.getBoolean("clear_cache", true)) {
598 clearCachePreference.setIcon(R.drawable.cache_cleared_dark);
600 clearCachePreference.setIcon(R.drawable.cache_cleared_light);
603 clearCachePreference.setIcon(R.drawable.cache_warning);
606 // Set the swipe to refresh preference icon.
607 if (savedPreferences.getBoolean("swipe_to_refresh", true)) {
609 swipeToRefreshPreference.setIcon(R.drawable.refresh_enabled_dark);
611 swipeToRefreshPreference.setIcon(R.drawable.refresh_enabled_light);
615 swipeToRefreshPreference.setIcon(R.drawable.refresh_disabled_dark);
617 swipeToRefreshPreference.setIcon(R.drawable.refresh_disabled_light);
621 // Set the scroll app bar preference icon.
622 if (savedPreferences.getBoolean("scroll_app_bar", true)) {
624 scrollAppBarPreference.setIcon(R.drawable.app_bar_enabled_dark);
626 scrollAppBarPreference.setIcon(R.drawable.app_bar_enabled_light);
630 scrollAppBarPreference.setIcon(R.drawable.app_bar_disabled_dark);
632 scrollAppBarPreference.setIcon(R.drawable.app_bar_disabled_light);
636 // Set the display additional app bar icons preference icon.
637 if (savedPreferences.getBoolean("display_additional_app_bar_icons", false)) {
639 displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_enabled_dark);
641 displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_enabled_light);
645 displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_disabled_dark);
647 displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_disabled_light);
651 // Set the download with external app preference icon.
652 if (savedPreferences.getBoolean("download_with_external_app", false)) {
654 downloadWithExternalAppPreference.setIcon(R.drawable.open_with_external_app_enabled_dark);
656 downloadWithExternalAppPreference.setIcon(R.drawable.open_with_external_app_enabled_light);
660 downloadWithExternalAppPreference.setIcon(R.drawable.open_with_external_app_disabled_dark);
662 downloadWithExternalAppPreference.setIcon(R.drawable.open_with_external_app_disabled_light);
666 // Set the dark theme preference icon.
667 if (savedPreferences.getBoolean("dark_theme", false)) {
668 darkThemePreference.setIcon(R.drawable.theme_dark);
670 darkThemePreference.setIcon(R.drawable.theme_light);
673 // Set the night mode preference icon.
676 nightModePreference.setIcon(R.drawable.night_mode_enabled_dark);
678 nightModePreference.setIcon(R.drawable.night_mode_enabled_light);
682 nightModePreference.setIcon(R.drawable.night_mode_disabled_dark);
684 nightModePreference.setIcon(R.drawable.night_mode_disabled_light);
688 // Set the display webpage images preference icon.
689 if (savedPreferences.getBoolean("display_webpage_images", true)) {
691 displayWebpageImagesPreference.setIcon(R.drawable.images_enabled_dark);
693 displayWebpageImagesPreference.setIcon(R.drawable.images_enabled_light);
697 displayWebpageImagesPreference.setIcon(R.drawable.images_disabled_dark);
699 displayWebpageImagesPreference.setIcon(R.drawable.images_disabled_light);
704 // Listen for preference changes.
705 preferencesListener = (SharedPreferences sharedPreferences, String key) -> {
708 // Update the icons and the DOM storage preference status.
709 if (sharedPreferences.getBoolean("javascript", false)) { // The JavaScript preference is enabled.
710 // Update the icon for the JavaScript preference.
711 javaScriptPreference.setIcon(R.drawable.javascript_enabled);
713 // Update the status of the DOM storage preference.
714 domStoragePreference.setEnabled(true);
716 // Update the icon for the DOM storage preference.
717 if (sharedPreferences.getBoolean("dom_storage", false)) {
718 domStoragePreference.setIcon(R.drawable.dom_storage_enabled);
721 domStoragePreference.setIcon(R.drawable.dom_storage_disabled_dark);
723 domStoragePreference.setIcon(R.drawable.dom_storage_disabled_light);
726 } else { // The JavaScript preference is disabled.
727 // Update the icon for the JavaScript preference.
728 javaScriptPreference.setIcon(R.drawable.privacy_mode);
730 // Update the status of the DOM storage preference.
731 domStoragePreference.setEnabled(false);
733 // Set the icon for DOM storage preference to be ghosted.
735 domStoragePreference.setIcon(R.drawable.dom_storage_ghosted_dark);
737 domStoragePreference.setIcon(R.drawable.dom_storage_ghosted_light);
742 case "first_party_cookies":
743 // Update the icons for `first_party_cookies` and `third_party_cookies`.
744 if (sharedPreferences.getBoolean("first_party_cookies", false)) {
745 // Set the icon for `first_party_cookies`.
746 firstPartyCookiesPreference.setIcon(R.drawable.cookies_enabled);
748 // Update the icon for `third_party_cookies`.
749 if (Build.VERSION.SDK_INT >= 21) {
750 if (sharedPreferences.getBoolean("third_party_cookies", false)) {
751 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_warning);
754 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_disabled_dark);
756 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_disabled_light);
761 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_ghosted_dark);
763 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_ghosted_light);
766 } else { // `first_party_cookies` is `false`.
767 // Update the icon for `first_party_cookies`.
769 firstPartyCookiesPreference.setIcon(R.drawable.cookies_disabled_dark);
771 firstPartyCookiesPreference.setIcon(R.drawable.cookies_disabled_light);
774 // Set the icon for `third_party_cookies` to be ghosted.
776 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_ghosted_dark);
778 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_ghosted_light);
782 // Enable `third_party_cookies` if `first_party_cookies` is `true` and API >= 21.
783 thirdPartyCookiesPreference.setEnabled(sharedPreferences.getBoolean("first_party_cookies", false) && (Build.VERSION.SDK_INT >= 21));
786 case "third_party_cookies":
788 if (sharedPreferences.getBoolean("third_party_cookies", false)) {
789 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_warning);
792 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_disabled_dark);
794 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_disabled_light);
801 if (sharedPreferences.getBoolean("dom_storage", false)) {
802 domStoragePreference.setIcon(R.drawable.dom_storage_enabled);
805 domStoragePreference.setIcon(R.drawable.dom_storage_disabled_dark);
807 domStoragePreference.setIcon(R.drawable.dom_storage_disabled_light);
812 // Save form data can be removed once the minimum API >= 26.
813 case "save_form_data":
815 if (sharedPreferences.getBoolean("save_form_data", false)) {
816 saveFormDataPreference.setIcon(R.drawable.form_data_enabled);
819 saveFormDataPreference.setIcon(R.drawable.form_data_disabled_dark);
821 saveFormDataPreference.setIcon(R.drawable.form_data_disabled_light);
827 // Get the new user agent name.
828 String newUserAgentName = sharedPreferences.getString("user_agent", getString(R.string.user_agent_default_value));
830 // Get the array position for the new user agent name.
831 int newUserAgentArrayPosition = userAgentNamesArray.getPosition(newUserAgentName);
833 // Get the translated new user agent name.
834 String translatedNewUserAgentName = translatedUserAgentNamesArray[newUserAgentArrayPosition];
836 // Populate the user agent summary.
837 switch (newUserAgentArrayPosition) {
838 case MainWebViewActivity.SETTINGS_WEBVIEW_DEFAULT_USER_AGENT:
839 // Get the user agent text from the webview (which changes based on the version of Android and WebView installed).
840 userAgentPreference.setSummary(translatedNewUserAgentName + ":\n" + bareWebView.getSettings().getUserAgentString());
842 // Disable the custom user agent preference.
843 customUserAgentPreference.setEnabled(false);
845 // Set the custom user agent preference icon according to the theme.
847 customUserAgentPreference.setIcon(R.drawable.custom_user_agent_ghosted_dark);
849 customUserAgentPreference.setIcon(R.drawable.custom_user_agent_ghosted_light);
853 case MainWebViewActivity.SETTINGS_CUSTOM_USER_AGENT:
854 // Set the summary text.
855 userAgentPreference.setSummary(R.string.custom_user_agent);
857 // Enable the custom user agent preference.
858 customUserAgentPreference.setEnabled(true);
860 // Set the custom user agent preference icon according to the theme.
862 customUserAgentPreference.setIcon(R.drawable.custom_user_agent_enabled_dark);
864 customUserAgentPreference.setIcon(R.drawable.custom_user_agent_enabled_light);
869 // Get the user agent summary from the user agent data array.
870 userAgentPreference.setSummary(translatedNewUserAgentName + ":\n" + userAgentDataArray[newUserAgentArrayPosition]);
872 // Disable the custom user agent preference.
873 customUserAgentPreference.setEnabled(false);
875 // Set the custom user agent preference icon according to the theme.
877 customUserAgentPreference.setIcon(R.drawable.custom_user_agent_ghosted_dark);
879 customUserAgentPreference.setIcon(R.drawable.custom_user_agent_ghosted_light);
884 case "custom_user_agent":
885 // Set the new custom user agent as the summary text for the preference.
886 customUserAgentPreference.setSummary(sharedPreferences.getString("custom_user_agent", getString(R.string.custom_user_agent_default_value)));
889 case "incognito_mode":
891 if (sharedPreferences.getBoolean("incognito_mode", false)) {
893 incognitoModePreference.setIcon(R.drawable.incognito_mode_enabled_dark);
895 incognitoModePreference.setIcon(R.drawable.incognito_mode_enabled_light);
899 incognitoModePreference.setIcon(R.drawable.incognito_mode_disabled_dark);
901 incognitoModePreference.setIcon(R.drawable.incognito_mode_disabled_light);
908 if (sharedPreferences.getBoolean("do_not_track", false)) {
910 doNotTrackPreference.setIcon(R.drawable.block_tracking_enabled_dark);
912 doNotTrackPreference.setIcon(R.drawable.block_tracking_enabled_light);
916 doNotTrackPreference.setIcon(R.drawable.block_tracking_disabled_dark);
918 doNotTrackPreference.setIcon(R.drawable.block_tracking_disabled_light);
924 case "allow_screenshots":
926 if (sharedPreferences.getBoolean("allow_screenshots", false)) {
928 allowScreenshotsPreference.setIcon(R.drawable.allow_screenshots_enabled_dark);
930 allowScreenshotsPreference.setIcon(R.drawable.allow_screenshots_enabled_light);
934 allowScreenshotsPreference.setIcon(R.drawable.allow_screenshots_disabled_dark);
936 allowScreenshotsPreference.setIcon(R.drawable.allow_screenshots_disabled_light);
940 // Create an intent to restart Privacy Browser.
941 Intent allowScreenshotsRestartIntent = getActivity().getParentActivityIntent();
943 // Assert that the intent is not null to remove the lint error below.
944 assert allowScreenshotsRestartIntent != null;
946 // `Intent.FLAG_ACTIVITY_CLEAR_TASK` removes all activities from the stack. It requires `Intent.FLAG_ACTIVITY_NEW_TASK`.
947 allowScreenshotsRestartIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
949 // Create a handler to restart the activity.
950 Handler allowScreenshotsRestartHandler = new Handler();
952 // Create a runnable to restart the activity.
953 Runnable allowScreenshotsRestartRunnable = () -> {
954 // Restart the activity.
955 startActivity(allowScreenshotsRestartIntent);
957 // Kill this instance of Privacy Browser. Otherwise, the app exhibits sporadic behavior after the restart.
961 // Restart the activity after 100 milliseconds, so that the app has enough time to save the change to the preference.
962 allowScreenshotsRestartHandler.postDelayed(allowScreenshotsRestartRunnable, 100);
967 if (sharedPreferences.getBoolean("easylist", true)) {
969 easyListPreference.setIcon(R.drawable.block_ads_enabled_dark);
971 easyListPreference.setIcon(R.drawable.block_ads_enabled_light);
975 easyListPreference.setIcon(R.drawable.block_ads_disabled_dark);
977 easyListPreference.setIcon(R.drawable.block_ads_disabled_light);
984 if (sharedPreferences.getBoolean("easyprivacy", true)) {
986 easyPrivacyPreference.setIcon(R.drawable.block_tracking_enabled_dark);
988 easyPrivacyPreference.setIcon(R.drawable.block_tracking_enabled_light);
992 easyPrivacyPreference.setIcon(R.drawable.block_tracking_disabled_dark);
994 easyPrivacyPreference.setIcon(R.drawable.block_tracking_disabled_light);
999 case "fanboys_annoyance_list":
1000 boolean currentFanboyAnnoyanceList = sharedPreferences.getBoolean("fanboys_annoyance_list", true);
1001 boolean currentFanboySocialBlockingList = sharedPreferences.getBoolean("fanboys_social_blocking_list", true);
1003 // Update the Fanboy icons.
1004 if (currentFanboyAnnoyanceList) { // Fanboy's annoyance list is enabled.
1006 // Update the Fanboy's annoyance list icon.
1007 fanboyAnnoyanceListPreference.setIcon(R.drawable.social_media_enabled_dark);
1009 // Update the Fanboy's social blocking list icon.
1010 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_ghosted_dark);
1012 // Update the Fanboy's annoyance list icon.
1013 fanboyAnnoyanceListPreference.setIcon(R.drawable.social_media_enabled_light);
1015 // Update the Fanboy's social blocking list icon.
1016 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_ghosted_light);
1018 } else { // Fanboy's annoyance list is disabled.
1020 // Update the Fanboy's annoyance list icon.
1021 fanboyAnnoyanceListPreference.setIcon(R.drawable.social_media_disabled_dark);
1023 // Update the Fanboy's social blocking list icon.
1024 if (currentFanboySocialBlockingList) {
1025 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_enabled_dark);
1027 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_disabled_dark);
1030 // Update the Fanboy's annoyance list icon.
1031 fanboyAnnoyanceListPreference.setIcon(R.drawable.social_media_disabled_light);
1033 // Update the Fanboy's social blocking list icon.
1034 if (currentFanboySocialBlockingList) {
1035 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_enabled_light);
1037 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_disabled_light);
1042 // Only enable Fanboy's social blocking list preference if Fanboy's annoyance list preference is disabled.
1043 fanboySocialBlockingListPreference.setEnabled(!currentFanboyAnnoyanceList);
1046 case "fanboys_social_blocking_list":
1048 if (sharedPreferences.getBoolean("fanboys_social_blocking_list", true)) {
1050 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_enabled_dark);
1052 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_enabled_light);
1056 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_disabled_dark);
1058 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_disabled_light);
1063 case "ultraprivacy":
1065 if (sharedPreferences.getBoolean("ultraprivacy", true)) {
1067 ultraPrivacyPreference.setIcon(R.drawable.block_tracking_enabled_dark);
1069 ultraPrivacyPreference.setIcon(R.drawable.block_tracking_enabled_light);
1073 ultraPrivacyPreference.setIcon(R.drawable.block_tracking_disabled_dark);
1075 ultraPrivacyPreference.setIcon(R.drawable.block_tracking_disabled_light);
1080 case "block_all_third_party_requests":
1082 if (sharedPreferences.getBoolean("block_all_third_party_requests", false)) {
1084 blockAllThirdPartyRequestsPreference.setIcon(R.drawable.block_all_third_party_requests_enabled_dark);
1086 blockAllThirdPartyRequestsPreference.setIcon(R.drawable.block_all_third_party_requests_enabled_light);
1090 blockAllThirdPartyRequestsPreference.setIcon(R.drawable.block_all_third_party_requests_disabled_dark);
1092 blockAllThirdPartyRequestsPreference.setIcon(R.drawable.block_all_third_party_requests_disabled_light);
1097 case "proxy_through_orbot":
1098 // Get current settings.
1099 boolean currentProxyThroughOrbot = sharedPreferences.getBoolean("proxy_through_orbot", false);
1100 String currentTorSearchString = sharedPreferences.getString("tor_search", getString(R.string.tor_search_default_value));
1102 // Enable the Tor custom URL search option only if `currentProxyThroughOrbot` is true and the search is set to `Custom URL`.
1103 torSearchCustomURLPreference.setEnabled(currentProxyThroughOrbot && currentTorSearchString.equals("Custom URL"));
1105 // Update the icons.
1106 if (currentProxyThroughOrbot) {
1107 // Set the Tor icons according to the theme.
1109 proxyThroughOrbotPreference.setIcon(R.drawable.orbot_enabled_dark);
1110 torHomepagePreference.setIcon(R.drawable.home_enabled_dark);
1111 torSearchPreference.setIcon(R.drawable.search_enabled_dark);
1113 // Set the `torSearchCustomURLPreference` icon.
1114 if (torSearchCustomURLPreference.isEnabled()) {
1115 torSearchCustomURLPreference.setIcon(R.drawable.search_custom_url_enabled_dark);
1117 torSearchCustomURLPreference.setIcon(R.drawable.search_custom_url_ghosted_dark);
1120 proxyThroughOrbotPreference.setIcon(R.drawable.orbot_enabled_light);
1121 torHomepagePreference.setIcon(R.drawable.home_enabled_light);
1122 torSearchPreference.setIcon(R.drawable.search_enabled_light);
1124 // Set the `torSearchCustomURLPreference` icon.
1125 if (torSearchCustomURLPreference.isEnabled()) {
1126 torSearchCustomURLPreference.setIcon(R.drawable.search_custom_url_enabled_light);
1128 torSearchCustomURLPreference.setIcon(R.drawable.search_custom_url_ghosted_light);
1131 } else { // Proxy through Orbot is disabled.
1133 proxyThroughOrbotPreference.setIcon(R.drawable.orbot_disabled_dark);
1134 torHomepagePreference.setIcon(R.drawable.home_ghosted_dark);
1135 torSearchPreference.setIcon(R.drawable.search_ghosted_dark);
1136 torSearchCustomURLPreference.setIcon(R.drawable.search_custom_url_ghosted_dark);
1138 proxyThroughOrbotPreference.setIcon(R.drawable.orbot_disabled_light);
1139 torHomepagePreference.setIcon(R.drawable.home_ghosted_light);
1140 torSearchPreference.setIcon(R.drawable.search_ghosted_light);
1141 torSearchCustomURLPreference.setIcon(R.drawable.search_custom_url_ghosted_light);
1146 case "tor_homepage":
1147 // Set the new tor homepage URL as the summary text for the `tor_homepage` preference. The default is Searx: `http://ulrn6sryqaifefld.onion/`.
1148 torHomepagePreference.setSummary(sharedPreferences.getString("tor_homepage", getString(R.string.tor_homepage_default_value)));
1152 // Get the present search string.
1153 String presentTorSearchString = sharedPreferences.getString("tor_search", getString(R.string.tor_search_default_value));
1155 // Update the preferences.
1156 if (presentTorSearchString.equals("Custom URL")) {
1157 // Use `R.string.custom_url`, which is translated, as the summary instead of the array value, which isn't.
1158 torSearchPreference.setSummary(R.string.custom_url);
1160 // Enable `torSearchCustomURLPreference`.
1161 torSearchCustomURLPreference.setEnabled(true);
1163 // Update the `torSearchCustomURLPreference` icon.
1165 torSearchCustomURLPreference.setIcon(R.drawable.search_custom_url_enabled_dark);
1167 torSearchCustomURLPreference.setIcon(R.drawable.search_custom_url_enabled_light);
1170 // Set the array value as the summary text.
1171 torSearchPreference.setSummary(presentTorSearchString);
1173 // Disable `torSearchCustomURLPreference`.
1174 torSearchCustomURLPreference.setEnabled(false);
1176 // Update the `torSearchCustomURLPreference` icon.
1178 torSearchCustomURLPreference.setIcon(R.drawable.search_custom_url_ghosted_dark);
1180 torSearchCustomURLPreference.setIcon(R.drawable.search_custom_url_ghosted_light);
1185 case "tor_search_custom_url":
1186 // Set the summary text for `tor_search_custom_url`.
1187 torSearchCustomURLPreference.setSummary(sharedPreferences.getString("tor_search_custom_url", getString(R.string.tor_search_custom_url_default_value)));
1191 // Store the new search string.
1192 String newSearchString = sharedPreferences.getString("search", getString(R.string.search_default_value));
1194 // Update `searchPreference` and `searchCustomURLPreference`.
1195 if (newSearchString.equals("Custom URL")) { // `Custom URL` is selected.
1196 // Set the summary text to `R.string.custom_url`, which is translated.
1197 searchPreference.setSummary(R.string.custom_url);
1199 // Enable `searchCustomURLPreference`.
1200 searchCustomURLPreference.setEnabled(true);
1202 // Set the `searchCustomURLPreference` according to the theme.
1204 searchCustomURLPreference.setIcon(R.drawable.search_custom_url_enabled_dark);
1206 searchCustomURLPreference.setIcon(R.drawable.search_custom_url_enabled_light);
1208 } else { // `Custom URL` is not selected.
1209 // Set the summary text to `newSearchString`.
1210 searchPreference.setSummary(newSearchString);
1212 // Disable `searchCustomURLPreference`.
1213 searchCustomURLPreference.setEnabled(false);
1215 // Set the `searchCustomURLPreference` according to the theme.
1217 searchCustomURLPreference.setIcon(R.drawable.search_custom_url_ghosted_dark);
1219 searchCustomURLPreference.setIcon(R.drawable.search_custom_url_ghosted_light);
1224 case "search_custom_url":
1225 // Set the new custom search URL as the summary text for `search_custom_url`. The default is `""`.
1226 searchCustomURLPreference.setSummary(sharedPreferences.getString("search_custom_url", getString(R.string.search_custom_url_default_value)));
1229 case "full_screen_browsing_mode":
1230 if (sharedPreferences.getBoolean("full_screen_browsing_mode", false)) { // Full screen browsing is enabled.
1231 // Set the full screen browsing mode preference icon according to the theme.
1233 fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_enabled_dark);
1235 fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_enabled_light);
1238 // Set the hide app bar preference icon.
1239 if (sharedPreferences.getBoolean("hide_app_bar", true)) { // Hide app bar is enabled.
1240 // Set the icon according to the theme.
1242 hideAppBarPreference.setIcon(R.drawable.app_bar_enabled_dark);
1244 hideAppBarPreference.setIcon(R.drawable.app_bar_enabled_light);
1246 } else { // Hide app bar is disabled.
1247 // Set the icon according to the theme.
1249 hideAppBarPreference.setIcon(R.drawable.app_bar_disabled_dark);
1251 hideAppBarPreference.setIcon(R.drawable.app_bar_disabled_light);
1254 } else { // Full screen browsing is disabled.
1255 // Update the icons according to the theme.
1257 fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_disabled_dark);
1258 hideAppBarPreference.setIcon(R.drawable.app_bar_ghosted_dark);
1260 fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_disabled_light);
1261 hideAppBarPreference.setIcon(R.drawable.app_bar_ghosted_light);
1266 case "hide_app_bar":
1268 if (sharedPreferences.getBoolean("hide_app_bar", true)) { // Hide app bar is enabled.
1269 // Set the icon according to the theme.
1271 hideAppBarPreference.setIcon(R.drawable.app_bar_enabled_dark);
1273 hideAppBarPreference.setIcon(R.drawable.app_bar_enabled_light);
1275 } else { // Hide app bar is disabled.
1276 // Set the icon according to the theme.
1278 hideAppBarPreference.setIcon(R.drawable.app_bar_disabled_dark);
1280 hideAppBarPreference.setIcon(R.drawable.app_bar_disabled_light);
1285 case "clear_everything":
1286 // Store the new `clear_everything` status
1287 boolean newClearEverythingBoolean = sharedPreferences.getBoolean("clear_everything", true);
1289 // Update the status of the `Clear and Exit` preferences.
1290 clearCookiesPreference.setEnabled(!newClearEverythingBoolean);
1291 clearDomStoragePreference.setEnabled(!newClearEverythingBoolean);
1292 clearFormDataPreference.setEnabled(!newClearEverythingBoolean); // This line can be removed once the minimum API >= 26.
1293 clearCachePreference.setEnabled(!newClearEverythingBoolean);
1295 // Update the `clearEverythingPreference` icon.
1296 if (newClearEverythingBoolean) {
1298 clearEverythingPreference.setIcon(R.drawable.clear_everything_enabled_dark);
1300 clearEverythingPreference.setIcon(R.drawable.clear_everything_enabled_light);
1303 clearEverythingPreference.setIcon(R.drawable.clear_everything_disabled);
1306 // Update the `clearCookiesPreference` icon.
1307 if (newClearEverythingBoolean || sharedPreferences.getBoolean("clear_cookies", true)) {
1309 clearCookiesPreference.setIcon(R.drawable.cookies_cleared_dark);
1311 clearCookiesPreference.setIcon(R.drawable.cookies_cleared_light);
1314 clearCookiesPreference.setIcon(R.drawable.cookies_warning);
1317 // Update the `clearDomStoragePreference` icon.
1318 if (newClearEverythingBoolean || sharedPreferences.getBoolean("clear_dom_storage", true)) {
1320 clearDomStoragePreference.setIcon(R.drawable.dom_storage_cleared_dark);
1322 clearDomStoragePreference.setIcon(R.drawable.dom_storage_cleared_light);
1325 clearDomStoragePreference.setIcon(R.drawable.dom_storage_warning);
1328 // Update the clear form data preference icon if the API < 26.
1329 if (Build.VERSION.SDK_INT < 26) {
1330 if (newClearEverythingBoolean || sharedPreferences.getBoolean("clear_form_data", true)) {
1332 clearFormDataPreference.setIcon(R.drawable.form_data_cleared_dark);
1334 clearFormDataPreference.setIcon(R.drawable.form_data_cleared_light);
1337 clearFormDataPreference.setIcon(R.drawable.form_data_warning);
1341 // Update the `clearCachePreference` icon.
1342 if (newClearEverythingBoolean || sharedPreferences.getBoolean("clear_cache", true)) {
1344 clearCachePreference.setIcon(R.drawable.cache_cleared_dark);
1346 clearCachePreference.setIcon(R.drawable.cache_cleared_light);
1349 clearCachePreference.setIcon(R.drawable.cache_warning);
1353 case "clear_cookies":
1355 if (sharedPreferences.getBoolean("clear_cookies", true)) {
1357 clearCookiesPreference.setIcon(R.drawable.cookies_cleared_dark);
1359 clearCookiesPreference.setIcon(R.drawable.cookies_cleared_light);
1362 clearCookiesPreference.setIcon(R.drawable.cookies_warning);
1366 case "clear_dom_storage":
1368 if (sharedPreferences.getBoolean("clear_dom_storage", true)) {
1370 clearDomStoragePreference.setIcon(R.drawable.dom_storage_cleared_dark);
1372 clearDomStoragePreference.setIcon(R.drawable.dom_storage_cleared_light);
1375 clearDomStoragePreference.setIcon(R.drawable.dom_storage_warning);
1379 // This section can be removed once the minimum API >= 26.
1380 case "clear_form_data":
1382 if (sharedPreferences.getBoolean("clear_form_data", true)) {
1384 clearFormDataPreference.setIcon(R.drawable.form_data_cleared_dark);
1386 clearFormDataPreference.setIcon(R.drawable.form_data_cleared_light);
1389 clearFormDataPreference.setIcon(R.drawable.form_data_warning);
1395 if (sharedPreferences.getBoolean("clear_cache", true)) {
1397 clearCachePreference.setIcon(R.drawable.cache_cleared_dark);
1399 clearCachePreference.setIcon(R.drawable.cache_cleared_light);
1402 clearCachePreference.setIcon(R.drawable.cache_warning);
1407 // Set the new homepage URL as the summary text for the Homepage preference.
1408 homepagePreference.setSummary(sharedPreferences.getString("homepage", getString(R.string.homepage_default_value)));
1412 // Update the font size summary text.
1413 fontSizePreference.setSummary(sharedPreferences.getString("font_size", getString(R.string.font_size_default_value)) + "%%");
1416 case "swipe_to_refresh":
1418 if (sharedPreferences.getBoolean("swipe_to_refresh", true)) {
1420 swipeToRefreshPreference.setIcon(R.drawable.refresh_enabled_dark);
1422 swipeToRefreshPreference.setIcon(R.drawable.refresh_enabled_light);
1426 swipeToRefreshPreference.setIcon(R.drawable.refresh_disabled_dark);
1428 swipeToRefreshPreference.setIcon(R.drawable.refresh_disabled_light);
1433 case "scroll_app_bar":
1435 if (sharedPreferences.getBoolean("scroll_app_bar", true)) {
1437 scrollAppBarPreference.setIcon(R.drawable.app_bar_enabled_dark);
1439 scrollAppBarPreference.setIcon(R.drawable.app_bar_enabled_light);
1443 scrollAppBarPreference.setIcon(R.drawable.app_bar_disabled_dark);
1445 scrollAppBarPreference.setIcon(R.drawable.app_bar_disabled_light);
1450 case "display_additional_app_bar_icons":
1452 if (sharedPreferences.getBoolean("display_additional_app_bar_icons", false)) {
1454 displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_enabled_dark);
1456 displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_enabled_light);
1460 displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_disabled_dark);
1462 displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_disabled_light);
1467 case "download_with_external_app":
1469 if (sharedPreferences.getBoolean("download_with_external_app", false)) {
1471 downloadWithExternalAppPreference.setIcon(R.drawable.open_with_external_app_enabled_dark);
1473 downloadWithExternalAppPreference.setIcon(R.drawable.open_with_external_app_enabled_light);
1477 downloadWithExternalAppPreference.setIcon(R.drawable.open_with_external_app_disabled_dark);
1479 downloadWithExternalAppPreference.setIcon(R.drawable.open_with_external_app_disabled_light);
1486 if (sharedPreferences.getBoolean("dark_theme", false)) {
1487 darkThemePreference.setIcon(R.drawable.theme_dark);
1489 darkThemePreference.setIcon(R.drawable.theme_light);
1492 // Create an intent to restart Privacy Browser.
1493 Intent changeThemeRestartIntent = getActivity().getParentActivityIntent();
1495 // Assert that the intent is not null to remove the lint error below.
1496 assert changeThemeRestartIntent != null;
1498 // `Intent.FLAG_ACTIVITY_CLEAR_TASK` removes all activities from the stack. It requires `Intent.FLAG_ACTIVITY_NEW_TASK`.
1499 changeThemeRestartIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
1501 // Create a handler to restart the activity.
1502 Handler changeThemeRestartHandler = new Handler();
1504 // Create a runnable to restart the activity.
1505 Runnable changeThemeRestartRunnable = () -> {
1506 // Restart the activity.
1507 startActivity(changeThemeRestartIntent);
1509 // Kill this instance of Privacy Browser. Otherwise, the app exhibits sporadic behavior after the restart.
1513 // Restart the activity after 100 milliseconds, so that the app has enought time to save the change to the preference.
1514 changeThemeRestartHandler.postDelayed(changeThemeRestartRunnable, 100);
1518 // Store the current night mode status.
1519 boolean currentNightModeBoolean = sharedPreferences.getBoolean("night_mode", false);
1520 boolean currentJavaScriptBoolean = sharedPreferences.getBoolean("javascript", false);
1523 if (currentNightModeBoolean) {
1525 nightModePreference.setIcon(R.drawable.night_mode_enabled_dark);
1527 nightModePreference.setIcon(R.drawable.night_mode_enabled_light);
1531 nightModePreference.setIcon(R.drawable.night_mode_disabled_dark);
1533 nightModePreference.setIcon(R.drawable.night_mode_disabled_light);
1537 // Update the status of `javaScriptPreference` and `domStoragePreference`.
1538 javaScriptPreference.setEnabled(!currentNightModeBoolean);
1539 domStoragePreference.setEnabled(currentNightModeBoolean || currentJavaScriptBoolean);
1541 // Update the `javaScriptPreference` icon.
1542 if (currentNightModeBoolean || currentJavaScriptBoolean) {
1543 javaScriptPreference.setIcon(R.drawable.javascript_enabled);
1545 javaScriptPreference.setIcon(R.drawable.privacy_mode);
1548 // Update the DOM storage preference icon.
1549 if (currentNightModeBoolean || currentJavaScriptBoolean) { // The preference is enabled.
1550 if (sharedPreferences.getBoolean("dom_storage", false)) { // DOM storage is enabled.
1551 domStoragePreference.setIcon(R.drawable.dom_storage_enabled);
1552 } else { // DOM storage is disabled.
1554 domStoragePreference.setIcon(R.drawable.dom_storage_disabled_dark);
1556 domStoragePreference.setIcon(R.drawable.dom_storage_disabled_light);
1559 } else { // The preference is disabled. The icon should be ghosted.
1561 domStoragePreference.setIcon(R.drawable.dom_storage_ghosted_dark);
1563 domStoragePreference.setIcon(R.drawable.dom_storage_ghosted_light);
1568 case "display_webpage_images":
1569 if (sharedPreferences.getBoolean("display_webpage_images", true)) {
1572 displayWebpageImagesPreference.setIcon(R.drawable.images_enabled_dark);
1574 displayWebpageImagesPreference.setIcon(R.drawable.images_enabled_light);
1579 displayWebpageImagesPreference.setIcon(R.drawable.images_disabled_dark);
1581 displayWebpageImagesPreference.setIcon(R.drawable.images_disabled_light);
1588 // Register the listener.
1589 savedPreferences.registerOnSharedPreferenceChangeListener(preferencesListener);
1592 // 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.
1594 public void onPause() {
1596 savedPreferences.unregisterOnSharedPreferenceChangeListener(preferencesListener);
1600 public void onResume() {
1602 savedPreferences.registerOnSharedPreferenceChangeListener(preferencesListener);