Reset the favorite icon and the `WebView` title when a new page loads. Implements...
[PrivacyBrowser.git] / app / src / main / java / com / stoutner / privacybrowser / fragments / SettingsFragment.java
1 /*
2  * Copyright 2016-2017 Soren Stoutner <soren@stoutner.com>.
3  *
4  * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
5  *
6  * Privacy Browser is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Privacy Browser is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Privacy Browser.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 package com.stoutner.privacybrowser.fragments;
21
22 import android.annotation.SuppressLint;
23 import android.content.SharedPreferences;
24 import android.os.Bundle;
25 import android.preference.Preference;
26 import android.preference.PreferenceFragment;
27 import android.view.LayoutInflater;
28 import android.view.View;
29 import android.webkit.WebView;
30
31 import com.stoutner.privacybrowser.R;
32
33 public class SettingsFragment extends PreferenceFragment {
34     private SharedPreferences.OnSharedPreferenceChangeListener preferencesListener;
35     private SharedPreferences savedPreferences;
36
37     @Override
38     public void onCreate(Bundle savedInstanceState) {
39         super.onCreate(savedInstanceState);
40         addPreferencesFromResource(R.xml.preferences);
41
42         // Initialize savedPreferences.
43         savedPreferences = getPreferenceScreen().getSharedPreferences();
44
45         // Get handles for the preferences we need to modify.
46         final Preference domStorageEnabled = findPreference("dom_storage_enabled");
47         final Preference thirdPartyCookiesEnabled = findPreference("third_party_cookies_enabled");
48         final Preference userAgentPreference = findPreference("user_agent");
49         final Preference customUserAgent = findPreference("custom_user_agent");
50         final Preference javaScriptDisabledSearchPreference = findPreference("javascript_disabled_search");
51         final Preference javaScriptDisabledSearchCustomURLPreference = findPreference("javascript_disabled_search_custom_url");
52         final Preference javaScriptEnabledSearchPreference = findPreference("javascript_enabled_search");
53         final Preference javaScriptEnabledSearchCustomURLPreference = findPreference("javascript_enabled_search_custom_url");
54         final Preference hideSystemBarsPreference = findPreference("hide_system_bars");
55         final Preference translucentNavigationBarPreference = findPreference("translucent_navigation_bar");
56         final Preference torHomepagePreference = findPreference("tor_homepage");
57         final Preference torJavaScriptDisabledSearchPreference = findPreference("tor_javascript_disabled_search");
58         final Preference torJavaScriptDisabledSearchCustomURLPreference = findPreference("tor_javascript_disabled_search_custom_url");
59         final Preference torJavaScriptEnabledSearchPreference = findPreference("tor_javascript_enabled_search");
60         final Preference torJavaScriptEnabledSearchCustomURLPreference = findPreference("tor_javascript_enabled_search_custom_url");
61         final Preference homepagePreference = findPreference("homepage");
62         final Preference defaultFontSizePreference = findPreference("default_font_size");
63
64         // Get booleans from the preferences.
65         final boolean fullScreenBrowsingModeEnabled = savedPreferences.getBoolean("enable_full_screen_browsing_mode", false);
66         final boolean proxyThroughOrbot = savedPreferences.getBoolean("proxy_through_orbot", false);
67
68         // Get strings from the preferences.
69         String javaScriptDisabledSearchString = savedPreferences.getString("javascript_disabled_search", "https://duckduckgo.com/html/?q=");
70         String javaScriptEnabledSearchString = savedPreferences.getString("javascript_enabled_search", "https://duckduckgo.com/?q=");
71         String torJavaScriptDisabledSearchString = savedPreferences.getString("tor_javascript_disabled_search", "https://3g2upl4pq6kufc4m.onion/html/?q=");
72         String torJavaScriptEnabledSearchString = savedPreferences.getString("tor_javascript_enabled_search", "https://3g2upl4pq6kufc4m.onion/?q=");
73         String defaultFontSizeString = savedPreferences.getString("default_font_size", "100");
74
75         // Allow the user to access "dom_storage_enabled" if "javascript_enabled" is enabled.  The default is false.
76         domStorageEnabled.setEnabled(savedPreferences.getBoolean("javascript_enabled", false));
77
78         // Allow the user to access "third_party_cookies_enabled" if "first_party_cookies_enabled" is enabled.  The default is false.
79         thirdPartyCookiesEnabled.setEnabled(savedPreferences.getBoolean("first_party_cookies_enabled", false));
80
81
82         // We need to inflated a `WebView` to get the default user agent.
83         LayoutInflater inflater = getActivity().getLayoutInflater();
84         // `@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.
85         @SuppressLint("InflateParams") View bareWebViewLayout = inflater.inflate(R.layout.bare_webview, null, false);
86         final WebView bareWebView = (WebView) bareWebViewLayout.findViewById(R.id.bare_webview);
87
88         // Set the current user-agent as the summary text for the "user_agent" preference when the preference screen is loaded.
89         switch (savedPreferences.getString("user_agent", "PrivacyBrowser/1.0")) {
90             case "WebView default user agent":
91                 // Get the user agent text from the webview (which changes based on the version of Android and WebView installed).
92                 userAgentPreference.setSummary(bareWebView.getSettings().getUserAgentString());
93                 break;
94
95             case "Custom user agent":
96                 // We can't use the string from the array because it is referenced in code and can't be translated.
97                 userAgentPreference.setSummary(R.string.custom_user_agent);
98                 break;
99
100             default:
101                 // Display the user agent from the preference as the summary text.
102                 userAgentPreference.setSummary(savedPreferences.getString("user_agent", "PrivacyBrowser/1.0"));
103                 break;
104         }
105
106         // Set the summary text for "custom_user_agent" (the default is "PrivacyBrowser/1.0") and enable it if "user_agent" it set to "Custom user agent".
107         customUserAgent.setSummary(savedPreferences.getString("custom_user_agent", "PrivacyBrowser/1.0"));
108         customUserAgent.setEnabled(userAgentPreference.getSummary().equals("Custom user agent"));
109
110
111         // Set the JavaScript-disabled search URL as the summary text for the JavaScript-disabled search preference when the preference screen is loaded.  The default is `https://duckduckgo.com/html/?q=`.
112         if (javaScriptDisabledSearchString.equals("Custom URL")) {
113             // Use R.string.custom_url, which will be translated, instead of the array value, which will not.
114             javaScriptDisabledSearchPreference.setSummary(R.string.custom_url);
115         } else {
116             // Set the array value as the summary text.
117             javaScriptDisabledSearchPreference.setSummary(javaScriptDisabledSearchString);
118         }
119
120         // Set the summary text for `javascript_disabled_search_custom_url` (the default is `""`) and enable it if `javascript_disabled_search` is set to `Custom URL`.
121         javaScriptDisabledSearchCustomURLPreference.setSummary(savedPreferences.getString("javascript_disabled_search_custom_url", ""));
122         javaScriptDisabledSearchCustomURLPreference.setEnabled(javaScriptDisabledSearchString.equals("Custom URL"));
123
124
125         // Set the JavaScript-enabled search URL as the summary text for the JavaScript-enabled search preference when the preference screen is loaded.  The default is `https://duckduckgo.com/?q=`.
126         if (javaScriptEnabledSearchString.equals("Custom URL")) {
127             // If set to "Custom URL", use R.string.custom_url, which will be translated, instead of the array value, which will not.
128             javaScriptEnabledSearchPreference.setSummary(R.string.custom_url);
129         } else {
130             // Set the array value as the summary text.
131             javaScriptEnabledSearchPreference.setSummary(javaScriptEnabledSearchString);
132         }
133
134         // Set the summary text for `javascript_enabled_search_custom_url` (the default is `""`) and enable it if `javascript_enabled_search` is set to `Custom URL`.
135         javaScriptEnabledSearchCustomURLPreference.setSummary(savedPreferences.getString("javascript_enabled_search_custom_url", ""));
136         javaScriptEnabledSearchCustomURLPreference.setEnabled(javaScriptEnabledSearchString.equals("Custom URL"));
137
138
139         // Enable the full screen options if full screen browsing mode is enabled.
140         if (!fullScreenBrowsingModeEnabled) {
141             // Disable the full screen options.
142             hideSystemBarsPreference.setEnabled(false);
143             translucentNavigationBarPreference.setEnabled(false);
144         } else {
145             // Disable `transparent_navigation_bar` if `hide_system_bars` is `true`.
146             translucentNavigationBarPreference.setEnabled(!savedPreferences.getBoolean("hide_system_bars", false));
147         }
148
149
150         // 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`.
151         torHomepagePreference.setSummary(savedPreferences.getString("tor_homepage", "https://3g2upl4pq6kufc4m.onion"));
152
153
154         // Set the Tor JavaScript-disabled search URL as the summary text for the Tor JavaScript-disabled search preference when the preference screen is loaded.  The default is `https://3g2upl4pq6kufc4m.onion/html/?q=`
155         if (torJavaScriptDisabledSearchString.equals("Custom URL")) {
156             // Use R.string.custom_url, which will be translated, instead of the array value, which will not.
157             torJavaScriptDisabledSearchPreference.setSummary(R.string.custom_url);
158         } else {
159             // Set the array value as the summary text.
160             torJavaScriptDisabledSearchPreference.setSummary(torJavaScriptDisabledSearchString);
161         }
162
163         // Set the summary text for `tor_javascript_disabled_search_custom_url`.  The default is `""`.
164         torJavaScriptDisabledSearchCustomURLPreference.setSummary(savedPreferences.getString("tor_javascript_disabled_search_custom_url", ""));
165
166
167         // Set the Tor JavaScript-enabled search URL as the summary text for the Tor Javascript-enabled search preference when the preference screen is loaded.  The default is `https://3g2upl4pq6kufc4m.onion/?q=`.
168         if (torJavaScriptEnabledSearchString.equals("Custom URL")) {
169             // Use R.string.custom_url, which will be translated, instead of the array value, which will not.
170             torJavaScriptEnabledSearchPreference.setSummary(R.string.custom_url);
171         } else {
172             // Set the array value as the summary text.
173             torJavaScriptEnabledSearchPreference.setSummary(torJavaScriptEnabledSearchString);
174         }
175
176         // Set the summary text for `tor_javascript_enabled_search_custom_url`.  The default is `""`.
177         torJavaScriptEnabledSearchCustomURLPreference.setSummary(savedPreferences.getString("tor_javascript_enabled_search_custom_url", ""));
178
179
180         // Enable the Tor preferences only if `proxy_through_orbot` is enabled.  The default is `false`.
181         torHomepagePreference.setEnabled(proxyThroughOrbot);
182         torJavaScriptDisabledSearchPreference.setEnabled(proxyThroughOrbot);
183         torJavaScriptEnabledSearchPreference.setEnabled(proxyThroughOrbot);
184
185         // Enable the Tor custom URL search options only if `proxyThroughOrbot` is true and the search is set to `Custom URL`.
186         torJavaScriptDisabledSearchCustomURLPreference.setEnabled(proxyThroughOrbot && torJavaScriptDisabledSearchString.equals("Custom URL"));
187         torJavaScriptEnabledSearchCustomURLPreference.setEnabled(proxyThroughOrbot && torJavaScriptEnabledSearchString.equals("Custom URL"));
188
189
190         // Set the homepage URL as the summary text for the `Homepage` preference when the preference screen is loaded.  The default is `https://duckduckgo.com`.
191         homepagePreference.setSummary(savedPreferences.getString("homepage", "https://duckduckgo.com"));
192
193         // 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`.
194         defaultFontSizePreference.setSummary(defaultFontSizeString + "%%");
195
196
197         // Listen for preference changes.
198         preferencesListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
199             @Override
200             // Remove Android Studio's warning about the dangers of using SetJavaScriptEnabled.  We know.
201             @SuppressLint("SetJavaScriptEnabled")
202             public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
203
204                 switch (key) {
205                     case "javascript_enabled":
206                         // Toggle the state of the `dom_storage_enabled` preference.  The default is `false`.
207                         final Preference domStorageEnabled = findPreference("dom_storage_enabled");
208                         domStorageEnabled.setEnabled(sharedPreferences.getBoolean("javascript_enabled", false));
209                         break;
210
211                     case "first_party_cookies_enabled":
212                         // Toggle the state of the `third_party_cookies_enabled` preference.  The default is `false`.
213                         final Preference thirdPartyCookiesEnabled = findPreference("third_party_cookies_enabled");
214                         thirdPartyCookiesEnabled.setEnabled(sharedPreferences.getBoolean("first_party_cookies_enabled", false));
215                         break;
216
217                     case "user_agent":
218                         String userAgentString = sharedPreferences.getString("user_agent", "PrivacyBrowser/1.0");
219
220                         switch (userAgentString) {
221                             case "WebView default user agent":
222                                 // Display the user agent as the summary text for `userAgentPreference`, and disable `customUserAgent`.
223                                 userAgentPreference.setSummary(bareWebView.getSettings().getUserAgentString());
224                                 customUserAgent.setEnabled(false);
225                                 break;
226
227                             case "Custom user agent":
228                                 // Display "Custom user agent" as the summary text for userAgentPreference, and enable customUserAgent.
229                                 userAgentPreference.setSummary(R.string.custom_user_agent);
230                                 customUserAgent.setEnabled(true);
231                                 break;
232
233                             default:
234                                 // Display the user agent as the summary text for userAgentPreference, and disable customUserAgent.
235                                 userAgentPreference.setSummary(sharedPreferences.getString("user_agent", "PrivacyBrowser/1.0"));
236                                 customUserAgent.setEnabled(false);
237                                 break;
238                         }
239                         break;
240
241                     case "custom_user_agent":
242                         // Set the new custom user agent as the summary text for `custom_user_agent`.  The default is `PrivacyBrowser/1.0`.
243                         customUserAgent.setSummary(sharedPreferences.getString("custom_user_agent", "PrivacyBrowser/1.0"));
244                         break;
245
246                     case "javascript_disabled_search":
247                         String newJavaScriptDisabledSearchString = sharedPreferences.getString("javascript_disabled_search", "https://duckduckgo.com/html/?q=");
248                         if (newJavaScriptDisabledSearchString.equals("Custom URL")) {  // Set the summary text to `R.string.custom_url`, which is translated.
249                             javaScriptDisabledSearchPreference.setSummary(R.string.custom_url);
250                         } else {  // Set the new search URL as the summary text for the JavaScript-disabled search preference.
251                             javaScriptDisabledSearchPreference.setSummary(newJavaScriptDisabledSearchString);
252                         }
253
254                         // Enable or disable javaScriptDisabledSearchCustomURLPreference.
255                         javaScriptDisabledSearchCustomURLPreference.setEnabled(newJavaScriptDisabledSearchString.equals("Custom URL"));
256                         break;
257
258                     case "javascript_disabled_search_custom_url":
259                         // Set the new custom search URL as the summary text for `javascript_disabled_search_custom_url`.  The default is `""`.
260                         javaScriptDisabledSearchCustomURLPreference.setSummary(sharedPreferences.getString("javascript_disabled_search_custom_url", ""));
261                         break;
262
263                     case "javascript_enabled_search":
264                         String newJavaScriptEnabledSearchString = sharedPreferences.getString("javascript_enabled_search", "https://duckduckgo.com/?q=");
265                         if (newJavaScriptEnabledSearchString.equals("Custom URL")) {  // Set the summary text to `R.string.custom_url`, which is translated.
266                             javaScriptEnabledSearchPreference.setSummary(R.string.custom_url);
267                         } else {  // Set the new search URL as the summary text for the JavaScript-enabled search preference..
268                             javaScriptEnabledSearchPreference.setSummary(newJavaScriptEnabledSearchString);
269                         }
270
271                         // Enable or disable javaScriptEnabledSearchCustomURLPreference.
272                         javaScriptEnabledSearchCustomURLPreference.setEnabled(newJavaScriptEnabledSearchString.equals("Custom URL"));
273                         break;
274
275                     case "javascript_enabled_search_custom_url":
276                         // Set the new custom search URL as the summary text for `javascript_enabled_search_custom_url`.  The default is `""`.
277                         javaScriptEnabledSearchCustomURLPreference.setSummary(sharedPreferences.getString("javascript_enabled_search_custom_url", ""));
278                         break;
279
280                     case "enable_full_screen_browsing_mode":
281                         boolean newFullScreenBrowsingModeEnabled = sharedPreferences.getBoolean("enable_full_screen_browsing_mode", false);
282                         if (newFullScreenBrowsingModeEnabled) {
283                             // Enable `hideSystemBarsPreference`.
284                             hideSystemBarsPreference.setEnabled(true);
285
286                             // Only enable `transparent_navigation_bar` if `hide_system_bars` is `false`.
287                             translucentNavigationBarPreference.setEnabled(!sharedPreferences.getBoolean("hide_system_bars", false));
288                         } else {
289                             // Disable the full screen options.
290                             hideSystemBarsPreference.setEnabled(false);
291                             translucentNavigationBarPreference.setEnabled(false);
292                         }
293                         break;
294
295                     case "proxy_through_orbot":
296                         // Get current settings.
297                         boolean currentProxyThroughOrbot = sharedPreferences.getBoolean("proxy_through_orbot", false);
298                         String currentTorJavaScriptDisabledSearchString = sharedPreferences.getString("tor_javascript_disabled_search", "https://3g2upl4pq6kufc4m.onion/html/?q=");
299                         String currentTorJavaScriptEnabledSearchString = sharedPreferences.getString("tor_javascript_enabled_search", "https://3g2upl4pq6kufc4m.onion/?q=");
300
301                         // Enable the Tor preferences only if `proxy_through_orbot` is enabled.  The default is `false`.
302                         torHomepagePreference.setEnabled(currentProxyThroughOrbot);
303                         torJavaScriptDisabledSearchPreference.setEnabled(currentProxyThroughOrbot);
304                         torJavaScriptEnabledSearchPreference.setEnabled(currentProxyThroughOrbot);
305
306                         // Enable the Tor custom URL search options only if `currentProxyThroughOrbot` is true and the search is set to `Custom URL`.
307                         torJavaScriptDisabledSearchCustomURLPreference.setEnabled(currentProxyThroughOrbot && currentTorJavaScriptDisabledSearchString.equals("Custom URL"));
308                         torJavaScriptEnabledSearchCustomURLPreference.setEnabled(currentProxyThroughOrbot && currentTorJavaScriptEnabledSearchString.equals("Custom URL"));
309                         break;
310
311                     case "tor_homepage":
312                         // Set the new tor homepage URL as the summary text for the `tor_homepage` preference.  The default is DuckDuckGo:  `https://3g2upl4pq6kufc4m.onion`.
313                         torHomepagePreference.setSummary(sharedPreferences.getString("tor_homepage", "https://3g2upl4pq6kufc4m.onion"));
314                         break;
315
316                     case "tor_javascript_disabled_search":
317                         // Get the present search string.
318                         String presentTorJavaScriptDisabledSearchString = sharedPreferences.getString("tor_javascript_disabled_search", "https://3g2upl4pq6kufc4m.onion/html/?q=");
319
320                         // Set the summary text for `tor_javascript_disabled_search`.
321                         if (presentTorJavaScriptDisabledSearchString.equals("Custom URL")) {
322                             // Use R.string.custom_url, which is translated, instead of the array value, which isn't.
323                             torJavaScriptDisabledSearchPreference.setSummary(R.string.custom_url);
324                         } else {
325                             // Set the array value as the summary text.
326                             torJavaScriptDisabledSearchPreference.setSummary(presentTorJavaScriptDisabledSearchString);
327                         }
328
329                         // Set the status of `torJavaScriptDisabledSearchCustomURLPreference`.
330                         torJavaScriptDisabledSearchCustomURLPreference.setEnabled(presentTorJavaScriptDisabledSearchString.equals("Custom URL"));
331                         break;
332
333                     case "tor_javascript_disabled_search_custom_url":
334                         // Set the summary text for `tor_javascript_disabled_search_custom_url`.
335                         torJavaScriptDisabledSearchCustomURLPreference.setSummary(sharedPreferences.getString("tor_javascript_disabled_search_custom_url", ""));
336                         break;
337
338                     case "tor_javascript_enabled_search":
339                         // Get the present search string.
340                         String presentTorJavaScriptEnabledSearchString = sharedPreferences.getString("tor_javascript_enabled_search", "https://3g2upl4pq6kufc4m.onion/?q=");
341
342                         // Set the summary text for `tor_javascript_enabled_search`.
343                         if (presentTorJavaScriptEnabledSearchString.equals("Custom URL")) {
344                             // Use R.string.custom_url, which is translated, instead of the array value, which isn't.
345                             torJavaScriptEnabledSearchPreference.setSummary(R.string.custom_url);
346                         } else {
347                             // Set the array value as the summary text.
348                             torJavaScriptEnabledSearchPreference.setSummary(presentTorJavaScriptEnabledSearchString);
349                         }
350
351                         // Set the status of `torJavaScriptEnabledSearchCustomURLPreference`.
352                         torJavaScriptEnabledSearchCustomURLPreference.setEnabled(presentTorJavaScriptEnabledSearchString.equals("Custom URL"));
353                         break;
354
355                     case "tor_javascript_enabled_search_custom_url":
356                         // Set the summary text for `tor_javascript_enabled_search_custom_url`.
357                         torJavaScriptEnabledSearchCustomURLPreference.setSummary(sharedPreferences.getString("tor_javascript_enabled_search_custom_url", ""));
358                         break;
359
360                     case "homepage":
361                         // Set the new homepage URL as the summary text for the Homepage preference.  The default is `https://www.duckduckgo.com`.
362                         homepagePreference.setSummary(sharedPreferences.getString("homepage", "https://www.duckduckgo.com"));
363                         break;
364
365                     case "default_font_size":
366                         // Get the default font size as a string.  The default is `100`.
367                         String newDefaultFontSizeString = sharedPreferences.getString("default_font_size", "100");
368
369                         // Update the summary text of `default_font_size`.
370                         defaultFontSizePreference.setSummary(newDefaultFontSizeString + "%%");
371                         break;
372
373                     case "hide_system_bars":
374                         // Enable `translucentNavigationBarPreference` if `hide_system_bars` is disabled.
375                         translucentNavigationBarPreference.setEnabled(!sharedPreferences.getBoolean("hide_system_bars", false));
376                         break;
377
378                     default:
379                         // If no match, do nothing.
380                         break;
381                 }
382             }
383         };
384
385         // Register the listener.
386         savedPreferences.registerOnSharedPreferenceChangeListener(preferencesListener);
387     }
388
389     // 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
390     // even while running in the foreground.
391     @Override
392     public void onPause() {
393         super.onPause();
394         savedPreferences.unregisterOnSharedPreferenceChangeListener(preferencesListener);
395     }
396
397     @Override
398     public void onResume() {
399         super.onResume();
400         savedPreferences.registerOnSharedPreferenceChangeListener(preferencesListener);
401     }
402 }