]> gitweb.stoutner.com Git - PrivacyBrowserAndroid.git/blob - app/src/main/java/com/stoutner/privacybrowser/fragments/SettingsFragment.java
Redesign file access to work with the scoped storage. https://redmine.stoutner.com...
[PrivacyBrowserAndroid.git] / app / src / main / java / com / stoutner / privacybrowser / fragments / SettingsFragment.java
1 /*
2  * Copyright © 2016-2021 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.os.Looper;
33 import android.view.LayoutInflater;
34 import android.view.View;
35 import android.webkit.WebView;
36 import android.widget.ArrayAdapter;
37
38 import androidx.appcompat.app.AppCompatDelegate;
39 import androidx.preference.Preference;
40 import androidx.preference.PreferenceCategory;
41 import androidx.preference.PreferenceFragmentCompat;
42
43 import com.stoutner.privacybrowser.R;
44 import com.stoutner.privacybrowser.activities.MainWebViewActivity;
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(getString(R.string.allow_screenshots_key));
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 clearLogcatPreference = findPreference(getString(R.string.clear_logcat_key));
106         Preference clearCachePreference = findPreference("clear_cache");
107         Preference homepagePreference = findPreference("homepage");
108         Preference fontSizePreference = findPreference("font_size");
109         Preference openIntentsInNewTabPreference = findPreference("open_intents_in_new_tab");
110         Preference swipeToRefreshPreference = findPreference("swipe_to_refresh");
111         Preference scrollAppBarPreference = findPreference("scroll_app_bar");
112         Preference displayAdditionalAppBarIconsPreference = findPreference("display_additional_app_bar_icons");
113         Preference appThemePreference = findPreference("app_theme");
114         Preference webViewThemePreference = findPreference("webview_theme");
115         Preference wideViewportPreference = findPreference("wide_viewport");
116         Preference displayWebpageImagesPreference = findPreference("display_webpage_images");
117
118         // Remove the lint warnings below that the preferences might be null.
119         assert javaScriptPreference != null;
120         assert firstPartyCookiesPreference != null;
121         assert thirdPartyCookiesPreference != null;
122         assert domStoragePreference != null;
123         assert formDataPreference != null;
124         assert userAgentPreference != null;
125         assert customUserAgentPreference != null;
126         assert incognitoModePreference != null;
127         assert doNotTrackPreference != null;
128         assert allowScreenshotsPreference != null;
129         assert easyListPreference != null;
130         assert easyPrivacyPreference != null;
131         assert fanboyAnnoyanceListPreference != null;
132         assert fanboySocialBlockingListPreference != null;
133         assert ultraListPreference != null;
134         assert ultraPrivacyPreference != null;
135         assert blockAllThirdPartyRequestsPreference != null;
136         assert googleAnalyticsPreference != null;
137         assert facebookClickIdsPreference != null;
138         assert twitterAmpRedirectsPreference != null;
139         assert searchPreference != null;
140         assert searchCustomURLPreference != null;
141         assert proxyPreference != null;
142         assert proxyCustomUrlPreference != null;
143         assert fullScreenBrowsingModePreference != null;
144         assert hideAppBarPreference != null;
145         assert clearEverythingPreference != null;
146         assert clearCookiesPreference != null;
147         assert clearDomStoragePreference != null;
148         assert clearFormDataPreference != null;
149         assert clearLogcatPreference != null;
150         assert clearCachePreference != null;
151         assert homepagePreference != null;
152         assert fontSizePreference != null;
153         assert openIntentsInNewTabPreference != null;
154         assert swipeToRefreshPreference != null;
155         assert scrollAppBarPreference != null;
156         assert displayAdditionalAppBarIconsPreference != null;
157         assert appThemePreference != null;
158         assert webViewThemePreference != null;
159         assert wideViewportPreference != null;
160         assert displayWebpageImagesPreference != null;
161
162         // Set the preference dependencies.
163         hideAppBarPreference.setDependency("full_screen_browsing_mode");
164         domStoragePreference.setDependency("javascript");
165
166         // Get strings from the preferences.
167         String userAgentName = savedPreferences.getString("user_agent", getString(R.string.user_agent_default_value));
168         String searchString = savedPreferences.getString("search", getString(R.string.search_default_value));
169         String proxyString = savedPreferences.getString("proxy", getString(R.string.proxy_default_value));
170
171         // Get booleans that are used in multiple places from the preferences.
172         boolean javaScriptEnabled = savedPreferences.getBoolean("javascript", false);
173         boolean firstPartyCookiesEnabled = savedPreferences.getBoolean("first_party_cookies", false);
174         boolean fanboyAnnoyanceListEnabled = savedPreferences.getBoolean("fanboys_annoyance_list", true);
175         boolean fanboySocialBlockingEnabled = savedPreferences.getBoolean("fanboys_social_blocking_list", true);
176         boolean fullScreenBrowsingMode = savedPreferences.getBoolean("full_screen_browsing_mode", false);
177         boolean clearEverything = savedPreferences.getBoolean("clear_everything", true);
178
179         // Only enable the third-party cookies preference if first-party cookies are enabled and API >= 21.
180         thirdPartyCookiesPreference.setEnabled(firstPartyCookiesEnabled && (Build.VERSION.SDK_INT >= 21));
181
182         // Remove the form data preferences if the API is >= 26 as they no longer do anything.
183         if (Build.VERSION.SDK_INT >= 26) {
184             // Get handles for the categories.
185             PreferenceCategory privacyCategory = findPreference("privacy");
186             PreferenceCategory clearAndExitCategory = findPreference("clear_and_exit");
187
188             // Remove the incorrect lint warnings below that the preference categories might be null.
189             assert privacyCategory != null;
190             assert clearAndExitCategory != null;
191
192             // Remove the form data preferences.
193             privacyCategory.removePreference(formDataPreference);
194             clearAndExitCategory.removePreference(clearFormDataPreference);
195         }
196
197         // Only enable Fanboy's social blocking list preference if Fanboy's annoyance list is disabled.
198         fanboySocialBlockingListPreference.setEnabled(!fanboyAnnoyanceListEnabled);
199
200
201         // Inflate a WebView to get the default user agent.
202         LayoutInflater inflater = getActivity().getLayoutInflater();
203
204         // `@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.
205         @SuppressLint("InflateParams") View bareWebViewLayout = inflater.inflate(R.layout.bare_webview, null, false);
206
207         // Get a handle for a bare WebView.
208         WebView bareWebView = bareWebViewLayout.findViewById(R.id.bare_webview);
209
210         // Get the user agent arrays.
211         ArrayAdapter<CharSequence> userAgentNamesArray = ArrayAdapter.createFromResource(context, R.array.user_agent_names, R.layout.spinner_item);
212         String[] translatedUserAgentNamesArray = resources.getStringArray(R.array.translated_user_agent_names);
213         String[] userAgentDataArray = resources.getStringArray(R.array.user_agent_data);
214
215         // Get the array position of the user agent name.
216         int userAgentArrayPosition = userAgentNamesArray.getPosition(userAgentName);
217
218         // Populate the user agent summary.
219         switch (userAgentArrayPosition) {
220             case MainWebViewActivity.UNRECOGNIZED_USER_AGENT:  // The user agent name is not on the canonical list.
221                 // 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.
222                 userAgentPreference.setSummary(userAgentName);
223                 break;
224
225             case MainWebViewActivity.SETTINGS_WEBVIEW_DEFAULT_USER_AGENT:
226                 // Get the user agent text from the webview (which changes based on the version of Android and WebView installed).
227                 userAgentPreference.setSummary(translatedUserAgentNamesArray[userAgentArrayPosition] + ":\n" + bareWebView.getSettings().getUserAgentString());
228                 break;
229
230             case MainWebViewActivity.SETTINGS_CUSTOM_USER_AGENT:
231                 // Set the summary text.
232                 userAgentPreference.setSummary(R.string.custom_user_agent);
233                 break;
234
235             default:
236                 // Get the user agent summary from the user agent data array.
237                 userAgentPreference.setSummary(translatedUserAgentNamesArray[userAgentArrayPosition] + ":\n" + userAgentDataArray[userAgentArrayPosition]);
238         }
239
240         // Set the summary text for the custom user agent preference.
241         customUserAgentPreference.setSummary(savedPreferences.getString("custom_user_agent", getString(R.string.custom_user_agent_default_value)));
242
243         // Only enable the custom user agent preference if the user agent is set to `Custom`.
244         customUserAgentPreference.setEnabled(userAgentPreference.getSummary().equals(getString(R.string.custom_user_agent)));
245
246
247         // Set the search URL as the summary text for the search preference when the preference screen is loaded.
248         if (searchString.equals("Custom URL")) {
249             // Use R.string.custom_url, which will be translated, instead of the array value, which will not.
250             searchPreference.setSummary(R.string.custom_url);
251         } else {
252             // Set the array value as the summary text.
253             searchPreference.setSummary(searchString);
254         }
255
256         // Set the summary text for the search custom URL (the default is `""`).
257         searchCustomURLPreference.setSummary(savedPreferences.getString("search_custom_url", getString(R.string.search_custom_url_default_value)));
258
259         // Only enable the search custom URL preference if the search is set to `Custom URL`.
260         searchCustomURLPreference.setEnabled(searchString.equals("Custom URL"));
261
262
263         // Set the summary text for the proxy preference when the preference screen is loaded.
264         switch (proxyString) {
265             case ProxyHelper.NONE:
266                 proxyPreference.setSummary(getString(R.string.no_proxy_enabled));
267                 break;
268
269             case ProxyHelper.TOR:
270                 if (Build.VERSION.SDK_INT == 19) {  // Proxying through SOCKS doesn't work on Android KitKat.
271                     proxyPreference.setSummary(getString(R.string.tor_enabled_kitkat));
272                 } else {
273                     proxyPreference.setSummary(getString(R.string.tor_enabled));
274                 }
275                 break;
276
277             case ProxyHelper.I2P:
278                 proxyPreference.setSummary(getString(R.string.i2p_enabled));
279                 break;
280
281             case ProxyHelper.CUSTOM:
282                 proxyPreference.setSummary(getString(R.string.custom_proxy));
283                 break;
284         }
285
286         // Set the summary text for the custom proxy URL.
287         proxyCustomUrlPreference.setSummary(savedPreferences.getString("proxy_custom_url", getString(R.string.proxy_custom_url_default_value)));
288
289         // Only enable the custom proxy URL if a custom proxy is selected.
290         proxyCustomUrlPreference.setEnabled(proxyString.equals("Custom"));
291
292
293         // Set the status of the clear and exit preferences.
294         clearCookiesPreference.setEnabled(!clearEverything);
295         clearDomStoragePreference.setEnabled(!clearEverything);
296         clearFormDataPreference.setEnabled(!clearEverything);  // The form data line can be removed once the minimum API is >= 26.
297         clearLogcatPreference.setEnabled(!clearEverything);
298         clearCachePreference.setEnabled(!clearEverything);
299
300
301         // Set the homepage URL as the summary text for the homepage preference.
302         homepagePreference.setSummary(savedPreferences.getString("homepage", getString(R.string.homepage_default_value)));
303
304
305         // Set the font size as the summary text for the preference.
306         fontSizePreference.setSummary(savedPreferences.getString("font_size", getString(R.string.font_size_default_value)) + "%");
307
308
309         // Get the app theme string arrays.
310         String[] appThemeEntriesStringArray = resources.getStringArray(R.array.app_theme_entries);
311         String[] appThemeEntryValuesStringArray = resources.getStringArray(R.array.app_theme_entry_values);
312
313         // Get the current app theme.
314         String currentAppTheme = savedPreferences.getString("app_theme", getString(R.string.app_theme_default_value));
315
316         // Define an app theme entry number.
317         int appThemeEntryNumber;
318
319         // 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.
320         if (currentAppTheme.equals(appThemeEntryValuesStringArray[1])) {  // The light theme is selected.
321             // Store the app theme entry number.
322             appThemeEntryNumber = 1;
323         } else if (currentAppTheme.equals(appThemeEntryValuesStringArray[2])) {  // The dark theme is selected.
324             // Store the app theme entry number.
325             appThemeEntryNumber = 2;
326         } else {  // The system default theme is selected.
327             // Store the app theme entry number.
328             appThemeEntryNumber = 0;
329         }
330
331         // Set the current theme as the summary text for the preference.
332         appThemePreference.setSummary(appThemeEntriesStringArray[appThemeEntryNumber]);
333
334
335         // Get the WebView theme string arrays.
336         String[] webViewThemeEntriesStringArray = resources.getStringArray(R.array.webview_theme_entries);
337         String[] webViewThemeEntryValuesStringArray = resources.getStringArray(R.array.webview_theme_entry_values);
338
339         // Get the current WebView theme.
340         String currentWebViewTheme = savedPreferences.getString("webview_theme", getString(R.string.webview_theme_default_value));
341
342         // Define a WebView theme entry number.
343         int webViewThemeEntryNumber;
344
345         // Get the WebView theme entry number that matches the current WebView theme.  A switch statement cannot be used because the WebView theme entry values string array is not a compile time constant.
346         if (currentWebViewTheme.equals(webViewThemeEntryValuesStringArray[1])) {  // The light theme is selected.
347             // Store the WebView theme entry number.
348             webViewThemeEntryNumber = 1;
349         } else if (currentWebViewTheme.equals(webViewThemeEntryValuesStringArray[2])) {  // The dark theme is selected.
350             // Store the WebView theme entry number.
351             webViewThemeEntryNumber = 2;
352         } else {  // The system default theme is selected.
353             // Store the WebView theme entry number.
354             webViewThemeEntryNumber = 0;
355         }
356
357         // Set the visibility of the WebView theme preference.
358         if (Build.VERSION.SDK_INT < 21) {  // The device is running API 19.
359             // Get a handle for the general category.
360             PreferenceCategory generalCategory = findPreference("general");
361
362             // Remove the incorrect lint warning below that the general preference category might be null.
363             assert generalCategory != null;
364
365             // Remove the WebView theme preference.
366             generalCategory.removePreference(webViewThemePreference);
367         } else {  // The device is running API >= 21
368             // Set the current theme as the summary text for the preference.
369             webViewThemePreference.setSummary(webViewThemeEntriesStringArray[webViewThemeEntryNumber]);
370         }
371
372
373         // Set the JavaScript icon.
374         if (javaScriptEnabled) {
375             javaScriptPreference.setIcon(R.drawable.javascript_enabled);
376         } else {
377             javaScriptPreference.setIcon(R.drawable.privacy_mode);
378         }
379
380         // Set the first-party cookies icon.
381         if (firstPartyCookiesEnabled) {
382             firstPartyCookiesPreference.setIcon(R.drawable.cookies_enabled);
383         } else {
384             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
385                 firstPartyCookiesPreference.setIcon(R.drawable.cookies_disabled_night);
386             } else {
387                 firstPartyCookiesPreference.setIcon(R.drawable.cookies_disabled_day);
388             }
389         }
390
391         // Set the third party cookies icon.
392         if (firstPartyCookiesEnabled && Build.VERSION.SDK_INT >= 21) {
393             if (savedPreferences.getBoolean("third_party_cookies", false)) {
394                 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_warning);
395             } else {
396                 if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
397                     thirdPartyCookiesPreference.setIcon(R.drawable.cookies_disabled_night);
398                 } else {
399                     thirdPartyCookiesPreference.setIcon(R.drawable.cookies_disabled_day);
400                 }
401             }
402         } else {
403             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
404                 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_ghosted_night);
405             } else {
406                 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_ghosted_day);
407             }
408         }
409
410         // Set the DOM storage icon.
411         if (javaScriptEnabled) {  // The preference is enabled.
412             if (savedPreferences.getBoolean("dom_storage", false)) {  // DOM storage is enabled.
413                 domStoragePreference.setIcon(R.drawable.dom_storage_enabled);
414             } else {  // DOM storage is disabled.
415                 if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
416                     domStoragePreference.setIcon(R.drawable.dom_storage_disabled_night);
417                 } else {
418                     domStoragePreference.setIcon(R.drawable.dom_storage_disabled_day);
419                 }
420             }
421         } else {  // The preference is disabled.  The icon should be ghosted.
422             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
423                 domStoragePreference.setIcon(R.drawable.dom_storage_ghosted_night);
424             } else {
425                 domStoragePreference.setIcon(R.drawable.dom_storage_ghosted_day);
426             }
427         }
428
429         // Set the save form data icon if API < 26.  Save form data has no effect on API >= 26.
430         if (Build.VERSION.SDK_INT < 26) {
431             if (savedPreferences.getBoolean("save_form_data", false)) {
432                 formDataPreference.setIcon(R.drawable.form_data_enabled);
433             } else {
434                 if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
435                     formDataPreference.setIcon(R.drawable.form_data_disabled_night);
436                 } else {
437                     formDataPreference.setIcon(R.drawable.form_data_disabled_day);
438                 }
439             }
440         }
441
442         // Set the custom user agent icon.
443         if (customUserAgentPreference.isEnabled()) {
444             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
445                 customUserAgentPreference.setIcon(R.drawable.custom_user_agent_enabled_night);
446             } else {
447                 customUserAgentPreference.setIcon(R.drawable.custom_user_agent_enabled_day);
448             }
449         } else {
450             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
451                 customUserAgentPreference.setIcon(R.drawable.custom_user_agent_ghosted_night);
452             } else {
453                 customUserAgentPreference.setIcon(R.drawable.custom_user_agent_ghosted_day);
454             }
455         }
456
457         // Set the incognito mode icon.
458         if (savedPreferences.getBoolean("incognito_mode", false)) {
459             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
460                 incognitoModePreference.setIcon(R.drawable.incognito_mode_enabled_night);
461             } else {
462                 incognitoModePreference.setIcon(R.drawable.incognito_mode_enabled_day);
463             }
464         } else {
465             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
466                 incognitoModePreference.setIcon(R.drawable.incognito_mode_disabled_night);
467             } else {
468                 incognitoModePreference.setIcon(R.drawable.incognito_mode_disabled_day);
469             }
470         }
471
472         // Set the Do Not Track icon.
473         if (savedPreferences.getBoolean("do_not_track", false)) {
474             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
475                 doNotTrackPreference.setIcon(R.drawable.block_tracking_enabled_night);
476             } else {
477                 doNotTrackPreference.setIcon(R.drawable.block_tracking_enabled_day);
478             }
479         } else {
480             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
481                 doNotTrackPreference.setIcon(R.drawable.block_tracking_disabled_night);
482             } else {
483                 doNotTrackPreference.setIcon(R.drawable.block_tracking_disabled_day);
484             }
485         }
486
487         // Set the allow screenshots icon.
488         if (savedPreferences.getBoolean(getString(R.string.allow_screenshots_key), false)) {
489             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_NO) {
490                 allowScreenshotsPreference.setIcon(R.drawable.allow_screenshots_enabled_day);
491             } else {
492                 allowScreenshotsPreference.setIcon(R.drawable.allow_screenshots_enabled_night);
493             }
494         } else {
495             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_NO) {
496                 allowScreenshotsPreference.setIcon(R.drawable.allow_screenshots_disabled_day);
497             } else {
498                 allowScreenshotsPreference.setIcon(R.drawable.allow_screenshots_disabled_night);
499             }
500         }
501
502         // Set the EasyList icon.
503         if (savedPreferences.getBoolean("easylist", true)) {
504             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
505                 easyListPreference.setIcon(R.drawable.block_ads_enabled_night);
506             } else {
507                 easyListPreference.setIcon(R.drawable.block_ads_enabled_day);
508             }
509         } else {
510             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
511                 easyListPreference.setIcon(R.drawable.block_ads_disabled_night);
512             } else {
513                 easyListPreference.setIcon(R.drawable.block_ads_disabled_day);
514             }
515         }
516
517         // Set the EasyPrivacy icon.
518         if (savedPreferences.getBoolean("easyprivacy", true)) {
519             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
520                 easyPrivacyPreference.setIcon(R.drawable.block_tracking_enabled_night);
521             } else {
522                 easyPrivacyPreference.setIcon(R.drawable.block_tracking_enabled_day);
523             }
524         } else {
525             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
526                 easyPrivacyPreference.setIcon(R.drawable.block_tracking_disabled_night);
527             } else {
528                 easyPrivacyPreference.setIcon(R.drawable.block_tracking_disabled_day);
529             }
530         }
531
532         // Set the Fanboy lists icons.
533         if (fanboyAnnoyanceListEnabled) {
534             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
535                 // Set the Fanboy annoyance list icon.
536                 fanboyAnnoyanceListPreference.setIcon(R.drawable.social_media_enabled_night);
537
538                 // Set the Fanboy social blocking list icon.
539                 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_ghosted_night);
540             } else {
541                 // Set the Fanboy annoyance list icon.
542                 fanboyAnnoyanceListPreference.setIcon(R.drawable.social_media_enabled_day);
543
544                 // Set the Fanboy social blocking list icon.
545                 fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_ghosted_day);
546             }
547         } else {
548             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
549                 // Set the Fanboy annoyance list icon.
550                 fanboyAnnoyanceListPreference.setIcon(R.drawable.social_media_disabled_night);
551
552                 // Set the Fanboy social blocking list icon.
553                 if (fanboySocialBlockingEnabled) {
554                     fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_enabled_night);
555                 } else {
556                     fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_disabled_night);
557                 }
558             } else {
559                 // Set the Fanboy annoyance list icon.
560                 fanboyAnnoyanceListPreference.setIcon(R.drawable.block_ads_disabled_day);
561
562                 // Set the Fanboy social blocking list icon.
563                 if (fanboySocialBlockingEnabled) {
564                     fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_enabled_day);
565                 } else {
566                     fanboySocialBlockingListPreference.setIcon(R.drawable.social_media_disabled_day);
567                 }
568             }
569         }
570
571         // Set the UltraList icon.
572         if (savedPreferences.getBoolean("ultralist", true)){
573             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
574                 ultraListPreference.setIcon(R.drawable.block_ads_enabled_night);
575             } else {
576                 ultraListPreference.setIcon(R.drawable.block_ads_enabled_day);
577             }
578         } else {
579             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
580                 ultraListPreference.setIcon(R.drawable.block_ads_disabled_night);
581             } else {
582                 ultraListPreference.setIcon(R.drawable.block_ads_disabled_day);
583             }
584         }
585
586         // Set the UltraPrivacy icon.
587         if (savedPreferences.getBoolean("ultraprivacy", true)) {
588             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
589                 ultraPrivacyPreference.setIcon(R.drawable.block_tracking_enabled_night);
590             } else {
591                 ultraPrivacyPreference.setIcon(R.drawable.block_tracking_enabled_day);
592             }
593         } else {
594             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
595                 ultraPrivacyPreference.setIcon(R.drawable.block_tracking_disabled_night);
596             } else {
597                 ultraPrivacyPreference.setIcon(R.drawable.block_tracking_disabled_day);
598             }
599         }
600
601         // Set the block all third-party requests icon.
602         if (savedPreferences.getBoolean("block_all_third_party_requests", false)) {
603             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
604                 blockAllThirdPartyRequestsPreference.setIcon(R.drawable.block_all_third_party_requests_enabled_night);
605             } else {
606                 blockAllThirdPartyRequestsPreference.setIcon(R.drawable.block_all_third_party_requests_enabled_day);
607             }
608         } else {
609             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
610                 blockAllThirdPartyRequestsPreference.setIcon(R.drawable.block_all_third_party_requests_disabled_night);
611             } else {
612                 blockAllThirdPartyRequestsPreference.setIcon(R.drawable.block_all_third_party_requests_disabled_day);
613             }
614         }
615
616         // Set the Google Analytics icon according to the theme.
617         if (savedPreferences.getBoolean("google_analytics", true)) {
618             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
619                 googleAnalyticsPreference.setIcon(R.drawable.modify_url_enabled_night);
620             } else {
621                 googleAnalyticsPreference.setIcon(R.drawable.modify_url_enabled_day);
622             }
623         } else {
624             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
625                 googleAnalyticsPreference.setIcon(R.drawable.modify_url_disabled_night);
626             } else {
627                 googleAnalyticsPreference.setIcon(R.drawable.modify_url_disabled_day);
628             }
629         }
630
631         // Set the Facebook Click IDs icon according to the theme.
632         if (savedPreferences.getBoolean("facebook_click_ids", true)) {
633             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
634                 facebookClickIdsPreference.setIcon(R.drawable.modify_url_enabled_night);
635             } else {
636                 facebookClickIdsPreference.setIcon(R.drawable.modify_url_enabled_day);
637             }
638         } else {
639             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
640                 facebookClickIdsPreference.setIcon(R.drawable.modify_url_disabled_night);
641             } else {
642                 facebookClickIdsPreference.setIcon(R.drawable.modify_url_disabled_day);
643             }
644         }
645
646         // Set the Twitter AMP redirects icon according to the theme.
647         if (savedPreferences.getBoolean("twitter_amp_redirects", true)) {
648             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
649                 twitterAmpRedirectsPreference.setIcon(R.drawable.modify_url_enabled_night);
650             } else {
651                 twitterAmpRedirectsPreference.setIcon(R.drawable.modify_url_enabled_day);
652             }
653         } else {
654             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
655                 twitterAmpRedirectsPreference.setIcon(R.drawable.modify_url_disabled_night);
656             } else {
657                 twitterAmpRedirectsPreference.setIcon(R.drawable.modify_url_disabled_day);
658             }
659         }
660
661         // Set the search custom URL icon.
662         if (searchCustomURLPreference.isEnabled()) {
663             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
664                 searchCustomURLPreference.setIcon(R.drawable.search_custom_url_enabled_night);
665             } else {
666                 searchCustomURLPreference.setIcon(R.drawable.search_custom_url_enabled_day);
667             }
668         } else {
669             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
670                 searchCustomURLPreference.setIcon(R.drawable.search_custom_url_ghosted_night);
671             } else {
672                 searchCustomURLPreference.setIcon(R.drawable.search_custom_url_ghosted_day);
673             }
674         }
675
676         // Set the Proxy icons according to the theme and status.
677         if (proxyString.equals("None")) {  // Proxying is disabled.
678             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {  // Dark theme.
679                 // Set the main proxy icon to be disabled.
680                 proxyPreference.setIcon(R.drawable.proxy_disabled_night);
681
682                 // Set the custom proxy URL icon to be ghosted.
683                 proxyCustomUrlPreference.setIcon(R.drawable.proxy_ghosted_night);
684             } else {  // Light theme.
685                 // Set the main proxy icon to be disabled.
686                 proxyPreference.setIcon(R.drawable.proxy_disabled_day);
687
688                 // Set the custom proxy URL icon to be ghosted.
689                 proxyCustomUrlPreference.setIcon(R.drawable.proxy_ghosted_day);
690             }
691         } else {  // Proxying is enabled.
692             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {  // Dark theme.
693                 // Set the main proxy icon to be enabled.
694                 proxyPreference.setIcon(R.drawable.proxy_enabled_night);
695
696                 // Set the custom proxy URL icon according to its status.
697                 if (proxyCustomUrlPreference.isEnabled()) {  // Custom proxy is enabled.
698                     proxyCustomUrlPreference.setIcon(R.drawable.proxy_enabled_night);
699                 } else {  // Custom proxy is disabled.
700                     proxyCustomUrlPreference.setIcon(R.drawable.proxy_ghosted_night);
701                 }
702             } else {  // Light theme.
703                 // Set the main proxy icon to be enabled.
704                 proxyPreference.setIcon(R.drawable.proxy_enabled_day);
705
706                 // Set the custom proxy URL icon according to its status.
707                 if (proxyCustomUrlPreference.isEnabled()) {  // Custom proxy is enabled.
708                     proxyCustomUrlPreference.setIcon(R.drawable.proxy_enabled_day);
709                 } else {  // Custom proxy is disabled.
710                     proxyCustomUrlPreference.setIcon(R.drawable.proxy_ghosted_day);
711                 }
712             }
713         }
714
715         // Set the full screen browsing mode icons.
716         if (fullScreenBrowsingMode) {  // Full screen browsing mode is enabled.
717             // Set the `fullScreenBrowsingModePreference` icon according to the theme.
718             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
719                 fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_enabled_night);
720             } else {
721                 fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_enabled_day);
722             }
723
724             // Set the hide app bar icon.
725             if (savedPreferences.getBoolean("hide_app_bar", true)) {  // Hide app bar is enabled.
726                 // Set the icon according to the theme.
727                 if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
728                     hideAppBarPreference.setIcon(R.drawable.app_bar_enabled_night);
729                 } else {
730                     hideAppBarPreference.setIcon(R.drawable.app_bar_enabled_day);
731                 }
732             } else {  // Hide app bar is disabled.
733                 // Set the icon according to the theme.
734                 if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
735                     hideAppBarPreference.setIcon(R.drawable.app_bar_disabled_night);
736                 } else {
737                     hideAppBarPreference.setIcon(R.drawable.app_bar_disabled_day);
738                 }
739             }
740         } else {  // Full screen browsing mode is disabled.
741             // Set the icons according to the theme.
742             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
743                 fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_disabled_night);
744                 hideAppBarPreference.setIcon(R.drawable.app_bar_ghosted_night);
745             } else {
746                 fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_disabled_day);
747                 hideAppBarPreference.setIcon(R.drawable.app_bar_ghosted_day);
748             }
749         }
750
751         // Set the clear everything preference icon.
752         if (clearEverything) {
753             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
754                 clearEverythingPreference.setIcon(R.drawable.clear_everything_enabled_night);
755             } else {
756                 clearEverythingPreference.setIcon(R.drawable.clear_everything_enabled_day);
757             }
758         } else {
759             clearEverythingPreference.setIcon(R.drawable.clear_everything_disabled);
760         }
761
762         // Set the clear cookies preference icon.
763         if (clearEverything || savedPreferences.getBoolean("clear_cookies", true)) {
764             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
765                 clearCookiesPreference.setIcon(R.drawable.cookies_cleared_night);
766             } else {
767                 clearCookiesPreference.setIcon(R.drawable.cookies_cleared_day);
768             }
769         } else {
770             clearCookiesPreference.setIcon(R.drawable.cookies_warning);
771         }
772
773         // Set the clear DOM storage preference icon.
774         if (clearEverything || savedPreferences.getBoolean("clear_dom_storage", true)) {
775             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
776                 clearDomStoragePreference.setIcon(R.drawable.dom_storage_cleared_night);
777             } else {
778                 clearDomStoragePreference.setIcon(R.drawable.dom_storage_cleared_day);
779             }
780         } else {
781             clearDomStoragePreference.setIcon(R.drawable.dom_storage_warning);
782         }
783
784         // Set the clear form data preference icon if the API < 26.  It has no effect on newer versions of Android.
785         if (Build.VERSION.SDK_INT < 26) {
786             if (clearEverything || savedPreferences.getBoolean("clear_form_data", true)) {
787                 if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
788                     clearFormDataPreference.setIcon(R.drawable.form_data_cleared_night);
789                 } else {
790                     clearFormDataPreference.setIcon(R.drawable.form_data_cleared_day);
791                 }
792             } else {
793                 clearFormDataPreference.setIcon(R.drawable.form_data_warning);
794             }
795         }
796
797         // Set the clear logcat preference icon.
798         if (clearEverything || savedPreferences.getBoolean(getString(R.string.clear_logcat_key), true)) {
799             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_NO) {
800                 clearLogcatPreference.setIcon(R.drawable.bug_cleared_day);
801             } else {
802                 clearLogcatPreference.setIcon(R.drawable.bug_cleared_night);
803             }
804         } else {
805             clearLogcatPreference.setIcon(R.drawable.bug_warning);
806         }
807
808         // Set the clear cache preference icon.
809         if (clearEverything || savedPreferences.getBoolean("clear_cache", true)) {
810             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
811                 clearCachePreference.setIcon(R.drawable.cache_cleared_night);
812             } else {
813                 clearCachePreference.setIcon(R.drawable.cache_cleared_day);
814             }
815         } else {
816             clearCachePreference.setIcon(R.drawable.cache_warning);
817         }
818
819         // Set the open intents in new tab preference icon.
820         if (savedPreferences.getBoolean("open_intents_in_new_tab", true)) {
821             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
822                 openIntentsInNewTabPreference.setIcon(R.drawable.tab_enabled_night);
823             } else {
824                 openIntentsInNewTabPreference.setIcon(R.drawable.tab_enabled_day);
825             }
826         } else {
827             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
828                 openIntentsInNewTabPreference.setIcon(R.drawable.tab_disabled_night);
829             } else {
830                 openIntentsInNewTabPreference.setIcon(R.drawable.tab_disabled_day);
831             }
832         }
833
834         // Set the swipe to refresh preference icon.
835         if (savedPreferences.getBoolean("swipe_to_refresh", true)) {
836             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
837                 swipeToRefreshPreference.setIcon(R.drawable.refresh_enabled_night);
838             } else {
839                 swipeToRefreshPreference.setIcon(R.drawable.refresh_enabled_day);
840             }
841         } else {
842             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
843                 swipeToRefreshPreference.setIcon(R.drawable.refresh_disabled_night);
844             } else {
845                 swipeToRefreshPreference.setIcon(R.drawable.refresh_disabled_day);
846             }
847         }
848
849         // Set the scroll app bar preference icon.
850         if (savedPreferences.getBoolean("scroll_app_bar", true)) {
851             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
852                 scrollAppBarPreference.setIcon(R.drawable.app_bar_enabled_night);
853             } else {
854                 scrollAppBarPreference.setIcon(R.drawable.app_bar_enabled_day);
855             }
856         } else {
857             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
858                 scrollAppBarPreference.setIcon(R.drawable.app_bar_disabled_night);
859             } else {
860                 scrollAppBarPreference.setIcon(R.drawable.app_bar_disabled_day);
861             }
862         }
863
864         // Set the display additional app bar icons preference icon.
865         if (savedPreferences.getBoolean("display_additional_app_bar_icons", false)) {
866             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
867                 displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_enabled_night);
868             } else {
869                 displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_enabled_day);
870             }
871         } else {
872             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
873                 displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_disabled_night);
874             } else {
875                 displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_disabled_day);
876             }
877         }
878
879         // Set the WebView theme preference icon.
880         switch (webViewThemeEntryNumber) {
881             case 0:  // The system default WebView theme is selected.
882                 // Set the icon according to the app theme.
883                 if (currentThemeStatus == Configuration.UI_MODE_NIGHT_NO) {
884                     webViewThemePreference.setIcon(R.drawable.webview_light_theme_day);
885                 } else {
886                     webViewThemePreference.setIcon(R.drawable.webview_dark_theme_night);
887                 }
888                 break;
889
890             case 1:  // The light WebView theme is selected.
891                 // Set the icon according to the app theme.
892                 if (currentThemeStatus == Configuration.UI_MODE_NIGHT_NO) {
893                     webViewThemePreference.setIcon(R.drawable.webview_light_theme_day);
894                 } else {
895                     webViewThemePreference.setIcon(R.drawable.webview_light_theme_night);
896                 }
897                 break;
898
899             case 2:  // The dark WebView theme is selected.
900                 if (currentThemeStatus == Configuration.UI_MODE_NIGHT_NO) {
901                     webViewThemePreference.setIcon(R.drawable.webview_dark_theme_day);
902                 } else {
903                     webViewThemePreference.setIcon(R.drawable.webview_dark_theme_night);
904                 }
905                 break;
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(getString(R.string.allow_screenshots_key), false)) {
1162                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_NO) {
1163                             allowScreenshotsPreference.setIcon(R.drawable.allow_screenshots_enabled_day);
1164                         } else {
1165                             allowScreenshotsPreference.setIcon(R.drawable.allow_screenshots_enabled_night);
1166                         }
1167                     } else {
1168                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_NO) {
1169                             allowScreenshotsPreference.setIcon(R.drawable.allow_screenshots_disabled_day);
1170                         } else {
1171                             allowScreenshotsPreference.setIcon(R.drawable.allow_screenshots_disabled_night);
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(Looper.getMainLooper());
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                     clearLogcatPreference.setEnabled(!newClearEverythingBoolean);
1579                     clearCachePreference.setEnabled(!newClearEverythingBoolean);
1580
1581                     // Update the clear everything preference icon.
1582                     if (newClearEverythingBoolean) {
1583                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1584                             clearEverythingPreference.setIcon(R.drawable.clear_everything_enabled_night);
1585                         } else {
1586                             clearEverythingPreference.setIcon(R.drawable.clear_everything_enabled_day);
1587                         }
1588                     } else {
1589                         clearEverythingPreference.setIcon(R.drawable.clear_everything_disabled);
1590                     }
1591
1592                     // Update the clear cookies preference icon.
1593                     if (newClearEverythingBoolean || sharedPreferences.getBoolean("clear_cookies", true)) {
1594                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1595                             clearCookiesPreference.setIcon(R.drawable.cookies_cleared_night);
1596                         } else {
1597                             clearCookiesPreference.setIcon(R.drawable.cookies_cleared_day);
1598                         }
1599                     } else {
1600                         clearCookiesPreference.setIcon(R.drawable.cookies_warning);
1601                     }
1602
1603                     // Update the clear dom storage preference icon.
1604                     if (newClearEverythingBoolean || sharedPreferences.getBoolean("clear_dom_storage", true)) {
1605                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1606                             clearDomStoragePreference.setIcon(R.drawable.dom_storage_cleared_night);
1607                         } else {
1608                             clearDomStoragePreference.setIcon(R.drawable.dom_storage_cleared_day);
1609                         }
1610                     } else {
1611                         clearDomStoragePreference.setIcon(R.drawable.dom_storage_warning);
1612                     }
1613
1614                     // Update the clear form data preference icon if the API < 26.
1615                     if (Build.VERSION.SDK_INT < 26) {
1616                         if (newClearEverythingBoolean || sharedPreferences.getBoolean("clear_form_data", true)) {
1617                             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1618                                 clearFormDataPreference.setIcon(R.drawable.form_data_cleared_night);
1619                             } else {
1620                                 clearFormDataPreference.setIcon(R.drawable.form_data_cleared_day);
1621                             }
1622                         } else {
1623                             clearFormDataPreference.setIcon(R.drawable.form_data_warning);
1624                         }
1625                     }
1626
1627                     // Update the clear logcat preference icon.
1628                     if (newClearEverythingBoolean || sharedPreferences.getBoolean(getString(R.string.clear_logcat_key), true)) {
1629                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_NO) {
1630                             clearLogcatPreference.setIcon(R.drawable.bug_cleared_day);
1631                         } else {
1632                             clearLogcatPreference.setIcon(R.drawable.bug_cleared_night);
1633                         }
1634                     } else {
1635                         clearLogcatPreference.setIcon(R.drawable.cache_warning);
1636                     }
1637
1638                     // Update the clear cache preference icon.
1639                     if (newClearEverythingBoolean || sharedPreferences.getBoolean("clear_cache", true)) {
1640                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1641                             clearCachePreference.setIcon(R.drawable.cache_cleared_night);
1642                         } else {
1643                             clearCachePreference.setIcon(R.drawable.cache_cleared_day);
1644                         }
1645                     } else {
1646                         clearCachePreference.setIcon(R.drawable.cache_warning);
1647                     }
1648                     break;
1649
1650                 case "clear_cookies":
1651                     // Update the icon.
1652                     if (sharedPreferences.getBoolean("clear_cookies", true)) {
1653                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1654                             clearCookiesPreference.setIcon(R.drawable.cookies_cleared_night);
1655                         } else {
1656                             clearCookiesPreference.setIcon(R.drawable.cookies_cleared_day);
1657                         }
1658                     } else {
1659                         clearCookiesPreference.setIcon(R.drawable.cookies_warning);
1660                     }
1661                     break;
1662
1663                 case "clear_dom_storage":
1664                     // Update the icon.
1665                     if (sharedPreferences.getBoolean("clear_dom_storage", true)) {
1666                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1667                             clearDomStoragePreference.setIcon(R.drawable.dom_storage_cleared_night);
1668                         } else {
1669                             clearDomStoragePreference.setIcon(R.drawable.dom_storage_cleared_day);
1670                         }
1671                     } else {
1672                         clearDomStoragePreference.setIcon(R.drawable.dom_storage_warning);
1673                     }
1674                     break;
1675
1676                 // This section can be removed once the minimum API >= 26.
1677                 case "clear_form_data":
1678                     // Update the icon.
1679                     if (sharedPreferences.getBoolean("clear_form_data", true)) {
1680                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1681                             clearFormDataPreference.setIcon(R.drawable.form_data_cleared_night);
1682                         } else {
1683                             clearFormDataPreference.setIcon(R.drawable.form_data_cleared_day);
1684                         }
1685                     } else {
1686                         clearFormDataPreference.setIcon(R.drawable.form_data_warning);
1687                     }
1688                     break;
1689
1690                 case "clear_logcat":
1691                     // Update the icon.
1692                     if (sharedPreferences.getBoolean(getString(R.string.clear_logcat_key), true)) {
1693                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_NO) {
1694                             clearLogcatPreference.setIcon(R.drawable.bug_cleared_day);
1695                         } else {
1696                             clearLogcatPreference.setIcon(R.drawable.bug_cleared_night);
1697                         }
1698                     } else {
1699                         clearLogcatPreference.setIcon(R.drawable.bug_warning);
1700                     }
1701                     break;
1702
1703                 case "clear_cache":
1704                     // Update the icon.
1705                     if (sharedPreferences.getBoolean("clear_cache", true)) {
1706                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1707                             clearCachePreference.setIcon(R.drawable.cache_cleared_night);
1708                         } else {
1709                             clearCachePreference.setIcon(R.drawable.cache_cleared_day);
1710                         }
1711                     } else {
1712                         clearCachePreference.setIcon(R.drawable.cache_warning);
1713                     }
1714                     break;
1715
1716                 case "homepage":
1717                     // Set the new homepage URL as the summary text for the Homepage preference.
1718                     homepagePreference.setSummary(sharedPreferences.getString("homepage", getString(R.string.homepage_default_value)));
1719                     break;
1720
1721                 case "font_size":
1722                     // Update the font size summary text.
1723                     fontSizePreference.setSummary(sharedPreferences.getString("font_size", getString(R.string.font_size_default_value)) + "%");
1724                     break;
1725
1726                 case "open_intents_in_new_tab":
1727                     // Update the icon.
1728                     if (sharedPreferences.getBoolean("open_intents_in_new_tab", true)) {
1729                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1730                             openIntentsInNewTabPreference.setIcon(R.drawable.tab_enabled_night);
1731                         } else {
1732                             openIntentsInNewTabPreference.setIcon(R.drawable.tab_enabled_day);
1733                         }
1734                     } else {
1735                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1736                             openIntentsInNewTabPreference.setIcon(R.drawable.tab_disabled_night);
1737                         } else {
1738                             openIntentsInNewTabPreference.setIcon(R.drawable.tab_disabled_day);
1739                         }
1740                     }
1741                     break;
1742
1743                 case "swipe_to_refresh":
1744                     // Update the icon.
1745                     if (sharedPreferences.getBoolean("swipe_to_refresh", true)) {
1746                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1747                             swipeToRefreshPreference.setIcon(R.drawable.refresh_enabled_night);
1748                         } else {
1749                             swipeToRefreshPreference.setIcon(R.drawable.refresh_enabled_day);
1750                         }
1751                     } else {
1752                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1753                             swipeToRefreshPreference.setIcon(R.drawable.refresh_disabled_night);
1754                         } else {
1755                             swipeToRefreshPreference.setIcon(R.drawable.refresh_disabled_day);
1756                         }
1757                     }
1758                     break;
1759
1760                 case "scroll_app_bar":
1761                     // Update the icon.
1762                     if (sharedPreferences.getBoolean("scroll_app_bar", true)) {
1763                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1764                             scrollAppBarPreference.setIcon(R.drawable.app_bar_enabled_night);
1765                         } else {
1766                             scrollAppBarPreference.setIcon(R.drawable.app_bar_enabled_day);
1767                         }
1768                     } else {
1769                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1770                             scrollAppBarPreference.setIcon(R.drawable.app_bar_disabled_night);
1771                         } else {
1772                             scrollAppBarPreference.setIcon(R.drawable.app_bar_disabled_day);
1773                         }
1774                     }
1775                     break;
1776
1777                 case "display_additional_app_bar_icons":
1778                     // Update the icon.
1779                     if (sharedPreferences.getBoolean("display_additional_app_bar_icons", false)) {
1780                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1781                             displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_enabled_night);
1782                         } else {
1783                             displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_enabled_day);
1784                         }
1785                     } else {
1786                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1787                             displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_disabled_night);
1788                         } else {
1789                             displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_disabled_day);
1790                         }
1791                     }
1792                     break;
1793
1794                 case "app_theme":
1795                     // Get the new theme.
1796                     String newAppTheme = sharedPreferences.getString("app_theme", getString(R.string.app_theme_default_value));
1797
1798                     // 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.
1799                     if (newAppTheme.equals(appThemeEntryValuesStringArray[1])) {  // The light theme is selected.
1800                         // Update the theme preference summary text.
1801                         appThemePreference.setSummary(appThemeEntriesStringArray[1]);
1802
1803                         // Apply the new theme.
1804                         AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
1805                     } else if (newAppTheme.equals(appThemeEntryValuesStringArray[2])) {  // The dark theme is selected.
1806                         // Update the theme preference summary text.
1807                         appThemePreference.setSummary(appThemeEntriesStringArray[2]);
1808
1809                         // Apply the new theme.
1810                         AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
1811                     } else {  // The system default theme is selected.
1812                         // Update the theme preference summary text.
1813                         appThemePreference.setSummary(appThemeEntriesStringArray[0]);
1814
1815                         // Apply the new theme.
1816                         if (Build.VERSION.SDK_INT >= 28) {  // The system default theme is supported.
1817                             // Follow the system default theme.
1818                             AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);
1819                         } else {// The system default theme is not supported.
1820                             // Follow the battery saver mode.
1821                             AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY);
1822                         }
1823                     }
1824
1825                     // Update the current theme status.
1826                     currentThemeStatus = getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
1827                     break;
1828
1829                 case "webview_theme":
1830                     // Get the new WebView theme.
1831                     String newWebViewTheme = sharedPreferences.getString("webview_theme", getString(R.string.webview_theme_default_value));
1832
1833                     // Define a new WebView theme entry number.
1834                     int newWebViewThemeEntryNumber;
1835
1836                     // 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.
1837                     if (newWebViewTheme.equals(webViewThemeEntriesStringArray[1])) {  // The light theme is selected.
1838                         // Store the new WebView theme entry number.
1839                         newWebViewThemeEntryNumber = 1;
1840                     } else if (newWebViewTheme.equals(webViewThemeEntryValuesStringArray[2])) {  // The dark theme is selected.
1841                         // Store the WebView theme entry number.
1842                         newWebViewThemeEntryNumber = 2;
1843                     } else {  // The system default theme is selected.
1844                         // Store the WebView theme entry number.
1845                         newWebViewThemeEntryNumber = 0;
1846                     }
1847
1848                     // Update the icon.
1849                     switch (newWebViewThemeEntryNumber) {
1850                         case 0:  // The system default WebView theme is selected.
1851                             // Set the icon according to the app theme.
1852                             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_NO) {
1853                                 webViewThemePreference.setIcon(R.drawable.webview_light_theme_day);
1854                             } else {
1855                                 webViewThemePreference.setIcon(R.drawable.webview_dark_theme_night);
1856                             }
1857                             break;
1858
1859                         case 1:  // The system default WebView theme is selected.
1860                             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_NO) {
1861                                 webViewThemePreference.setIcon(R.drawable.webview_light_theme_day);
1862                             } else {
1863                                 webViewThemePreference.setIcon(R.drawable.webview_light_theme_night);
1864                             }
1865                             break;
1866
1867                         case 2:  // The system default WebView theme is selected.
1868                             if (currentThemeStatus == Configuration.UI_MODE_NIGHT_NO) {
1869                                 webViewThemePreference.setIcon(R.drawable.webview_dark_theme_day);
1870                             } else {
1871                                 webViewThemePreference.setIcon(R.drawable.webview_dark_theme_night);
1872                             }
1873                             break;
1874                     }
1875
1876                     // Set the current theme as the summary text for the preference.
1877                     webViewThemePreference.setSummary(webViewThemeEntriesStringArray[newWebViewThemeEntryNumber]);
1878                     break;
1879
1880                 case "wide_viewport":
1881                     // Update the icon.
1882                     if (sharedPreferences.getBoolean("wide_viewport", true)) {
1883                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1884                             wideViewportPreference.setIcon(R.drawable.wide_viewport_enabled_night);
1885                         } else {
1886                             wideViewportPreference.setIcon(R.drawable.wide_viewport_enabled_day);
1887                         }
1888                     } else {
1889                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1890                             wideViewportPreference.setIcon(R.drawable.wide_viewport_disabled_night);
1891                         } else {
1892                             wideViewportPreference.setIcon(R.drawable.wide_viewport_disabled_day);
1893                         }
1894                     }
1895                     break;
1896
1897                 case "display_webpage_images":
1898                     // Update the icon.
1899                     if (sharedPreferences.getBoolean("display_webpage_images", true)) {
1900                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1901                             displayWebpageImagesPreference.setIcon(R.drawable.images_enabled_night);
1902                         } else {
1903                             displayWebpageImagesPreference.setIcon(R.drawable.images_enabled_day);
1904                         }
1905                     } else {
1906                         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
1907                             displayWebpageImagesPreference.setIcon(R.drawable.images_disabled_night);
1908                         } else {
1909                             displayWebpageImagesPreference.setIcon(R.drawable.images_disabled_day);
1910                         }
1911                     }
1912                     break;
1913             }
1914         };
1915
1916         // Register the listener.
1917         savedPreferences.registerOnSharedPreferenceChangeListener(preferencesListener);
1918     }
1919
1920     // 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.
1921     @Override
1922     public void onPause() {
1923         super.onPause();
1924         savedPreferences.unregisterOnSharedPreferenceChangeListener(preferencesListener);
1925     }
1926
1927     @Override
1928     public void onResume() {
1929         super.onResume();
1930         savedPreferences.registerOnSharedPreferenceChangeListener(preferencesListener);
1931     }
1932 }