0f7330bb83010555acafd6be440d24d2d47b3e2d
[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 an inflated `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.
85         // `false` does not attach the view to the root.
86         @SuppressLint("InflateParams") View bareWebViewLayout = inflater.inflate(R.layout.bare_webview, null, false);
87         final WebView bareWebView = (WebView) bareWebViewLayout.findViewById(R.id.bare_webview);
88
89         // Set the current user-agent as the summary text for the "user_agent" preference when the preference screen is loaded.
90         switch (savedPreferences.getString("user_agent", "PrivacyBrowser/1.0")) {
91             case "Default user agent":
92                 // Get the user agent text from the webview (which changes based on the version of Android and WebView installed).
93                 userAgentPreference.setSummary(bareWebView.getSettings().getUserAgentString());
94                 break;
95
96             case "Custom user agent":
97                 // We can't use the string from the array because it is referenced in code and can't be translated.
98                 userAgentPreference.setSummary(R.string.custom_user_agent);
99                 break;
100
101             default:
102                 // Display the user agent from the preference as the summary text.
103                 userAgentPreference.setSummary(savedPreferences.getString("user_agent", "PrivacyBrowser/1.0"));
104                 break;
105         }
106
107         // 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".
108         customUserAgent.setSummary(savedPreferences.getString("custom_user_agent", "PrivacyBrowser/1.0"));
109         customUserAgent.setEnabled(userAgentPreference.getSummary().equals("Custom user agent"));
110
111
112         // 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=`.
113         if (javaScriptDisabledSearchString.equals("Custom URL")) {
114             // Use R.string.custom_url, which will be translated, instead of the array value, which will not.
115             javaScriptDisabledSearchPreference.setSummary(R.string.custom_url);
116         } else {
117             // Set the array value as the summary text.
118             javaScriptDisabledSearchPreference.setSummary(javaScriptDisabledSearchString);
119         }
120
121         // 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`.
122         javaScriptDisabledSearchCustomURLPreference.setSummary(savedPreferences.getString("javascript_disabled_search_custom_url", ""));
123         javaScriptDisabledSearchCustomURLPreference.setEnabled(javaScriptDisabledSearchString.equals("Custom URL"));
124
125
126         // 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=`.
127         if (javaScriptEnabledSearchString.equals("Custom URL")) {
128             // If set to "Custom URL", use R.string.custom_url, which will be translated, instead of the array value, which will not.
129             javaScriptEnabledSearchPreference.setSummary(R.string.custom_url);
130         } else {
131             // Set the array value as the summary text.
132             javaScriptEnabledSearchPreference.setSummary(javaScriptEnabledSearchString);
133         }
134
135         // 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`.
136         javaScriptEnabledSearchCustomURLPreference.setSummary(savedPreferences.getString("javascript_enabled_search_custom_url", ""));
137         javaScriptEnabledSearchCustomURLPreference.setEnabled(javaScriptEnabledSearchString.equals("Custom URL"));
138
139
140         // Enable the full screen options if full screen browsing mode is enabled.
141         if (!fullScreenBrowsingModeEnabled) {
142             // Disable the full screen options.
143             hideSystemBarsPreference.setEnabled(false);
144             translucentNavigationBarPreference.setEnabled(false);
145         } else {
146             // Disable `transparent_navigation_bar` if `hide_system_bars` is `true`.
147             translucentNavigationBarPreference.setEnabled(!savedPreferences.getBoolean("hide_system_bars", false));
148         }
149
150
151         // 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`.
152         torHomepagePreference.setSummary(savedPreferences.getString("tor_homepage", "https://3g2upl4pq6kufc4m.onion"));
153
154
155         // 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=`
156         if (torJavaScriptDisabledSearchString.equals("Custom URL")) {
157             // Use R.string.custom_url, which will be translated, instead of the array value, which will not.
158             torJavaScriptDisabledSearchPreference.setSummary(R.string.custom_url);
159         } else {
160             // Set the array value as the summary text.
161             torJavaScriptDisabledSearchPreference.setSummary(torJavaScriptDisabledSearchString);
162         }
163
164         // Set the summary text for `tor_javascript_disabled_search_custom_url`.  The default is `""`.
165         torJavaScriptDisabledSearchCustomURLPreference.setSummary(savedPreferences.getString("tor_javascript_disabled_search_custom_url", ""));
166
167
168         // 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=`.
169         if (torJavaScriptEnabledSearchString.equals("Custom URL")) {
170             // Use R.string.custom_url, which will be translated, instead of the array value, which will not.
171             torJavaScriptEnabledSearchPreference.setSummary(R.string.custom_url);
172         } else {
173             // Set the array value as the summary text.
174             torJavaScriptEnabledSearchPreference.setSummary(torJavaScriptEnabledSearchString);
175         }
176
177         // Set the summary text for `tor_javascript_enabled_search_custom_url`.  The default is `""`.
178         torJavaScriptEnabledSearchCustomURLPreference.setSummary(savedPreferences.getString("tor_javascript_enabled_search_custom_url", ""));
179
180
181         // Enable the Tor preferences only if `proxy_through_orbot` is enabled.  The default is `false`.
182         torHomepagePreference.setEnabled(proxyThroughOrbot);
183         torJavaScriptDisabledSearchPreference.setEnabled(proxyThroughOrbot);
184         torJavaScriptEnabledSearchPreference.setEnabled(proxyThroughOrbot);
185
186         // Enable the Tor custom URL search options only if `proxyThroughOrbot` is true and the search is set to `Custom URL`.
187         torJavaScriptDisabledSearchCustomURLPreference.setEnabled(proxyThroughOrbot && torJavaScriptDisabledSearchString.equals("Custom URL"));
188         torJavaScriptEnabledSearchCustomURLPreference.setEnabled(proxyThroughOrbot && torJavaScriptEnabledSearchString.equals("Custom URL"));
189
190
191         // Set the homepage URL as the summary text for the `Homepage` preference when the preference screen is loaded.  The default is `https://www.duckduckgo.com`.
192         homepagePreference.setSummary(savedPreferences.getString("homepage", "https://www.duckduckgo.com"));
193
194         // 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`.
195         defaultFontSizePreference.setSummary(defaultFontSizeString + "%%");
196
197
198         // Listen for preference changes.
199         preferencesListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
200             @Override
201             // Remove Android Studio's warning about the dangers of using SetJavaScriptEnabled.  We know.
202             @SuppressLint("SetJavaScriptEnabled")
203             public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
204
205                 switch (key) {
206                     case "javascript_enabled":
207                         // Toggle the state of the `dom_storage_enabled` preference.  The default is `false`.
208                         final Preference domStorageEnabled = findPreference("dom_storage_enabled");
209                         domStorageEnabled.setEnabled(sharedPreferences.getBoolean("javascript_enabled", false));
210                         break;
211
212                     case "first_party_cookies_enabled":
213                         // Toggle the state of the `third_party_cookies_enabled` preference.  The default is `false`.
214                         final Preference thirdPartyCookiesEnabled = findPreference("third_party_cookies_enabled");
215                         thirdPartyCookiesEnabled.setEnabled(sharedPreferences.getBoolean("first_party_cookies_enabled", false));
216                         break;
217
218                     case "user_agent":
219                         String userAgentString = sharedPreferences.getString("user_agent", "PrivacyBrowser/1.0");
220
221                         switch (userAgentString) {
222                             case "Default user agent":
223                                 // Display the user agent as the summary text for `userAgentPreference`, and disable `customUserAgent`.
224                                 userAgentPreference.setSummary(bareWebView.getSettings().getUserAgentString());
225                                 customUserAgent.setEnabled(false);
226                                 break;
227
228                             case "Custom user agent":
229                                 // Display "Custom user agent" as the summary text for userAgentPreference, and enable customUserAgent.
230                                 userAgentPreference.setSummary(R.string.custom_user_agent);
231                                 customUserAgent.setEnabled(true);
232                                 break;
233
234                             default:
235                                 // Display the user agent as the summary text for userAgentPreference, and disable customUserAgent.
236                                 userAgentPreference.setSummary(sharedPreferences.getString("user_agent", "PrivacyBrowser/1.0"));
237                                 customUserAgent.setEnabled(false);
238                                 break;
239                         }
240                         break;
241
242                     case "custom_user_agent":
243                         // Set the new custom user agent as the summary text for `custom_user_agent`.  The default is `PrivacyBrowser/1.0`.
244                         customUserAgent.setSummary(sharedPreferences.getString("custom_user_agent", "PrivacyBrowser/1.0"));
245                         break;
246
247                     case "javascript_disabled_search":
248                         String newJavaScriptDisabledSearchString = sharedPreferences.getString("javascript_disabled_search", "https://duckduckgo.com/html/?q=");
249                         if (newJavaScriptDisabledSearchString.equals("Custom URL")) {  // Set the summary text to `R.string.custom_url`, which is translated.
250                             javaScriptDisabledSearchPreference.setSummary(R.string.custom_url);
251                         } else {  // Set the new search URL as the summary text for the JavaScript-disabled search preference.
252                             javaScriptDisabledSearchPreference.setSummary(newJavaScriptDisabledSearchString);
253                         }
254
255                         // Enable or disable javaScriptDisabledSearchCustomURLPreference.
256                         javaScriptDisabledSearchCustomURLPreference.setEnabled(newJavaScriptDisabledSearchString.equals("Custom URL"));
257                         break;
258
259                     case "javascript_disabled_search_custom_url":
260                         // Set the new custom search URL as the summary text for `javascript_disabled_search_custom_url`.  The default is `""`.
261                         javaScriptDisabledSearchCustomURLPreference.setSummary(sharedPreferences.getString("javascript_disabled_search_custom_url", ""));
262                         break;
263
264                     case "javascript_enabled_search":
265                         String newJavaScriptEnabledSearchString = sharedPreferences.getString("javascript_enabled_search", "https://duckduckgo.com/?q=");
266                         if (newJavaScriptEnabledSearchString.equals("Custom URL")) {  // Set the summary text to `R.string.custom_url`, which is translated.
267                             javaScriptEnabledSearchPreference.setSummary(R.string.custom_url);
268                         } else {  // Set the new search URL as the summary text for the JavaScript-enabled search preference..
269                             javaScriptEnabledSearchPreference.setSummary(newJavaScriptEnabledSearchString);
270                         }
271
272                         // Enable or disable javaScriptEnabledSearchCustomURLPreference.
273                         javaScriptEnabledSearchCustomURLPreference.setEnabled(newJavaScriptEnabledSearchString.equals("Custom URL"));
274                         break;
275
276                     case "javascript_enabled_search_custom_url":
277                         // Set the new custom search URL as the summary text for `javascript_enabled_search_custom_url`.  The default is `""`.
278                         javaScriptEnabledSearchCustomURLPreference.setSummary(sharedPreferences.getString("javascript_enabled_search_custom_url", ""));
279                         break;
280
281                     case "enable_full_screen_browsing_mode":
282                         boolean newFullScreenBrowsingModeEnabled = sharedPreferences.getBoolean("enable_full_screen_browsing_mode", false);
283                         if (newFullScreenBrowsingModeEnabled) {
284                             // Enable `hideSystemBarsPreference`.
285                             hideSystemBarsPreference.setEnabled(true);
286
287                             // Only enable `transparent_navigation_bar` if `hide_system_bars` is `false`.
288                             translucentNavigationBarPreference.setEnabled(!sharedPreferences.getBoolean("hide_system_bars", false));
289                         } else {
290                             // Disable the full screen options.
291                             hideSystemBarsPreference.setEnabled(false);
292                             translucentNavigationBarPreference.setEnabled(false);
293                         }
294                         break;
295
296                     case "proxy_through_orbot":
297                         // Get current settings.
298                         boolean currentProxyThroughOrbot = sharedPreferences.getBoolean("proxy_through_orbot", false);
299                         String currentTorJavaScriptDisabledSearchString = sharedPreferences.getString("tor_javascript_disabled_search", "https://3g2upl4pq6kufc4m.onion/html/?q=");
300                         String currentTorJavaScriptEnabledSearchString = sharedPreferences.getString("tor_javascript_enabled_search", "https://3g2upl4pq6kufc4m.onion/?q=");
301
302                         // Enable the Tor preferences only if `proxy_through_orbot` is enabled.  The default is `false`.
303                         torHomepagePreference.setEnabled(currentProxyThroughOrbot);
304                         torJavaScriptDisabledSearchPreference.setEnabled(currentProxyThroughOrbot);
305                         torJavaScriptEnabledSearchPreference.setEnabled(currentProxyThroughOrbot);
306
307                         // Enable the Tor custom URL search options only if `currentProxyThroughOrbot` is true and the search is set to `Custom URL`.
308                         torJavaScriptDisabledSearchCustomURLPreference.setEnabled(currentProxyThroughOrbot && currentTorJavaScriptDisabledSearchString.equals("Custom URL"));
309                         torJavaScriptEnabledSearchCustomURLPreference.setEnabled(currentProxyThroughOrbot && currentTorJavaScriptEnabledSearchString.equals("Custom URL"));
310                         break;
311
312                     case "tor_homepage":
313                         // Set the new tor homepage URL as the summary text for the `tor_homepage` preference.  The default is DuckDuckGo:  `https://3g2upl4pq6kufc4m.onion`.
314                         torHomepagePreference.setSummary(sharedPreferences.getString("tor_homepage", "https://3g2upl4pq6kufc4m.onion"));
315                         break;
316
317                     case "tor_javascript_disabled_search":
318                         // Get the present search string.
319                         String presentTorJavaScriptDisabledSearchString = sharedPreferences.getString("tor_javascript_disabled_search", "https://3g2upl4pq6kufc4m.onion/html/?q=");
320
321                         // Set the summary text for `tor_javascript_disabled_search`.
322                         if (presentTorJavaScriptDisabledSearchString.equals("Custom URL")) {
323                             // Use R.string.custom_url, which is translated, instead of the array value, which isn't.
324                             torJavaScriptDisabledSearchPreference.setSummary(R.string.custom_url);
325                         } else {
326                             // Set the array value as the summary text.
327                             torJavaScriptDisabledSearchPreference.setSummary(presentTorJavaScriptDisabledSearchString);
328                         }
329
330                         // Set the status of `torJavaScriptDisabledSearchCustomURLPreference`.
331                         torJavaScriptDisabledSearchCustomURLPreference.setEnabled(presentTorJavaScriptDisabledSearchString.equals("Custom URL"));
332                         break;
333
334                     case "tor_javascript_disabled_search_custom_url":
335                         // Set the summary text for `tor_javascript_disabled_search_custom_url`.
336                         torJavaScriptDisabledSearchCustomURLPreference.setSummary(sharedPreferences.getString("tor_javascript_disabled_search_custom_url", ""));
337                         break;
338
339                     case "tor_javascript_enabled_search":
340                         // Get the present search string.
341                         String presentTorJavaScriptEnabledSearchString = sharedPreferences.getString("tor_javascript_enabled_search", "https://3g2upl4pq6kufc4m.onion/?q=");
342
343                         // Set the summary text for `tor_javascript_enabled_search`.
344                         if (presentTorJavaScriptEnabledSearchString.equals("Custom URL")) {
345                             // Use R.string.custom_url, which is translated, instead of the array value, which isn't.
346                             torJavaScriptEnabledSearchPreference.setSummary(R.string.custom_url);
347                         } else {
348                             // Set the array value as the summary text.
349                             torJavaScriptEnabledSearchPreference.setSummary(presentTorJavaScriptEnabledSearchString);
350                         }
351
352                         // Set the status of `torJavaScriptEnabledSearchCustomURLPreference`.
353                         torJavaScriptEnabledSearchCustomURLPreference.setEnabled(presentTorJavaScriptEnabledSearchString.equals("Custom URL"));
354                         break;
355
356                     case "tor_javascript_enabled_search_custom_url":
357                         // Set the summary text for `tor_javascript_enabled_search_custom_url`.
358                         torJavaScriptEnabledSearchCustomURLPreference.setSummary(sharedPreferences.getString("tor_javascript_enabled_search_custom_url", ""));
359                         break;
360
361                     case "homepage":
362                         // Set the new homepage URL as the summary text for the Homepage preference.  The default is `https://www.duckduckgo.com`.
363                         homepagePreference.setSummary(sharedPreferences.getString("homepage", "https://www.duckduckgo.com"));
364                         break;
365
366                     case "default_font_size":
367                         // Get the default font size as a string.  The default is `100`.
368                         String newDefaultFontSizeString = sharedPreferences.getString("default_font_size", "100");
369
370                         // Update the summary text of `default_font_size`.
371                         defaultFontSizePreference.setSummary(newDefaultFontSizeString + "%%");
372                         break;
373
374                     case "hide_system_bars":
375                         // Enable `translucentNavigationBarPreference` if `hide_system_bars` is disabled.
376                         translucentNavigationBarPreference.setEnabled(!sharedPreferences.getBoolean("hide_system_bars", false));
377                         break;
378
379                     default:
380                         // If no match, do nothing.
381                         break;
382                 }
383             }
384         };
385
386         // Register the listener.
387         savedPreferences.registerOnSharedPreferenceChangeListener(preferencesListener);
388     }
389
390     // 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
391     // even while running in the foreground.
392     @Override
393     public void onPause() {
394         super.onPause();
395         savedPreferences.unregisterOnSharedPreferenceChangeListener(preferencesListener);
396     }
397
398     @Override
399     public void onResume() {
400         super.onResume();
401         savedPreferences.registerOnSharedPreferenceChangeListener(preferencesListener);
402     }
403 }