]> gitweb.stoutner.com Git - PrivacyBrowserAndroid.git/blob - app/src/main/java/com/stoutner/privacybrowser/fragments/DomainSettingsFragment.java
5362026c8232735cf8621ef83bf0c3b1f459a021
[PrivacyBrowserAndroid.git] / app / src / main / java / com / stoutner / privacybrowser / fragments / DomainSettingsFragment.java
1 /*
2  * Copyright © 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.Context;
24 import android.database.Cursor;
25 import android.os.Build;
26 import android.os.Bundle;
27 // We have to use `android.support.v4.app.Fragment` until minimum API >= 23.  Otherwise we cannot call `getContext()`.
28 import android.support.v4.app.Fragment;
29 import android.view.LayoutInflater;
30 import android.view.View;
31 import android.view.ViewGroup;
32 import android.webkit.WebView;
33 import android.widget.AdapterView;
34 import android.widget.ArrayAdapter;
35 import android.widget.CompoundButton;
36 import android.widget.EditText;
37 import android.widget.ImageView;
38 import android.widget.LinearLayout;
39 import android.widget.Spinner;
40 import android.widget.Switch;
41 import android.widget.TextView;
42
43 import com.stoutner.privacybrowser.R;
44 import com.stoutner.privacybrowser.activities.MainWebViewActivity;
45 import com.stoutner.privacybrowser.helpers.DomainsDatabaseHelper;
46
47 public class DomainSettingsFragment extends Fragment {
48     // `DATABASE_ID` is used by activities calling this fragment.
49     public static final String DATABASE_ID = "database_id";
50
51     // `databaseId` is used in `onCreate()` and `onCreateView()`.
52     private int databaseId;
53
54     @Override
55     public void onCreate(Bundle savedInstanceState) {
56         super.onCreate(savedInstanceState);
57
58         // Store the database id in `databaseId`.
59         databaseId = getArguments().getInt(DATABASE_ID);
60     }
61
62     // We have to use the deprecated `getDrawable()` until the minimum API >= 21.
63     @SuppressWarnings("deprecation")
64     @Override
65     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
66         // Inflate `domain_settings`.  `false` does not attach it to the root `container`.
67         View domainSettingsView = inflater.inflate(R.layout.domain_settings, container, false);
68
69         // Get a handle for the `Context`.
70         Context context = getContext();
71
72         // Get handles for the views in the fragment.
73         EditText domainNameEditText = (EditText) domainSettingsView.findViewById(R.id.domain_settings_name_edittext);
74         Switch javaScriptEnabledSwitch = (Switch) domainSettingsView.findViewById(R.id.domain_settings_javascript_switch);
75         final ImageView javaScriptImageView = (ImageView) domainSettingsView.findViewById(R.id.domain_settings_javascript_imageview);
76         Switch firstPartyCookiesEnabledSwitch = (Switch) domainSettingsView.findViewById(R.id.domain_settings_first_party_cookies_switch);
77         final ImageView firstPartyCookiesImageView = (ImageView) domainSettingsView.findViewById(R.id.domain_settings_first_party_cookies_imageview);
78         LinearLayout thirdPartyCookiesLinearLayout = (LinearLayout) domainSettingsView.findViewById(R.id.domain_settings_third_party_cookies_linearlayout);
79         final Switch thirdPartyCookiesEnabledSwitch = (Switch) domainSettingsView.findViewById(R.id.domain_settings_third_party_cookies_switch);
80         final ImageView thirdPartyCookiesImageView = (ImageView) domainSettingsView.findViewById(R.id.domain_settings_third_party_cookies_imageview);
81         final Switch domStorageEnabledSwitch = (Switch) domainSettingsView.findViewById(R.id.domain_settings_dom_storage_switch);
82         final ImageView domStorageImageView = (ImageView) domainSettingsView.findViewById(R.id.domain_settings_dom_storage_imageview);
83         Switch formDataEnabledSwitch = (Switch) domainSettingsView.findViewById(R.id.domain_settings_form_data_switch);
84         final ImageView formDataImageView = (ImageView) domainSettingsView.findViewById(R.id.domain_settings_form_data_imageview);
85         Spinner userAgentSpinner = (Spinner) domainSettingsView.findViewById(R.id.domain_settings_user_agent_spinner);
86         final TextView userAgentTextView = (TextView) domainSettingsView.findViewById(R.id.domain_settings_user_agent_textview);
87         final EditText customUserAgentEditText = (EditText) domainSettingsView.findViewById(R.id.domain_settings_custom_user_agent_edittext);
88         Spinner fontSizeSpinner = (Spinner) domainSettingsView.findViewById(R.id.domain_settings_font_size_spinner);
89         final ImageView displayWebpageImagesImageView = (ImageView) domainSettingsView.findViewById(R.id.domain_settings_display_webpage_images_imageview);
90         Spinner displayWebpageImagesSpinner = (Spinner) domainSettingsView.findViewById(R.id.domain_settings_display_webpage_images_spinner);
91
92         // Initialize the database handler.  `this` specifies the context.  The two `nulls` do not specify the database name or a `CursorFactory`.
93         // The `0` specifies the database version, but that is ignored and set instead using a constant in `DomainsDatabaseHelper`.
94         DomainsDatabaseHelper domainsDatabaseHelper = new DomainsDatabaseHelper(getContext(), null, null, 0);
95
96         // Get the database `Cursor` for this ID and move it to the first row.
97         Cursor domainCursor = domainsDatabaseHelper.getCursorForId(databaseId);
98         domainCursor.moveToFirst();
99
100         // Save the `Cursor` entries as variables.
101         String domainNameString = domainCursor.getString(domainCursor.getColumnIndex(DomainsDatabaseHelper.DOMAIN_NAME));
102         int javaScriptEnabledInt = domainCursor.getInt(domainCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_JAVASCRIPT));
103         int firstPartyCookiesEnabledInt = domainCursor.getInt(domainCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_FIRST_PARTY_COOKIES));
104         int thirdPartyCookiesEnabledInt = domainCursor.getInt(domainCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_THIRD_PARTY_COOKIES));
105         int domStorageEnabledInt = domainCursor.getInt(domainCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_DOM_STORAGE));
106         int formDataEnabledInt = domainCursor.getInt(domainCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_FORM_DATA));
107         final String currentUserAgentString = domainCursor.getString(domainCursor.getColumnIndex(DomainsDatabaseHelper.USER_AGENT));
108         int fontSizeInt = domainCursor.getInt(domainCursor.getColumnIndex(DomainsDatabaseHelper.FONT_SIZE));
109         int displayImagesInt = domainCursor.getInt(domainCursor.getColumnIndex(DomainsDatabaseHelper.DISPLAY_IMAGES));
110
111         // Create `ArrayAdapters` for the `Spinners`and their `entry values`.
112         ArrayAdapter<CharSequence> userAgentArrayAdapter = ArrayAdapter.createFromResource(context, R.array.user_agent_entries, android.R.layout.simple_spinner_item);
113         final ArrayAdapter<CharSequence> userAgentEntryValuesArrayAdapter = ArrayAdapter.createFromResource(context, R.array.user_agent_entry_values, android.R.layout.simple_spinner_item);
114         ArrayAdapter<CharSequence> fontSizeArrayAdapter = ArrayAdapter.createFromResource(context, R.array.default_font_size_entries, android.R.layout.simple_spinner_item);
115         ArrayAdapter<CharSequence> fontSizeEntryValuesArrayAdapter = ArrayAdapter.createFromResource(context, R.array.default_font_size_entry_values, android.R.layout.simple_spinner_item);
116         final ArrayAdapter<CharSequence> displayImagesArrayAdapter = ArrayAdapter.createFromResource(context, R.array.display_website_images_array, android.R.layout.simple_spinner_item);
117
118         // Set the drop down style for the `ArrayAdapters`.
119         fontSizeArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
120         displayImagesArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
121
122         // Some phones running Huawei's customized Android 7.0 don't display a spinner that requires scrolling correctly with the default `simple_spinner_dropdown_item`.  The Huawei P9 Lite is known to be affected.
123         if (Build.BRAND.equals("HUAWEI") && (Build.VERSION.SDK_INT == 24)) {  // The device is manufactured by Huawei and is running Android 7.0.
124             // Use a customized `simple_spinner_dropdown_item`.
125             userAgentArrayAdapter.setDropDownViewResource(R.layout.simple_spinner_dropdown_item_huawei_fix);
126         } else {  // Use the standard `android.R.layout.simple_spinner_dropdown_item` on all other devices.
127             userAgentArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
128         }
129
130         // Set the `ArrayAdapters` for the `Spinners`.
131         userAgentSpinner.setAdapter(userAgentArrayAdapter);
132         fontSizeSpinner.setAdapter(fontSizeArrayAdapter);
133         displayWebpageImagesSpinner.setAdapter(displayImagesArrayAdapter);
134
135         // Set the domain name from the the database cursor.
136         domainNameEditText.setText(domainNameString);
137
138         // Set the JavaScript status.
139         if (javaScriptEnabledInt == 1) {  // JavaScript is enabled.
140             javaScriptEnabledSwitch.setChecked(true);
141             javaScriptImageView.setImageDrawable(getResources().getDrawable(R.drawable.javascript_enabled));
142         } else {  // JavaScript is disabled.
143             javaScriptEnabledSwitch.setChecked(false);
144             javaScriptImageView.setImageDrawable(getResources().getDrawable(R.drawable.privacy_mode));
145         }
146
147         // Set the first-party cookies status.  Once minimum API >= 21 we can use a selector as the tint mode instead of specifying different icons.
148         if (firstPartyCookiesEnabledInt == 1) {  // First-party cookies are enabled.
149             firstPartyCookiesEnabledSwitch.setChecked(true);
150             firstPartyCookiesImageView.setImageDrawable(getResources().getDrawable(R.drawable.cookies_enabled));
151         } else {  // First-party cookies are disabled.
152             firstPartyCookiesEnabledSwitch.setChecked(false);
153             firstPartyCookiesImageView.setImageDrawable(getResources().getDrawable(R.drawable.cookies_disabled));
154         }
155
156         // Only display third-party cookies if SDK_INT >= 21.
157         if (Build.VERSION.SDK_INT >= 21) {  // Third-party cookies can be configured for API >= 21.
158             // Only enable third-party-cookies if first-party cookies are enabled.
159             if (firstPartyCookiesEnabledInt == 1) {  // First-party cookies are enabled.
160                 // Set the third-party cookies status.  Once minimum API >= 21 we can use a selector as the tint mode instead of specifying different icons.
161                 if (thirdPartyCookiesEnabledInt == 1) {  // Both first-party and third-party cookies are enabled.
162                     thirdPartyCookiesEnabledSwitch.setChecked(true);
163                     thirdPartyCookiesImageView.setImageDrawable(getResources().getDrawable(R.drawable.cookies_warning));
164                 } else {  // First party cookies are enabled but third-party cookies are disabled.
165                     thirdPartyCookiesEnabledSwitch.setChecked(false);
166                     thirdPartyCookiesImageView.setImageDrawable(getResources().getDrawable(R.drawable.cookies_disabled));
167                 }
168             } else {  // First-party cookies are disabled.
169                 // Set the status of third-party cookies, but disable it.
170                 if (thirdPartyCookiesEnabledInt == 1) {  // Third-party cookies are enabled but first-party cookies are disabled.
171                     thirdPartyCookiesEnabledSwitch.setChecked(true);
172                     thirdPartyCookiesEnabledSwitch.setEnabled(false);
173                     thirdPartyCookiesImageView.setImageDrawable(getResources().getDrawable(R.drawable.cookies_ghosted));
174                 } else {  // Both first party and third-party cookies are disabled.
175                     thirdPartyCookiesEnabledSwitch.setChecked(false);
176                     thirdPartyCookiesEnabledSwitch.setEnabled(false);
177                     thirdPartyCookiesImageView.setImageDrawable(getResources().getDrawable(R.drawable.cookies_ghosted));
178                 }
179             }
180         } else {  // Third-party cookies cannot be configured for API <= 21.
181             // Hide the `LinearLayout` for third-party cookies.
182             thirdPartyCookiesLinearLayout.setVisibility(View.GONE);
183         }
184
185         // Only enable DOM storage if JavaScript is enabled.
186         if (javaScriptEnabledInt == 1) {  // JavaScript is enabled.
187             // Set the DOM storage status.  Once minimum API >= 21 we can use a selector as the tint mode instead of specifying different icons.
188             if (domStorageEnabledInt == 1) {  // Both JavaScript and DOM storage are enabled.
189                 domStorageEnabledSwitch.setChecked(true);
190                 domStorageImageView.setImageDrawable(getResources().getDrawable(R.drawable.dom_storage_enabled));
191             } else {  // JavaScript is enabled but DOM storage is disabled.
192                 domStorageEnabledSwitch.setChecked(false);
193                 domStorageImageView.setImageDrawable(getResources().getDrawable(R.drawable.dom_storage_disabled));
194             }
195         } else {  // JavaScript is disabled.
196             // Set the checked status of DOM storage.
197             if (domStorageEnabledInt == 1) {  // DOM storage is enabled but JavaScript is disabled.
198                 domStorageEnabledSwitch.setChecked(true);
199             } else {  // Both JavaScript and DOM storage are disabled.
200                 domStorageEnabledSwitch.setChecked(false);
201             }
202
203             // Disable `domStorageEnabledSwitch` and set the icon to be ghosted.
204             domStorageEnabledSwitch.setEnabled(false);
205             domStorageImageView.setImageDrawable(getResources().getDrawable(R.drawable.dom_storage_ghosted));
206         }
207
208         // Set the form data status.  Once minimum API >= 21 we can use a selector as the tint mode instead of specifying different icons.
209         if (formDataEnabledInt == 1) {  // Form data is enabled.
210             formDataEnabledSwitch.setChecked(true);
211             formDataImageView.setImageDrawable(getResources().getDrawable(R.drawable.form_data_enabled));
212         } else {  // Form data is disabled.
213             formDataEnabledSwitch.setChecked(false);
214             formDataImageView.setImageDrawable(getResources().getDrawable(R.drawable.form_data_disabled));
215         }
216
217         // We need to inflated a `WebView` to get the default user agent.
218         // `@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.
219         @SuppressLint("InflateParams") View bareWebViewLayout = inflater.inflate(R.layout.bare_webview, null, false);
220         WebView bareWebView = (WebView) bareWebViewLayout.findViewById(R.id.bare_webview);
221         final String webViewDefaultUserAgentString = bareWebView.getSettings().getUserAgentString();
222
223         // Get the position of the user agent in `userAgentEntryValuesArrayAdapter`.
224         int userAgentArrayPosition = userAgentEntryValuesArrayAdapter.getPosition(currentUserAgentString);
225
226         // Set the user agent.
227         if (userAgentArrayPosition == -1) {  // We are using a custom `userAgentString`.
228             // Set `userAgentSpinner` to `Custom`.
229             userAgentSpinner.setSelection(userAgentEntryValuesArrayAdapter.getPosition("Custom user agent"));
230
231             // Hide `userAgentTextView`.
232             userAgentTextView.setVisibility(View.GONE);
233
234             // Show `customUserAgentEditText` and set `userAgentString` as the text.
235             customUserAgentEditText.setVisibility(View.VISIBLE);
236             customUserAgentEditText.setText(currentUserAgentString);
237         } else if (currentUserAgentString.equals("WebView default user agent")) {  // We are using the `WebView` default user agent.
238             // Set the `userAgentSpinner` selection.
239             userAgentSpinner.setSelection(userAgentArrayPosition);
240
241             // Show `userAgentTextView` and set the text.
242             userAgentTextView.setVisibility(View.VISIBLE);
243             userAgentTextView.setText(webViewDefaultUserAgentString);
244
245             // Hide `customUserAgentEditText`.
246             customUserAgentEditText.setVisibility(View.GONE);
247         } else {  // We are using a standard user agent.
248             // Set the `userAgentSpinner` selection.
249             userAgentSpinner.setSelection(userAgentArrayPosition);
250
251             // Show `userAgentTextView` and set the text.
252             userAgentTextView.setVisibility(View.VISIBLE);
253             userAgentTextView.setText(currentUserAgentString);
254
255             // Hide `customUserAgentEditText`.
256             customUserAgentEditText.setVisibility(View.GONE);
257         }
258
259         // Set the selected font size.
260         int fontSizeArrayPosition = fontSizeEntryValuesArrayAdapter.getPosition(String.valueOf(fontSizeInt));
261         fontSizeSpinner.setSelection(fontSizeArrayPosition);
262
263         // Set the selected display website images mode.
264         displayWebpageImagesSpinner.setSelection(displayImagesInt);
265
266         // Set the display website images icon.
267         switch (displayImagesInt) {
268             case DomainsDatabaseHelper.DISPLAY_WEBPAGE_IMAGES_SYSTEM_DEFAULT:
269                 if (MainWebViewActivity.displayWebpageImagesBoolean) {
270                     displayWebpageImagesImageView.setImageDrawable(getResources().getDrawable(R.drawable.images_enabled));
271                 } else {
272                     displayWebpageImagesImageView.setImageDrawable(getResources().getDrawable(R.drawable.images_disabled));
273                 }
274                 break;
275
276             case DomainsDatabaseHelper.DISPLAY_WEBPAGE_IMAGES_ENABLED:
277                 displayWebpageImagesImageView.setImageDrawable(getResources().getDrawable(R.drawable.images_enabled));
278                 break;
279
280             case DomainsDatabaseHelper.DISPLAY_WEBPAGE_IMAGES_DISABLED:
281                 displayWebpageImagesImageView.setImageDrawable(getResources().getDrawable(R.drawable.images_disabled));
282                 break;
283         }
284
285
286         // Set the `javaScriptEnabledSwitch` `OnCheckedChangeListener()`.
287         javaScriptEnabledSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
288             @Override
289             public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
290                 if (isChecked) {  // JavaScript is enabled.
291                     // Update the JavaScript icon.
292                     javaScriptImageView.setImageDrawable(getResources().getDrawable(R.drawable.javascript_enabled));
293
294                     // Enable the DOM storage `Switch`.
295                     domStorageEnabledSwitch.setEnabled(true);
296
297                     // Update the DOM storage icon.
298                     if (domStorageEnabledSwitch.isChecked()) {  // DOM storage is enabled.
299                         domStorageImageView.setImageDrawable(getResources().getDrawable(R.drawable.dom_storage_enabled));
300                     } else {  // DOM storage is disabled.
301                         domStorageImageView.setImageDrawable(getResources().getDrawable(R.drawable.dom_storage_disabled));
302                     }
303                 } else {  // JavaScript is disabled.
304                     // Update the JavaScript icon.
305                     javaScriptImageView.setImageDrawable(getResources().getDrawable(R.drawable.privacy_mode));
306
307                     // Disable the DOM storage `Switch`.
308                     domStorageEnabledSwitch.setEnabled(false);
309
310                     // Set the DOM storage icon to be ghosted.
311                     domStorageImageView.setImageDrawable(getResources().getDrawable(R.drawable.dom_storage_ghosted));
312                 }
313             }
314         });
315
316         // Set the `firstPartyCookiesEnabledSwitch` `OnCheckedChangeListener()`.
317         firstPartyCookiesEnabledSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
318             @Override
319             public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
320                 if (isChecked) {  // First-party cookies are enabled.
321                     // Update the first-party cookies icon.
322                     firstPartyCookiesImageView.setImageDrawable(getResources().getDrawable(R.drawable.cookies_enabled));
323
324                     // Enable the third-party cookies `Switch`.
325                     thirdPartyCookiesEnabledSwitch.setEnabled(true);
326
327                     // Update the third-party cookies icon.
328                     if (thirdPartyCookiesEnabledSwitch.isChecked()) {  // Third-party cookies are enabled.
329                         thirdPartyCookiesImageView.setImageDrawable(getResources().getDrawable(R.drawable.cookies_warning));
330                     } else {  // Third-party cookies are disabled.
331                         thirdPartyCookiesImageView.setImageDrawable(getResources().getDrawable(R.drawable.cookies_disabled));
332                     }
333                 } else {  // First-party cookies are disabled.
334                     // Update the first-party cookies icon.
335                     firstPartyCookiesImageView.setImageDrawable(getResources().getDrawable(R.drawable.cookies_disabled));
336
337                     // Disable the third-party cookies `Switch`.
338                     thirdPartyCookiesEnabledSwitch.setEnabled(false);
339
340                     // Set the third-party cookies icon to be ghosted.
341                     thirdPartyCookiesImageView.setImageDrawable(getResources().getDrawable(R.drawable.cookies_ghosted));
342                 }
343             }
344         });
345
346         // Set the `thirdPartyCookiesEnabledSwitch` `OnCheckedChangeListener()`.
347         thirdPartyCookiesEnabledSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
348             @Override
349             public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
350                 // Update the icon.
351                 if (isChecked) {
352                     thirdPartyCookiesImageView.setImageDrawable(getResources().getDrawable(R.drawable.cookies_warning));
353                 } else {
354                     thirdPartyCookiesImageView.setImageDrawable(getResources().getDrawable(R.drawable.cookies_disabled));
355                 }
356             }
357         });
358
359         // Set the `domStorageEnabledSwitch` `OnCheckedChangeListener()`.
360         domStorageEnabledSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
361             @Override
362             public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
363                 // Update the icon.
364                 if (isChecked) {
365                     domStorageImageView.setImageDrawable(getResources().getDrawable(R.drawable.dom_storage_enabled));
366                 } else {
367                     domStorageImageView.setImageDrawable(getResources().getDrawable(R.drawable.dom_storage_disabled));
368                 }
369             }
370         });
371
372         // Set the `formDataEnabledSwitch` `OnCheckedChangeListener()`.
373         formDataEnabledSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
374             @Override
375             public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
376                 // Update the icon.
377                 if (isChecked) {
378                     formDataImageView.setImageDrawable(getResources().getDrawable(R.drawable.form_data_enabled));
379                 } else {
380                     formDataImageView.setImageDrawable(getResources().getDrawable(R.drawable.form_data_disabled));
381                 }
382             }
383         });
384
385         // Set the `userAgentSpinner` `onItemClickListener()`.
386         userAgentSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
387             @Override
388             public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
389                 // Store the new user agent string.
390                 String newUserAgentString = getResources().getStringArray(R.array.user_agent_entry_values)[position];
391
392                 // Set the new user agent.
393                 switch (newUserAgentString) {
394                     case "Custom user agent":
395                         // Hide `userAgentTextView`.
396                         userAgentTextView.setVisibility(View.GONE);
397
398                         // Show `customUserAgentEditText` and set `userAgentString` as the text.
399                         customUserAgentEditText.setVisibility(View.VISIBLE);
400                         customUserAgentEditText.setText(currentUserAgentString);
401                         break;
402
403                     case "WebView default user agent":
404                         // Show `userAgentTextView` and set the text.
405                         userAgentTextView.setVisibility(View.VISIBLE);
406                         userAgentTextView.setText(webViewDefaultUserAgentString);
407
408                         // Hide `customUserAgentEditText`.
409                         customUserAgentEditText.setVisibility(View.GONE);
410                         break;
411
412                     default:
413                         // Show `userAgentTextView` and set the text.
414                         userAgentTextView.setVisibility(View.VISIBLE);
415                         userAgentTextView.setText(getResources().getStringArray(R.array.user_agent_entry_values)[position]);
416
417                         // Hide `customUserAgentEditText`.
418                         customUserAgentEditText.setVisibility(View.GONE);
419                         break;
420                 }
421             }
422
423             @Override
424             public void onNothingSelected(AdapterView<?> parent) {
425                 // Do nothing.
426             }
427         });
428
429         // Set the `displayImagesSwitch` `onItemClickListener()`.
430         displayWebpageImagesSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
431             @Override
432             public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
433                 // Update the icon.
434                 switch (position) {
435                     case DomainsDatabaseHelper.DISPLAY_WEBPAGE_IMAGES_SYSTEM_DEFAULT:
436                         if (MainWebViewActivity.displayWebpageImagesBoolean) {
437                             displayWebpageImagesImageView.setImageDrawable(getResources().getDrawable(R.drawable.images_enabled));
438                         } else {
439                             displayWebpageImagesImageView.setImageDrawable(getResources().getDrawable(R.drawable.images_disabled));
440                         }
441                         break;
442
443                     case DomainsDatabaseHelper.DISPLAY_WEBPAGE_IMAGES_ENABLED:
444                         displayWebpageImagesImageView.setImageDrawable(getResources().getDrawable(R.drawable.images_enabled));
445                         break;
446
447                     case DomainsDatabaseHelper.DISPLAY_WEBPAGE_IMAGES_DISABLED:
448                         displayWebpageImagesImageView.setImageDrawable(getResources().getDrawable(R.drawable.images_disabled));
449                         break;
450                 }
451             }
452
453             @Override
454             public void onNothingSelected(AdapterView<?> parent) {
455                 // Do nothing.
456             }
457         });
458
459         return domainSettingsView;
460     }
461 }