]> gitweb.stoutner.com Git - PrivacyBrowserAndroid.git/blob - app/src/main/java/com/stoutner/privacybrowser/fragments/SettingsFragment.java
Add option to remove Facebook Click IDs from URLs. https://redmine.stoutner.com...
[PrivacyBrowserAndroid.git] / app / src / main / java / com / stoutner / privacybrowser / fragments / SettingsFragment.java
1 /*
2  * Copyright © 2016-2019 Soren Stoutner <soren@stoutner.com>.
3  *
4  * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
5  *
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.
10  *
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.
15  *
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/>.
18  */
19
20 package com.stoutner.privacybrowser.fragments;
21
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;
36
37 import com.stoutner.privacybrowser.R;
38 import com.stoutner.privacybrowser.activities.MainWebViewActivity;
39
40 public class SettingsFragment extends PreferenceFragment {
41     private SharedPreferences.OnSharedPreferenceChangeListener preferencesListener;
42     private SharedPreferences savedPreferences;
43
44     @Override
45     public void onCreate(Bundle savedInstanceState) {
46         // Run the default commands.
47         super.onCreate(savedInstanceState);
48
49         // Load the preferences from the XML file.
50         addPreferencesFromResource(R.xml.preferences);
51
52         // Get a handle for the context.
53         Context context = getActivity().getApplicationContext();
54
55         // Initialize savedPreferences.
56         savedPreferences = getPreferenceScreen().getSharedPreferences();
57
58         // Get handles for the preferences.
59         Preference javaScriptPreference = findPreference("javascript");
60         Preference firstPartyCookiesPreference = findPreference("first_party_cookies");
61         Preference thirdPartyCookiesPreference = findPreference("third_party_cookies");
62         Preference domStoragePreference = findPreference("dom_storage");
63         Preference formDataPreference = findPreference("save_form_data");  // The form data preference can be removed once the minimum API >= 26.
64         Preference userAgentPreference = findPreference("user_agent");
65         Preference customUserAgentPreference = findPreference("custom_user_agent");
66         Preference incognitoModePreference = findPreference("incognito_mode");
67         Preference doNotTrackPreference = findPreference("do_not_track");
68         Preference allowScreenshotsPreference = findPreference("allow_screenshots");
69         Preference easyListPreference = findPreference("easylist");
70         Preference easyPrivacyPreference = findPreference("easyprivacy");
71         Preference fanboyAnnoyanceListPreference = findPreference("fanboys_annoyance_list");
72         Preference fanboySocialBlockingListPreference = findPreference("fanboys_social_blocking_list");
73         Preference ultraPrivacyPreference = findPreference("ultraprivacy");
74         Preference blockAllThirdPartyRequestsPreference = findPreference("block_all_third_party_requests");
75         Preference googleAnalyticsPreference = findPreference("google_analytics");
76         Preference facebookClickIdsPreference = findPreference("facebook_click_ids");
77         Preference proxyThroughOrbotPreference = findPreference("proxy_through_orbot");
78         Preference torHomepagePreference = findPreference("tor_homepage");
79         Preference torSearchPreference = findPreference("tor_search");
80         Preference torSearchCustomURLPreference = findPreference("tor_search_custom_url");
81         Preference searchPreference = findPreference("search");
82         Preference searchCustomURLPreference = findPreference("search_custom_url");
83         Preference fullScreenBrowsingModePreference = findPreference("full_screen_browsing_mode");
84         Preference hideAppBarPreference = findPreference("hide_app_bar");
85         Preference clearEverythingPreference = findPreference("clear_everything");
86         Preference clearCookiesPreference = findPreference("clear_cookies");
87         Preference clearDomStoragePreference = findPreference("clear_dom_storage");
88         Preference clearFormDataPreference = findPreference("clear_form_data");  // The clear form data preference can be removed once the minimum API >= 26.
89         Preference clearCachePreference = findPreference("clear_cache");
90         Preference homepagePreference = findPreference("homepage");
91         Preference fontSizePreference = findPreference("font_size");
92         Preference openIntentsInNewTabPreference = findPreference("open_intents_in_new_tab");
93         Preference swipeToRefreshPreference = findPreference("swipe_to_refresh");
94         Preference scrollAppBarPreference = findPreference("scroll_app_bar");
95         Preference displayAdditionalAppBarIconsPreference = findPreference("display_additional_app_bar_icons");
96         Preference downloadWithExternalAppPreference = findPreference("download_with_external_app");
97         Preference darkThemePreference = findPreference("dark_theme");
98         Preference nightModePreference = findPreference("night_mode");
99         Preference displayWebpageImagesPreference = findPreference("display_webpage_images");
100
101         // Set dependencies.
102         torHomepagePreference.setDependency("proxy_through_orbot");
103         torSearchPreference.setDependency("proxy_through_orbot");
104         hideAppBarPreference.setDependency("full_screen_browsing_mode");
105
106         // Get strings from the preferences.
107         String torSearchString = savedPreferences.getString("tor_search", getString(R.string.tor_search_default_value));
108         String searchString = savedPreferences.getString("search", getString(R.string.search_default_value));
109
110         // Get booleans that are used in multiple places from the preferences.
111         boolean javaScriptEnabled = savedPreferences.getBoolean("javascript", false);
112         boolean firstPartyCookiesEnabled = savedPreferences.getBoolean("first_party_cookies", false);
113         boolean thirdPartyCookiesEnabled = savedPreferences.getBoolean("third_party_cookies", false);
114         boolean fanboyAnnoyanceListEnabled = savedPreferences.getBoolean("fanboys_annoyance_list", true);
115         boolean fanboySocialBlockingEnabled = savedPreferences.getBoolean("fanboys_social_blocking_list", true);
116         boolean proxyThroughOrbot = savedPreferences.getBoolean("proxy_through_orbot", false);
117         boolean fullScreenBrowsingMode = savedPreferences.getBoolean("full_screen_browsing_mode", false);
118         boolean clearEverything = savedPreferences.getBoolean("clear_everything", true);
119         boolean darkTheme = savedPreferences.getBoolean("dark_theme", false);
120         boolean nightMode = savedPreferences.getBoolean("night_mode", false);
121
122         // Only enable the third-party cookies preference if first-party cookies are enabled and API >= 21.
123         thirdPartyCookiesPreference.setEnabled(firstPartyCookiesEnabled && (Build.VERSION.SDK_INT >= 21));
124
125         // Only enable the DOM storage preference if either JavaScript or Night Mode is enabled.
126         domStoragePreference.setEnabled(javaScriptEnabled || nightMode);
127
128         // Remove the form data preferences if the API is >= 26 as they no longer do anything.
129         if (Build.VERSION.SDK_INT >= 26) {
130             // Get the categories.
131             PreferenceCategory privacyCategory = (PreferenceCategory) findPreference("privacy");
132             PreferenceCategory clearAndExitCategory = (PreferenceCategory) findPreference("clear_and_exit");
133
134             // Remove the form data preferences.
135             privacyCategory.removePreference(formDataPreference);
136             clearAndExitCategory.removePreference(clearFormDataPreference);
137         }
138
139         // Only enable Fanboy's social blocking list preference if Fanboy's annoyance list is disabled.
140         fanboySocialBlockingListPreference.setEnabled(!fanboyAnnoyanceListEnabled);
141
142         // Inflate a WebView to get the default user agent.
143         LayoutInflater inflater = getActivity().getLayoutInflater();
144         // `@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.
145         @SuppressLint("InflateParams") View bareWebViewLayout = inflater.inflate(R.layout.bare_webview, null, false);
146         WebView bareWebView = bareWebViewLayout.findViewById(R.id.bare_webview);
147
148         // Get the user agent arrays.
149         ArrayAdapter<CharSequence> userAgentNamesArray = ArrayAdapter.createFromResource(context, R.array.user_agent_names, R.layout.spinner_item);
150         String[] translatedUserAgentNamesArray = getResources().getStringArray(R.array.translated_user_agent_names);
151         String[] userAgentDataArray = getResources().getStringArray(R.array.user_agent_data);
152
153         // Get the current user agent name from the preference.
154         String userAgentName = savedPreferences.getString("user_agent", getString(R.string.user_agent_default_value));
155
156         // Get the array position of the user agent name.
157         int userAgentArrayPosition = userAgentNamesArray.getPosition(userAgentName);
158
159         // Populate the user agent summary.
160         switch (userAgentArrayPosition) {
161             case MainWebViewActivity.UNRECOGNIZED_USER_AGENT:  // The user agent name is not on the canonical list.
162                 // 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.
163                 userAgentPreference.setSummary(userAgentName);
164                 break;
165
166             case MainWebViewActivity.SETTINGS_WEBVIEW_DEFAULT_USER_AGENT:
167                 // Get the user agent text from the webview (which changes based on the version of Android and WebView installed).
168                 userAgentPreference.setSummary(translatedUserAgentNamesArray[userAgentArrayPosition] + ":\n" + bareWebView.getSettings().getUserAgentString());
169                 break;
170
171             case MainWebViewActivity.SETTINGS_CUSTOM_USER_AGENT:
172                 // Set the summary text.
173                 userAgentPreference.setSummary(R.string.custom_user_agent);
174                 break;
175
176             default:
177                 // Get the user agent summary from the user agent data array.
178                 userAgentPreference.setSummary(translatedUserAgentNamesArray[userAgentArrayPosition] + ":\n" + userAgentDataArray[userAgentArrayPosition]);
179         }
180
181         // Set the summary text for the custom user agent preference and enable it if user agent preference is set to custom.
182         customUserAgentPreference.setSummary(savedPreferences.getString("custom_user_agent", getString(R.string.custom_user_agent_default_value)));
183         customUserAgentPreference.setEnabled(userAgentPreference.getSummary().equals(getString(R.string.custom_user_agent)));
184
185
186         // 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/`.
187         torHomepagePreference.setSummary(savedPreferences.getString("tor_homepage", getString(R.string.tor_homepage_default_value)));
188
189
190         // Set the Tor search URL as the summary text for the Tor preference when the preference screen is loaded.
191         if (torSearchString.equals("Custom URL")) {
192             // Use R.string.custom_url, which will be translated, instead of the array value, which will not.
193             torSearchPreference.setSummary(R.string.custom_url);
194         } else {
195             // Set the array value as the summary text.
196             torSearchPreference.setSummary(torSearchString);
197         }
198
199         // Set the summary text for `tor_search_custom_url`.  The default is `""`.
200         torSearchCustomURLPreference.setSummary(savedPreferences.getString("tor_search_custom_url", getString(R.string.tor_search_custom_url_default_value)));
201
202         // Enable the Tor custom URL search options only if proxying through Orbot and the search is set to `Custom URL`.
203         torSearchCustomURLPreference.setEnabled(proxyThroughOrbot && torSearchString.equals("Custom URL"));
204
205
206         // Set the search URL as the summary text for the search preference when the preference screen is loaded.
207         if (searchString.equals("Custom URL")) {
208             // Use R.string.custom_url, which will be translated, instead of the array value, which will not.
209             searchPreference.setSummary(R.string.custom_url);
210         } else {
211             // Set the array value as the summary text.
212             searchPreference.setSummary(searchString);
213         }
214
215         // Set the summary text for `search_custom_url` (the default is `""`) and enable it if `search` is set to `Custom URL`.
216         searchCustomURLPreference.setSummary(savedPreferences.getString("search_custom_url", getString(R.string.search_custom_url_default_value)));
217         searchCustomURLPreference.setEnabled(searchString.equals("Custom URL"));
218
219         // Set the status of the Clear and Exit preferences.
220         clearCookiesPreference.setEnabled(!clearEverything);
221         clearDomStoragePreference.setEnabled(!clearEverything);
222         clearFormDataPreference.setEnabled(!clearEverything);  // The form data line can be removed once the minimum API is >= 26.
223         clearCachePreference.setEnabled(!clearEverything);
224
225         // Set the homepage URL as the summary text for the homepage preference.
226         homepagePreference.setSummary(savedPreferences.getString("homepage", getString(R.string.homepage_default_value)));
227
228         // Set the font size as the summary text for the preference.
229         fontSizePreference.setSummary(savedPreferences.getString("font_size", getString(R.string.font_size_default_value)) + "%%");
230
231         // Disable the JavaScript preference if Night Mode is enabled.  JavaScript will be enabled for all web pages.
232         javaScriptPreference.setEnabled(!nightMode);
233
234         // Set the JavaScript icon.
235         if (javaScriptEnabled || nightMode) {
236             javaScriptPreference.setIcon(R.drawable.javascript_enabled);
237         } else {
238             javaScriptPreference.setIcon(R.drawable.privacy_mode);
239         }
240
241         // Set the first-party cookies icon.
242         if (firstPartyCookiesEnabled) {
243             firstPartyCookiesPreference.setIcon(R.drawable.cookies_enabled);
244         } else {
245             if (darkTheme) {
246                 firstPartyCookiesPreference.setIcon(R.drawable.cookies_disabled_dark);
247             } else {
248                 firstPartyCookiesPreference.setIcon(R.drawable.cookies_disabled_light);
249             }
250         }
251
252         // Set the third party cookies icon.
253         if (firstPartyCookiesEnabled && Build.VERSION.SDK_INT >= 21) {
254             if (thirdPartyCookiesEnabled) {
255                 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_warning);
256             } else {
257                 if (darkTheme) {
258                     thirdPartyCookiesPreference.setIcon(R.drawable.cookies_disabled_dark);
259                 } else {
260                     thirdPartyCookiesPreference.setIcon(R.drawable.cookies_disabled_light);
261                 }
262             }
263         } else {
264             if (darkTheme) {
265                 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_ghosted_dark);
266             } else {
267                 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_ghosted_light);
268             }
269         }
270
271         // Set the DOM storage icon.
272         if (javaScriptEnabled || nightMode) {  // The preference is enabled.
273             if (savedPreferences.getBoolean("dom_storage", false)) {  // DOM storage is enabled.
274                 domStoragePreference.setIcon(R.drawable.dom_storage_enabled);
275             } else {  // DOM storage is disabled.
276                 if (darkTheme) {
277                     domStoragePreference.setIcon(R.drawable.dom_storage_disabled_dark);
278                 } else {
279                     domStoragePreference.setIcon(R.drawable.dom_storage_disabled_light);
280                 }
281             }
282         } else {  // The preference is disabled.  The icon should be ghosted.
283             if (darkTheme) {
284                 domStoragePreference.setIcon(R.drawable.dom_storage_ghosted_dark);
285             } else {
286                 domStoragePreference.setIcon(R.drawable.dom_storage_ghosted_light);
287             }
288         }
289
290         // Set the save form data icon if API < 26.  Save form data has no effect on API >= 26.
291         if (Build.VERSION.SDK_INT < 26) {
292             if (savedPreferences.getBoolean("save_form_data", false)) {
293                 formDataPreference.setIcon(R.drawable.form_data_enabled);
294             } else {
295                 if (darkTheme) {
296                     formDataPreference.setIcon(R.drawable.form_data_disabled_dark);
297                 } else {
298                     formDataPreference.setIcon(R.drawable.form_data_disabled_light);
299                 }
300             }
301         }
302
303         // Set the custom user agent icon.
304         if (customUserAgentPreference.isEnabled()) {
305             if (darkTheme) {
306                 customUserAgentPreference.setIcon(R.drawable.custom_user_agent_enabled_dark);
307             } else {
308                 customUserAgentPreference.setIcon(R.drawable.custom_user_agent_enabled_light);
309             }
310         } else {
311             if (darkTheme) {
312                 customUserAgentPreference.setIcon(R.drawable.custom_user_agent_ghosted_dark);
313             } else {
314                 customUserAgentPreference.setIcon(R.drawable.custom_user_agent_ghosted_light);
315             }
316         }
317
318         // Set the incognito mode icon.
319         if (savedPreferences.getBoolean("incognito_mode", false)) {
320             if (darkTheme) {
321                 incognitoModePreference.setIcon(R.drawable.incognito_mode_enabled_dark);
322             } else {
323                 incognitoModePreference.setIcon(R.drawable.incognito_mode_enabled_light);
324             }
325         } else {
326             if (darkTheme) {
327                 incognitoModePreference.setIcon(R.drawable.incognito_mode_disabled_dark);
328             } else {
329                 incognitoModePreference.setIcon(R.drawable.incognito_mode_disabled_light);
330             }
331         }
332
333         // Set the Do Not Track icon.
334         if (savedPreferences.getBoolean("do_not_track", false)) {
335             if (darkTheme) {
336                 doNotTrackPreference.setIcon(R.drawable.block_tracking_enabled_dark);
337             } else {
338                 doNotTrackPreference.setIcon(R.drawable.block_tracking_enabled_light);
339             }
340         } else {
341             if (darkTheme) {
342                 doNotTrackPreference.setIcon(R.drawable.block_tracking_disabled_dark);
343             } else {
344                 doNotTrackPreference.setIcon(R.drawable.block_tracking_disabled_light);
345             }
346         }
347
348         // Set the allow screenshots icon.
349         if (savedPreferences.getBoolean("allow_screenshots", false)) {
350             if (darkTheme) {
351                 allowScreenshotsPreference.setIcon(R.drawable.allow_screenshots_enabled_dark);
352             } else {
353                 allowScreenshotsPreference.setIcon(R.drawable.allow_screenshots_enabled_light);
354             }
355         } else {
356             if (darkTheme) {
357                 allowScreenshotsPreference.setIcon(R.drawable.allow_screenshots_disabled_dark);
358             } else {
359                 allowScreenshotsPreference.setIcon(R.drawable.allow_screenshots_disabled_light);
360             }
361         }
362
363         // Set the EasyList icon.
364         if (savedPreferences.getBoolean("easylist", true)) {
365             if (darkTheme) {
366                 easyListPreference.setIcon(R.drawable.block_ads_enabled_dark);
367             } else {
368                 easyListPreference.setIcon(R.drawable.block_ads_enabled_light);
369             }
370         } else {
371             if (darkTheme) {
372                 easyListPreference.setIcon(R.drawable.block_ads_disabled_dark);
373             } else {
374                 easyListPreference.setIcon(R.drawable.block_ads_disabled_light);
375             }
376         }
377
378         // Set the EasyPrivacy icon.
379         if (savedPreferences.getBoolean("easyprivacy", true)) {
380             if (darkTheme) {
381                 easyPrivacyPreference.setIcon(R.drawable.block_tracking_enabled_dark);
382             } else {
383                 easyPrivacyPreference.setIcon(R.drawable.block_tracking_enabled_light);
384             }
385         } else {
386             if (darkTheme) {
387                 easyPrivacyPreference.setIcon(R.drawable.block_tracking_disabled_dark);
388             } else {
389                 easyPrivacyPreference.setIcon(R.drawable.block_tracking_disabled_light);
390             }
391         }
392
393         // Set the Fanboy lists icons.
394         if (fanboyAnnoyanceListEnabled) {
395             if (darkTheme) {
396                 // Set the Fanboy annoyance list icon.
397                 fanboyAnnoyanceListPreference.setIcon(R.drawable.social_media_enabled_dark);
398
399                 // Set the Fanboy social blocking list icon.
400                 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_ghosted_dark);
401             } else {
402                 // Set the Fanboy annoyance list icon.
403                 fanboyAnnoyanceListPreference.setIcon(R.drawable.social_media_enabled_light);
404
405                 // Set the Fanboy social blocking list icon.
406                 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_ghosted_light);
407             }
408         } else {
409             if (darkTheme) {
410                 // Set the Fanboy annoyance list icon.
411                 fanboyAnnoyanceListPreference.setIcon(R.drawable.social_media_disabled_dark);
412
413                 // Set the Fanboy social blocking list icon.
414                 if (fanboySocialBlockingEnabled) {
415                     fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_enabled_dark);
416                 } else {
417                     fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_disabled_dark);
418                 }
419             } else {
420                 // Set the Fanboy annoyance list icon.
421                 fanboyAnnoyanceListPreference.setIcon(R.drawable.block_ads_disabled_light);
422
423                 // Set the Fanboy social blocking list icon.
424                 if (fanboySocialBlockingEnabled) {
425                     fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_enabled_light);
426                 } else {
427                     fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_disabled_light);
428                 }
429             }
430         }
431
432         // Set the UltraPrivacy icon.
433         if (savedPreferences.getBoolean("ultraprivacy", true)) {
434             if (darkTheme) {
435                 ultraPrivacyPreference.setIcon(R.drawable.block_tracking_enabled_dark);
436             } else {
437                 ultraPrivacyPreference.setIcon(R.drawable.block_tracking_enabled_light);
438             }
439         } else {
440             if (darkTheme) {
441                 ultraPrivacyPreference.setIcon(R.drawable.block_tracking_disabled_dark);
442             } else {
443                 ultraPrivacyPreference.setIcon(R.drawable.block_tracking_disabled_light);
444             }
445         }
446
447         // Set the block all third-party requests icon.
448         if (savedPreferences.getBoolean("block_all_third_party_requests", false)) {
449             if (darkTheme) {
450                 blockAllThirdPartyRequestsPreference.setIcon(R.drawable.block_all_third_party_requests_enabled_dark);
451             } else {
452                 blockAllThirdPartyRequestsPreference.setIcon(R.drawable.block_all_third_party_requests_enabled_light);
453             }
454         } else {
455             if (darkTheme) {
456                 blockAllThirdPartyRequestsPreference.setIcon(R.drawable.block_all_third_party_requests_disabled_dark);
457             } else {
458                 blockAllThirdPartyRequestsPreference.setIcon(R.drawable.block_all_third_party_requests_disabled_light);
459             }
460         }
461
462         // Set the Google Analytics icon according to the theme.
463         if (savedPreferences.getBoolean("google_analytics", true)) {
464             if (darkTheme) {
465                 googleAnalyticsPreference.setIcon(R.drawable.modify_url_enabled_dark);
466             } else {
467                 googleAnalyticsPreference.setIcon(R.drawable.modify_url_enabled_light);
468             }
469         } else {
470             if (darkTheme) {
471                 googleAnalyticsPreference.setIcon(R.drawable.modify_url_disabled_dark);
472             } else {
473                 googleAnalyticsPreference.setIcon(R.drawable.modify_url_disabled_light);
474             }
475         }
476
477         // Set the Facebook Click IDs icon according to the theme.
478         if (savedPreferences.getBoolean("facebook_click_ids", true)) {
479             if (darkTheme) {
480                 facebookClickIdsPreference.setIcon(R.drawable.modify_url_enabled_dark);
481             } else {
482                 facebookClickIdsPreference.setIcon(R.drawable.modify_url_enabled_light);
483             }
484         } else {
485             if (darkTheme) {
486                 facebookClickIdsPreference.setIcon(R.drawable.modify_url_disabled_dark);
487             } else {
488                 facebookClickIdsPreference.setIcon(R.drawable.modify_url_disabled_light);
489             }
490         }
491
492         // Set the Tor icons according to the theme.
493         if (proxyThroughOrbot) {  // Proxying is enabled.
494             if (darkTheme) {
495                 proxyThroughOrbotPreference.setIcon(R.drawable.orbot_enabled_dark);
496                 torHomepagePreference.setIcon(R.drawable.home_enabled_dark);
497                 torSearchPreference.setIcon(R.drawable.search_enabled_dark);
498
499                 // Set the custom search icon.
500                 if (torSearchCustomURLPreference.isEnabled()) {
501                     torSearchCustomURLPreference.setIcon(R.drawable.search_custom_url_enabled_dark);
502                 } else {
503                     torSearchCustomURLPreference.setIcon(R.drawable.search_custom_url_ghosted_dark);
504                 }
505             } else {
506                 proxyThroughOrbotPreference.setIcon(R.drawable.orbot_enabled_light);
507                 torHomepagePreference.setIcon(R.drawable.home_enabled_light);
508                 torSearchPreference.setIcon(R.drawable.search_enabled_light);
509
510                 // Set the custom search icon.
511                 if (torSearchCustomURLPreference.isEnabled()) {
512                     torSearchCustomURLPreference.setIcon(R.drawable.search_custom_url_enabled_light);
513                 } else {
514                     torSearchCustomURLPreference.setIcon(R.drawable.search_custom_url_ghosted_light);
515                 }
516             }
517         } else {  // Proxying is disabled.
518             if (darkTheme) {
519                 proxyThroughOrbotPreference.setIcon(R.drawable.orbot_disabled_dark);
520                 torHomepagePreference.setIcon(R.drawable.home_ghosted_dark);
521                 torSearchPreference.setIcon(R.drawable.search_ghosted_dark);
522                 torSearchCustomURLPreference.setIcon(R.drawable.search_custom_url_ghosted_dark);
523             } else {
524                 proxyThroughOrbotPreference.setIcon(R.drawable.orbot_disabled_light);
525                 torHomepagePreference.setIcon(R.drawable.home_ghosted_light);
526                 torSearchPreference.setIcon(R.drawable.search_ghosted_light);
527                 torSearchCustomURLPreference.setIcon(R.drawable.search_custom_url_ghosted_light);
528             }
529         }
530
531         // Set the search custom URL icon.
532         if (searchCustomURLPreference.isEnabled()) {
533             if (darkTheme) {
534                 searchCustomURLPreference.setIcon(R.drawable.search_custom_url_enabled_dark);
535             } else {
536                 searchCustomURLPreference.setIcon(R.drawable.search_custom_url_enabled_light);
537             }
538         } else {
539             if (darkTheme) {
540                 searchCustomURLPreference.setIcon(R.drawable.search_custom_url_ghosted_dark);
541             } else {
542                 searchCustomURLPreference.setIcon(R.drawable.search_custom_url_ghosted_light);
543             }
544         }
545
546         // Set the full screen browsing mode icons.
547         if (fullScreenBrowsingMode) {  // Full screen browsing mode is enabled.
548             // Set the `fullScreenBrowsingModePreference` icon according to the theme.
549             if (darkTheme) {
550                 fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_enabled_dark);
551             } else {
552                 fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_enabled_light);
553             }
554
555             // Set the hide app bar icon.
556             if (savedPreferences.getBoolean("hide_app_bar", true)) {  // Hide app bar is enabled.
557                 // Set the icon according to the theme.
558                 if (darkTheme) {
559                     hideAppBarPreference.setIcon(R.drawable.app_bar_enabled_dark);
560                 } else {
561                     hideAppBarPreference.setIcon(R.drawable.app_bar_enabled_light);
562                 }
563             } else {  // Hide app bar is disabled.
564                 // Set the icon according to the theme.
565                 if (darkTheme) {
566                     hideAppBarPreference.setIcon(R.drawable.app_bar_disabled_dark);
567                 } else {
568                     hideAppBarPreference.setIcon(R.drawable.app_bar_disabled_light);
569                 }
570             }
571         } else {  // Full screen browsing mode is disabled.
572             // Set the icons according to the theme.
573             if (darkTheme) {
574                 fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_disabled_dark);
575                 hideAppBarPreference.setIcon(R.drawable.app_bar_ghosted_dark);
576             } else {
577                 fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_disabled_light);
578                 hideAppBarPreference.setIcon(R.drawable.app_bar_ghosted_light);
579             }
580         }
581
582         // Set the clear everything preference icon.
583         if (clearEverything) {
584             if (darkTheme) {
585                 clearEverythingPreference.setIcon(R.drawable.clear_everything_enabled_dark);
586             } else {
587                 clearEverythingPreference.setIcon(R.drawable.clear_everything_enabled_light);
588             }
589         } else {
590             clearEverythingPreference.setIcon(R.drawable.clear_everything_disabled);
591         }
592
593         // Set the clear cookies preference icon.
594         if (clearEverything || savedPreferences.getBoolean("clear_cookies", true)) {
595             if (darkTheme) {
596                 clearCookiesPreference.setIcon(R.drawable.cookies_cleared_dark);
597             } else {
598                 clearCookiesPreference.setIcon(R.drawable.cookies_cleared_light);
599             }
600         } else {
601             clearCookiesPreference.setIcon(R.drawable.cookies_warning);
602         }
603
604         // Set the clear DOM storage preference icon.
605         if (clearEverything || savedPreferences.getBoolean("clear_dom_storage", true)) {
606             if (darkTheme) {
607                 clearDomStoragePreference.setIcon(R.drawable.dom_storage_cleared_dark);
608             } else {
609                 clearDomStoragePreference.setIcon(R.drawable.dom_storage_cleared_light);
610             }
611         } else {
612             clearDomStoragePreference.setIcon(R.drawable.dom_storage_warning);
613         }
614
615         // Set the clear form data preference icon if the API < 26.  It has no effect on newer versions of Android.
616         if (Build.VERSION.SDK_INT < 26) {
617             if (clearEverything || savedPreferences.getBoolean("clear_form_data", true)) {
618                 if (darkTheme) {
619                     clearFormDataPreference.setIcon(R.drawable.form_data_cleared_dark);
620                 } else {
621                     clearFormDataPreference.setIcon(R.drawable.form_data_cleared_light);
622                 }
623             } else {
624                 clearFormDataPreference.setIcon(R.drawable.form_data_warning);
625             }
626         }
627
628         // Set the clear cache preference icon.
629         if (clearEverything || savedPreferences.getBoolean("clear_cache", true)) {
630             if (darkTheme) {
631                 clearCachePreference.setIcon(R.drawable.cache_cleared_dark);
632             } else {
633                 clearCachePreference.setIcon(R.drawable.cache_cleared_light);
634             }
635         } else {
636             clearCachePreference.setIcon(R.drawable.cache_warning);
637         }
638
639         // Set the open intents in new tab preference icon.
640         if (savedPreferences.getBoolean("open_intents_in_new_tab", true)) {
641             if (darkTheme) {
642                 openIntentsInNewTabPreference.setIcon(R.drawable.tab_enabled_dark);
643             } else {
644                 openIntentsInNewTabPreference.setIcon(R.drawable.tab_enabled_light);
645             }
646         } else {
647             if (darkTheme) {
648                 openIntentsInNewTabPreference.setIcon(R.drawable.tab_disabled_dark);
649             } else {
650                 openIntentsInNewTabPreference.setIcon(R.drawable.tab_disabled_light);
651             }
652         }
653
654         // Set the swipe to refresh preference icon.
655         if (savedPreferences.getBoolean("swipe_to_refresh", true)) {
656             if (darkTheme) {
657                 swipeToRefreshPreference.setIcon(R.drawable.refresh_enabled_dark);
658             } else {
659                 swipeToRefreshPreference.setIcon(R.drawable.refresh_enabled_light);
660             }
661         } else {
662             if (darkTheme) {
663                 swipeToRefreshPreference.setIcon(R.drawable.refresh_disabled_dark);
664             } else {
665                 swipeToRefreshPreference.setIcon(R.drawable.refresh_disabled_light);
666             }
667         }
668
669         // Set the scroll app bar preference icon.
670         if (savedPreferences.getBoolean("scroll_app_bar", true)) {
671             if (darkTheme) {
672                 scrollAppBarPreference.setIcon(R.drawable.app_bar_enabled_dark);
673             } else {
674                 scrollAppBarPreference.setIcon(R.drawable.app_bar_enabled_light);
675             }
676         } else {
677             if (darkTheme) {
678                 scrollAppBarPreference.setIcon(R.drawable.app_bar_disabled_dark);
679             } else {
680                 scrollAppBarPreference.setIcon(R.drawable.app_bar_disabled_light);
681             }
682         }
683
684         // Set the display additional app bar icons preference icon.
685         if (savedPreferences.getBoolean("display_additional_app_bar_icons", false)) {
686             if (darkTheme) {
687                 displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_enabled_dark);
688             } else {
689                 displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_enabled_light);
690             }
691         } else {
692             if (darkTheme) {
693                 displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_disabled_dark);
694             } else {
695                 displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_disabled_light);
696             }
697         }
698
699         // Set the download with external app preference icon.
700         if (savedPreferences.getBoolean("download_with_external_app", false)) {
701             if (darkTheme) {
702                 downloadWithExternalAppPreference.setIcon(R.drawable.open_with_external_app_enabled_dark);
703             } else {
704                 downloadWithExternalAppPreference.setIcon(R.drawable.open_with_external_app_enabled_light);
705             }
706         } else {
707             if (darkTheme) {
708                 downloadWithExternalAppPreference.setIcon(R.drawable.open_with_external_app_disabled_dark);
709             } else {
710                 downloadWithExternalAppPreference.setIcon(R.drawable.open_with_external_app_disabled_light);
711             }
712         }
713
714         // Set the dark theme preference icon.
715         if (savedPreferences.getBoolean("dark_theme", false)) {
716             darkThemePreference.setIcon(R.drawable.theme_dark);
717         } else {
718             darkThemePreference.setIcon(R.drawable.theme_light);
719         }
720
721         // Set the night mode preference icon.
722         if (nightMode) {
723             if (darkTheme) {
724                 nightModePreference.setIcon(R.drawable.night_mode_enabled_dark);
725             } else {
726                 nightModePreference.setIcon(R.drawable.night_mode_enabled_light);
727             }
728         } else {
729             if (darkTheme) {
730                 nightModePreference.setIcon(R.drawable.night_mode_disabled_dark);
731             } else {
732                 nightModePreference.setIcon(R.drawable.night_mode_disabled_light);
733             }
734         }
735
736         // Set the display webpage images preference icon.
737         if (savedPreferences.getBoolean("display_webpage_images", true)) {
738             if (darkTheme) {
739                 displayWebpageImagesPreference.setIcon(R.drawable.images_enabled_dark);
740             } else {
741                 displayWebpageImagesPreference.setIcon(R.drawable.images_enabled_light);
742             }
743         } else {
744             if (darkTheme) {
745                 displayWebpageImagesPreference.setIcon(R.drawable.images_disabled_dark);
746             } else {
747                 displayWebpageImagesPreference.setIcon(R.drawable.images_disabled_light);
748             }
749         }
750
751
752         // Listen for preference changes.
753         preferencesListener = (SharedPreferences sharedPreferences, String key) -> {
754             switch (key) {
755                 case "javascript":
756                     // Update the icons and the DOM storage preference status.
757                     if (sharedPreferences.getBoolean("javascript", false)) {  // The JavaScript preference is enabled.
758                         // Update the icon for the JavaScript preference.
759                         javaScriptPreference.setIcon(R.drawable.javascript_enabled);
760
761                         // Update the status of the DOM storage preference.
762                         domStoragePreference.setEnabled(true);
763
764                         // Update the icon for the DOM storage preference.
765                         if (sharedPreferences.getBoolean("dom_storage", false)) {
766                             domStoragePreference.setIcon(R.drawable.dom_storage_enabled);
767                         } else {
768                             if (darkTheme) {
769                                 domStoragePreference.setIcon(R.drawable.dom_storage_disabled_dark);
770                             } else {
771                                 domStoragePreference.setIcon(R.drawable.dom_storage_disabled_light);
772                             }
773                         }
774                     } else {  // The JavaScript preference is disabled.
775                         // Update the icon for the JavaScript preference.
776                         javaScriptPreference.setIcon(R.drawable.privacy_mode);
777
778                         // Update the status of the DOM storage preference.
779                         domStoragePreference.setEnabled(false);
780
781                         // Set the icon for DOM storage preference to be ghosted.
782                         if (darkTheme) {
783                             domStoragePreference.setIcon(R.drawable.dom_storage_ghosted_dark);
784                         } else {
785                             domStoragePreference.setIcon(R.drawable.dom_storage_ghosted_light);
786                         }
787                     }
788                     break;
789
790                 case "first_party_cookies":
791                     // Update the icons for `first_party_cookies` and `third_party_cookies`.
792                     if (sharedPreferences.getBoolean("first_party_cookies", false)) {
793                         // Set the icon for `first_party_cookies`.
794                         firstPartyCookiesPreference.setIcon(R.drawable.cookies_enabled);
795
796                         // Update the icon for `third_party_cookies`.
797                         if (Build.VERSION.SDK_INT >= 21) {
798                             if (sharedPreferences.getBoolean("third_party_cookies", false)) {
799                                 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_warning);
800                             } else {
801                                 if (darkTheme) {
802                                     thirdPartyCookiesPreference.setIcon(R.drawable.cookies_disabled_dark);
803                                 } else {
804                                     thirdPartyCookiesPreference.setIcon(R.drawable.cookies_disabled_light);
805                                 }
806                             }
807                         } else {
808                             if (darkTheme) {
809                                 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_ghosted_dark);
810                             } else {
811                                 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_ghosted_light);
812                             }
813                         }
814                     } else {  // `first_party_cookies` is `false`.
815                         // Update the icon for `first_party_cookies`.
816                         if (darkTheme) {
817                             firstPartyCookiesPreference.setIcon(R.drawable.cookies_disabled_dark);
818                         } else {
819                             firstPartyCookiesPreference.setIcon(R.drawable.cookies_disabled_light);
820                         }
821
822                         // Set the icon for `third_party_cookies` to be ghosted.
823                         if (darkTheme) {
824                             thirdPartyCookiesPreference.setIcon(R.drawable.cookies_ghosted_dark);
825                         } else {
826                             thirdPartyCookiesPreference.setIcon(R.drawable.cookies_ghosted_light);
827                         }
828                     }
829
830                     // Enable `third_party_cookies` if `first_party_cookies` is `true` and API >= 21.
831                     thirdPartyCookiesPreference.setEnabled(sharedPreferences.getBoolean("first_party_cookies", false) && (Build.VERSION.SDK_INT >= 21));
832                     break;
833
834                 case "third_party_cookies":
835                     // Update the icon.
836                     if (sharedPreferences.getBoolean("third_party_cookies", false)) {
837                         thirdPartyCookiesPreference.setIcon(R.drawable.cookies_warning);
838                     } else {
839                         if (darkTheme) {
840                             thirdPartyCookiesPreference.setIcon(R.drawable.cookies_disabled_dark);
841                         } else {
842                             thirdPartyCookiesPreference.setIcon(R.drawable.cookies_disabled_light);
843                         }
844                     }
845                     break;
846
847                 case "dom_storage":
848                     // Update the icon.
849                     if (sharedPreferences.getBoolean("dom_storage", false)) {
850                         domStoragePreference.setIcon(R.drawable.dom_storage_enabled);
851                     } else {
852                         if (darkTheme) {
853                             domStoragePreference.setIcon(R.drawable.dom_storage_disabled_dark);
854                         } else {
855                             domStoragePreference.setIcon(R.drawable.dom_storage_disabled_light);
856                         }
857                     }
858                     break;
859
860                 // Save form data can be removed once the minimum API >= 26.
861                 case "save_form_data":
862                     // Update the icon.
863                     if (sharedPreferences.getBoolean("save_form_data", false)) {
864                         formDataPreference.setIcon(R.drawable.form_data_enabled);
865                     } else {
866                         if (darkTheme) {
867                             formDataPreference.setIcon(R.drawable.form_data_disabled_dark);
868                         } else {
869                             formDataPreference.setIcon(R.drawable.form_data_disabled_light);
870                         }
871                     }
872                     break;
873
874                 case "user_agent":
875                     // Get the new user agent name.
876                     String newUserAgentName = sharedPreferences.getString("user_agent", getString(R.string.user_agent_default_value));
877
878                     // Get the array position for the new user agent name.
879                     int newUserAgentArrayPosition = userAgentNamesArray.getPosition(newUserAgentName);
880
881                     // Get the translated new user agent name.
882                     String translatedNewUserAgentName = translatedUserAgentNamesArray[newUserAgentArrayPosition];
883
884                     // Populate the user agent summary.
885                     switch (newUserAgentArrayPosition) {
886                         case MainWebViewActivity.SETTINGS_WEBVIEW_DEFAULT_USER_AGENT:
887                             // Get the user agent text from the webview (which changes based on the version of Android and WebView installed).
888                             userAgentPreference.setSummary(translatedNewUserAgentName + ":\n" + bareWebView.getSettings().getUserAgentString());
889
890                             // Disable the custom user agent preference.
891                             customUserAgentPreference.setEnabled(false);
892
893                             // Set the custom user agent preference icon according to the theme.
894                             if (darkTheme) {
895                                 customUserAgentPreference.setIcon(R.drawable.custom_user_agent_ghosted_dark);
896                             } else {
897                                 customUserAgentPreference.setIcon(R.drawable.custom_user_agent_ghosted_light);
898                             }
899                             break;
900
901                         case MainWebViewActivity.SETTINGS_CUSTOM_USER_AGENT:
902                             // Set the summary text.
903                             userAgentPreference.setSummary(R.string.custom_user_agent);
904
905                             // Enable the custom user agent preference.
906                             customUserAgentPreference.setEnabled(true);
907
908                             // Set the custom user agent preference icon according to the theme.
909                             if (darkTheme) {
910                                 customUserAgentPreference.setIcon(R.drawable.custom_user_agent_enabled_dark);
911                             } else {
912                                 customUserAgentPreference.setIcon(R.drawable.custom_user_agent_enabled_light);
913                             }
914                             break;
915
916                         default:
917                             // Get the user agent summary from the user agent data array.
918                             userAgentPreference.setSummary(translatedNewUserAgentName + ":\n" + userAgentDataArray[newUserAgentArrayPosition]);
919
920                             // Disable the custom user agent preference.
921                             customUserAgentPreference.setEnabled(false);
922
923                             // Set the custom user agent preference icon according to the theme.
924                             if (darkTheme) {
925                                 customUserAgentPreference.setIcon(R.drawable.custom_user_agent_ghosted_dark);
926                             } else {
927                                 customUserAgentPreference.setIcon(R.drawable.custom_user_agent_ghosted_light);
928                             }
929                     }
930                     break;
931
932                 case "custom_user_agent":
933                     // Set the new custom user agent as the summary text for the preference.
934                     customUserAgentPreference.setSummary(sharedPreferences.getString("custom_user_agent", getString(R.string.custom_user_agent_default_value)));
935                     break;
936
937                 case "incognito_mode":
938                     // Update the icon.
939                     if (sharedPreferences.getBoolean("incognito_mode", false)) {
940                         if (darkTheme) {
941                             incognitoModePreference.setIcon(R.drawable.incognito_mode_enabled_dark);
942                         } else {
943                             incognitoModePreference.setIcon(R.drawable.incognito_mode_enabled_light);
944                         }
945                     } else {
946                         if (darkTheme) {
947                             incognitoModePreference.setIcon(R.drawable.incognito_mode_disabled_dark);
948                         } else {
949                             incognitoModePreference.setIcon(R.drawable.incognito_mode_disabled_light);
950                         }
951                     }
952                     break;
953
954                 case "do_not_track":
955                     // Update the icon.
956                     if (sharedPreferences.getBoolean("do_not_track", false)) {
957                         if (darkTheme) {
958                             doNotTrackPreference.setIcon(R.drawable.block_tracking_enabled_dark);
959                         } else {
960                             doNotTrackPreference.setIcon(R.drawable.block_tracking_enabled_light);
961                         }
962                     } else {
963                         if (darkTheme) {
964                             doNotTrackPreference.setIcon(R.drawable.block_tracking_disabled_dark);
965                         } else {
966                             doNotTrackPreference.setIcon(R.drawable.block_tracking_disabled_light);
967                         }
968                     }
969
970                     break;
971
972                 case "allow_screenshots":
973                     // Update the icon.
974                     if (sharedPreferences.getBoolean("allow_screenshots", false)) {
975                         if (darkTheme) {
976                             allowScreenshotsPreference.setIcon(R.drawable.allow_screenshots_enabled_dark);
977                         } else {
978                             allowScreenshotsPreference.setIcon(R.drawable.allow_screenshots_enabled_light);
979                         }
980                     } else {
981                         if (darkTheme) {
982                             allowScreenshotsPreference.setIcon(R.drawable.allow_screenshots_disabled_dark);
983                         } else {
984                             allowScreenshotsPreference.setIcon(R.drawable.allow_screenshots_disabled_light);
985                         }
986                     }
987
988                     // Create an intent to restart Privacy Browser.
989                     Intent allowScreenshotsRestartIntent = getActivity().getParentActivityIntent();
990
991                     // Assert that the intent is not null to remove the lint error below.
992                     assert allowScreenshotsRestartIntent != null;
993
994                     // `Intent.FLAG_ACTIVITY_CLEAR_TASK` removes all activities from the stack.  It requires `Intent.FLAG_ACTIVITY_NEW_TASK`.
995                     allowScreenshotsRestartIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
996
997                     // Create a handler to restart the activity.
998                     Handler allowScreenshotsRestartHandler = new Handler();
999
1000                     // Create a runnable to restart the activity.
1001                     Runnable allowScreenshotsRestartRunnable = () -> {
1002                         // Restart the activity.
1003                         startActivity(allowScreenshotsRestartIntent);
1004
1005                         // Kill this instance of Privacy Browser.  Otherwise, the app exhibits sporadic behavior after the restart.
1006                         System.exit(0);
1007                     };
1008
1009                     // Restart the activity after 100 milliseconds, so that the app has enough time to save the change to the preference.
1010                     allowScreenshotsRestartHandler.postDelayed(allowScreenshotsRestartRunnable, 100);
1011                     break;
1012
1013                 case "easylist":
1014                     // Update the icon.
1015                     if (sharedPreferences.getBoolean("easylist", true)) {
1016                         if (darkTheme) {
1017                             easyListPreference.setIcon(R.drawable.block_ads_enabled_dark);
1018                         } else {
1019                             easyListPreference.setIcon(R.drawable.block_ads_enabled_light);
1020                         }
1021                     } else {
1022                         if (darkTheme) {
1023                             easyListPreference.setIcon(R.drawable.block_ads_disabled_dark);
1024                         } else {
1025                             easyListPreference.setIcon(R.drawable.block_ads_disabled_light);
1026                         }
1027                     }
1028                     break;
1029
1030                 case "easyprivacy":
1031                     // Update the icon.
1032                     if (sharedPreferences.getBoolean("easyprivacy", true)) {
1033                         if (darkTheme) {
1034                             easyPrivacyPreference.setIcon(R.drawable.block_tracking_enabled_dark);
1035                         } else {
1036                             easyPrivacyPreference.setIcon(R.drawable.block_tracking_enabled_light);
1037                         }
1038                     } else {
1039                         if (darkTheme) {
1040                             easyPrivacyPreference.setIcon(R.drawable.block_tracking_disabled_dark);
1041                         } else {
1042                             easyPrivacyPreference.setIcon(R.drawable.block_tracking_disabled_light);
1043                         }
1044                     }
1045                     break;
1046
1047                 case "fanboys_annoyance_list":
1048                     boolean currentFanboyAnnoyanceList = sharedPreferences.getBoolean("fanboys_annoyance_list", true);
1049                     boolean currentFanboySocialBlockingList = sharedPreferences.getBoolean("fanboys_social_blocking_list", true);
1050
1051                     // Update the Fanboy icons.
1052                     if (currentFanboyAnnoyanceList) {  // Fanboy's annoyance list is enabled.
1053                         if (darkTheme) {
1054                             // Update the Fanboy's annoyance list icon.
1055                             fanboyAnnoyanceListPreference.setIcon(R.drawable.social_media_enabled_dark);
1056
1057                             // Update the Fanboy's social blocking list icon.
1058                             fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_ghosted_dark);
1059                         } else {
1060                             // Update the Fanboy's annoyance list icon.
1061                             fanboyAnnoyanceListPreference.setIcon(R.drawable.social_media_enabled_light);
1062
1063                             // Update the Fanboy's social blocking list icon.
1064                             fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_ghosted_light);
1065                         }
1066                     } else {  // Fanboy's annoyance list is disabled.
1067                         if (darkTheme) {
1068                             // Update the Fanboy's annoyance list icon.
1069                             fanboyAnnoyanceListPreference.setIcon(R.drawable.social_media_disabled_dark);
1070
1071                             // Update the Fanboy's social blocking list icon.
1072                             if (currentFanboySocialBlockingList) {
1073                                 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_enabled_dark);
1074                             } else {
1075                                 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_disabled_dark);
1076                             }
1077                         } else {
1078                             // Update the Fanboy's annoyance list icon.
1079                             fanboyAnnoyanceListPreference.setIcon(R.drawable.social_media_disabled_light);
1080
1081                             // Update the Fanboy's social blocking list icon.
1082                             if (currentFanboySocialBlockingList) {
1083                                 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_enabled_light);
1084                             } else {
1085                                 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_disabled_light);
1086                             }
1087                         }
1088                     }
1089
1090                     // Only enable Fanboy's social blocking list preference if Fanboy's annoyance list preference is disabled.
1091                     fanboySocialBlockingListPreference.setEnabled(!currentFanboyAnnoyanceList);
1092                     break;
1093
1094                 case "fanboys_social_blocking_list":
1095                     // Update the icon.
1096                     if (sharedPreferences.getBoolean("fanboys_social_blocking_list", true)) {
1097                         if (darkTheme) {
1098                             fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_enabled_dark);
1099                         } else {
1100                             fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_enabled_light);
1101                         }
1102                     } else {
1103                         if (darkTheme) {
1104                             fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_disabled_dark);
1105                         } else {
1106                             fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_disabled_light);
1107                         }
1108                     }
1109                     break;
1110
1111                 case "ultraprivacy":
1112                     // Update the icon.
1113                     if (sharedPreferences.getBoolean("ultraprivacy", true)) {
1114                         if (darkTheme) {
1115                             ultraPrivacyPreference.setIcon(R.drawable.block_tracking_enabled_dark);
1116                         } else {
1117                             ultraPrivacyPreference.setIcon(R.drawable.block_tracking_enabled_light);
1118                         }
1119                     } else {
1120                         if (darkTheme) {
1121                             ultraPrivacyPreference.setIcon(R.drawable.block_tracking_disabled_dark);
1122                         } else {
1123                             ultraPrivacyPreference.setIcon(R.drawable.block_tracking_disabled_light);
1124                         }
1125                     }
1126                     break;
1127
1128                 case "block_all_third_party_requests":
1129                     // Update the icon.
1130                     if (sharedPreferences.getBoolean("block_all_third_party_requests", false)) {
1131                         if (darkTheme) {
1132                             blockAllThirdPartyRequestsPreference.setIcon(R.drawable.block_all_third_party_requests_enabled_dark);
1133                         } else {
1134                             blockAllThirdPartyRequestsPreference.setIcon(R.drawable.block_all_third_party_requests_enabled_light);
1135                         }
1136                     } else {
1137                         if (darkTheme) {
1138                             blockAllThirdPartyRequestsPreference.setIcon(R.drawable.block_all_third_party_requests_disabled_dark);
1139                         } else {
1140                             blockAllThirdPartyRequestsPreference.setIcon(R.drawable.block_all_third_party_requests_disabled_light);
1141                         }
1142                     }
1143                     break;
1144
1145                 case "google_analytics":
1146                     // Update the icon.
1147                     if (sharedPreferences.getBoolean("google_analytics", true)) {
1148                         if (darkTheme) {
1149                             googleAnalyticsPreference.setIcon(R.drawable.modify_url_enabled_dark);
1150                         } else {
1151                             googleAnalyticsPreference.setIcon(R.drawable.modify_url_enabled_light);
1152                         }
1153                     } else {
1154                         if (darkTheme) {
1155                             googleAnalyticsPreference.setIcon(R.drawable.modify_url_disabled_dark);
1156                         } else {
1157                             googleAnalyticsPreference.setIcon(R.drawable.modify_url_disabled_light);
1158                         }
1159                     }
1160                     break;
1161
1162                 case "facebook_click_ids":
1163                     // Update the icon.
1164                     if (sharedPreferences.getBoolean("facebook_click_ids", true)) {
1165                         if (darkTheme) {
1166                             facebookClickIdsPreference.setIcon(R.drawable.modify_url_enabled_dark);
1167                         } else {
1168                             facebookClickIdsPreference.setIcon(R.drawable.modify_url_enabled_light);
1169                         }
1170                     } else {
1171                         if (darkTheme) {
1172                             facebookClickIdsPreference.setIcon(R.drawable.modify_url_disabled_dark);
1173                         } else {
1174                             facebookClickIdsPreference.setIcon(R.drawable.modify_url_disabled_light);
1175                         }
1176                     }
1177                     break;
1178
1179                 case "proxy_through_orbot":
1180                     // Get current settings.
1181                     boolean currentProxyThroughOrbot = sharedPreferences.getBoolean("proxy_through_orbot", false);
1182                     String currentTorSearchString = sharedPreferences.getString("tor_search", getString(R.string.tor_search_default_value));
1183
1184                     // Enable the Tor custom URL search option only if `currentProxyThroughOrbot` is true and the search is set to `Custom URL`.
1185                     torSearchCustomURLPreference.setEnabled(currentProxyThroughOrbot && currentTorSearchString.equals("Custom URL"));
1186
1187                     // Update the icons.
1188                     if (currentProxyThroughOrbot) {
1189                         // Set the Tor icons according to the theme.
1190                         if (darkTheme) {
1191                             proxyThroughOrbotPreference.setIcon(R.drawable.orbot_enabled_dark);
1192                             torHomepagePreference.setIcon(R.drawable.home_enabled_dark);
1193                             torSearchPreference.setIcon(R.drawable.search_enabled_dark);
1194
1195                             // Set the `torSearchCustomURLPreference` icon.
1196                             if (torSearchCustomURLPreference.isEnabled()) {
1197                                 torSearchCustomURLPreference.setIcon(R.drawable.search_custom_url_enabled_dark);
1198                             } else {
1199                                 torSearchCustomURLPreference.setIcon(R.drawable.search_custom_url_ghosted_dark);
1200                             }
1201                         } else {
1202                             proxyThroughOrbotPreference.setIcon(R.drawable.orbot_enabled_light);
1203                             torHomepagePreference.setIcon(R.drawable.home_enabled_light);
1204                             torSearchPreference.setIcon(R.drawable.search_enabled_light);
1205
1206                             // Set the `torSearchCustomURLPreference` icon.
1207                             if (torSearchCustomURLPreference.isEnabled()) {
1208                                 torSearchCustomURLPreference.setIcon(R.drawable.search_custom_url_enabled_light);
1209                             } else {
1210                                 torSearchCustomURLPreference.setIcon(R.drawable.search_custom_url_ghosted_light);
1211                             }
1212                         }
1213                     } else {  // Proxy through Orbot is disabled.
1214                         if (darkTheme) {
1215                             proxyThroughOrbotPreference.setIcon(R.drawable.orbot_disabled_dark);
1216                             torHomepagePreference.setIcon(R.drawable.home_ghosted_dark);
1217                             torSearchPreference.setIcon(R.drawable.search_ghosted_dark);
1218                             torSearchCustomURLPreference.setIcon(R.drawable.search_custom_url_ghosted_dark);
1219                         } else {
1220                             proxyThroughOrbotPreference.setIcon(R.drawable.orbot_disabled_light);
1221                             torHomepagePreference.setIcon(R.drawable.home_ghosted_light);
1222                             torSearchPreference.setIcon(R.drawable.search_ghosted_light);
1223                             torSearchCustomURLPreference.setIcon(R.drawable.search_custom_url_ghosted_light);
1224                         }
1225                     }
1226                     break;
1227
1228                 case "tor_homepage":
1229                     // Set the new tor homepage URL as the summary text for the `tor_homepage` preference.  The default is Searx:  `http://ulrn6sryqaifefld.onion/`.
1230                     torHomepagePreference.setSummary(sharedPreferences.getString("tor_homepage", getString(R.string.tor_homepage_default_value)));
1231                     break;
1232
1233                 case "tor_search":
1234                     // Get the present search string.
1235                     String presentTorSearchString = sharedPreferences.getString("tor_search", getString(R.string.tor_search_default_value));
1236
1237                     // Update the preferences.
1238                     if (presentTorSearchString.equals("Custom URL")) {
1239                         // Use `R.string.custom_url`, which is translated, as the summary instead of the array value, which isn't.
1240                         torSearchPreference.setSummary(R.string.custom_url);
1241
1242                         // Enable `torSearchCustomURLPreference`.
1243                         torSearchCustomURLPreference.setEnabled(true);
1244
1245                         // Update the `torSearchCustomURLPreference` icon.
1246                         if (darkTheme) {
1247                             torSearchCustomURLPreference.setIcon(R.drawable.search_custom_url_enabled_dark);
1248                         } else {
1249                             torSearchCustomURLPreference.setIcon(R.drawable.search_custom_url_enabled_light);
1250                         }
1251                     } else {
1252                         // Set the array value as the summary text.
1253                         torSearchPreference.setSummary(presentTorSearchString);
1254
1255                         // Disable `torSearchCustomURLPreference`.
1256                         torSearchCustomURLPreference.setEnabled(false);
1257
1258                         // Update the `torSearchCustomURLPreference` icon.
1259                         if (darkTheme) {
1260                             torSearchCustomURLPreference.setIcon(R.drawable.search_custom_url_ghosted_dark);
1261                         } else {
1262                             torSearchCustomURLPreference.setIcon(R.drawable.search_custom_url_ghosted_light);
1263                         }
1264                     }
1265                     break;
1266
1267                 case "tor_search_custom_url":
1268                     // Set the summary text for `tor_search_custom_url`.
1269                     torSearchCustomURLPreference.setSummary(sharedPreferences.getString("tor_search_custom_url", getString(R.string.tor_search_custom_url_default_value)));
1270                     break;
1271
1272                 case "search":
1273                     // Store the new search string.
1274                     String newSearchString = sharedPreferences.getString("search", getString(R.string.search_default_value));
1275
1276                     // Update `searchPreference` and `searchCustomURLPreference`.
1277                     if (newSearchString.equals("Custom URL")) {  // `Custom URL` is selected.
1278                         // Set the summary text to `R.string.custom_url`, which is translated.
1279                         searchPreference.setSummary(R.string.custom_url);
1280
1281                         // Enable `searchCustomURLPreference`.
1282                         searchCustomURLPreference.setEnabled(true);
1283
1284                         // Set the `searchCustomURLPreference` according to the theme.
1285                         if (darkTheme) {
1286                             searchCustomURLPreference.setIcon(R.drawable.search_custom_url_enabled_dark);
1287                         } else {
1288                             searchCustomURLPreference.setIcon(R.drawable.search_custom_url_enabled_light);
1289                         }
1290                     } else {  // `Custom URL` is not selected.
1291                         // Set the summary text to `newSearchString`.
1292                         searchPreference.setSummary(newSearchString);
1293
1294                         // Disable `searchCustomURLPreference`.
1295                         searchCustomURLPreference.setEnabled(false);
1296
1297                         // Set the `searchCustomURLPreference` according to the theme.
1298                         if (darkTheme) {
1299                             searchCustomURLPreference.setIcon(R.drawable.search_custom_url_ghosted_dark);
1300                         } else {
1301                             searchCustomURLPreference.setIcon(R.drawable.search_custom_url_ghosted_light);
1302                         }
1303                     }
1304                     break;
1305
1306                 case "search_custom_url":
1307                     // Set the new custom search URL as the summary text for `search_custom_url`.  The default is `""`.
1308                     searchCustomURLPreference.setSummary(sharedPreferences.getString("search_custom_url", getString(R.string.search_custom_url_default_value)));
1309                     break;
1310
1311                 case "full_screen_browsing_mode":
1312                     if (sharedPreferences.getBoolean("full_screen_browsing_mode", false)) {  // Full screen browsing is enabled.
1313                         // Set the full screen browsing mode preference icon according to the theme.
1314                         if (darkTheme) {
1315                             fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_enabled_dark);
1316                         } else {
1317                             fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_enabled_light);
1318                         }
1319
1320                         // Set the hide app bar preference icon.
1321                         if (sharedPreferences.getBoolean("hide_app_bar", true)) {  //  Hide app bar is enabled.
1322                             // Set the icon according to the theme.
1323                             if (darkTheme) {
1324                                 hideAppBarPreference.setIcon(R.drawable.app_bar_enabled_dark);
1325                             } else {
1326                                 hideAppBarPreference.setIcon(R.drawable.app_bar_enabled_light);
1327                             }
1328                         } else {  // Hide app bar is disabled.
1329                             // Set the icon according to the theme.
1330                             if (darkTheme) {
1331                                 hideAppBarPreference.setIcon(R.drawable.app_bar_disabled_dark);
1332                             } else {
1333                                 hideAppBarPreference.setIcon(R.drawable.app_bar_disabled_light);
1334                             }
1335                         }
1336                     } else {  // Full screen browsing is disabled.
1337                         // Update the icons according to the theme.
1338                         if (darkTheme) {
1339                             fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_disabled_dark);
1340                             hideAppBarPreference.setIcon(R.drawable.app_bar_ghosted_dark);
1341                         } else {
1342                             fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_disabled_light);
1343                             hideAppBarPreference.setIcon(R.drawable.app_bar_ghosted_light);
1344                         }
1345                     }
1346                     break;
1347
1348                 case "hide_app_bar":
1349                     // Update the icon.
1350                     if (sharedPreferences.getBoolean("hide_app_bar", true)) {  // Hide app bar is enabled.
1351                         // Set the icon according to the theme.
1352                         if (darkTheme) {
1353                             hideAppBarPreference.setIcon(R.drawable.app_bar_enabled_dark);
1354                         } else {
1355                             hideAppBarPreference.setIcon(R.drawable.app_bar_enabled_light);
1356                         }
1357                     } else {  // Hide app bar is disabled.
1358                         // Set the icon according to the theme.
1359                         if (darkTheme) {
1360                             hideAppBarPreference.setIcon(R.drawable.app_bar_disabled_dark);
1361                         } else {
1362                             hideAppBarPreference.setIcon(R.drawable.app_bar_disabled_light);
1363                         }
1364                     }
1365                     break;
1366
1367                 case "clear_everything":
1368                     // Store the new `clear_everything` status
1369                     boolean newClearEverythingBoolean = sharedPreferences.getBoolean("clear_everything", true);
1370
1371                     // Update the status of the `Clear and Exit` preferences.
1372                     clearCookiesPreference.setEnabled(!newClearEverythingBoolean);
1373                     clearDomStoragePreference.setEnabled(!newClearEverythingBoolean);
1374                     clearFormDataPreference.setEnabled(!newClearEverythingBoolean);  // This line can be removed once the minimum API >= 26.
1375                     clearCachePreference.setEnabled(!newClearEverythingBoolean);
1376
1377                     // Update the `clearEverythingPreference` icon.
1378                     if (newClearEverythingBoolean) {
1379                         if (darkTheme) {
1380                             clearEverythingPreference.setIcon(R.drawable.clear_everything_enabled_dark);
1381                         } else {
1382                             clearEverythingPreference.setIcon(R.drawable.clear_everything_enabled_light);
1383                         }
1384                     } else {
1385                         clearEverythingPreference.setIcon(R.drawable.clear_everything_disabled);
1386                     }
1387
1388                     // Update the `clearCookiesPreference` icon.
1389                     if (newClearEverythingBoolean || sharedPreferences.getBoolean("clear_cookies", true)) {
1390                         if (darkTheme) {
1391                             clearCookiesPreference.setIcon(R.drawable.cookies_cleared_dark);
1392                         } else {
1393                             clearCookiesPreference.setIcon(R.drawable.cookies_cleared_light);
1394                         }
1395                     } else {
1396                         clearCookiesPreference.setIcon(R.drawable.cookies_warning);
1397                     }
1398
1399                     // Update the `clearDomStoragePreference` icon.
1400                     if (newClearEverythingBoolean || sharedPreferences.getBoolean("clear_dom_storage", true)) {
1401                         if (darkTheme) {
1402                             clearDomStoragePreference.setIcon(R.drawable.dom_storage_cleared_dark);
1403                         } else {
1404                             clearDomStoragePreference.setIcon(R.drawable.dom_storage_cleared_light);
1405                         }
1406                     } else {
1407                         clearDomStoragePreference.setIcon(R.drawable.dom_storage_warning);
1408                     }
1409
1410                     // Update the clear form data preference icon if the API < 26.
1411                     if (Build.VERSION.SDK_INT < 26) {
1412                         if (newClearEverythingBoolean || sharedPreferences.getBoolean("clear_form_data", true)) {
1413                             if (darkTheme) {
1414                                 clearFormDataPreference.setIcon(R.drawable.form_data_cleared_dark);
1415                             } else {
1416                                 clearFormDataPreference.setIcon(R.drawable.form_data_cleared_light);
1417                             }
1418                         } else {
1419                             clearFormDataPreference.setIcon(R.drawable.form_data_warning);
1420                         }
1421                     }
1422
1423                     // Update the `clearCachePreference` icon.
1424                     if (newClearEverythingBoolean || sharedPreferences.getBoolean("clear_cache", true)) {
1425                         if (darkTheme) {
1426                             clearCachePreference.setIcon(R.drawable.cache_cleared_dark);
1427                         } else {
1428                             clearCachePreference.setIcon(R.drawable.cache_cleared_light);
1429                         }
1430                     } else {
1431                         clearCachePreference.setIcon(R.drawable.cache_warning);
1432                     }
1433                     break;
1434
1435                 case "clear_cookies":
1436                     // Update the icon.
1437                     if (sharedPreferences.getBoolean("clear_cookies", true)) {
1438                         if (darkTheme) {
1439                             clearCookiesPreference.setIcon(R.drawable.cookies_cleared_dark);
1440                         } else {
1441                             clearCookiesPreference.setIcon(R.drawable.cookies_cleared_light);
1442                         }
1443                     } else {
1444                         clearCookiesPreference.setIcon(R.drawable.cookies_warning);
1445                     }
1446                     break;
1447
1448                 case "clear_dom_storage":
1449                     // Update the icon.
1450                     if (sharedPreferences.getBoolean("clear_dom_storage", true)) {
1451                         if (darkTheme) {
1452                             clearDomStoragePreference.setIcon(R.drawable.dom_storage_cleared_dark);
1453                         } else {
1454                             clearDomStoragePreference.setIcon(R.drawable.dom_storage_cleared_light);
1455                         }
1456                     } else {
1457                         clearDomStoragePreference.setIcon(R.drawable.dom_storage_warning);
1458                     }
1459                     break;
1460
1461                 // This section can be removed once the minimum API >= 26.
1462                 case "clear_form_data":
1463                     // Update the icon.
1464                     if (sharedPreferences.getBoolean("clear_form_data", true)) {
1465                         if (darkTheme) {
1466                             clearFormDataPreference.setIcon(R.drawable.form_data_cleared_dark);
1467                         } else {
1468                             clearFormDataPreference.setIcon(R.drawable.form_data_cleared_light);
1469                         }
1470                     } else {
1471                         clearFormDataPreference.setIcon(R.drawable.form_data_warning);
1472                     }
1473                     break;
1474
1475                 case "clear_cache":
1476                     // Update the icon.
1477                     if (sharedPreferences.getBoolean("clear_cache", true)) {
1478                         if (darkTheme) {
1479                             clearCachePreference.setIcon(R.drawable.cache_cleared_dark);
1480                         } else {
1481                             clearCachePreference.setIcon(R.drawable.cache_cleared_light);
1482                         }
1483                     } else {
1484                         clearCachePreference.setIcon(R.drawable.cache_warning);
1485                     }
1486                     break;
1487
1488                 case "homepage":
1489                     // Set the new homepage URL as the summary text for the Homepage preference.
1490                     homepagePreference.setSummary(sharedPreferences.getString("homepage", getString(R.string.homepage_default_value)));
1491                     break;
1492
1493                 case "font_size":
1494                     // Update the font size summary text.
1495                     fontSizePreference.setSummary(sharedPreferences.getString("font_size", getString(R.string.font_size_default_value)) + "%%");
1496                     break;
1497
1498                 case "open_intents_in_new_tab":
1499                     // Update the icon.
1500                     if (sharedPreferences.getBoolean("open_intents_in_new_tab", true)) {
1501                         if (darkTheme) {
1502                             openIntentsInNewTabPreference.setIcon(R.drawable.tab_enabled_dark);
1503                         } else {
1504                             openIntentsInNewTabPreference.setIcon(R.drawable.tab_enabled_light);
1505                         }
1506                     } else {
1507                         if (darkTheme) {
1508                             openIntentsInNewTabPreference.setIcon(R.drawable.tab_disabled_dark);
1509                         } else {
1510                             openIntentsInNewTabPreference.setIcon(R.drawable.tab_disabled_light);
1511                         }
1512                     }
1513                     break;
1514
1515                 case "swipe_to_refresh":
1516                     // Update the icon.
1517                     if (sharedPreferences.getBoolean("swipe_to_refresh", true)) {
1518                         if (darkTheme) {
1519                             swipeToRefreshPreference.setIcon(R.drawable.refresh_enabled_dark);
1520                         } else {
1521                             swipeToRefreshPreference.setIcon(R.drawable.refresh_enabled_light);
1522                         }
1523                     } else {
1524                         if (darkTheme) {
1525                             swipeToRefreshPreference.setIcon(R.drawable.refresh_disabled_dark);
1526                         } else {
1527                             swipeToRefreshPreference.setIcon(R.drawable.refresh_disabled_light);
1528                         }
1529                     }
1530                     break;
1531
1532                 case "scroll_app_bar":
1533                     // Update the icon.
1534                     if (sharedPreferences.getBoolean("scroll_app_bar", true)) {
1535                         if (darkTheme) {
1536                             scrollAppBarPreference.setIcon(R.drawable.app_bar_enabled_dark);
1537                         } else {
1538                             scrollAppBarPreference.setIcon(R.drawable.app_bar_enabled_light);
1539                         }
1540                     } else {
1541                         if (darkTheme) {
1542                             scrollAppBarPreference.setIcon(R.drawable.app_bar_disabled_dark);
1543                         } else {
1544                             scrollAppBarPreference.setIcon(R.drawable.app_bar_disabled_light);
1545                         }
1546                     }
1547                     break;
1548
1549                 case "display_additional_app_bar_icons":
1550                     // Update the icon.
1551                     if (sharedPreferences.getBoolean("display_additional_app_bar_icons", false)) {
1552                         if (darkTheme) {
1553                             displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_enabled_dark);
1554                         } else {
1555                             displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_enabled_light);
1556                         }
1557                     } else {
1558                         if (darkTheme) {
1559                             displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_disabled_dark);
1560                         } else {
1561                             displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_disabled_light);
1562                         }
1563                     }
1564                     break;
1565
1566                 case "download_with_external_app":
1567                     // Update the icon.
1568                     if (sharedPreferences.getBoolean("download_with_external_app", false)) {
1569                         if (darkTheme) {
1570                             downloadWithExternalAppPreference.setIcon(R.drawable.open_with_external_app_enabled_dark);
1571                         } else {
1572                             downloadWithExternalAppPreference.setIcon(R.drawable.open_with_external_app_enabled_light);
1573                         }
1574                     } else {
1575                         if (darkTheme) {
1576                             downloadWithExternalAppPreference.setIcon(R.drawable.open_with_external_app_disabled_dark);
1577                         } else {
1578                             downloadWithExternalAppPreference.setIcon(R.drawable.open_with_external_app_disabled_light);
1579                         }
1580                     }
1581                     break;
1582
1583                 case "dark_theme":
1584                     // Update the icon.
1585                     if (sharedPreferences.getBoolean("dark_theme", false)) {
1586                         darkThemePreference.setIcon(R.drawable.theme_dark);
1587                     } else {
1588                         darkThemePreference.setIcon(R.drawable.theme_light);
1589                     }
1590
1591                     // Create an intent to restart Privacy Browser.
1592                     Intent changeThemeRestartIntent = getActivity().getParentActivityIntent();
1593
1594                     // Assert that the intent is not null to remove the lint error below.
1595                     assert changeThemeRestartIntent != null;
1596
1597                     // `Intent.FLAG_ACTIVITY_CLEAR_TASK` removes all activities from the stack.  It requires `Intent.FLAG_ACTIVITY_NEW_TASK`.
1598                     changeThemeRestartIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
1599
1600                     // Create a handler to restart the activity.
1601                     Handler changeThemeRestartHandler = new Handler();
1602
1603                     // Create a runnable to restart the activity.
1604                     Runnable changeThemeRestartRunnable = () -> {
1605                         // Restart the activity.
1606                         startActivity(changeThemeRestartIntent);
1607
1608                         // Kill this instance of Privacy Browser.  Otherwise, the app exhibits sporadic behavior after the restart.
1609                         System.exit(0);
1610                     };
1611
1612                     // Restart the activity after 100 milliseconds, so that the app has enough time to save the change to the preference.
1613                     changeThemeRestartHandler.postDelayed(changeThemeRestartRunnable, 100);
1614                     break;
1615
1616                 case "night_mode":
1617                     // Store the current night mode status.
1618                     boolean currentNightModeBoolean = sharedPreferences.getBoolean("night_mode", false);
1619                     boolean currentJavaScriptBoolean = sharedPreferences.getBoolean("javascript", false);
1620
1621                     // Update the icon.
1622                     if (currentNightModeBoolean) {
1623                         if (darkTheme) {
1624                             nightModePreference.setIcon(R.drawable.night_mode_enabled_dark);
1625                         } else {
1626                             nightModePreference.setIcon(R.drawable.night_mode_enabled_light);
1627                         }
1628                     } else {
1629                         if (darkTheme) {
1630                             nightModePreference.setIcon(R.drawable.night_mode_disabled_dark);
1631                         } else {
1632                             nightModePreference.setIcon(R.drawable.night_mode_disabled_light);
1633                         }
1634                     }
1635
1636                     // Update the status of `javaScriptPreference` and `domStoragePreference`.
1637                     javaScriptPreference.setEnabled(!currentNightModeBoolean);
1638                     domStoragePreference.setEnabled(currentNightModeBoolean || currentJavaScriptBoolean);
1639
1640                     // Update the `javaScriptPreference` icon.
1641                     if (currentNightModeBoolean || currentJavaScriptBoolean) {
1642                         javaScriptPreference.setIcon(R.drawable.javascript_enabled);
1643                     } else {
1644                         javaScriptPreference.setIcon(R.drawable.privacy_mode);
1645                     }
1646
1647                     // Update the DOM storage preference icon.
1648                     if (currentNightModeBoolean || currentJavaScriptBoolean) {  // The preference is enabled.
1649                         if (sharedPreferences.getBoolean("dom_storage", false)) {  // DOM storage is enabled.
1650                             domStoragePreference.setIcon(R.drawable.dom_storage_enabled);
1651                         } else {  // DOM storage is disabled.
1652                             if (darkTheme) {
1653                                 domStoragePreference.setIcon(R.drawable.dom_storage_disabled_dark);
1654                             } else {
1655                                 domStoragePreference.setIcon(R.drawable.dom_storage_disabled_light);
1656                             }
1657                         }
1658                     } else {  // The preference is disabled.  The icon should be ghosted.
1659                         if (darkTheme) {
1660                             domStoragePreference.setIcon(R.drawable.dom_storage_ghosted_dark);
1661                         } else {
1662                             domStoragePreference.setIcon(R.drawable.dom_storage_ghosted_light);
1663                         }
1664                     }
1665                     break;
1666
1667                 case "display_webpage_images":
1668                     if (sharedPreferences.getBoolean("display_webpage_images", true)) {
1669                         // Update the icon.
1670                         if (darkTheme) {
1671                             displayWebpageImagesPreference.setIcon(R.drawable.images_enabled_dark);
1672                         } else {
1673                             displayWebpageImagesPreference.setIcon(R.drawable.images_enabled_light);
1674                         }
1675                     } else {
1676                         // Update the icon.
1677                         if (darkTheme) {
1678                             displayWebpageImagesPreference.setIcon(R.drawable.images_disabled_dark);
1679                         } else {
1680                             displayWebpageImagesPreference.setIcon(R.drawable.images_disabled_light);
1681                         }
1682                     }
1683                     break;
1684             }
1685         };
1686
1687         // Register the listener.
1688         savedPreferences.registerOnSharedPreferenceChangeListener(preferencesListener);
1689     }
1690
1691     // 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.
1692     @Override
1693     public void onPause() {
1694         super.onPause();
1695         savedPreferences.unregisterOnSharedPreferenceChangeListener(preferencesListener);
1696     }
1697
1698     @Override
1699     public void onResume() {
1700         super.onResume();
1701         savedPreferences.registerOnSharedPreferenceChangeListener(preferencesListener);
1702     }
1703 }