]> gitweb.stoutner.com Git - PrivacyBrowserAndroid.git/blob - app/src/main/java/com/stoutner/privacybrowser/fragments/SettingsFragment.java
Fix custom headers not being loaded for links initialed from the WebView. https...
[PrivacyBrowserAndroid.git] / app / src / main / java / com / stoutner / privacybrowser / fragments / SettingsFragment.java
1 /*
2  * Copyright © 2016-2020 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.app.Activity;
24 import android.content.Context;
25 import android.content.Intent;
26 import android.content.SharedPreferences;
27 import android.content.res.Configuration;
28 import android.content.res.Resources;
29 import android.os.Build;
30 import android.os.Bundle;
31 import android.os.Handler;
32 import android.view.LayoutInflater;
33 import android.view.View;
34 import android.webkit.WebView;
35 import android.widget.ArrayAdapter;
36
37 import androidx.appcompat.app.AppCompatDelegate;
38 import androidx.preference.Preference;
39 import androidx.preference.PreferenceCategory;
40 import androidx.preference.PreferenceFragmentCompat;
41
42 import com.stoutner.privacybrowser.R;
43 import com.stoutner.privacybrowser.activities.MainWebViewActivity;
44 import com.stoutner.privacybrowser.helpers.DownloadLocationHelper;
45 import com.stoutner.privacybrowser.helpers.ProxyHelper;
46
47 public class SettingsFragment extends PreferenceFragmentCompat {
48     // Define the class variables.
49     private SharedPreferences.OnSharedPreferenceChangeListener preferencesListener;
50     private SharedPreferences savedPreferences;
51     private int currentThemeStatus;
52
53     @Override
54     public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
55         // Load the preferences from the XML file.
56         setPreferencesFromResource(R.xml.preferences, rootKey);
57
58         // Get a handle for the activity.
59         Activity activity = getActivity();
60
61         // Remove the lint warning below that `getApplicationContext()` might produce a null pointer exception.
62         assert activity != null;
63
64         // Get a handle for the context and the resources.
65         Context context = activity.getApplicationContext();
66         Resources resources = getResources();
67
68         // Get the current theme status.
69         currentThemeStatus = getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
70
71         // Initialize savedPreferences.
72         savedPreferences = getPreferenceScreen().getSharedPreferences();
73
74         // Get handles for the preferences.
75         Preference javaScriptPreference = findPreference("javascript");
76         Preference firstPartyCookiesPreference = findPreference("first_party_cookies");
77         Preference thirdPartyCookiesPreference = findPreference("third_party_cookies");
78         Preference domStoragePreference = findPreference("dom_storage");
79         Preference formDataPreference = findPreference("save_form_data");  // The form data preference can be removed once the minimum API >= 26.
80         Preference userAgentPreference = findPreference("user_agent");
81         Preference customUserAgentPreference = findPreference("custom_user_agent");
82         Preference incognitoModePreference = findPreference("incognito_mode");
83         Preference doNotTrackPreference = findPreference("do_not_track");
84         Preference allowScreenshotsPreference = findPreference("allow_screenshots");
85         Preference easyListPreference = findPreference("easylist");
86         Preference easyPrivacyPreference = findPreference("easyprivacy");
87         Preference fanboyAnnoyanceListPreference = findPreference("fanboys_annoyance_list");
88         Preference fanboySocialBlockingListPreference = findPreference("fanboys_social_blocking_list");
89         Preference ultraListPreference = findPreference("ultralist");
90         Preference ultraPrivacyPreference = findPreference("ultraprivacy");
91         Preference blockAllThirdPartyRequestsPreference = findPreference("block_all_third_party_requests");
92         Preference googleAnalyticsPreference = findPreference("google_analytics");
93         Preference facebookClickIdsPreference = findPreference("facebook_click_ids");
94         Preference twitterAmpRedirectsPreference = findPreference("twitter_amp_redirects");
95         Preference searchPreference = findPreference("search");
96         Preference searchCustomURLPreference = findPreference("search_custom_url");
97         Preference proxyPreference = findPreference("proxy");
98         Preference proxyCustomUrlPreference = findPreference("proxy_custom_url");
99         Preference fullScreenBrowsingModePreference = findPreference("full_screen_browsing_mode");
100         Preference hideAppBarPreference = findPreference("hide_app_bar");
101         Preference clearEverythingPreference = findPreference("clear_everything");
102         Preference clearCookiesPreference = findPreference("clear_cookies");
103         Preference clearDomStoragePreference = findPreference("clear_dom_storage");
104         Preference clearFormDataPreference = findPreference("clear_form_data");  // The clear form data preference can be removed once the minimum API >= 26.
105         Preference clearCachePreference = findPreference("clear_cache");
106         Preference homepagePreference = findPreference("homepage");
107         Preference downloadLocationPreference = findPreference("download_location");
108         Preference downloadCustomLocationPreference = findPreference("download_custom_location");
109         Preference fontSizePreference = findPreference("font_size");
110         Preference openIntentsInNewTabPreference = findPreference("open_intents_in_new_tab");
111         Preference swipeToRefreshPreference = findPreference("swipe_to_refresh");
112         Preference scrollAppBarPreference = findPreference("scroll_app_bar");
113         Preference displayAdditionalAppBarIconsPreference = findPreference("display_additional_app_bar_icons");
114         Preference appThemePreference = findPreference("app_theme");
115         Preference webViewThemePreference = findPreference("webview_theme");
116         Preference wideViewportPreference = findPreference("wide_viewport");
117         Preference displayWebpageImagesPreference = findPreference("display_webpage_images");
118
119         // Remove the lint warnings below that the preferences might be null.
120         assert javaScriptPreference != null;
121         assert firstPartyCookiesPreference != null;
122         assert thirdPartyCookiesPreference != null;
123         assert domStoragePreference != null;
124         assert formDataPreference != null;
125         assert userAgentPreference != null;
126         assert customUserAgentPreference != null;
127         assert incognitoModePreference != null;
128         assert doNotTrackPreference != null;
129         assert allowScreenshotsPreference != null;
130         assert easyListPreference != null;
131         assert easyPrivacyPreference != null;
132         assert fanboyAnnoyanceListPreference != null;
133         assert fanboySocialBlockingListPreference != null;
134         assert ultraListPreference != null;
135         assert ultraPrivacyPreference != null;
136         assert blockAllThirdPartyRequestsPreference != null;
137         assert googleAnalyticsPreference != null;
138         assert facebookClickIdsPreference != null;
139         assert twitterAmpRedirectsPreference != null;
140         assert searchPreference != null;
141         assert searchCustomURLPreference != null;
142         assert proxyPreference != null;
143         assert proxyCustomUrlPreference != null;
144         assert fullScreenBrowsingModePreference != null;
145         assert hideAppBarPreference != null;
146         assert clearEverythingPreference != null;
147         assert clearCookiesPreference != null;
148         assert clearDomStoragePreference != null;
149         assert clearFormDataPreference != null;
150         assert clearCachePreference != null;
151         assert homepagePreference != null;
152         assert downloadLocationPreference != null;
153         assert downloadCustomLocationPreference != null;
154         assert fontSizePreference != null;
155         assert openIntentsInNewTabPreference != null;
156         assert swipeToRefreshPreference != null;
157         assert scrollAppBarPreference != null;
158         assert displayAdditionalAppBarIconsPreference != null;
159         assert appThemePreference != null;
160         assert webViewThemePreference != null;
161         assert wideViewportPreference != null;
162         assert displayWebpageImagesPreference != null;
163
164         // Set the preference dependencies.
165         hideAppBarPreference.setDependency("full_screen_browsing_mode");
166         domStoragePreference.setDependency("javascript");
167
168         // Get strings from the preferences.
169         String userAgentName = savedPreferences.getString("user_agent", getString(R.string.user_agent_default_value));
170         String searchString = savedPreferences.getString("search", getString(R.string.search_default_value));
171         String proxyString = savedPreferences.getString("proxy", getString(R.string.proxy_default_value));
172         String downloadLocationString = savedPreferences.getString("download_location", getString(R.string.download_location_default_value));
173
174         // Get booleans that are used in multiple places from the preferences.
175         boolean javaScriptEnabled = savedPreferences.getBoolean("javascript", false);
176         boolean firstPartyCookiesEnabled = savedPreferences.getBoolean("first_party_cookies", false);
177         boolean fanboyAnnoyanceListEnabled = savedPreferences.getBoolean("fanboys_annoyance_list", true);
178         boolean fanboySocialBlockingEnabled = savedPreferences.getBoolean("fanboys_social_blocking_list", true);
179         boolean fullScreenBrowsingMode = savedPreferences.getBoolean("full_screen_browsing_mode", false);
180         boolean clearEverything = savedPreferences.getBoolean("clear_everything", true);
181
182         // Only enable the third-party cookies preference if first-party cookies are enabled and API >= 21.
183         thirdPartyCookiesPreference.setEnabled(firstPartyCookiesEnabled && (Build.VERSION.SDK_INT >= 21));
184
185         // Remove the form data preferences if the API is >= 26 as they no longer do anything.
186         if (Build.VERSION.SDK_INT >= 26) {
187             // Get handles for the categories.
188             PreferenceCategory privacyCategory = findPreference("privacy");
189             PreferenceCategory clearAndExitCategory = findPreference("clear_and_exit");
190
191             // Remove the incorrect lint warnings below that the preference categories might be null.
192             assert privacyCategory != null;
193             assert clearAndExitCategory != null;
194
195             // Remove the form data preferences.
196             privacyCategory.removePreference(formDataPreference);
197             clearAndExitCategory.removePreference(clearFormDataPreference);
198         }
199
200         // Only enable Fanboy's social blocking list preference if Fanboy's annoyance list is disabled.
201         fanboySocialBlockingListPreference.setEnabled(!fanboyAnnoyanceListEnabled);
202
203
204         // Inflate a WebView to get the default user agent.
205         LayoutInflater inflater = getActivity().getLayoutInflater();
206
207         // `@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.
208         @SuppressLint("InflateParams") View bareWebViewLayout = inflater.inflate(R.layout.bare_webview, null, false);
209
210         // Get a handle for a bare WebView.
211         WebView bareWebView = bareWebViewLayout.findViewById(R.id.bare_webview);
212
213         // Get the user agent arrays.
214         ArrayAdapter<CharSequence> userAgentNamesArray = ArrayAdapter.createFromResource(context, R.array.user_agent_names, R.layout.spinner_item);
215         String[] translatedUserAgentNamesArray = resources.getStringArray(R.array.translated_user_agent_names);
216         String[] userAgentDataArray = resources.getStringArray(R.array.user_agent_data);
217
218         // Get the array position of the user agent name.
219         int userAgentArrayPosition = userAgentNamesArray.getPosition(userAgentName);
220
221         // Populate the user agent summary.
222         switch (userAgentArrayPosition) {
223             case MainWebViewActivity.UNRECOGNIZED_USER_AGENT:  // The user agent name is not on the canonical list.
224                 // 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.
225                 userAgentPreference.setSummary(userAgentName);
226                 break;
227
228             case MainWebViewActivity.SETTINGS_WEBVIEW_DEFAULT_USER_AGENT:
229                 // Get the user agent text from the webview (which changes based on the version of Android and WebView installed).
230                 userAgentPreference.setSummary(translatedUserAgentNamesArray[userAgentArrayPosition] + ":\n" + bareWebView.getSettings().getUserAgentString());
231                 break;
232
233             case MainWebViewActivity.SETTINGS_CUSTOM_USER_AGENT:
234                 // Set the summary text.
235                 userAgentPreference.setSummary(R.string.custom_user_agent);
236                 break;
237
238             default:
239                 // Get the user agent summary from the user agent data array.
240                 userAgentPreference.setSummary(translatedUserAgentNamesArray[userAgentArrayPosition] + ":\n" + userAgentDataArray[userAgentArrayPosition]);
241         }
242
243         // Set the summary text for the custom user agent preference.
244         customUserAgentPreference.setSummary(savedPreferences.getString("custom_user_agent", getString(R.string.custom_user_agent_default_value)));
245
246         // Only enable the custom user agent preference if the user agent is set to `Custom`.
247         customUserAgentPreference.setEnabled(userAgentPreference.getSummary().equals(getString(R.string.custom_user_agent)));
248
249
250         // Set the search URL as the summary text for the search preference when the preference screen is loaded.
251         if (searchString.equals("Custom URL")) {
252             // Use R.string.custom_url, which will be translated, instead of the array value, which will not.
253             searchPreference.setSummary(R.string.custom_url);
254         } else {
255             // Set the array value as the summary text.
256             searchPreference.setSummary(searchString);
257         }
258
259         // Set the summary text for the search custom URL (the default is `""`).
260         searchCustomURLPreference.setSummary(savedPreferences.getString("search_custom_url", getString(R.string.search_custom_url_default_value)));
261
262         // Only enable the search custom URL preference if the search is set to `Custom URL`.
263         searchCustomURLPreference.setEnabled(searchString.equals("Custom URL"));
264
265
266         // Set the summary text for the proxy preference when the preference screen is loaded.
267         switch (proxyString) {
268             case ProxyHelper.NONE:
269                 proxyPreference.setSummary(getString(R.string.no_proxy_enabled));
270                 break;
271
272             case ProxyHelper.TOR:
273                 if (Build.VERSION.SDK_INT == 19) {  // Proxying through SOCKS doesn't work on Android KitKat.
274                     proxyPreference.setSummary(getString(R.string.tor_enabled_kitkat));
275                 } else {
276                     proxyPreference.setSummary(getString(R.string.tor_enabled));
277                 }
278                 break;
279
280             case ProxyHelper.I2P:
281                 proxyPreference.setSummary(getString(R.string.i2p_enabled));
282                 break;
283
284             case ProxyHelper.CUSTOM:
285                 proxyPreference.setSummary(getString(R.string.custom_proxy));
286                 break;
287         }
288
289         // Set the summary text for the custom proxy URL.
290         proxyCustomUrlPreference.setSummary(savedPreferences.getString("proxy_custom_url", getString(R.string.proxy_custom_url_default_value)));
291
292         // Only enable the custom proxy URL if a custom proxy is selected.
293         proxyCustomUrlPreference.setEnabled(proxyString.equals("Custom"));
294
295
296         // Set the status of the Clear and Exit preferences.
297         clearCookiesPreference.setEnabled(!clearEverything);
298         clearDomStoragePreference.setEnabled(!clearEverything);
299         clearFormDataPreference.setEnabled(!clearEverything);  // The form data line can be removed once the minimum API is >= 26.
300         clearCachePreference.setEnabled(!clearEverything);
301
302
303         // Set the homepage URL as the summary text for the homepage preference.
304         homepagePreference.setSummary(savedPreferences.getString("homepage", getString(R.string.homepage_default_value)));
305
306
307         // Get the download location string arrays.
308         String[] downloadLocationEntriesStringArray = resources.getStringArray(R.array.download_location_entries);
309         String[] downloadLocationEntryValuesStringArray = resources.getStringArray(R.array.download_location_entry_values);
310
311         // Instantiate the download location helper.
312         DownloadLocationHelper downloadLocationHelper = new DownloadLocationHelper();
313
314         // Check to see if a download custom location is selected.
315         if (downloadLocationString.equals(downloadLocationEntryValuesStringArray[3])) {  // A download custom location is selected.
316             // Set the download location summary text to be `Custom`.
317             downloadLocationPreference.setSummary(downloadLocationEntriesStringArray[3]);
318         } else {  // A custom download location is not selected.
319             // Set the download location summary text to be the download location.
320             downloadLocationPreference.setSummary(downloadLocationHelper.getDownloadLocation(context));
321
322             // Disable the download custom location preference.
323             downloadCustomLocationPreference.setEnabled(false);
324         }
325
326         // Set the summary text for the download custom location (the default is `"`).
327         downloadCustomLocationPreference.setSummary(savedPreferences.getString("download_custom_location", getString(R.string.download_custom_location_default_value)));
328
329
330         // Set the font size as the summary text for the preference.
331         fontSizePreference.setSummary(savedPreferences.getString("font_size", getString(R.string.font_size_default_value)) + "%");
332
333
334         // Get the app theme string arrays.
335         String[] appThemeEntriesStringArray = resources.getStringArray(R.array.app_theme_entries);
336         String[] appThemeEntryValuesStringArray = resources.getStringArray(R.array.app_theme_entry_values);
337
338         // Get the current app theme.
339         String currentAppTheme = savedPreferences.getString("app_theme", getString(R.string.app_theme_default_value));
340
341         // Define an app theme entry number.
342         int appThemeEntryNumber;
343
344         // Get the app theme entry number that matches the current app theme.  A switch statement cannot be used because the theme entry values string array is not a compile time constant.
345         if (currentAppTheme.equals(appThemeEntryValuesStringArray[1])) {  // The light theme is selected.
346             // Store the app theme entry number.
347             appThemeEntryNumber = 1;
348         } else if (currentAppTheme.equals(appThemeEntryValuesStringArray[2])) {  // The dark theme is selected.
349             // Store the app theme entry number.
350             appThemeEntryNumber = 2;
351         } else {  // The system default theme is selected.
352             // Store the app theme entry number.
353             appThemeEntryNumber = 0;
354         }
355
356         // Set the current theme as the summary text for the preference.
357         appThemePreference.setSummary(appThemeEntriesStringArray[appThemeEntryNumber]);
358
359
360         // Get the WebView theme string arrays.
361         String[] webViewThemeEntriesStringArray = resources.getStringArray(R.array.webview_theme_entries);
362         String[] webViewThemeEntryValuesStringArray = resources.getStringArray(R.array.webview_theme_entry_values);
363
364         // Hide the WebView theme preference if the API < 21.
365         if (Build.VERSION.SDK_INT < 21) {  // The device is running API 19.
366             // Get a handle for the general category.
367             PreferenceCategory generalCategory = findPreference("general");
368
369             // Remove the incorrect lint warning below that the general preference category might be null.
370             assert generalCategory != null;
371
372             // Remove the WebView theme preference.
373             generalCategory.removePreference(webViewThemePreference);
374         } else {  // The device is running API >= 21
375             // Get the current WebView theme.
376             String currentWebViewTheme = savedPreferences.getString("webview_theme", getString(R.string.webview_theme_default_value));
377
378             // Define a WebView theme entry number.
379             int webViewThemeEntryNumber;
380
381             // Get the WebView theme entry number that matches the current WebView theme.  A switch statement cannot be used because the theme entry values string array is not a compile time constant.
382             if (currentWebViewTheme.equals(webViewThemeEntryValuesStringArray[1])) {  // The light theme is selected.
383                 // Store the WebView theme entry number.
384                 webViewThemeEntryNumber = 1;
385             } else if (currentWebViewTheme.equals(webViewThemeEntryValuesStringArray[2])) {  // The dark theme is selected.
386                 // Store the WebView theme entry number.
387                 webViewThemeEntryNumber = 2;
388             } else {  // The system default theme is selected.
389                 // Store the WebView theme entry number.
390                 webViewThemeEntryNumber = 0;
391             }
392
393             // Set the current theme as the summary text for the preference.
394             webViewThemePreference.setSummary(webViewThemeEntriesStringArray[webViewThemeEntryNumber]);
395         }
396
397
398         // Set the JavaScript icon.
399         if (javaScriptEnabled) {
400             javaScriptPreference.setIcon(R.drawable.javascript_enabled);
401         } else {
402             javaScriptPreference.setIcon(R.drawable.privacy_mode);
403         }
404
405         // Set the first-party cookies icon.
406         if (firstPartyCookiesEnabled) {
407             firstPartyCookiesPreference.setIcon(R.drawable.cookies_enabled);
408         } else {
409             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
410                 firstPartyCookiesPreference.setIcon(R.drawable.cookies_disabled_night);
411             } else {
412                 firstPartyCookiesPreference.setIcon(R.drawable.cookies_disabled_day);
413             }
414         }
415
416         // Set the third party cookies icon.
417         if (firstPartyCookiesEnabled && Build.VERSION.SDK_INT >= 21) {
418             if (savedPreferences.getBoolean("third_party_cookies", false)) {
419                 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_warning);
420             } else {
421                 if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
422                     thirdPartyCookiesPreference.setIcon(R.drawable.cookies_disabled_night);
423                 } else {
424                     thirdPartyCookiesPreference.setIcon(R.drawable.cookies_disabled_day);
425                 }
426             }
427         } else {
428             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
429                 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_ghosted_night);
430             } else {
431                 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_ghosted_day);
432             }
433         }
434
435         // Set the DOM storage icon.
436         if (javaScriptEnabled) {  // The preference is enabled.
437             if (savedPreferences.getBoolean("dom_storage", false)) {  // DOM storage is enabled.
438                 domStoragePreference.setIcon(R.drawable.dom_storage_enabled);
439             } else {  // DOM storage is disabled.
440                 if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
441                     domStoragePreference.setIcon(R.drawable.dom_storage_disabled_night);
442                 } else {
443                     domStoragePreference.setIcon(R.drawable.dom_storage_disabled_day);
444                 }
445             }
446         } else {  // The preference is disabled.  The icon should be ghosted.
447             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
448                 domStoragePreference.setIcon(R.drawable.dom_storage_ghosted_night);
449             } else {
450                 domStoragePreference.setIcon(R.drawable.dom_storage_ghosted_day);
451             }
452         }
453
454         // Set the save form data icon if API < 26.  Save form data has no effect on API >= 26.
455         if (Build.VERSION.SDK_INT < 26) {
456             if (savedPreferences.getBoolean("save_form_data", false)) {
457                 formDataPreference.setIcon(R.drawable.form_data_enabled);
458             } else {
459                 if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
460                     formDataPreference.setIcon(R.drawable.form_data_disabled_night);
461                 } else {
462                     formDataPreference.setIcon(R.drawable.form_data_disabled_day);
463                 }
464             }
465         }
466
467         // Set the custom user agent icon.
468         if (customUserAgentPreference.isEnabled()) {
469             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
470                 customUserAgentPreference.setIcon(R.drawable.custom_user_agent_enabled_night);
471             } else {
472                 customUserAgentPreference.setIcon(R.drawable.custom_user_agent_enabled_day);
473             }
474         } else {
475             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
476                 customUserAgentPreference.setIcon(R.drawable.custom_user_agent_ghosted_night);
477             } else {
478                 customUserAgentPreference.setIcon(R.drawable.custom_user_agent_ghosted_day);
479             }
480         }
481
482         // Set the incognito mode icon.
483         if (savedPreferences.getBoolean("incognito_mode", false)) {
484             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
485                 incognitoModePreference.setIcon(R.drawable.incognito_mode_enabled_night);
486             } else {
487                 incognitoModePreference.setIcon(R.drawable.incognito_mode_enabled_day);
488             }
489         } else {
490             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
491                 incognitoModePreference.setIcon(R.drawable.incognito_mode_disabled_night);
492             } else {
493                 incognitoModePreference.setIcon(R.drawable.incognito_mode_disabled_day);
494             }
495         }
496
497         // Set the Do Not Track icon.
498         if (savedPreferences.getBoolean("do_not_track", false)) {
499             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
500                 doNotTrackPreference.setIcon(R.drawable.block_tracking_enabled_night);
501             } else {
502                 doNotTrackPreference.setIcon(R.drawable.block_tracking_enabled_day);
503             }
504         } else {
505             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
506                 doNotTrackPreference.setIcon(R.drawable.block_tracking_disabled_night);
507             } else {
508                 doNotTrackPreference.setIcon(R.drawable.block_tracking_disabled_day);
509             }
510         }
511
512         // Set the allow screenshots icon.
513         if (savedPreferences.getBoolean("allow_screenshots", false)) {
514             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
515                 allowScreenshotsPreference.setIcon(R.drawable.allow_screenshots_enabled_night);
516             } else {
517                 allowScreenshotsPreference.setIcon(R.drawable.allow_screenshots_enabled_day);
518             }
519         } else {
520             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
521                 allowScreenshotsPreference.setIcon(R.drawable.allow_screenshots_disabled_night);
522             } else {
523                 allowScreenshotsPreference.setIcon(R.drawable.allow_screenshots_disabled_day);
524             }
525         }
526
527         // Set the EasyList icon.
528         if (savedPreferences.getBoolean("easylist", true)) {
529             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
530                 easyListPreference.setIcon(R.drawable.block_ads_enabled_night);
531             } else {
532                 easyListPreference.setIcon(R.drawable.block_ads_enabled_day);
533             }
534         } else {
535             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
536                 easyListPreference.setIcon(R.drawable.block_ads_disabled_night);
537             } else {
538                 easyListPreference.setIcon(R.drawable.block_ads_disabled_day);
539             }
540         }
541
542         // Set the EasyPrivacy icon.
543         if (savedPreferences.getBoolean("easyprivacy", true)) {
544             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
545                 easyPrivacyPreference.setIcon(R.drawable.block_tracking_enabled_night);
546             } else {
547                 easyPrivacyPreference.setIcon(R.drawable.block_tracking_enabled_day);
548             }
549         } else {
550             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
551                 easyPrivacyPreference.setIcon(R.drawable.block_tracking_disabled_night);
552             } else {
553                 easyPrivacyPreference.setIcon(R.drawable.block_tracking_disabled_day);
554             }
555         }
556
557         // Set the Fanboy lists icons.
558         if (fanboyAnnoyanceListEnabled) {
559             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
560                 // Set the Fanboy annoyance list icon.
561                 fanboyAnnoyanceListPreference.setIcon(R.drawable.social_media_enabled_night);
562
563                 // Set the Fanboy social blocking list icon.
564                 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_ghosted_night);
565             } else {
566                 // Set the Fanboy annoyance list icon.
567                 fanboyAnnoyanceListPreference.setIcon(R.drawable.social_media_enabled_day);
568
569                 // Set the Fanboy social blocking list icon.
570                 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_ghosted_day);
571             }
572         } else {
573             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
574                 // Set the Fanboy annoyance list icon.
575                 fanboyAnnoyanceListPreference.setIcon(R.drawable.social_media_disabled_night);
576
577                 // Set the Fanboy social blocking list icon.
578                 if (fanboySocialBlockingEnabled) {
579                     fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_enabled_night);
580                 } else {
581                     fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_disabled_night);
582                 }
583             } else {
584                 // Set the Fanboy annoyance list icon.
585                 fanboyAnnoyanceListPreference.setIcon(R.drawable.block_ads_disabled_day);
586
587                 // Set the Fanboy social blocking list icon.
588                 if (fanboySocialBlockingEnabled) {
589                     fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_enabled_day);
590                 } else {
591                     fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_disabled_day);
592                 }
593             }
594         }
595
596         // Set the UltraList icon.
597         if (savedPreferences.getBoolean("ultralist", true)){
598             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
599                 ultraListPreference.setIcon(R.drawable.block_ads_enabled_night);
600             } else {
601                 ultraListPreference.setIcon(R.drawable.block_ads_enabled_day);
602             }
603         } else {
604             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
605                 ultraListPreference.setIcon(R.drawable.block_ads_disabled_night);
606             } else {
607                 ultraListPreference.setIcon(R.drawable.block_ads_disabled_day);
608             }
609         }
610
611         // Set the UltraPrivacy icon.
612         if (savedPreferences.getBoolean("ultraprivacy", true)) {
613             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
614                 ultraPrivacyPreference.setIcon(R.drawable.block_tracking_enabled_night);
615             } else {
616                 ultraPrivacyPreference.setIcon(R.drawable.block_tracking_enabled_day);
617             }
618         } else {
619             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
620                 ultraPrivacyPreference.setIcon(R.drawable.block_tracking_disabled_night);
621             } else {
622                 ultraPrivacyPreference.setIcon(R.drawable.block_tracking_disabled_day);
623             }
624         }
625
626         // Set the block all third-party requests icon.
627         if (savedPreferences.getBoolean("block_all_third_party_requests", false)) {
628             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
629                 blockAllThirdPartyRequestsPreference.setIcon(R.drawable.block_all_third_party_requests_enabled_night);
630             } else {
631                 blockAllThirdPartyRequestsPreference.setIcon(R.drawable.block_all_third_party_requests_enabled_day);
632             }
633         } else {
634             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
635                 blockAllThirdPartyRequestsPreference.setIcon(R.drawable.block_all_third_party_requests_disabled_night);
636             } else {
637                 blockAllThirdPartyRequestsPreference.setIcon(R.drawable.block_all_third_party_requests_disabled_day);
638             }
639         }
640
641         // Set the Google Analytics icon according to the theme.
642         if (savedPreferences.getBoolean("google_analytics", true)) {
643             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
644                 googleAnalyticsPreference.setIcon(R.drawable.modify_url_enabled_night);
645             } else {
646                 googleAnalyticsPreference.setIcon(R.drawable.modify_url_enabled_day);
647             }
648         } else {
649             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
650                 googleAnalyticsPreference.setIcon(R.drawable.modify_url_disabled_night);
651             } else {
652                 googleAnalyticsPreference.setIcon(R.drawable.modify_url_disabled_day);
653             }
654         }
655
656         // Set the Facebook Click IDs icon according to the theme.
657         if (savedPreferences.getBoolean("facebook_click_ids", true)) {
658             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
659                 facebookClickIdsPreference.setIcon(R.drawable.modify_url_enabled_night);
660             } else {
661                 facebookClickIdsPreference.setIcon(R.drawable.modify_url_enabled_day);
662             }
663         } else {
664             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
665                 facebookClickIdsPreference.setIcon(R.drawable.modify_url_disabled_night);
666             } else {
667                 facebookClickIdsPreference.setIcon(R.drawable.modify_url_disabled_day);
668             }
669         }
670
671         // Set the Twitter AMP redirects icon according to the theme.
672         if (savedPreferences.getBoolean("twitter_amp_redirects", true)) {
673             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
674                 twitterAmpRedirectsPreference.setIcon(R.drawable.modify_url_enabled_night);
675             } else {
676                 twitterAmpRedirectsPreference.setIcon(R.drawable.modify_url_enabled_day);
677             }
678         } else {
679             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
680                 twitterAmpRedirectsPreference.setIcon(R.drawable.modify_url_disabled_night);
681             } else {
682                 twitterAmpRedirectsPreference.setIcon(R.drawable.modify_url_disabled_day);
683             }
684         }
685
686         // Set the search custom URL icon.
687         if (searchCustomURLPreference.isEnabled()) {
688             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
689                 searchCustomURLPreference.setIcon(R.drawable.search_custom_url_enabled_night);
690             } else {
691                 searchCustomURLPreference.setIcon(R.drawable.search_custom_url_enabled_day);
692             }
693         } else {
694             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
695                 searchCustomURLPreference.setIcon(R.drawable.search_custom_url_ghosted_night);
696             } else {
697                 searchCustomURLPreference.setIcon(R.drawable.search_custom_url_ghosted_day);
698             }
699         }
700
701         // Set the Proxy icons according to the theme and status.
702         if (proxyString.equals("None")) {  // Proxying is disabled.
703             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {  // Dark theme.
704                 // Set the main proxy icon to be disabled.
705                 proxyPreference.setIcon(R.drawable.proxy_disabled_night);
706
707                 // Set the custom proxy URL icon to be ghosted.
708                 proxyCustomUrlPreference.setIcon(R.drawable.proxy_ghosted_night);
709             } else {  // Light theme.
710                 // Set the main proxy icon to be disabled.
711                 proxyPreference.setIcon(R.drawable.proxy_disabled_day);
712
713                 // Set the custom proxy URL icon to be ghosted.
714                 proxyCustomUrlPreference.setIcon(R.drawable.proxy_ghosted_day);
715             }
716         } else {  // Proxying is enabled.
717             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {  // Dark theme.
718                 // Set the main proxy icon to be enabled.
719                 proxyPreference.setIcon(R.drawable.proxy_enabled_night);
720
721                 // Set the custom proxy URL icon according to its status.
722                 if (proxyCustomUrlPreference.isEnabled()) {  // Custom proxy is enabled.
723                     proxyCustomUrlPreference.setIcon(R.drawable.proxy_enabled_night);
724                 } else {  // Custom proxy is disabled.
725                     proxyCustomUrlPreference.setIcon(R.drawable.proxy_ghosted_night);
726                 }
727             } else {  // Light theme.
728                 // Set the main proxy icon to be enabled.
729                 proxyPreference.setIcon(R.drawable.proxy_enabled_day);
730
731                 // Set the custom proxy URL icon according to its status.
732                 if (proxyCustomUrlPreference.isEnabled()) {  // Custom proxy is enabled.
733                     proxyCustomUrlPreference.setIcon(R.drawable.proxy_enabled_day);
734                 } else {  // Custom proxy is disabled.
735                     proxyCustomUrlPreference.setIcon(R.drawable.proxy_ghosted_day);
736                 }
737             }
738         }
739
740         // Set the full screen browsing mode icons.
741         if (fullScreenBrowsingMode) {  // Full screen browsing mode is enabled.
742             // Set the `fullScreenBrowsingModePreference` icon according to the theme.
743             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
744                 fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_enabled_night);
745             } else {
746                 fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_enabled_day);
747             }
748
749             // Set the hide app bar icon.
750             if (savedPreferences.getBoolean("hide_app_bar", true)) {  // Hide app bar is enabled.
751                 // Set the icon according to the theme.
752                 if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
753                     hideAppBarPreference.setIcon(R.drawable.app_bar_enabled_night);
754                 } else {
755                     hideAppBarPreference.setIcon(R.drawable.app_bar_enabled_day);
756                 }
757             } else {  // Hide app bar is disabled.
758                 // Set the icon according to the theme.
759                 if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
760                     hideAppBarPreference.setIcon(R.drawable.app_bar_disabled_night);
761                 } else {
762                     hideAppBarPreference.setIcon(R.drawable.app_bar_disabled_day);
763                 }
764             }
765         } else {  // Full screen browsing mode is disabled.
766             // Set the icons according to the theme.
767             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
768                 fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_disabled_night);
769                 hideAppBarPreference.setIcon(R.drawable.app_bar_ghosted_night);
770             } else {
771                 fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_disabled_day);
772                 hideAppBarPreference.setIcon(R.drawable.app_bar_ghosted_day);
773             }
774         }
775
776         // Set the clear everything preference icon.
777         if (clearEverything) {
778             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
779                 clearEverythingPreference.setIcon(R.drawable.clear_everything_enabled_night);
780             } else {
781                 clearEverythingPreference.setIcon(R.drawable.clear_everything_enabled_day);
782             }
783         } else {
784             clearEverythingPreference.setIcon(R.drawable.clear_everything_disabled);
785         }
786
787         // Set the clear cookies preference icon.
788         if (clearEverything || savedPreferences.getBoolean("clear_cookies", true)) {
789             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
790                 clearCookiesPreference.setIcon(R.drawable.cookies_cleared_night);
791             } else {
792                 clearCookiesPreference.setIcon(R.drawable.cookies_cleared_day);
793             }
794         } else {
795             clearCookiesPreference.setIcon(R.drawable.cookies_warning);
796         }
797
798         // Set the clear DOM storage preference icon.
799         if (clearEverything || savedPreferences.getBoolean("clear_dom_storage", true)) {
800             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
801                 clearDomStoragePreference.setIcon(R.drawable.dom_storage_cleared_night);
802             } else {
803                 clearDomStoragePreference.setIcon(R.drawable.dom_storage_cleared_day);
804             }
805         } else {
806             clearDomStoragePreference.setIcon(R.drawable.dom_storage_warning);
807         }
808
809         // Set the clear form data preference icon if the API < 26.  It has no effect on newer versions of Android.
810         if (Build.VERSION.SDK_INT < 26) {
811             if (clearEverything || savedPreferences.getBoolean("clear_form_data", true)) {
812                 if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
813                     clearFormDataPreference.setIcon(R.drawable.form_data_cleared_night);
814                 } else {
815                     clearFormDataPreference.setIcon(R.drawable.form_data_cleared_day);
816                 }
817             } else {
818                 clearFormDataPreference.setIcon(R.drawable.form_data_warning);
819             }
820         }
821
822         // Set the clear cache preference icon.
823         if (clearEverything || savedPreferences.getBoolean("clear_cache", true)) {
824             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
825                 clearCachePreference.setIcon(R.drawable.cache_cleared_night);
826             } else {
827                 clearCachePreference.setIcon(R.drawable.cache_cleared_day);
828             }
829         } else {
830             clearCachePreference.setIcon(R.drawable.cache_warning);
831         }
832
833         // Set the download custom location icon.
834         if (downloadCustomLocationPreference.isEnabled()) {
835             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
836                 downloadCustomLocationPreference.setIcon(R.drawable.downloads_enabled_night);
837             } else {
838                 downloadCustomLocationPreference.setIcon(R.drawable.downloads_enabled_day);
839             }
840         } else {
841             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
842                 downloadCustomLocationPreference.setIcon(R.drawable.downloads_ghosted_night);
843             } else {
844                 downloadCustomLocationPreference.setIcon(R.drawable.downloads_ghosted_day);
845             }
846         }
847
848         // Set the open intents in new tab preference icon.
849         if (savedPreferences.getBoolean("open_intents_in_new_tab", true)) {
850             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
851                 openIntentsInNewTabPreference.setIcon(R.drawable.tab_enabled_night);
852             } else {
853                 openIntentsInNewTabPreference.setIcon(R.drawable.tab_enabled_day);
854             }
855         } else {
856             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
857                 openIntentsInNewTabPreference.setIcon(R.drawable.tab_disabled_night);
858             } else {
859                 openIntentsInNewTabPreference.setIcon(R.drawable.tab_disabled_day);
860             }
861         }
862
863         // Set the swipe to refresh preference icon.
864         if (savedPreferences.getBoolean("swipe_to_refresh", true)) {
865             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
866                 swipeToRefreshPreference.setIcon(R.drawable.refresh_enabled_night);
867             } else {
868                 swipeToRefreshPreference.setIcon(R.drawable.refresh_enabled_day);
869             }
870         } else {
871             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
872                 swipeToRefreshPreference.setIcon(R.drawable.refresh_disabled_night);
873             } else {
874                 swipeToRefreshPreference.setIcon(R.drawable.refresh_disabled_day);
875             }
876         }
877
878         // Set the scroll app bar preference icon.
879         if (savedPreferences.getBoolean("scroll_app_bar", true)) {
880             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
881                 scrollAppBarPreference.setIcon(R.drawable.app_bar_enabled_night);
882             } else {
883                 scrollAppBarPreference.setIcon(R.drawable.app_bar_enabled_day);
884             }
885         } else {
886             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
887                 scrollAppBarPreference.setIcon(R.drawable.app_bar_disabled_night);
888             } else {
889                 scrollAppBarPreference.setIcon(R.drawable.app_bar_disabled_day);
890             }
891         }
892
893         // Set the display additional app bar icons preference icon.
894         if (savedPreferences.getBoolean("display_additional_app_bar_icons", false)) {
895             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
896                 displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_enabled_night);
897             } else {
898                 displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_enabled_day);
899             }
900         } else {
901             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
902                 displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_disabled_night);
903             } else {
904                 displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_disabled_day);
905             }
906         }
907
908         // Set the wide viewport preference icon.
909         if (savedPreferences.getBoolean("wide_viewport", true)) {
910             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
911                 wideViewportPreference.setIcon(R.drawable.wide_viewport_enabled_night);
912             } else {
913                 wideViewportPreference.setIcon(R.drawable.wide_viewport_enabled_day);
914             }
915         } else {
916             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
917                 wideViewportPreference.setIcon(R.drawable.wide_viewport_disabled_night);
918             } else {
919                 wideViewportPreference.setIcon(R.drawable.wide_viewport_disabled_day);
920             }
921         }
922
923         // Set the display webpage images preference icon.
924         if (savedPreferences.getBoolean("display_webpage_images", true)) {
925             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
926                 displayWebpageImagesPreference.setIcon(R.drawable.images_enabled_night);
927             } else {
928                 displayWebpageImagesPreference.setIcon(R.drawable.images_enabled_day);
929             }
930         } else {
931             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
932                 displayWebpageImagesPreference.setIcon(R.drawable.images_disabled_night);
933             } else {
934                 displayWebpageImagesPreference.setIcon(R.drawable.images_disabled_day);
935             }
936         }
937
938
939         // Listen for preference changes.
940         preferencesListener = (SharedPreferences sharedPreferences, String key) -> {
941             switch (key) {
942                 case "javascript":
943                     // Update the icons and the DOM storage preference status.
944                     if (sharedPreferences.getBoolean("javascript", false)) {  // The JavaScript preference is enabled.
945                         // Update the icon for the JavaScript preference.
946                         javaScriptPreference.setIcon(R.drawable.javascript_enabled);
947
948                         // Update the status of the DOM storage preference.
949                         domStoragePreference.setEnabled(true);
950
951                         // Update the icon for the DOM storage preference.
952                         if (sharedPreferences.getBoolean("dom_storage", false)) {
953                             domStoragePreference.setIcon(R.drawable.dom_storage_enabled);
954                         } else {
955                             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
956                                 domStoragePreference.setIcon(R.drawable.dom_storage_disabled_night);
957                             } else {
958                                 domStoragePreference.setIcon(R.drawable.dom_storage_disabled_day);
959                             }
960                         }
961                     } else {  // The JavaScript preference is disabled.
962                         // Update the icon for the JavaScript preference.
963                         javaScriptPreference.setIcon(R.drawable.privacy_mode);
964
965                         // Update the status of the DOM storage preference.
966                         domStoragePreference.setEnabled(false);
967
968                         // Set the icon for DOM storage preference to be ghosted.
969                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
970                             domStoragePreference.setIcon(R.drawable.dom_storage_ghosted_night);
971                         } else {
972                             domStoragePreference.setIcon(R.drawable.dom_storage_ghosted_day);
973                         }
974                     }
975                     break;
976
977                 case "first_party_cookies":
978                     // Update the icons for `first_party_cookies` and `third_party_cookies`.
979                     if (sharedPreferences.getBoolean("first_party_cookies", false)) {
980                         // Set the icon for `first_party_cookies`.
981                         firstPartyCookiesPreference.setIcon(R.drawable.cookies_enabled);
982
983                         // Update the icon for `third_party_cookies`.
984                         if (Build.VERSION.SDK_INT >= 21) {
985                             if (sharedPreferences.getBoolean("third_party_cookies", false)) {
986                                 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_warning);
987                             } else {
988                                 if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
989                                     thirdPartyCookiesPreference.setIcon(R.drawable.cookies_disabled_night);
990                                 } else {
991                                     thirdPartyCookiesPreference.setIcon(R.drawable.cookies_disabled_day);
992                                 }
993                             }
994                         } else {
995                             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
996                                 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_ghosted_night);
997                             } else {
998                                 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_ghosted_day);
999                             }
1000                         }
1001                     } else {  // `first_party_cookies` is `false`.
1002                         // Update the icon for `first_party_cookies`.
1003                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1004                             firstPartyCookiesPreference.setIcon(R.drawable.cookies_disabled_night);
1005                         } else {
1006                             firstPartyCookiesPreference.setIcon(R.drawable.cookies_disabled_day);
1007                         }
1008
1009                         // Set the icon for `third_party_cookies` to be ghosted.
1010                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1011                             thirdPartyCookiesPreference.setIcon(R.drawable.cookies_ghosted_night);
1012                         } else {
1013                             thirdPartyCookiesPreference.setIcon(R.drawable.cookies_ghosted_day);
1014                         }
1015                     }
1016
1017                     // Enable `third_party_cookies` if `first_party_cookies` is `true` and API >= 21.
1018                     thirdPartyCookiesPreference.setEnabled(sharedPreferences.getBoolean("first_party_cookies", false) && (Build.VERSION.SDK_INT >= 21));
1019                     break;
1020
1021                 case "third_party_cookies":
1022                     // Update the icon.
1023                     if (sharedPreferences.getBoolean("third_party_cookies", false)) {
1024                         thirdPartyCookiesPreference.setIcon(R.drawable.cookies_warning);
1025                     } else {
1026                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1027                             thirdPartyCookiesPreference.setIcon(R.drawable.cookies_disabled_night);
1028                         } else {
1029                             thirdPartyCookiesPreference.setIcon(R.drawable.cookies_disabled_day);
1030                         }
1031                     }
1032                     break;
1033
1034                 case "dom_storage":
1035                     // Update the icon.
1036                     if (sharedPreferences.getBoolean("dom_storage", false)) {
1037                         domStoragePreference.setIcon(R.drawable.dom_storage_enabled);
1038                     } else {
1039                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1040                             domStoragePreference.setIcon(R.drawable.dom_storage_disabled_night);
1041                         } else {
1042                             domStoragePreference.setIcon(R.drawable.dom_storage_disabled_day);
1043                         }
1044                     }
1045                     break;
1046
1047                 // Save form data can be removed once the minimum API >= 26.
1048                 case "save_form_data":
1049                     // Update the icon.
1050                     if (sharedPreferences.getBoolean("save_form_data", false)) {
1051                         formDataPreference.setIcon(R.drawable.form_data_enabled);
1052                     } else {
1053                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1054                             formDataPreference.setIcon(R.drawable.form_data_disabled_night);
1055                         } else {
1056                             formDataPreference.setIcon(R.drawable.form_data_disabled_day);
1057                         }
1058                     }
1059                     break;
1060
1061                 case "user_agent":
1062                     // Get the new user agent name.
1063                     String newUserAgentName = sharedPreferences.getString("user_agent", getString(R.string.user_agent_default_value));
1064
1065                     // Get the array position for the new user agent name.
1066                     int newUserAgentArrayPosition = userAgentNamesArray.getPosition(newUserAgentName);
1067
1068                     // Get the translated new user agent name.
1069                     String translatedNewUserAgentName = translatedUserAgentNamesArray[newUserAgentArrayPosition];
1070
1071                     // Populate the user agent summary.
1072                     switch (newUserAgentArrayPosition) {
1073                         case MainWebViewActivity.SETTINGS_WEBVIEW_DEFAULT_USER_AGENT:
1074                             // Get the user agent text from the webview (which changes based on the version of Android and WebView installed).
1075                             userAgentPreference.setSummary(translatedNewUserAgentName + ":\n" + bareWebView.getSettings().getUserAgentString());
1076
1077                             // Disable the custom user agent preference.
1078                             customUserAgentPreference.setEnabled(false);
1079
1080                             // Set the custom user agent preference icon according to the theme.
1081                             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1082                                 customUserAgentPreference.setIcon(R.drawable.custom_user_agent_ghosted_night);
1083                             } else {
1084                                 customUserAgentPreference.setIcon(R.drawable.custom_user_agent_ghosted_day);
1085                             }
1086                             break;
1087
1088                         case MainWebViewActivity.SETTINGS_CUSTOM_USER_AGENT:
1089                             // Set the summary text.
1090                             userAgentPreference.setSummary(R.string.custom_user_agent);
1091
1092                             // Enable the custom user agent preference.
1093                             customUserAgentPreference.setEnabled(true);
1094
1095                             // Set the custom user agent preference icon according to the theme.
1096                             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1097                                 customUserAgentPreference.setIcon(R.drawable.custom_user_agent_enabled_night);
1098                             } else {
1099                                 customUserAgentPreference.setIcon(R.drawable.custom_user_agent_enabled_day);
1100                             }
1101                             break;
1102
1103                         default:
1104                             // Get the user agent summary from the user agent data array.
1105                             userAgentPreference.setSummary(translatedNewUserAgentName + ":\n" + userAgentDataArray[newUserAgentArrayPosition]);
1106
1107                             // Disable the custom user agent preference.
1108                             customUserAgentPreference.setEnabled(false);
1109
1110                             // Set the custom user agent preference icon according to the theme.
1111                             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1112                                 customUserAgentPreference.setIcon(R.drawable.custom_user_agent_ghosted_night);
1113                             } else {
1114                                 customUserAgentPreference.setIcon(R.drawable.custom_user_agent_ghosted_day);
1115                             }
1116                     }
1117                     break;
1118
1119                 case "custom_user_agent":
1120                     // Set the new custom user agent as the summary text for the preference.
1121                     customUserAgentPreference.setSummary(sharedPreferences.getString("custom_user_agent", getString(R.string.custom_user_agent_default_value)));
1122                     break;
1123
1124                 case "incognito_mode":
1125                     // Update the icon.
1126                     if (sharedPreferences.getBoolean("incognito_mode", false)) {
1127                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1128                             incognitoModePreference.setIcon(R.drawable.incognito_mode_enabled_night);
1129                         } else {
1130                             incognitoModePreference.setIcon(R.drawable.incognito_mode_enabled_day);
1131                         }
1132                     } else {
1133                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1134                             incognitoModePreference.setIcon(R.drawable.incognito_mode_disabled_night);
1135                         } else {
1136                             incognitoModePreference.setIcon(R.drawable.incognito_mode_disabled_day);
1137                         }
1138                     }
1139                     break;
1140
1141                 case "do_not_track":
1142                     // Update the icon.
1143                     if (sharedPreferences.getBoolean("do_not_track", false)) {
1144                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1145                             doNotTrackPreference.setIcon(R.drawable.block_tracking_enabled_night);
1146                         } else {
1147                             doNotTrackPreference.setIcon(R.drawable.block_tracking_enabled_day);
1148                         }
1149                     } else {
1150                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1151                             doNotTrackPreference.setIcon(R.drawable.block_tracking_disabled_night);
1152                         } else {
1153                             doNotTrackPreference.setIcon(R.drawable.block_tracking_disabled_day);
1154                         }
1155                     }
1156
1157                     break;
1158
1159                 case "allow_screenshots":
1160                     // Update the icon.
1161                     if (sharedPreferences.getBoolean("allow_screenshots", false)) {
1162                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1163                             allowScreenshotsPreference.setIcon(R.drawable.allow_screenshots_enabled_night);
1164                         } else {
1165                             allowScreenshotsPreference.setIcon(R.drawable.allow_screenshots_enabled_day);
1166                         }
1167                     } else {
1168                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1169                             allowScreenshotsPreference.setIcon(R.drawable.allow_screenshots_disabled_night);
1170                         } else {
1171                             allowScreenshotsPreference.setIcon(R.drawable.allow_screenshots_disabled_day);
1172                         }
1173                     }
1174
1175                     // Create an intent to restart Privacy Browser.
1176                     Intent allowScreenshotsRestartIntent = getActivity().getParentActivityIntent();
1177
1178                     // Assert that the intent is not null to remove the lint error below.
1179                     assert allowScreenshotsRestartIntent != null;
1180
1181                     // `Intent.FLAG_ACTIVITY_CLEAR_TASK` removes all activities from the stack.  It requires `Intent.FLAG_ACTIVITY_NEW_TASK`.
1182                     allowScreenshotsRestartIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
1183
1184                     // Create a handler to restart the activity.
1185                     Handler allowScreenshotsRestartHandler = new Handler();
1186
1187                     // Create a runnable to restart the activity.
1188                     Runnable allowScreenshotsRestartRunnable = () -> {
1189                         // Restart the activity.
1190                         startActivity(allowScreenshotsRestartIntent);
1191
1192                         // Kill this instance of Privacy Browser.  Otherwise, the app exhibits sporadic behavior after the restart.
1193                         System.exit(0);
1194                     };
1195
1196                     // Restart the activity after 150 milliseconds, so that the app has enough time to save the change to the preference.
1197                     allowScreenshotsRestartHandler.postDelayed(allowScreenshotsRestartRunnable, 150);
1198                     break;
1199
1200                 case "easylist":
1201                     // Update the icon.
1202                     if (sharedPreferences.getBoolean("easylist", true)) {
1203                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1204                             easyListPreference.setIcon(R.drawable.block_ads_enabled_night);
1205                         } else {
1206                             easyListPreference.setIcon(R.drawable.block_ads_enabled_day);
1207                         }
1208                     } else {
1209                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1210                             easyListPreference.setIcon(R.drawable.block_ads_disabled_night);
1211                         } else {
1212                             easyListPreference.setIcon(R.drawable.block_ads_disabled_day);
1213                         }
1214                     }
1215                     break;
1216
1217                 case "easyprivacy":
1218                     // Update the icon.
1219                     if (sharedPreferences.getBoolean("easyprivacy", true)) {
1220                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1221                             easyPrivacyPreference.setIcon(R.drawable.block_tracking_enabled_night);
1222                         } else {
1223                             easyPrivacyPreference.setIcon(R.drawable.block_tracking_enabled_day);
1224                         }
1225                     } else {
1226                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1227                             easyPrivacyPreference.setIcon(R.drawable.block_tracking_disabled_night);
1228                         } else {
1229                             easyPrivacyPreference.setIcon(R.drawable.block_tracking_disabled_day);
1230                         }
1231                     }
1232                     break;
1233
1234                 case "fanboys_annoyance_list":
1235                     boolean currentFanboyAnnoyanceList = sharedPreferences.getBoolean("fanboys_annoyance_list", true);
1236                     boolean currentFanboySocialBlockingList = sharedPreferences.getBoolean("fanboys_social_blocking_list", true);
1237
1238                     // Update the Fanboy icons.
1239                     if (currentFanboyAnnoyanceList) {  // Fanboy's annoyance list is enabled.
1240                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1241                             // Update the Fanboy's annoyance list icon.
1242                             fanboyAnnoyanceListPreference.setIcon(R.drawable.social_media_enabled_night);
1243
1244                             // Update the Fanboy's social blocking list icon.
1245                             fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_ghosted_night);
1246                         } else {
1247                             // Update the Fanboy's annoyance list icon.
1248                             fanboyAnnoyanceListPreference.setIcon(R.drawable.social_media_enabled_day);
1249
1250                             // Update the Fanboy's social blocking list icon.
1251                             fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_ghosted_day);
1252                         }
1253                     } else {  // Fanboy's annoyance list is disabled.
1254                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1255                             // Update the Fanboy's annoyance list icon.
1256                             fanboyAnnoyanceListPreference.setIcon(R.drawable.social_media_disabled_night);
1257
1258                             // Update the Fanboy's social blocking list icon.
1259                             if (currentFanboySocialBlockingList) {
1260                                 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_enabled_night);
1261                             } else {
1262                                 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_disabled_night);
1263                             }
1264                         } else {
1265                             // Update the Fanboy's annoyance list icon.
1266                             fanboyAnnoyanceListPreference.setIcon(R.drawable.social_media_disabled_day);
1267
1268                             // Update the Fanboy's social blocking list icon.
1269                             if (currentFanboySocialBlockingList) {
1270                                 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_enabled_day);
1271                             } else {
1272                                 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_disabled_day);
1273                             }
1274                         }
1275                     }
1276
1277                     // Only enable Fanboy's social blocking list preference if Fanboy's annoyance list preference is disabled.
1278                     fanboySocialBlockingListPreference.setEnabled(!currentFanboyAnnoyanceList);
1279                     break;
1280
1281                 case "fanboys_social_blocking_list":
1282                     // Update the icon.
1283                     if (sharedPreferences.getBoolean("fanboys_social_blocking_list", true)) {
1284                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1285                             fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_enabled_night);
1286                         } else {
1287                             fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_enabled_day);
1288                         }
1289                     } else {
1290                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1291                             fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_disabled_night);
1292                         } else {
1293                             fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_disabled_day);
1294                         }
1295                     }
1296                     break;
1297
1298                 case "ultralist":
1299                     // Update the icon.
1300                     if (sharedPreferences.getBoolean("ultralist", true)) {
1301                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1302                             ultraListPreference.setIcon(R.drawable.block_ads_enabled_night);
1303                         } else {
1304                             ultraListPreference.setIcon(R.drawable.block_ads_enabled_day);
1305                         }
1306                     } else {
1307                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1308                             ultraListPreference.setIcon(R.drawable.block_ads_disabled_night);
1309                         } else {
1310                             ultraListPreference.setIcon(R.drawable.block_ads_disabled_day);
1311                         }
1312                     }
1313                     break;
1314
1315                 case "ultraprivacy":
1316                     // Update the icon.
1317                     if (sharedPreferences.getBoolean("ultraprivacy", true)) {
1318                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1319                             ultraPrivacyPreference.setIcon(R.drawable.block_tracking_enabled_night);
1320                         } else {
1321                             ultraPrivacyPreference.setIcon(R.drawable.block_tracking_enabled_day);
1322                         }
1323                     } else {
1324                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1325                             ultraPrivacyPreference.setIcon(R.drawable.block_tracking_disabled_night);
1326                         } else {
1327                             ultraPrivacyPreference.setIcon(R.drawable.block_tracking_disabled_day);
1328                         }
1329                     }
1330                     break;
1331
1332                 case "block_all_third_party_requests":
1333                     // Update the icon.
1334                     if (sharedPreferences.getBoolean("block_all_third_party_requests", false)) {
1335                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1336                             blockAllThirdPartyRequestsPreference.setIcon(R.drawable.block_all_third_party_requests_enabled_night);
1337                         } else {
1338                             blockAllThirdPartyRequestsPreference.setIcon(R.drawable.block_all_third_party_requests_enabled_day);
1339                         }
1340                     } else {
1341                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1342                             blockAllThirdPartyRequestsPreference.setIcon(R.drawable.block_all_third_party_requests_disabled_night);
1343                         } else {
1344                             blockAllThirdPartyRequestsPreference.setIcon(R.drawable.block_all_third_party_requests_disabled_day);
1345                         }
1346                     }
1347                     break;
1348
1349                 case "google_analytics":
1350                     // Update the icon.
1351                     if (sharedPreferences.getBoolean("google_analytics", true)) {
1352                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1353                             googleAnalyticsPreference.setIcon(R.drawable.modify_url_enabled_night);
1354                         } else {
1355                             googleAnalyticsPreference.setIcon(R.drawable.modify_url_enabled_day);
1356                         }
1357                     } else {
1358                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1359                             googleAnalyticsPreference.setIcon(R.drawable.modify_url_disabled_night);
1360                         } else {
1361                             googleAnalyticsPreference.setIcon(R.drawable.modify_url_disabled_day);
1362                         }
1363                     }
1364                     break;
1365
1366                 case "facebook_click_ids":
1367                     // Update the icon.
1368                     if (sharedPreferences.getBoolean("facebook_click_ids", true)) {
1369                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1370                             facebookClickIdsPreference.setIcon(R.drawable.modify_url_enabled_night);
1371                         } else {
1372                             facebookClickIdsPreference.setIcon(R.drawable.modify_url_enabled_day);
1373                         }
1374                     } else {
1375                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1376                             facebookClickIdsPreference.setIcon(R.drawable.modify_url_disabled_night);
1377                         } else {
1378                             facebookClickIdsPreference.setIcon(R.drawable.modify_url_disabled_day);
1379                         }
1380                     }
1381                     break;
1382
1383                 case "twitter_amp_redirects":
1384                     // Update the icon.
1385                     if (sharedPreferences.getBoolean("twitter_amp_redirects", true)) {
1386                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1387                             twitterAmpRedirectsPreference.setIcon(R.drawable.modify_url_enabled_night);
1388                         } else {
1389                             twitterAmpRedirectsPreference.setIcon(R.drawable.modify_url_enabled_day);
1390                         }
1391                     } else {
1392                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1393                             twitterAmpRedirectsPreference.setIcon(R.drawable.modify_url_disabled_night);
1394                         } else {
1395                             twitterAmpRedirectsPreference.setIcon(R.drawable.modify_url_disabled_day);
1396                         }
1397                     }
1398                     break;
1399
1400                 case "search":
1401                     // Store the new search string.
1402                     String newSearchString = sharedPreferences.getString("search", getString(R.string.search_default_value));
1403
1404                     // Update the search and search custom URL preferences.
1405                     if (newSearchString.equals("Custom URL")) {  // `Custom URL` is selected.
1406                         // Set the summary text to `R.string.custom_url`, which is translated.
1407                         searchPreference.setSummary(R.string.custom_url);
1408
1409                         // Enable `searchCustomURLPreference`.
1410                         searchCustomURLPreference.setEnabled(true);
1411
1412                         // Set the `searchCustomURLPreference` according to the theme.
1413                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1414                             searchCustomURLPreference.setIcon(R.drawable.search_custom_url_enabled_night);
1415                         } else {
1416                             searchCustomURLPreference.setIcon(R.drawable.search_custom_url_enabled_day);
1417                         }
1418                     } else {  // `Custom URL` is not selected.
1419                         // Set the summary text to `newSearchString`.
1420                         searchPreference.setSummary(newSearchString);
1421
1422                         // Disable `searchCustomURLPreference`.
1423                         searchCustomURLPreference.setEnabled(false);
1424
1425                         // Set the `searchCustomURLPreference` according to the theme.
1426                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1427                             searchCustomURLPreference.setIcon(R.drawable.search_custom_url_ghosted_night);
1428                         } else {
1429                             searchCustomURLPreference.setIcon(R.drawable.search_custom_url_ghosted_day);
1430                         }
1431                     }
1432                     break;
1433
1434                 case "search_custom_url":
1435                     // Set the new search custom URL as the summary text for the preference.
1436                     searchCustomURLPreference.setSummary(sharedPreferences.getString("search_custom_url", getString(R.string.search_custom_url_default_value)));
1437                     break;
1438
1439                 case "proxy":
1440                     // Get current proxy string.
1441                     String currentProxyString = sharedPreferences.getString("proxy", getString(R.string.proxy_default_value));
1442
1443                     // Update the summary text for the proxy preference.
1444                     switch (currentProxyString) {
1445                         case ProxyHelper.NONE:
1446                             proxyPreference.setSummary(getString(R.string.no_proxy_enabled));
1447                             break;
1448
1449                         case ProxyHelper.TOR:
1450                             if (Build.VERSION.SDK_INT == 19) {  // Proxying through SOCKS doesn't work on Android KitKat.
1451                                 proxyPreference.setSummary(getString(R.string.tor_enabled_kitkat));
1452                             } else {
1453                                 proxyPreference.setSummary(getString(R.string.tor_enabled));
1454                             }
1455                             break;
1456
1457                         case ProxyHelper.I2P:
1458                             proxyPreference.setSummary(getString(R.string.i2p_enabled));
1459                             break;
1460
1461                         case ProxyHelper.CUSTOM:
1462                             proxyPreference.setSummary(getString(R.string.custom_proxy));
1463                             break;
1464                     }
1465
1466                     // Update the status of the custom URL preference.
1467                     proxyCustomUrlPreference.setEnabled(currentProxyString.equals("Custom"));
1468
1469                     // Update the icons.
1470                     if (currentProxyString.equals("None")) {  // Proxying is disabled.
1471                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {  // Dark theme.
1472                             // Set the main proxy icon to be disabled
1473                             proxyPreference.setIcon(R.drawable.proxy_disabled_night);
1474
1475                             // Set the custom proxy URL icon to be ghosted.
1476                             proxyCustomUrlPreference.setIcon(R.drawable.proxy_ghosted_night);
1477                         } else {  // Light theme.
1478                             // Set the main proxy icon to be disabled.
1479                             proxyPreference.setIcon(R.drawable.proxy_disabled_day);
1480
1481                             // Set the custom proxy URL icon to be ghosted.
1482                             proxyCustomUrlPreference.setIcon(R.drawable.proxy_ghosted_day);
1483                         }
1484                     } else {  // Proxying is enabled.
1485                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {  // Dark theme.
1486                             // Set the main proxy icon to be enabled.
1487                             proxyPreference.setIcon(R.drawable.proxy_enabled_night);
1488
1489                             /// Set the custom proxy URL icon according to its status.
1490                             if (proxyCustomUrlPreference.isEnabled()) {  // Custom proxy is enabled.
1491                                 proxyCustomUrlPreference.setIcon(R.drawable.proxy_enabled_night);
1492                             } else {  // Custom proxy is disabled.
1493                                 proxyCustomUrlPreference.setIcon(R.drawable.proxy_ghosted_night);
1494                             }
1495                         } else {  // Light theme.
1496                             // Set the main proxy icon to be enabled.
1497                             proxyPreference.setIcon(R.drawable.proxy_enabled_day);
1498
1499                             // Set the custom proxy URL icon according to its status.
1500                             if (proxyCustomUrlPreference.isEnabled()) {  // Custom proxy is enabled.
1501                                 proxyCustomUrlPreference.setIcon(R.drawable.proxy_enabled_day);
1502                             } else {  // Custom proxy is disabled.
1503                                 proxyCustomUrlPreference.setIcon(R.drawable.proxy_ghosted_day);
1504                             }
1505                         }
1506                     }
1507                     break;
1508
1509                 case "proxy_custom_url":
1510                     // Set the summary text for the proxy custom URL.
1511                     proxyCustomUrlPreference.setSummary(sharedPreferences.getString("proxy_custom_url", getString(R.string.proxy_custom_url_default_value)));
1512                     break;
1513
1514                 case "full_screen_browsing_mode":
1515                     if (sharedPreferences.getBoolean("full_screen_browsing_mode", false)) {  // Full screen browsing is enabled.
1516                         // Set the full screen browsing mode preference icon according to the theme.
1517                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1518                             fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_enabled_night);
1519                         } else {
1520                             fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_enabled_day);
1521                         }
1522
1523                         // Set the hide app bar preference icon.
1524                         if (sharedPreferences.getBoolean("hide_app_bar", true)) {  //  Hide app bar is enabled.
1525                             // Set the icon according to the theme.
1526                             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1527                                 hideAppBarPreference.setIcon(R.drawable.app_bar_enabled_night);
1528                             } else {
1529                                 hideAppBarPreference.setIcon(R.drawable.app_bar_enabled_day);
1530                             }
1531                         } else {  // Hide app bar is disabled.
1532                             // Set the icon according to the theme.
1533                             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1534                                 hideAppBarPreference.setIcon(R.drawable.app_bar_disabled_night);
1535                             } else {
1536                                 hideAppBarPreference.setIcon(R.drawable.app_bar_disabled_day);
1537                             }
1538                         }
1539                     } else {  // Full screen browsing is disabled.
1540                         // Update the icons according to the theme.
1541                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1542                             fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_disabled_night);
1543                             hideAppBarPreference.setIcon(R.drawable.app_bar_ghosted_night);
1544                         } else {
1545                             fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_disabled_day);
1546                             hideAppBarPreference.setIcon(R.drawable.app_bar_ghosted_day);
1547                         }
1548                     }
1549                     break;
1550
1551                 case "hide_app_bar":
1552                     // Update the icon.
1553                     if (sharedPreferences.getBoolean("hide_app_bar", true)) {  // Hide app bar is enabled.
1554                         // Set the icon according to the theme.
1555                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1556                             hideAppBarPreference.setIcon(R.drawable.app_bar_enabled_night);
1557                         } else {
1558                             hideAppBarPreference.setIcon(R.drawable.app_bar_enabled_day);
1559                         }
1560                     } else {  // Hide app bar is disabled.
1561                         // Set the icon according to the theme.
1562                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1563                             hideAppBarPreference.setIcon(R.drawable.app_bar_disabled_night);
1564                         } else {
1565                             hideAppBarPreference.setIcon(R.drawable.app_bar_disabled_day);
1566                         }
1567                     }
1568                     break;
1569
1570                 case "clear_everything":
1571                     // Store the new `clear_everything` status
1572                     boolean newClearEverythingBoolean = sharedPreferences.getBoolean("clear_everything", true);
1573
1574                     // Update the status of the `Clear and Exit` preferences.
1575                     clearCookiesPreference.setEnabled(!newClearEverythingBoolean);
1576                     clearDomStoragePreference.setEnabled(!newClearEverythingBoolean);
1577                     clearFormDataPreference.setEnabled(!newClearEverythingBoolean);  // This line can be removed once the minimum API >= 26.
1578                     clearCachePreference.setEnabled(!newClearEverythingBoolean);
1579
1580                     // Update the `clearEverythingPreference` icon.
1581                     if (newClearEverythingBoolean) {
1582                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1583                             clearEverythingPreference.setIcon(R.drawable.clear_everything_enabled_night);
1584                         } else {
1585                             clearEverythingPreference.setIcon(R.drawable.clear_everything_enabled_day);
1586                         }
1587                     } else {
1588                         clearEverythingPreference.setIcon(R.drawable.clear_everything_disabled);
1589                     }
1590
1591                     // Update the `clearCookiesPreference` icon.
1592                     if (newClearEverythingBoolean || sharedPreferences.getBoolean("clear_cookies", true)) {
1593                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1594                             clearCookiesPreference.setIcon(R.drawable.cookies_cleared_night);
1595                         } else {
1596                             clearCookiesPreference.setIcon(R.drawable.cookies_cleared_day);
1597                         }
1598                     } else {
1599                         clearCookiesPreference.setIcon(R.drawable.cookies_warning);
1600                     }
1601
1602                     // Update the `clearDomStoragePreference` icon.
1603                     if (newClearEverythingBoolean || sharedPreferences.getBoolean("clear_dom_storage", true)) {
1604                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1605                             clearDomStoragePreference.setIcon(R.drawable.dom_storage_cleared_night);
1606                         } else {
1607                             clearDomStoragePreference.setIcon(R.drawable.dom_storage_cleared_day);
1608                         }
1609                     } else {
1610                         clearDomStoragePreference.setIcon(R.drawable.dom_storage_warning);
1611                     }
1612
1613                     // Update the clear form data preference icon if the API < 26.
1614                     if (Build.VERSION.SDK_INT < 26) {
1615                         if (newClearEverythingBoolean || sharedPreferences.getBoolean("clear_form_data", true)) {
1616                             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1617                                 clearFormDataPreference.setIcon(R.drawable.form_data_cleared_night);
1618                             } else {
1619                                 clearFormDataPreference.setIcon(R.drawable.form_data_cleared_day);
1620                             }
1621                         } else {
1622                             clearFormDataPreference.setIcon(R.drawable.form_data_warning);
1623                         }
1624                     }
1625
1626                     // Update the `clearCachePreference` icon.
1627                     if (newClearEverythingBoolean || sharedPreferences.getBoolean("clear_cache", true)) {
1628                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1629                             clearCachePreference.setIcon(R.drawable.cache_cleared_night);
1630                         } else {
1631                             clearCachePreference.setIcon(R.drawable.cache_cleared_day);
1632                         }
1633                     } else {
1634                         clearCachePreference.setIcon(R.drawable.cache_warning);
1635                     }
1636                     break;
1637
1638                 case "clear_cookies":
1639                     // Update the icon.
1640                     if (sharedPreferences.getBoolean("clear_cookies", true)) {
1641                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1642                             clearCookiesPreference.setIcon(R.drawable.cookies_cleared_night);
1643                         } else {
1644                             clearCookiesPreference.setIcon(R.drawable.cookies_cleared_day);
1645                         }
1646                     } else {
1647                         clearCookiesPreference.setIcon(R.drawable.cookies_warning);
1648                     }
1649                     break;
1650
1651                 case "clear_dom_storage":
1652                     // Update the icon.
1653                     if (sharedPreferences.getBoolean("clear_dom_storage", true)) {
1654                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1655                             clearDomStoragePreference.setIcon(R.drawable.dom_storage_cleared_night);
1656                         } else {
1657                             clearDomStoragePreference.setIcon(R.drawable.dom_storage_cleared_day);
1658                         }
1659                     } else {
1660                         clearDomStoragePreference.setIcon(R.drawable.dom_storage_warning);
1661                     }
1662                     break;
1663
1664                 // This section can be removed once the minimum API >= 26.
1665                 case "clear_form_data":
1666                     // Update the icon.
1667                     if (sharedPreferences.getBoolean("clear_form_data", true)) {
1668                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1669                             clearFormDataPreference.setIcon(R.drawable.form_data_cleared_night);
1670                         } else {
1671                             clearFormDataPreference.setIcon(R.drawable.form_data_cleared_day);
1672                         }
1673                     } else {
1674                         clearFormDataPreference.setIcon(R.drawable.form_data_warning);
1675                     }
1676                     break;
1677
1678                 case "clear_cache":
1679                     // Update the icon.
1680                     if (sharedPreferences.getBoolean("clear_cache", true)) {
1681                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1682                             clearCachePreference.setIcon(R.drawable.cache_cleared_night);
1683                         } else {
1684                             clearCachePreference.setIcon(R.drawable.cache_cleared_day);
1685                         }
1686                     } else {
1687                         clearCachePreference.setIcon(R.drawable.cache_warning);
1688                     }
1689                     break;
1690
1691                 case "homepage":
1692                     // Set the new homepage URL as the summary text for the Homepage preference.
1693                     homepagePreference.setSummary(sharedPreferences.getString("homepage", getString(R.string.homepage_default_value)));
1694                     break;
1695
1696                 case "download_location":
1697                     // Get the new download location.
1698                     String newDownloadLocationString = sharedPreferences.getString("download_location", getString(R.string.download_location_default_value));
1699
1700                     // Check to see if a download custom location is selected.
1701                     if (newDownloadLocationString.equals(downloadLocationEntryValuesStringArray[3])) {  // A download custom location is selected.
1702                         // Set the download location summary text to be `Custom`.
1703                         downloadLocationPreference.setSummary(downloadLocationEntriesStringArray[3]);
1704
1705                         // Enable the download custom location preference.
1706                         downloadCustomLocationPreference.setEnabled(true);
1707                     } else {  // A download custom location is not selected.
1708                         // Set the download location summary text to be the download location.
1709                         downloadLocationPreference.setSummary(downloadLocationHelper.getDownloadLocation(context));
1710
1711                         // Disable the download custom location.
1712                         downloadCustomLocationPreference.setEnabled(newDownloadLocationString.equals(downloadLocationEntryValuesStringArray[3]));
1713                     }
1714
1715                     // Update the download custom location icon.
1716                     if (downloadCustomLocationPreference.isEnabled()) {
1717                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1718                             downloadCustomLocationPreference.setIcon(R.drawable.downloads_enabled_night);
1719                         } else {
1720                             downloadCustomLocationPreference.setIcon(R.drawable.downloads_enabled_day);
1721                         }
1722                     } else {
1723                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1724                             downloadCustomLocationPreference.setIcon(R.drawable.downloads_ghosted_night);
1725                         } else {
1726                             downloadCustomLocationPreference.setIcon(R.drawable.downloads_ghosted_day);
1727                         }
1728                     }
1729                     break;
1730
1731                 case "download_custom_location":
1732                     // Set the new download custom location as the summary text for the preference.
1733                     downloadCustomLocationPreference.setSummary(sharedPreferences.getString("download_custom_location", getString(R.string.download_custom_location_default_value)));
1734                     break;
1735
1736                 case "font_size":
1737                     // Update the font size summary text.
1738                     fontSizePreference.setSummary(sharedPreferences.getString("font_size", getString(R.string.font_size_default_value)) + "%");
1739                     break;
1740
1741                 case "open_intents_in_new_tab":
1742                     // Update the icon.
1743                     if (sharedPreferences.getBoolean("open_intents_in_new_tab", true)) {
1744                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1745                             openIntentsInNewTabPreference.setIcon(R.drawable.tab_enabled_night);
1746                         } else {
1747                             openIntentsInNewTabPreference.setIcon(R.drawable.tab_enabled_day);
1748                         }
1749                     } else {
1750                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1751                             openIntentsInNewTabPreference.setIcon(R.drawable.tab_disabled_night);
1752                         } else {
1753                             openIntentsInNewTabPreference.setIcon(R.drawable.tab_disabled_day);
1754                         }
1755                     }
1756                     break;
1757
1758                 case "swipe_to_refresh":
1759                     // Update the icon.
1760                     if (sharedPreferences.getBoolean("swipe_to_refresh", true)) {
1761                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1762                             swipeToRefreshPreference.setIcon(R.drawable.refresh_enabled_night);
1763                         } else {
1764                             swipeToRefreshPreference.setIcon(R.drawable.refresh_enabled_day);
1765                         }
1766                     } else {
1767                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1768                             swipeToRefreshPreference.setIcon(R.drawable.refresh_disabled_night);
1769                         } else {
1770                             swipeToRefreshPreference.setIcon(R.drawable.refresh_disabled_day);
1771                         }
1772                     }
1773                     break;
1774
1775                 case "scroll_app_bar":
1776                     // Update the icon.
1777                     if (sharedPreferences.getBoolean("scroll_app_bar", true)) {
1778                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1779                             scrollAppBarPreference.setIcon(R.drawable.app_bar_enabled_night);
1780                         } else {
1781                             scrollAppBarPreference.setIcon(R.drawable.app_bar_enabled_day);
1782                         }
1783                     } else {
1784                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1785                             scrollAppBarPreference.setIcon(R.drawable.app_bar_disabled_night);
1786                         } else {
1787                             scrollAppBarPreference.setIcon(R.drawable.app_bar_disabled_day);
1788                         }
1789                     }
1790                     break;
1791
1792                 case "display_additional_app_bar_icons":
1793                     // Update the icon.
1794                     if (sharedPreferences.getBoolean("display_additional_app_bar_icons", false)) {
1795                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1796                             displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_enabled_night);
1797                         } else {
1798                             displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_enabled_day);
1799                         }
1800                     } else {
1801                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1802                             displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_disabled_night);
1803                         } else {
1804                             displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_disabled_day);
1805                         }
1806                     }
1807                     break;
1808
1809                 case "app_theme":
1810                     // Get the new theme.
1811                     String newAppTheme = sharedPreferences.getString("app_theme", getString(R.string.app_theme_default_value));
1812
1813                     // Update the system according to the new theme.  A switch statement cannot be used because the theme entry values string array is not a compile time constant.
1814                     if (newAppTheme.equals(appThemeEntryValuesStringArray[1])) {  // The light theme is selected.
1815                         // Update the theme preference summary text.
1816                         appThemePreference.setSummary(appThemeEntriesStringArray[1]);
1817
1818                         // Apply the new theme.
1819                         AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
1820                     } else if (newAppTheme.equals(appThemeEntryValuesStringArray[2])) {  // The dark theme is selected.
1821                         // Update the theme preference summary text.
1822                         appThemePreference.setSummary(appThemeEntriesStringArray[2]);
1823
1824                         // Apply the new theme.
1825                         AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
1826                     } else {  // The system default theme is selected.
1827                         // Update the theme preference summary text.
1828                         appThemePreference.setSummary(appThemeEntriesStringArray[0]);
1829
1830                         // Apply the new theme.
1831                         if (Build.VERSION.SDK_INT >= 28) {  // The system default theme is supported.
1832                             // Follow the system default theme.
1833                             AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);
1834                         } else {// The system default theme is not supported.
1835                             // Follow the battery saver mode.
1836                             AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY);
1837                         }
1838                     }
1839
1840                     // Update the current theme status.
1841                     currentThemeStatus = getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
1842                     break;
1843
1844                 case "webview_theme":
1845                     // Get the new WebView theme.
1846                     String newWebViewTheme = sharedPreferences.getString("webview_theme", getString(R.string.webview_theme_default_value));
1847
1848                     // Define a new WebView theme entry number.
1849                     int newWebViewThemeEntryNumber;
1850
1851                     // Get the webView theme entry number that matches the new WebView theme.  A switch statement cannot be used because the theme entry values string array is not a compile time constant.
1852                     if (newWebViewTheme.equals(webViewThemeEntriesStringArray[1])) {  // The light theme is selected.
1853                         // Store the new WebView theme entry number.
1854                         newWebViewThemeEntryNumber = 1;
1855                     } else if (newWebViewTheme.equals(webViewThemeEntryValuesStringArray[2])) {  // The dark theme is selected.
1856                         // Store the WebView theme entry number.
1857                         newWebViewThemeEntryNumber = 2;
1858                     } else {  // The system default theme is selected.
1859                         // Store the WebView theme entry number.
1860                         newWebViewThemeEntryNumber = 0;
1861                     }
1862
1863                     // Set the current theme as the summary text for the preference.
1864                     webViewThemePreference.setSummary(webViewThemeEntriesStringArray[newWebViewThemeEntryNumber]);
1865                     break;
1866
1867                 case "wide_viewport":
1868                     // Update the icon.
1869                     if (sharedPreferences.getBoolean("wide_viewport", true)) {
1870                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1871                             wideViewportPreference.setIcon(R.drawable.wide_viewport_enabled_night);
1872                         } else {
1873                             wideViewportPreference.setIcon(R.drawable.wide_viewport_enabled_day);
1874                         }
1875                     } else {
1876                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1877                             wideViewportPreference.setIcon(R.drawable.wide_viewport_disabled_night);
1878                         } else {
1879                             wideViewportPreference.setIcon(R.drawable.wide_viewport_disabled_day);
1880                         }
1881                     }
1882                     break;
1883
1884                 case "display_webpage_images":
1885                     // Update the icon.
1886                     if (sharedPreferences.getBoolean("display_webpage_images", true)) {
1887                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1888                             displayWebpageImagesPreference.setIcon(R.drawable.images_enabled_night);
1889                         } else {
1890                             displayWebpageImagesPreference.setIcon(R.drawable.images_enabled_day);
1891                         }
1892                     } else {
1893                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1894                             displayWebpageImagesPreference.setIcon(R.drawable.images_disabled_night);
1895                         } else {
1896                             displayWebpageImagesPreference.setIcon(R.drawable.images_disabled_day);
1897                         }
1898                     }
1899                     break;
1900             }
1901         };
1902
1903         // Register the listener.
1904         savedPreferences.registerOnSharedPreferenceChangeListener(preferencesListener);
1905     }
1906
1907     // 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.
1908     @Override
1909     public void onPause() {
1910         super.onPause();
1911         savedPreferences.unregisterOnSharedPreferenceChangeListener(preferencesListener);
1912     }
1913
1914     @Override
1915     public void onResume() {
1916         super.onResume();
1917         savedPreferences.registerOnSharedPreferenceChangeListener(preferencesListener);
1918     }
1919 }