2 * Copyright © 2016-2017 Soren Stoutner <soren@stoutner.com>.
4 * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
6 * Privacy Browser is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * Privacy Browser is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with Privacy Browser. If not, see <http://www.gnu.org/licenses/>.
20 package com.stoutner.privacybrowser.fragments;
22 import android.annotation.SuppressLint;
23 import android.content.SharedPreferences;
24 import android.os.Build;
25 import android.os.Bundle;
26 import android.preference.Preference;
27 import android.preference.PreferenceFragment;
28 import android.view.LayoutInflater;
29 import android.view.View;
30 import android.webkit.WebView;
32 import com.stoutner.privacybrowser.R;
33 import com.stoutner.privacybrowser.activities.MainWebViewActivity;
35 public class SettingsFragment extends PreferenceFragment {
36 private SharedPreferences.OnSharedPreferenceChangeListener preferencesListener;
37 private SharedPreferences savedPreferences;
40 public void onCreate(Bundle savedInstanceState) {
41 super.onCreate(savedInstanceState);
42 addPreferencesFromResource(R.xml.preferences);
44 // Initialize savedPreferences.
45 savedPreferences = getPreferenceScreen().getSharedPreferences();
47 // Get handles for the preferences we need to modify.
48 final Preference javaScriptPreference = findPreference("javascript_enabled");
49 final Preference firstPartyCookiesPreference = findPreference("first_party_cookies_enabled");
50 final Preference thirdPartyCookiesPreference = findPreference("third_party_cookies_enabled");
51 final Preference domStoragePreference = findPreference("dom_storage_enabled");
52 final Preference saveFormDataPreference = findPreference("save_form_data_enabled");
53 final Preference userAgentPreference = findPreference("user_agent");
54 final Preference customUserAgentPreference = findPreference("custom_user_agent");
55 final Preference blockAdsPreference = findPreference("block_ads");
56 final Preference incognitoModePreference = findPreference("incognito_mode");
57 final Preference doNotTrackPreference = findPreference("do_not_track");
58 final Preference proxyThroughOrbotPreference = findPreference("proxy_through_orbot");
59 final Preference torHomepagePreference = findPreference("tor_homepage");
60 final Preference torSearchPreference = findPreference("tor_search");
61 final Preference torSearchCustomURLPreference = findPreference("tor_search_custom_url");
62 final Preference searchPreference = findPreference("search");
63 final Preference searchCustomURLPreference = findPreference("search_custom_url");
64 final Preference fullScreenBrowsingModePreference = findPreference("full_screen_browsing_mode");
65 final Preference hideSystemBarsPreference = findPreference("hide_system_bars");
66 final Preference translucentNavigationBarPreference = findPreference("translucent_navigation_bar");
67 final Preference clearEverythingPreference = findPreference("clear_everything");
68 final Preference clearCookiesPreference = findPreference("clear_cookies");
69 final Preference clearDomStoragePreference = findPreference("clear_dom_storage");
70 final Preference clearFormDataPreference = findPreference("clear_form_data");
71 final Preference clearCachePreference = findPreference("clear_cache");
72 final Preference homepagePreference = findPreference("homepage");
73 final Preference defaultFontSizePreference = findPreference("default_font_size");
74 final Preference swipeToRefreshPreference = findPreference("swipe_to_refresh");
75 final Preference displayAdditionalAppBarIconsPreference = findPreference("display_additional_app_bar_icons");
76 final Preference darkThemePreference = findPreference("dark_theme");
77 final Preference displayWebpageImagesPreference = findPreference("display_webpage_images");
80 domStoragePreference.setDependency("javascript_enabled");
81 torHomepagePreference.setDependency("proxy_through_orbot");
82 torSearchPreference.setDependency("proxy_through_orbot");
83 hideSystemBarsPreference.setDependency("full_screen_browsing_mode");
85 // Get strings from the preferences.
86 String torSearchString = savedPreferences.getString("tor_search", "https://3g2upl4pq6kufc4m.onion/html/?q=");
87 String searchString = savedPreferences.getString("search", "https://duckduckgo.com/html/?q=");
89 // Get booleans from the preferences.
90 boolean javaScriptEnabledBoolean = savedPreferences.getBoolean("javascript_enabled", false);
91 boolean firstPartyCookiesEnabledBoolean = savedPreferences.getBoolean("first_party_cookies_enabled", false);
92 boolean thirdPartyCookiesEnabledBoolean = savedPreferences.getBoolean("third_party_cookies_enabled", false);
93 boolean proxyThroughOrbotBoolean = savedPreferences.getBoolean("proxy_through_orbot", false);
94 boolean fullScreenBrowsingModeBoolean = savedPreferences.getBoolean("full_screen_browsing_mode", false);
95 boolean hideSystemBarsBoolean = savedPreferences.getBoolean("hide_system_bars", false);
96 boolean clearEverythingBoolean = savedPreferences.getBoolean("clear_everything", true);
98 // Only enable `thirdPartyCookiesPreference` if `firstPartyCookiesEnabledBoolean` is `true` and API >= 21.
99 thirdPartyCookiesPreference.setEnabled(firstPartyCookiesEnabledBoolean && (Build.VERSION.SDK_INT >= 21));
101 // We need to inflated a `WebView` to get the default user agent.
102 LayoutInflater inflater = getActivity().getLayoutInflater();
103 // `@SuppressLint("InflateParams")` removes the warning about using `null` as the `ViewGroup`, which in this case makes sense because we don't want to display `bare_webview` on the screen. `false` does not attach the view to the root.
104 @SuppressLint("InflateParams") View bareWebViewLayout = inflater.inflate(R.layout.bare_webview, null, false);
105 final WebView bareWebView = (WebView) bareWebViewLayout.findViewById(R.id.bare_webview);
107 // Set the current user-agent as the summary text for the "user_agent" preference when the preference screen is loaded.
108 switch (savedPreferences.getString("user_agent", "PrivacyBrowser/1.0")) {
109 case "WebView default user agent":
110 // Get the user agent text from the webview (which changes based on the version of Android and WebView installed).
111 userAgentPreference.setSummary(bareWebView.getSettings().getUserAgentString());
114 case "Custom user agent":
115 // We can't use the string from the array because it is referenced in code and can't be translated.
116 userAgentPreference.setSummary(R.string.custom_user_agent);
120 // Display the user agent from the preference as the summary text.
121 userAgentPreference.setSummary(savedPreferences.getString("user_agent", "PrivacyBrowser/1.0"));
125 // Set the summary text for "customUserAgentPreference" (the default is `PrivacyBrowser/1.0`) and enable it if `userAgentPreference` it set to `Custom user agent`.
126 customUserAgentPreference.setSummary(savedPreferences.getString("custom_user_agent", "PrivacyBrowser/1.0"));
127 customUserAgentPreference.setEnabled(userAgentPreference.getSummary().equals("Custom user agent"));
130 // Set the Tor homepage URL as the summary text for the `tor_homepage` preference when the preference screen is loaded. The default is DuckDuckGo: `https://3g2upl4pq6kufc4m.onion`.
131 torHomepagePreference.setSummary(savedPreferences.getString("tor_homepage", "https://3g2upl4pq6kufc4m.onion"));
134 // Set the Tor search URL as the summary text for the Tor preference when the preference screen is loaded. The default is `https://3g2upl4pq6kufc4m.onion/html/?q=`
135 if (torSearchString.equals("Custom URL")) {
136 // Use R.string.custom_url, which will be translated, instead of the array value, which will not.
137 torSearchPreference.setSummary(R.string.custom_url);
139 // Set the array value as the summary text.
140 torSearchPreference.setSummary(torSearchString);
143 // Set the summary text for `tor_search_custom_url`. The default is `""`.
144 torSearchCustomURLPreference.setSummary(savedPreferences.getString("tor_search_custom_url", ""));
146 // Enable the Tor custom URL search options only if proxying through Orbot and the search is set to `Custom URL`.
147 torSearchCustomURLPreference.setEnabled(proxyThroughOrbotBoolean && torSearchString.equals("Custom URL"));
150 // Set the search URL as the summary text for the search preference when the preference screen is loaded. The default is `https://duckduckgo.com/html/?q=`.
151 if (searchString.equals("Custom URL")) {
152 // Use R.string.custom_url, which will be translated, instead of the array value, which will not.
153 searchPreference.setSummary(R.string.custom_url);
155 // Set the array value as the summary text.
156 searchPreference.setSummary(searchString);
159 // Set the summary text for `search_custom_url` (the default is `""`) and enable it if `search` is set to `Custom URL`.
160 searchCustomURLPreference.setSummary(savedPreferences.getString("search_custom_url", ""));
161 searchCustomURLPreference.setEnabled(searchString.equals("Custom URL"));
164 // Enable `translucentNavigationBarPreference` only if full screen browsing mode is enabled and `hide_system_bars` is disabled.
165 translucentNavigationBarPreference.setEnabled(fullScreenBrowsingModeBoolean && !hideSystemBarsBoolean);
167 // Set the status of the `Clear and Exit` preferences.
168 clearCookiesPreference.setEnabled(!clearEverythingBoolean);
169 clearDomStoragePreference.setEnabled(!clearEverythingBoolean);
170 clearFormDataPreference.setEnabled(!clearEverythingBoolean);
171 clearCachePreference.setEnabled(!clearEverythingBoolean);
173 // Set the homepage URL as the summary text for the `Homepage` preference when the preference screen is loaded. The default is `https://duckduckgo.com`.
174 homepagePreference.setSummary(savedPreferences.getString("homepage", "https://duckduckgo.com"));
176 // Set the default font size as the summary text for the `Default Font Size` preference when the preference screen is loaded. The default is `100`.
177 defaultFontSizePreference.setSummary(savedPreferences.getString("default_font_size", "100") + "%%");
180 // Set the `javaScriptPreference` icon.
181 if (javaScriptEnabledBoolean) {
182 javaScriptPreference.setIcon(R.drawable.javascript_enabled);
184 javaScriptPreference.setIcon(R.drawable.privacy_mode);
187 // Set the `firstPartyCookiesPreference` icon.
188 if (firstPartyCookiesEnabledBoolean) {
189 firstPartyCookiesPreference.setIcon(R.drawable.cookies_enabled);
191 firstPartyCookiesPreference.setIcon(R.drawable.cookies_disabled);
194 // Set the `thirdPartyCookiesPreference` icon.
195 if (firstPartyCookiesEnabledBoolean && Build.VERSION.SDK_INT >= 21) {
196 if (thirdPartyCookiesEnabledBoolean) {
197 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_warning);
199 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_disabled);
202 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_ghosted);
205 // Set the `domStoragePreference` icon.
206 if (javaScriptEnabledBoolean) {
207 if (savedPreferences.getBoolean("dom_storage_enabled", false)) {
208 domStoragePreference.setIcon(R.drawable.dom_storage_enabled);
210 domStoragePreference.setIcon(R.drawable.dom_storage_disabled);
213 domStoragePreference.setIcon(R.drawable.dom_storage_ghosted);
216 // Set the `saveFormDataPreference` icon.
217 if (savedPreferences.getBoolean("save_form_data_enabled", false)) {
218 saveFormDataPreference.setIcon(R.drawable.form_data_enabled);
220 saveFormDataPreference.setIcon(R.drawable.form_data_disabled);
223 // Set the `customUserAgentPreference` icon.
224 if (customUserAgentPreference.isEnabled()) {
225 customUserAgentPreference.setIcon(R.drawable.custom_user_agent_enabled);
227 customUserAgentPreference.setIcon(R.drawable.custom_user_agent_ghosted);
230 // Set the `blockAdsPreference` icon.
231 if (savedPreferences.getBoolean("block_ads", true)) {
232 blockAdsPreference.setIcon(R.drawable.block_ads_enabled);
234 blockAdsPreference.setIcon(R.drawable.block_ads_disabled);
237 // Set the `incognitoModePreference` icon.
238 if (savedPreferences.getBoolean("incognito_mode", false)) {
239 incognitoModePreference.setIcon(R.drawable.incognito_mode_enabled);
241 incognitoModePreference.setIcon(R.drawable.incognito_mode_disabled);
244 // Set the `doNotTrackPreference` icon.
245 if (savedPreferences.getBoolean("do_not_track", false)) {
246 doNotTrackPreference.setIcon(R.drawable.do_not_track_enabled);
248 doNotTrackPreference.setIcon(R.drawable.do_not_track_disabled);
251 // Set the `proxyThroughOrbotPreference` icon.
252 if (proxyThroughOrbotBoolean) {
253 proxyThroughOrbotPreference.setIcon(R.drawable.orbot_enabled);
255 proxyThroughOrbotPreference.setIcon(R.drawable.orbot_disabled);
258 // Set the `torSearchPreference` and `torSearchCustomURLPreference` icons.
259 if (proxyThroughOrbotBoolean) {
260 // Set the `torHomepagePreference` and `torSearchPreference` icons.
261 torHomepagePreference.setIcon(R.drawable.home_enabled);
262 torSearchPreference.setIcon(R.drawable.search_enabled);
264 // Set the `torSearchCustomURLPreference` icon.
265 if (torSearchCustomURLPreference.isEnabled()) {
266 torSearchCustomURLPreference.setIcon(R.drawable.search_custom_url_enabled);
268 torSearchCustomURLPreference.setIcon(R.drawable.search_custom_url_disabled);
270 } else { // Proxy through Orbot is disabled.
271 torHomepagePreference.setIcon(R.drawable.home_ghosted);
272 torSearchPreference.setIcon(R.drawable.search_ghosted);
273 torSearchCustomURLPreference.setIcon(R.drawable.search_custom_url_ghosted);
276 // Set the `searchCustomURLPreference` icon.
277 if (searchCustomURLPreference.isEnabled()) {
278 searchCustomURLPreference.setIcon(R.drawable.search_custom_url_enabled);
280 searchCustomURLPreference.setIcon(R.drawable.search_custom_url_ghosted);
283 // Set the full screen browsing mode icons.
284 if (fullScreenBrowsingModeBoolean) {
285 // Set the `fullScreenBrowsingModePreference` icon.
286 fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_enabled);
288 if (hideSystemBarsBoolean) {
289 // Set `hideSystemBarsPreference` to use the enabled icon.
290 hideSystemBarsPreference.setIcon(R.drawable.hide_system_bars_enabled);
292 // Set `translucentNavigationBarPreference` to use the ghosted icon.
293 translucentNavigationBarPreference.setIcon(R.drawable.translucent_bar_ghosted);
294 } else { // `hideSystemBarsBoolean` is false.
295 // Set `hideSystemBarsPreference` to use the disabled icon.
296 hideSystemBarsPreference.setIcon(R.drawable.hide_system_bars_disabled);
298 // Set the correct icon for `translucentNavigationBarPreference`.
299 if (savedPreferences.getBoolean("translucent_navigation_bar", true)) {
300 translucentNavigationBarPreference.setIcon(R.drawable.translucent_bar_enabled);
302 translucentNavigationBarPreference.setIcon(R.drawable.translucent_bar_disabled);
305 } else { // `fullScreenBrowsingModeBoolean` is false.
306 fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_disabled);
307 hideSystemBarsPreference.setIcon(R.drawable.hide_system_bars_ghosted);
308 translucentNavigationBarPreference.setIcon(R.drawable.translucent_bar_ghosted);
311 // Set the `clearEverythingPreference` icon.
312 if (clearEverythingBoolean) {
313 clearEverythingPreference.setIcon(R.drawable.clear_everything_enabled);
315 clearEverythingPreference.setIcon(R.drawable.clear_everything_disabled);
318 // Set the `clearCookiesPreference` icon.
319 if (clearEverythingBoolean || savedPreferences.getBoolean("clear_cookies", true)) {
320 clearCookiesPreference.setIcon(R.drawable.cookies_cleared);
322 clearCookiesPreference.setIcon(R.drawable.cookies_warning);
325 // Set the `clearDomStoragePreference` icon.
326 if (clearEverythingBoolean || savedPreferences.getBoolean("clear_dom_storage", true)) {
327 clearDomStoragePreference.setIcon(R.drawable.dom_storage_cleared);
329 clearDomStoragePreference.setIcon(R.drawable.dom_storage_warning);
332 // Set the `clearFormDataPreference` icon.
333 if (clearEverythingBoolean || savedPreferences.getBoolean("clear_form_data", true)) {
334 clearFormDataPreference.setIcon(R.drawable.form_data_cleared);
336 clearFormDataPreference.setIcon(R.drawable.form_data_warning);
339 // Set the `clearCachePreference` icon.
340 if (clearEverythingBoolean || savedPreferences.getBoolean("clear_cache", true)) {
341 clearCachePreference.setIcon(R.drawable.cache_cleared);
343 clearCachePreference.setIcon(R.drawable.cache_warning);
346 // Set the `swipeToRefreshPreference` icon.
347 if (savedPreferences.getBoolean("swipe_to_refresh", false)) {
348 swipeToRefreshPreference.setIcon(R.drawable.refresh_enabled);
350 swipeToRefreshPreference.setIcon(R.drawable.refresh_disabled);
353 // Set the `displayAdditionalAppBarIconsPreference` icon.
354 if (savedPreferences.getBoolean("display_additional_app_bar_icons", false)) {
355 displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_enabled);
357 displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_disabled);
360 // Set the `darkThemePreference` icon.
361 if (savedPreferences.getBoolean("dark_theme", false)) {
362 darkThemePreference.setIcon(R.drawable.theme_dark);
364 darkThemePreference.setIcon(R.drawable.theme_light);
367 // Set the `displayWebpageImagesPreference` icon.
368 if (savedPreferences.getBoolean("display_webpage_images", true)) {
369 displayWebpageImagesPreference.setIcon(R.drawable.images_enabled);
371 displayWebpageImagesPreference.setIcon(R.drawable.images_disabled);
375 // Listen for preference changes.
376 preferencesListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
378 // Remove Android Studio's warning about the dangers of using SetJavaScriptEnabled. We know.
379 @SuppressLint("SetJavaScriptEnabled")
380 public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
383 case "javascript_enabled":
385 if (sharedPreferences.getBoolean("javascript_enabled", false)) {
386 // Update the icon for `javascript_enabled`.
387 javaScriptPreference.setIcon(R.drawable.javascript_enabled);
389 // Update the icon for `dom_storage_enabled`.
390 if (sharedPreferences.getBoolean("dom_storage_enabled", false)) {
391 domStoragePreference.setIcon(R.drawable.dom_storage_enabled);
393 domStoragePreference.setIcon(R.drawable.dom_storage_disabled);
395 } else { // `javascript_enabled` is `false`.
396 // Update the icon for `javascript_enabled`.
397 javaScriptPreference.setIcon(R.drawable.privacy_mode);
399 // Set the icon for `dom_storage_disabled` to be ghosted.
400 domStoragePreference.setIcon(R.drawable.dom_storage_ghosted);
404 case "first_party_cookies_enabled":
405 // Update the icons for `first_party_cookies_enabled` and `third_party_cookies_enabled`.
406 if (sharedPreferences.getBoolean("first_party_cookies_enabled", false)) {
407 // Set the icon for `first_party_cookies_enabled`.
408 firstPartyCookiesPreference.setIcon(R.drawable.cookies_enabled);
410 // Update the icon for `third_party_cookies_enabled`.
411 if (Build.VERSION.SDK_INT >= 21) {
412 if (sharedPreferences.getBoolean("third_party_cookies_enabled", false)) {
413 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_warning);
415 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_disabled);
418 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_ghosted);
420 } else { // `first_party_cookies_enabled` is `false`.
421 // Update the icon for `first_party_cookies_enabled`.
422 firstPartyCookiesPreference.setIcon(R.drawable.cookies_disabled);
424 // Set the icon for `third_party_cookies_enabled` to be ghosted.
425 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_ghosted);
428 // Enable `third_party_cookies_enabled` if `first_party_cookies_enabled` is `true` and API >= 21.
429 thirdPartyCookiesPreference.setEnabled(sharedPreferences.getBoolean("first_party_cookies_enabled", false) && (Build.VERSION.SDK_INT >= 21));
432 case "third_party_cookies_enabled":
434 if (sharedPreferences.getBoolean("third_party_cookies_enabled", false)) {
435 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_warning);
437 thirdPartyCookiesPreference.setIcon(R.drawable.cookies_disabled);
441 case "dom_storage_enabled":
443 if (sharedPreferences.getBoolean("dom_storage_enabled", false)) {
444 domStoragePreference.setIcon(R.drawable.dom_storage_enabled);
446 domStoragePreference.setIcon(R.drawable.dom_storage_disabled);
450 case "save_form_data_enabled":
452 if (sharedPreferences.getBoolean("save_form_data_enabled", false)) {
453 saveFormDataPreference.setIcon(R.drawable.form_data_enabled);
455 saveFormDataPreference.setIcon(R.drawable.form_data_disabled);
459 String userAgentString = sharedPreferences.getString("user_agent", "PrivacyBrowser/1.0");
461 switch (userAgentString) {
462 case "WebView default user agent":
463 // Display the user agent as the summary text for `userAgentPreference`.
464 userAgentPreference.setSummary(bareWebView.getSettings().getUserAgentString());
466 // Update `customUserAgentPreference`.
467 customUserAgentPreference.setEnabled(false);
468 customUserAgentPreference.setIcon(R.drawable.custom_user_agent_ghosted);
471 case "Custom user agent":
472 // Display `Custom user agent` as the summary text for `userAgentPreference`.
473 userAgentPreference.setSummary(R.string.custom_user_agent);
475 // Update `customUserAgentPreference`.
476 customUserAgentPreference.setEnabled(true);
477 customUserAgentPreference.setIcon(R.drawable.custom_user_agent_enabled);
481 // Display the user agent as the summary text for `userAgentPreference`.
482 userAgentPreference.setSummary(sharedPreferences.getString("user_agent", "PrivacyBrowser/1.0"));
484 // Update `customUserAgentPreference`.
485 customUserAgentPreference.setEnabled(false);
486 customUserAgentPreference.setIcon(R.drawable.custom_user_agent_ghosted);
491 case "custom_user_agent":
492 // Set the new custom user agent as the summary text for `custom_user_agent`. The default is `PrivacyBrowser/1.0`.
493 customUserAgentPreference.setSummary(sharedPreferences.getString("custom_user_agent", "PrivacyBrowser/1.0"));
498 if (sharedPreferences.getBoolean("block_ads", true)) {
499 blockAdsPreference.setIcon(R.drawable.block_ads_enabled);
501 blockAdsPreference.setIcon(R.drawable.block_ads_disabled);
505 case "incognito_mode":
507 if (sharedPreferences.getBoolean("incognito_mode", false)) {
508 incognitoModePreference.setIcon(R.drawable.incognito_mode_enabled);
510 incognitoModePreference.setIcon(R.drawable.incognito_mode_disabled);
516 if (sharedPreferences.getBoolean("do_not_track", false)) {
517 doNotTrackPreference.setIcon(R.drawable.do_not_track_enabled);
519 doNotTrackPreference.setIcon(R.drawable.do_not_track_disabled);
524 case "proxy_through_orbot":
525 // Get current settings.
526 boolean currentProxyThroughOrbot = sharedPreferences.getBoolean("proxy_through_orbot", false);
527 String currentTorSearchString = sharedPreferences.getString("tor_search", "https://3g2upl4pq6kufc4m.onion/html/?q=");
529 // Enable the Tor custom URL search option only if `currentProxyThroughOrbot` is true and the search is set to `Custom URL`.
530 torSearchCustomURLPreference.setEnabled(currentProxyThroughOrbot && currentTorSearchString.equals("Custom URL"));
533 if (currentProxyThroughOrbot) {
534 // Set the `proxyThroughOrbotPreference`, `torHomepagePreference`, and `torSearchPreference` icons.
535 proxyThroughOrbotPreference.setIcon(R.drawable.orbot_enabled);
536 torHomepagePreference.setIcon(R.drawable.home_enabled);
537 torSearchPreference.setIcon(R.drawable.search_enabled);
539 // Set the `torSearchCustomURLPreference` icon.
540 if (torSearchCustomURLPreference.isEnabled()) {
541 torSearchCustomURLPreference.setIcon(R.drawable.search_custom_url_enabled);
543 torSearchCustomURLPreference.setIcon(R.drawable.search_custom_url_disabled);
545 } else { // Proxy through Orbot is disabled.
546 proxyThroughOrbotPreference.setIcon(R.drawable.orbot_disabled);
547 torHomepagePreference.setIcon(R.drawable.home_ghosted);
548 torSearchPreference.setIcon(R.drawable.search_ghosted);
549 torSearchCustomURLPreference.setIcon(R.drawable.search_custom_url_ghosted);
554 // Set the new tor homepage URL as the summary text for the `tor_homepage` preference. The default is DuckDuckGo: `https://3g2upl4pq6kufc4m.onion`.
555 torHomepagePreference.setSummary(sharedPreferences.getString("tor_homepage", "https://3g2upl4pq6kufc4m.onion"));
559 // Get the present search string.
560 String presentTorSearchString = sharedPreferences.getString("tor_search", "https://3g2upl4pq6kufc4m.onion/html/?q=");
562 // Update the preferences.
563 if (presentTorSearchString.equals("Custom URL")) {
564 // Use `R.string.custom_url`, which is translated, as the summary instead of the array value, which isn't.
565 torSearchPreference.setSummary(R.string.custom_url);
567 // Update `torSearchCustomURLPreference`.
568 torSearchCustomURLPreference.setEnabled(true);
569 torSearchCustomURLPreference.setIcon(R.drawable.search_custom_url_enabled);
571 // Set the array value as the summary text.
572 torSearchPreference.setSummary(presentTorSearchString);
574 // Update `torSearchCustomURLPreference`.
575 torSearchCustomURLPreference.setEnabled(false);
576 torSearchCustomURLPreference.setIcon(R.drawable.search_custom_url_disabled);
580 case "tor_search_custom_url":
581 // Set the summary text for `tor_search_custom_url`.
582 torSearchCustomURLPreference.setSummary(sharedPreferences.getString("tor_search_custom_url", ""));
586 // Store the new search string.
587 String newSearchString = sharedPreferences.getString("search", "https://duckduckgo.com/html/?q=");
589 // Update `searchPreference` and `searchCustomURLPreference`.
590 if (newSearchString.equals("Custom URL")) { // `Custom URL` is selected.
591 // Set the summary text to `R.string.custom_url`, which is translated.
592 searchPreference.setSummary(R.string.custom_url);
594 // Update `searchCustomURLPreference`.
595 searchCustomURLPreference.setEnabled(true);
596 searchCustomURLPreference.setIcon(R.drawable.search_custom_url_enabled);
597 } else { // `Custom URL` is not selected.
598 // Set the summary text to `newSearchString`.
599 searchPreference.setSummary(newSearchString);
601 // Update `searchCustomURLPreference`.
602 searchCustomURLPreference.setEnabled(false);
603 searchCustomURLPreference.setIcon(R.drawable.search_custom_url_ghosted);
607 case "search_custom_url":
608 // Set the new custom search URL as the summary text for `search_custom_url`. The default is `""`.
609 searchCustomURLPreference.setSummary(sharedPreferences.getString("search_custom_url", ""));
612 case "full_screen_browsing_mode":
613 if (sharedPreferences.getBoolean("full_screen_browsing_mode", false)) {
614 // Set `fullScreenBrowsingModePreference` to use the enabled icon.
615 fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_enabled);
617 if (sharedPreferences.getBoolean("hide_system_bars", false)) {
618 // Set `hideSystemBarsPreference` to use the enabled icon.
619 hideSystemBarsPreference.setIcon(R.drawable.hide_system_bars_enabled);
621 // Update `translucentNavigationBarPreference`.
622 translucentNavigationBarPreference.setEnabled(false);
623 translucentNavigationBarPreference.setIcon(R.drawable.translucent_bar_ghosted);
624 } else { // `hide_system_bars` is false.
625 // Set `hideSystemBarsPreference` to use the disabled icon.
626 hideSystemBarsPreference.setIcon(R.drawable.hide_system_bars_disabled);
628 // Update `translucentNavigationBarPreference`.
629 translucentNavigationBarPreference.setEnabled(true);
630 if (sharedPreferences.getBoolean("translucent_navigation_bar", true)) {
631 translucentNavigationBarPreference.setIcon(R.drawable.translucent_bar_enabled);
633 translucentNavigationBarPreference.setIcon(R.drawable.translucent_bar_disabled);
636 } else { // `full_screen_browsing_mode` is false.
637 // Disable `translucentNavigationBarPreference`.
638 translucentNavigationBarPreference.setEnabled(false);
641 fullScreenBrowsingModePreference.setIcon(R.drawable.full_screen_disabled);
642 hideSystemBarsPreference.setIcon(R.drawable.hide_system_bars_ghosted);
643 translucentNavigationBarPreference.setIcon(R.drawable.translucent_bar_ghosted);
647 case "hide_system_bars":
648 if (sharedPreferences.getBoolean("hide_system_bars", false)) {
649 // Set `hideSystemBarsPreference` to use the enabled icon.
650 hideSystemBarsPreference.setIcon(R.drawable.hide_system_bars_enabled);
652 // Update `translucentNavigationBarPreference`.
653 translucentNavigationBarPreference.setEnabled(false);
654 translucentNavigationBarPreference.setIcon(R.drawable.translucent_bar_ghosted);
655 } else { // `hide_system_bars` is false.
656 // Set `hideSystemBarsPreference` to use the disabled icon.
657 hideSystemBarsPreference.setIcon(R.drawable.hide_system_bars_disabled);
659 // Update `translucentNavigationBarPreference`.
660 translucentNavigationBarPreference.setEnabled(true);
661 if (sharedPreferences.getBoolean("translucent_navigation_bar", true)) {
662 translucentNavigationBarPreference.setIcon(R.drawable.translucent_bar_enabled);
664 translucentNavigationBarPreference.setIcon(R.drawable.translucent_bar_disabled);
669 case "translucent_navigation_bar":
671 if (sharedPreferences.getBoolean("translucent_navigation_bar", true)) {
672 translucentNavigationBarPreference.setIcon(R.drawable.translucent_bar_enabled);
674 translucentNavigationBarPreference.setIcon(R.drawable.translucent_bar_disabled);
678 case "clear_everything":
679 // Store the new `clear_everything` status
680 boolean newClearEverythingBoolean = sharedPreferences.getBoolean("clear_everything", true);
682 // Update the status of the `Clear and Exit` preferences.
683 clearCookiesPreference.setEnabled(!newClearEverythingBoolean);
684 clearDomStoragePreference.setEnabled(!newClearEverythingBoolean);
685 clearFormDataPreference.setEnabled(!newClearEverythingBoolean);
686 clearCachePreference.setEnabled(!newClearEverythingBoolean);
688 // Update the `clearEverythingPreference` icon.
689 if (newClearEverythingBoolean) {
690 clearEverythingPreference.setIcon(R.drawable.clear_everything_enabled);
692 clearEverythingPreference.setIcon(R.drawable.clear_everything_disabled);
695 // Update the `clearCookiesPreference` icon.
696 if (newClearEverythingBoolean || sharedPreferences.getBoolean("clear_cookies", true)) {
697 clearCookiesPreference.setIcon(R.drawable.cookies_cleared);
699 clearCookiesPreference.setIcon(R.drawable.cookies_warning);
702 // Update the `clearDomStoragePreference` icon.
703 if (newClearEverythingBoolean || sharedPreferences.getBoolean("clear_dom_storage", true)) {
704 clearDomStoragePreference.setIcon(R.drawable.dom_storage_cleared);
706 clearDomStoragePreference.setIcon(R.drawable.dom_storage_warning);
709 // Update the `clearFormDataPreference` icon.
710 if (newClearEverythingBoolean || sharedPreferences.getBoolean("clear_form_data", true)) {
711 clearFormDataPreference.setIcon(R.drawable.form_data_cleared);
713 clearFormDataPreference.setIcon(R.drawable.form_data_warning);
716 // Update the `clearCachePreference` icon.
717 if (newClearEverythingBoolean || sharedPreferences.getBoolean("clear_cache", true)) {
718 clearCachePreference.setIcon(R.drawable.cache_cleared);
720 clearCachePreference.setIcon(R.drawable.cache_warning);
724 case "clear_cookies":
726 if (sharedPreferences.getBoolean("clear_cookies", true)) {
727 clearCookiesPreference.setIcon(R.drawable.cookies_cleared);
729 clearCookiesPreference.setIcon(R.drawable.cookies_warning);
733 case "clear_dom_storage":
735 if (sharedPreferences.getBoolean("clear_dom_storage", true)) {
736 clearDomStoragePreference.setIcon(R.drawable.dom_storage_cleared);
738 clearDomStoragePreference.setIcon(R.drawable.dom_storage_warning);
742 case "clear_form_data":
744 if (sharedPreferences.getBoolean("clear_form_data", true)) {
745 clearFormDataPreference.setIcon(R.drawable.form_data_cleared);
747 clearFormDataPreference.setIcon(R.drawable.form_data_warning);
753 if (sharedPreferences.getBoolean("clear_cache", true)) {
754 clearCachePreference.setIcon(R.drawable.cache_cleared);
756 clearCachePreference.setIcon(R.drawable.cache_warning);
761 // Set the new homepage URL as the summary text for the Homepage preference. The default is `https://www.duckduckgo.com`.
762 homepagePreference.setSummary(sharedPreferences.getString("homepage", "https://www.duckduckgo.com"));
765 case "default_font_size":
766 // Update the summary text of `default_font_size`.
767 defaultFontSizePreference.setSummary(sharedPreferences.getString("default_font_size", "100") + "%%");
770 case "swipe_to_refresh":
772 if (sharedPreferences.getBoolean("swipe_to_refresh", false)) {
773 swipeToRefreshPreference.setIcon(R.drawable.refresh_enabled);
775 swipeToRefreshPreference.setIcon(R.drawable.refresh_disabled);
779 case "display_additional_app_bar_icons":
781 if (sharedPreferences.getBoolean("display_additional_app_bar_icons", false)) {
782 displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_enabled);
784 displayAdditionalAppBarIconsPreference.setIcon(R.drawable.more_disabled);
790 if (sharedPreferences.getBoolean("dark_theme", false)) {
791 darkThemePreference.setIcon(R.drawable.theme_dark);
793 darkThemePreference.setIcon(R.drawable.theme_light);
797 case "display_webpage_images":
798 if (sharedPreferences.getBoolean("display_webpage_images", true)) {
800 displayWebpageImagesPreference.setIcon(R.drawable.images_enabled);
802 // `mainWebView` does not need to be reloaded because unloaded images will load automatically.
803 MainWebViewActivity.reloadOnRestartBoolean = false;
806 displayWebpageImagesPreference.setIcon(R.drawable.images_disabled);
808 // Set `mainWebView` to reload on restart to remove the current images.
809 MainWebViewActivity.reloadOnRestartBoolean = true;
816 // Register the listener.
817 savedPreferences.registerOnSharedPreferenceChangeListener(preferencesListener);
820 // 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
821 // even while running in the foreground.
823 public void onPause() {
825 savedPreferences.unregisterOnSharedPreferenceChangeListener(preferencesListener);
829 public void onResume() {
831 savedPreferences.registerOnSharedPreferenceChangeListener(preferencesListener);