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