]> gitweb.stoutner.com Git - PrivacyBrowserAndroid.git/blobdiff - app/src/main/java/com/stoutner/privacybrowser/activities/DomainsActivity.java
Add import and export of settings. https://redmine.stoutner.com/issues/23
[PrivacyBrowserAndroid.git] / app / src / main / java / com / stoutner / privacybrowser / activities / DomainsActivity.java
index 8c6ff345923dda3d75beb4bf43f9903f7f515820..1d9a62a6aadd858273001888b6c064a0c80315fa 100644 (file)
 
 package com.stoutner.privacybrowser.activities;
 
+import android.app.Activity;
 import android.content.Context;
 import android.content.Intent;
+import android.content.res.Resources;
 import android.database.Cursor;
 import android.net.http.SslCertificate;
 import android.os.Bundle;
@@ -38,6 +40,7 @@ import android.view.Menu;
 import android.view.MenuItem;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.WindowManager;
 import android.widget.CursorAdapter;
 import android.widget.EditText;
 import android.widget.ListView;
@@ -52,6 +55,8 @@ import com.stoutner.privacybrowser.fragments.DomainSettingsFragment;
 import com.stoutner.privacybrowser.fragments.DomainsListFragment;
 import com.stoutner.privacybrowser.helpers.DomainsDatabaseHelper;
 
+import java.util.Objects;
+
 public class DomainsActivity extends AppCompatActivity implements AddDomainDialog.AddDomainListener {
     // `twoPanedMode` is public static so it can be accessed from `DomainsListFragment`.  It is also used in `onCreate()`, `onCreateOptionsMenu()`, and `populateDomainsListView()`.
     public static boolean twoPanedMode;
@@ -68,13 +73,16 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo
     // `dismissingSnackbar` is public static so it can be accessed from `DomainsListFragment`.  It is also used in `onOptionsItemSelected()`.
     public static boolean dismissingSnackbar;
 
+    // `closeActivityAfterDismissingSnackbar` is used in `onOptionsItemSelected()`, and `onBackPressed()`.
+    private boolean closeActivityAfterDismissingSnackbar;
+
     // `context` is used in `onCreate()`, `onOptionsItemSelected()`, and `onAddDomain()`.
     private Context context;
 
     // `supportFragmentManager` is used in `onCreate()` and `onCreateOptionsMenu()`.
     private FragmentManager supportFragmentManager;
 
-    // `domainsDatabaseHelper` is used in `onCreate()` and `saveDomainSettings()`.
+    // `domainsDatabaseHelper` is used in `onCreate()`, `saveDomainSettings()`, and `onDestroy()`.
     private static DomainsDatabaseHelper domainsDatabaseHelper;
 
     // `domainsListView` is used in `onCreate()` and `populateDomainsList()`.
@@ -96,10 +104,24 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo
     private int domainSettingsDatabaseIdBeforeRotate;
 
     // `goDirectlyToDatabaseId` is used in `onCreate()` and `onCreateOptionsMenu()`.
-    int goDirectlyToDatabaseId;
+    private int goDirectlyToDatabaseId;
+
+    // `closeOnBack` is used in `onCreate()`, `onOptionsItemSelected()` and `onBackPressed()`.
+    private boolean closeOnBack;
+
+    // `coordinatorLayout` is use in `onCreate()`, `onOptionsItemSelected()`, and `onSaveInstanceState()`.
+    private View coordinatorLayout;
+
+    // `resources` is used in `onCreate()`, `onOptionsItemSelected()`, and `onSaveInstanceState()`.
+    private Resources resources;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
+        // Disable screenshots if not allowed.
+        if (!MainWebViewActivity.allowScreenshots) {
+            getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
+        }
+
         // Set the activity theme.
         if (MainWebViewActivity.darkTheme) {
             setTheme(R.style.PrivacyBrowserDark_SecondaryActivity);
@@ -121,27 +143,30 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo
         Intent intent = getIntent();
 
         // Extract the domain to load if there is one.  `-1` is the default value.
-        goDirectlyToDatabaseId = intent.getIntExtra("LoadDomain", -1);
+        goDirectlyToDatabaseId = intent.getIntExtra("loadDomain", -1);
+
+        // Get the status of close-on-back, which is true when the domains activity is called from the options menu.
+        closeOnBack = intent.getBooleanExtra("closeOnBack", false);
 
         // Set the content view.
         setContentView(R.layout.domains_coordinatorlayout);
 
-        // Get a handle for the context.
+        // Populate the class variables.
+        coordinatorLayout = findViewById(R.id.domains_coordinatorlayout);
+        resources = getResources();
         context = this;
-
-        // Get a handle for the fragment manager.
         supportFragmentManager = getSupportFragmentManager();
 
         // `SupportActionBar` from `android.support.v7.app.ActionBar` must be used until the minimum API is >= 21.
         final Toolbar domainsAppBar = findViewById(R.id.domains_toolbar);
         setSupportActionBar(domainsAppBar);
 
-        // Display the home arrow on `SupportActionBar`.
+        // Display the home arrow on the support action bar.
         ActionBar appBar = getSupportActionBar();
         assert appBar != null;// This assert removes the incorrect warning in Android Studio on the following line that `appBar` might be null.
         appBar.setDisplayHomeAsUpEnabled(true);
 
-        // Initialize the database handler.  The two `nulls` do not specify the database name or a `CursorFactory`.  The `0` specifies the database version, but that is ignored and set instead using a constant in `DomainsDatabaseHelper`.
+        // Initialize the database handler.  The `0` specifies the database version, but that is ignored and set instead using a constant in `DomainsDatabaseHelper`.
         domainsDatabaseHelper = new DomainsDatabaseHelper(context, null, null, 0);
 
         // Determine if we are in two pane mode.  `domain_settings_fragment_container` does not exist on devices with a width less than 900dp.
@@ -152,7 +177,7 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo
         addDomainFAB.setOnClickListener((View view) -> {
             // Show the add domain `AlertDialog`.
             AppCompatDialogFragment addDomainDialog = new AddDomainDialog();
-            addDomainDialog.show(supportFragmentManager, getResources().getString(R.string.add_domain));
+            addDomainDialog.show(supportFragmentManager, resources.getString(R.string.add_domain));
         });
     }
 
@@ -260,31 +285,31 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo
                 if (twoPanedMode) {  // The device is in two-paned mode.
                     // Save the current domain settings if the domain settings fragment is displayed.
                     if (findViewById(R.id.domain_settings_scrollview) != null) {
-                        saveDomainSettings();
+                        saveDomainSettings(coordinatorLayout, resources);
                     }
 
                     // Dismiss the undo delete `SnackBar` if it is shown.
                     if (undoDeleteSnackbar != null && undoDeleteSnackbar.isShown()) {
-                        undoDeleteSnackbar.dismiss();
-
-                        // Create a `Runnable` to return to the main activity.
-                        Runnable navigateHomeRunnable = () -> {
-                            // Go home.
-                            NavUtils.navigateUpFromSameTask(this);
-                        };
+                        // Set the close flag.
+                        closeActivityAfterDismissingSnackbar = true;
 
-                        // Navigate home after 300 milliseconds to make sure that the previous domain has been deleted from the database.
-                        Handler handler = new Handler();
-                        handler.postDelayed(navigateHomeRunnable, 300);
+                        // Dismiss the snackbar.
+                        undoDeleteSnackbar.dismiss();
                     } else {
                         // Go home.
                         NavUtils.navigateUpFromSameTask(this);
                     }
-                } else if (findViewById(R.id.domain_settings_scrollview) != null) {  // The device is in single-paned mode and `DomainSettingsFragment` is displayed.
+                } else if (closeOnBack) {  // Go directly back to the main WebView activity because the domains activity was launched from the options menu.
                     // Save the current domain settings.
-                    saveDomainSettings();
+                    saveDomainSettings(coordinatorLayout, resources);
 
-                    // Display `DomainsListFragment`.
+                    // Go home.
+                    NavUtils.navigateUpFromSameTask(this);
+                } else if (findViewById(R.id.domain_settings_scrollview) != null) {  // The device is in single-paned mode and the domain settings fragment is displayed.
+                    // Save the current domain settings.
+                    saveDomainSettings(coordinatorLayout, resources);
+
+                    // Display the domains list fragment.
                     DomainsListFragment domainsListFragment = new DomainsListFragment();
                     supportFragmentManager.beginTransaction().replace(R.id.domains_listview_fragment_container, domainsListFragment).commit();
                     supportFragmentManager.executePendingTransactions();
@@ -292,25 +317,19 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo
                     // Populate the list of domains.  `-1` highlights the first domain if in two-paned mode.  It has no effect in single-paned mode.
                     populateDomainsListView(-1);
 
-                    // Display `addDomainFAB`.
+                    // Display the add domain FAB.
                     addDomainFAB.setVisibility(View.VISIBLE);
 
-                    // Hide `deleteMenuItem`.
+                    // Hide the delete menu item.
                     deleteMenuItem.setVisible(false);
                 } else {  // The device is in single-paned mode and `DomainsListFragment` is displayed.
                     // Dismiss the undo delete `SnackBar` if it is shown.
                     if (undoDeleteSnackbar != null && undoDeleteSnackbar.isShown()) {
-                        undoDeleteSnackbar.dismiss();
+                        // Set the close flag.
+                        closeActivityAfterDismissingSnackbar = true;
 
-                        // Create a `Runnable` to return to the main activity.
-                        Runnable navigateHomeRunnable = () -> {
-                            // Go home.
-                            NavUtils.navigateUpFromSameTask(this);
-                        };
-
-                        // Navigate home after 300 milliseconds to make sure that the previous domain has been deleted from the database.
-                        Handler handler = new Handler();
-                        handler.postDelayed(navigateHomeRunnable, 300);
+                        // Dismiss the snackbar.
+                        undoDeleteSnackbar.dismiss();
                     } else {
                         // Go home.
                         NavUtils.navigateUpFromSameTask(this);
@@ -319,6 +338,9 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo
                 break;
 
             case R.id.delete_domain:
+                // Reset close-on-back, which otherwise can cause errors if the system attempts to save settings for a domain that no longer exists.
+                closeOnBack = false;
+
                 // Store a copy of `currentDomainDatabaseId` because it could change while the `Snackbar` is displayed.
                 final int databaseIdToDelete = currentDomainDatabaseId;
 
@@ -332,7 +354,7 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo
                     deleteMenuItem.setIcon(R.drawable.delete_blue);
 
                     // Remove the domain settings fragment.
-                    supportFragmentManager.beginTransaction().remove(supportFragmentManager.findFragmentById(R.id.domain_settings_fragment_container)).commit();
+                    supportFragmentManager.beginTransaction().remove(Objects.requireNonNull(supportFragmentManager.findFragmentById(R.id.domain_settings_fragment_container))).commit();
                 } else {  // Single-paned mode.
                     // Display `DomainsListFragment`.
                     DomainsListFragment domainsListFragment = new DomainsListFragment();
@@ -372,6 +394,9 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo
                 // Update the `ListView`.
                 domainsListView.setAdapter(domainsPendingDeleteCursorAdapter);
 
+                // Get a handle for the activity.
+                Activity activity = this;
+
                 // Display a `Snackbar`.
                 undoDeleteSnackbar = Snackbar.make(domainsListView, R.string.domain_deleted, Snackbar.LENGTH_LONG)
                         .setAction(R.string.undo, (View v) -> {
@@ -445,7 +470,7 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo
                                         // Delete the selected domain.
                                         domainsDatabaseHelper.deleteDomain(databaseIdToDelete);
 
-                                        // enable `deleteMenuItem` if the system was waiting for a `Snackbar` to be dismissed.
+                                        // Enable the delete menu item if the system was waiting for a snackbar to be dismissed.
                                         if (dismissingSnackbar) {
                                             // Create a `Runnable` to enable the delete menu item.
                                             Runnable enableDeleteMenuItemRunnable = () -> {
@@ -469,14 +494,23 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo
                                                 dismissingSnackbar = false;
                                             };
 
-                                            // Run `enableDeleteMenuItemRunnable` after 100 milliseconds to make sure that the previous domain has been deleted from the database.
+                                            // Enable the delete menu icon after 100 milliseconds to make sure that the previous domain has been deleted from the database.
                                             Handler handler = new Handler();
                                             handler.postDelayed(enableDeleteMenuItemRunnable, 100);
                                         }
+
+                                        // Close the activity if back was pressed.
+                                        if (closeActivityAfterDismissingSnackbar) {
+                                            // Go home.
+                                            NavUtils.navigateUpFromSameTask(activity);
+                                        }
+
                                         break;
                                 }
                             }
                         });
+
+                // Show the Snackbar.
                 undoDeleteSnackbar.show();
                 break;
         }
@@ -490,7 +524,7 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo
         // Store the current `DomainSettingsFragment` state in `outState`.
         if (findViewById(R.id.domain_settings_scrollview) != null) {  // `DomainSettingsFragment` is displayed.
             // Save any changes that have been made to the domain settings.
-            saveDomainSettings();
+            saveDomainSettings(coordinatorLayout, resources);
 
             // Store `DomainSettingsDisplayed`.
             outState.putBoolean("domainSettingsDisplayed", true);
@@ -509,26 +543,29 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo
         if (twoPanedMode) {  // The device is in two-paned mode.
             // Save the current domain settings if the domain settings fragment is displayed.
             if (findViewById(R.id.domain_settings_scrollview) != null) {
-                saveDomainSettings();
+                saveDomainSettings(coordinatorLayout, resources);
             }
 
             // Dismiss the undo delete SnackBar if it is shown.
-            if (undoDeleteSnackbar != null && undoDeleteSnackbar.isShown()) {
-                undoDeleteSnackbar.dismiss();
-
-                // Create a runnable to return to the main activity.
-                Runnable navigateHomeRunnable = super::onBackPressed;
+            if ((undoDeleteSnackbar != null) && undoDeleteSnackbar.isShown()) {
+                // Set the close flag.
+                closeActivityAfterDismissingSnackbar = true;
 
-                // Navigate home after 300 milliseconds to make sure that the previous domain has been deleted from the database.
-                Handler handler = new Handler();
-                handler.postDelayed(navigateHomeRunnable, 300);
+                // Dismiss the snackbar.
+                undoDeleteSnackbar.dismiss();
             } else {
                 // Pass `onBackPressed()` to the system.
                 super.onBackPressed();
             }
-        } else if (findViewById(R.id.domain_settings_scrollview) != null) {  // The device is in single-paned mode and `DomainSettingsFragment` is displayed.
+        } else if (closeOnBack) {  // Go directly back to the main WebView activity because the domains activity was launched from the options menu.
             // Save the current domain settings.
-            saveDomainSettings();
+            saveDomainSettings(coordinatorLayout, resources);
+
+            // Pass `onBackPressed()` to the system.
+            super.onBackPressed();
+        } else if (findViewById(R.id.domain_settings_scrollview) != null) {  // The device is in single-paned mode and domain settings fragment is displayed.
+            // Save the current domain settings.
+            saveDomainSettings(coordinatorLayout, resources);
 
             // Display the domains list fragment.
             DomainsListFragment domainsListFragment = new DomainsListFragment();
@@ -538,22 +575,19 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo
             // Populate the list of domains.  `-1` highlights the first domain if in two-paned mode.  It has no effect in single-paned mode.
             populateDomainsListView(-1);
 
-            // Display `addDomainFAB`.
+            // Display the add domain FAB.
             addDomainFAB.setVisibility(View.VISIBLE);
 
-            // Hide `deleteMenuItem`.
+            // Hide the delete menu item.
             deleteMenuItem.setVisible(false);
-        } else {  // The device is in single-paned mode and `DomainsListFragment` is displayed.
-            // Dismiss the undo delete `SnackBar` if it is shown.
-            if (undoDeleteSnackbar != null && undoDeleteSnackbar.isShown()) {
-                undoDeleteSnackbar.dismiss();
-
-                // Create a runnable to return to the main activity.
-                Runnable navigateHomeRunnable = super::onBackPressed;
+        } else {  // The device is in single-paned mode and the domain list fragment is displayed.
+            // Dismiss the undo delete SnackBar if it is shown.
+            if ((undoDeleteSnackbar != null) && undoDeleteSnackbar.isShown()) {
+                // Set the close flag.
+                closeActivityAfterDismissingSnackbar = true;
 
-                // Navigate home after 300 milliseconds to make sure that the previous domain has been deleted from the database.
-                Handler handler = new Handler();
-                handler.postDelayed(navigateHomeRunnable, 300);
+                // Dismiss the snackbar.
+                undoDeleteSnackbar.dismiss();
             } else {
                 // Pass `onBackPressed()` to the system.
                 super.onBackPressed();
@@ -564,7 +598,7 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo
     @Override
     public void onAddDomain(AppCompatDialogFragment dialogFragment) {
         // Dismiss the undo delete snackbar if it is currently displayed.
-        if ((undoDeleteSnackbar != null) && (undoDeleteSnackbar.isShown())) {
+        if ((undoDeleteSnackbar != null) && undoDeleteSnackbar.isShown()) {
             undoDeleteSnackbar.dismiss();
         }
 
@@ -598,26 +632,29 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo
         }
     }
 
-    private void saveDomainSettings() {
+    public void saveDomainSettings(View view, Resources resources) {
         // Get handles for the domain settings.
-        EditText domainNameEditText = findViewById(R.id.domain_settings_name_edittext);
-        Switch javaScriptSwitch = findViewById(R.id.domain_settings_javascript_switch);
-        Switch firstPartyCookiesSwitch = findViewById(R.id.domain_settings_first_party_cookies_switch);
-        Switch thirdPartyCookiesSwitch = findViewById(R.id.domain_settings_third_party_cookies_switch);
-        Switch domStorageSwitch = findViewById(R.id.domain_settings_dom_storage_switch);
-        Switch formDataSwitch = findViewById(R.id.domain_settings_form_data_switch);
-        Switch easyListSwitch = findViewById(R.id.domain_settings_easylist_switch);
-        Switch easyPrivacySwitch = findViewById(R.id.domain_settings_easyprivacy_switch);
-        Switch fanboysAnnoyanceSwitch = findViewById(R.id.domain_settings_fanboys_annoyance_list_switch);
-        Switch fanboysSocialBlockingSwitch = findViewById(R.id.domain_settings_fanboys_social_blocking_list_switch);
-        Spinner userAgentSpinner = findViewById(R.id.domain_settings_user_agent_spinner);
-        EditText customUserAgentEditText = findViewById(R.id.domain_settings_custom_user_agent_edittext);
-        Spinner fontSizeSpinner = findViewById(R.id.domain_settings_font_size_spinner);
-        Spinner displayWebpageImagesSpinner = findViewById(R.id.domain_settings_display_webpage_images_spinner);
-        Spinner nightModeSpinner = findViewById(R.id.domain_settings_night_mode_spinner);
-        Switch pinnedSslCertificateSwitch = findViewById(R.id.domain_settings_pinned_ssl_certificate_switch);
-        RadioButton savedSslCertificateRadioButton = findViewById(R.id.saved_ssl_certificate_radiobutton);
-        RadioButton currentWebsiteCertificateRadioButton = findViewById(R.id.current_website_certificate_radiobutton);
+        EditText domainNameEditText = view.findViewById(R.id.domain_settings_name_edittext);
+        Switch javaScriptSwitch = view.findViewById(R.id.domain_settings_javascript_switch);
+        Switch firstPartyCookiesSwitch = view.findViewById(R.id.domain_settings_first_party_cookies_switch);
+        Switch thirdPartyCookiesSwitch = view.findViewById(R.id.domain_settings_third_party_cookies_switch);
+        Switch domStorageSwitch = view.findViewById(R.id.domain_settings_dom_storage_switch);
+        Switch formDataSwitch = view.findViewById(R.id.domain_settings_form_data_switch);  // Form data can be removed once the minimum API >= 26.
+        Switch easyListSwitch = view.findViewById(R.id.domain_settings_easylist_switch);
+        Switch easyPrivacySwitch = view.findViewById(R.id.domain_settings_easyprivacy_switch);
+        Switch fanboysAnnoyanceSwitch = view.findViewById(R.id.domain_settings_fanboys_annoyance_list_switch);
+        Switch fanboysSocialBlockingSwitch = view.findViewById(R.id.domain_settings_fanboys_social_blocking_list_switch);
+        Switch ultraPrivacySwitch = view.findViewById(R.id.domain_settings_ultraprivacy_switch);
+        Switch blockAllThirdPartyRequestsSwitch = view.findViewById(R.id.domain_settings_block_all_third_party_requests_switch);
+        Spinner userAgentSpinner = view.findViewById(R.id.domain_settings_user_agent_spinner);
+        EditText customUserAgentEditText = view.findViewById(R.id.domain_settings_custom_user_agent_edittext);
+        Spinner fontSizeSpinner = view.findViewById(R.id.domain_settings_font_size_spinner);
+        Spinner swipeToRefreshSpinner = view.findViewById(R.id.domain_settings_swipe_to_refresh_spinner);
+        Spinner displayWebpageImagesSpinner = view.findViewById(R.id.domain_settings_display_webpage_images_spinner);
+        Spinner nightModeSpinner = view.findViewById(R.id.domain_settings_night_mode_spinner);
+        Switch pinnedSslCertificateSwitch = view.findViewById(R.id.domain_settings_pinned_ssl_certificate_switch);
+        RadioButton savedSslCertificateRadioButton = view.findViewById(R.id.saved_ssl_certificate_radiobutton);
+        RadioButton currentWebsiteCertificateRadioButton = view.findViewById(R.id.current_website_certificate_radiobutton);
 
         // Extract the data for the domain settings.
         String domainNameString = domainNameEditText.getText().toString();
@@ -625,33 +662,52 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo
         boolean firstPartyCookiesEnabled = firstPartyCookiesSwitch.isChecked();
         boolean thirdPartyCookiesEnabled = thirdPartyCookiesSwitch.isChecked();
         boolean domStorageEnabled  = domStorageSwitch.isChecked();
-        boolean formDataEnabled = formDataSwitch.isChecked();
+        boolean formDataEnabled = formDataSwitch.isChecked();  // Form data can be removed once the minimum API >= 26.
         boolean easyListEnabled = easyListSwitch.isChecked();
         boolean easyPrivacyEnabled = easyPrivacySwitch.isChecked();
         boolean fanboysAnnoyanceEnabled = fanboysAnnoyanceSwitch.isChecked();
         boolean fanboysSocialBlockingEnabled = fanboysSocialBlockingSwitch.isChecked();
-        int userAgentPositionInt = userAgentSpinner.getSelectedItemPosition();
-        int fontSizePositionInt = fontSizeSpinner.getSelectedItemPosition();
+        boolean ultraPrivacyEnabled = ultraPrivacySwitch.isChecked();
+        boolean blockAllThirdPartyRequests = blockAllThirdPartyRequestsSwitch.isChecked();
+        int userAgentPosition = userAgentSpinner.getSelectedItemPosition();
+        int fontSizePosition = fontSizeSpinner.getSelectedItemPosition();
+        int swipeToRefreshInt = swipeToRefreshSpinner.getSelectedItemPosition();
         int displayWebpageImagesInt = displayWebpageImagesSpinner.getSelectedItemPosition();
         int nightModeInt = nightModeSpinner.getSelectedItemPosition();
         boolean pinnedSslCertificate = pinnedSslCertificateSwitch.isChecked();
 
-        // Get the data for the `Spinners` from the entry values string arrays.
-        String userAgentString = getResources().getStringArray(R.array.domain_settings_user_agent_entry_values)[userAgentPositionInt];
-        int fontSizeInt = Integer.parseInt(getResources().getStringArray(R.array.domain_settings_font_size_entry_values)[fontSizePositionInt]);
+        // Initialize the user agent name string.
+        String userAgentName;
 
-        // Check to see if we are using a custom user agent.
-        if (userAgentString.equals("Custom user agent")) {
-            // Set `userAgentString` to the custom user agent string.
-            userAgentString = customUserAgentEditText.getText().toString();
+        // Set the user agent name.
+        switch (userAgentPosition) {
+            case MainWebViewActivity.DOMAINS_SYSTEM_DEFAULT_USER_AGENT:
+                // Set the user agent name to be `System default user agent`.
+                userAgentName = resources.getString(R.string.system_default_user_agent);
+                break;
+
+            case MainWebViewActivity.DOMAINS_CUSTOM_USER_AGENT:
+                // Set the user agent name to be the custom user agent.
+                userAgentName = customUserAgentEditText.getText().toString();
+                break;
+
+            default:
+                // Get the array of user agent names.
+                String[] userAgentNameArray = resources.getStringArray(R.array.user_agent_names);
+
+                // Set the user agent name from the array.  The domain spinner has one more entry than the name array, so the position must be decremented.
+                userAgentName = userAgentNameArray[userAgentPosition - 1];
         }
 
+        // Get the font size integer.
+        int fontSizeInt = Integer.parseInt(resources.getStringArray(R.array.domain_settings_font_size_entry_values)[fontSizePosition]);
+
         // Save the domain settings.
         if (savedSslCertificateRadioButton.isChecked()) {  // The current certificate is being used.
             // Update the database except for the certificate.
             domainsDatabaseHelper.updateDomainExceptCertificate(DomainsActivity.currentDomainDatabaseId, domainNameString, javaScriptEnabled, firstPartyCookiesEnabled, thirdPartyCookiesEnabled,
-                    domStorageEnabled, formDataEnabled, easyListEnabled, easyPrivacyEnabled, fanboysAnnoyanceEnabled, fanboysSocialBlockingEnabled, userAgentString, fontSizeInt, displayWebpageImagesInt,
-                    nightModeInt, pinnedSslCertificate);
+                    domStorageEnabled, formDataEnabled, easyListEnabled, easyPrivacyEnabled, fanboysAnnoyanceEnabled, fanboysSocialBlockingEnabled, ultraPrivacyEnabled, blockAllThirdPartyRequests,
+                    userAgentName, fontSizeInt, swipeToRefreshInt, nightModeInt, displayWebpageImagesInt, pinnedSslCertificate);
         } else if (currentWebsiteCertificateRadioButton.isChecked()) {  // The certificate is being updated with the current website certificate.
             // Get the current website SSL certificate.
             SslCertificate currentWebsiteSslCertificate = MainWebViewActivity.sslCertificate;
@@ -668,14 +724,15 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo
 
             // Update the database.
             domainsDatabaseHelper.updateDomainWithCertificate(currentDomainDatabaseId, domainNameString, javaScriptEnabled, firstPartyCookiesEnabled, thirdPartyCookiesEnabled, domStorageEnabled,
-                    formDataEnabled, easyListEnabled, easyPrivacyEnabled, fanboysAnnoyanceEnabled, fanboysSocialBlockingEnabled, userAgentString, fontSizeInt, displayWebpageImagesInt, nightModeInt,
-                    pinnedSslCertificate, issuedToCommonName, issuedToOrganization, issuedToOrganizationalUnit, issuedByCommonName, issuedByOrganization, issuedByOrganizationalUnit, startDateLong, endDateLong);
+                    formDataEnabled, easyListEnabled, easyPrivacyEnabled, fanboysAnnoyanceEnabled, fanboysSocialBlockingEnabled, ultraPrivacyEnabled, blockAllThirdPartyRequests, userAgentName, fontSizeInt,
+                    swipeToRefreshInt, nightModeInt, displayWebpageImagesInt, pinnedSslCertificate, issuedToCommonName, issuedToOrganization, issuedToOrganizationalUnit, issuedByCommonName,
+                    issuedByOrganization, issuedByOrganizationalUnit, startDateLong, endDateLong);
 
         } else {  // No certificate is selected.
             // Update the database, with PINNED_SSL_CERTIFICATE set to false.
             domainsDatabaseHelper.updateDomainExceptCertificate(currentDomainDatabaseId, domainNameString, javaScriptEnabled, firstPartyCookiesEnabled, thirdPartyCookiesEnabled, domStorageEnabled,
-                    formDataEnabled, easyListEnabled, easyPrivacyEnabled, fanboysAnnoyanceEnabled, fanboysSocialBlockingEnabled, userAgentString, fontSizeInt, displayWebpageImagesInt, nightModeInt,
-                    false);
+                    formDataEnabled, easyListEnabled, easyPrivacyEnabled, fanboysAnnoyanceEnabled, fanboysSocialBlockingEnabled, ultraPrivacyEnabled, blockAllThirdPartyRequests, userAgentName, fontSizeInt,
+                    swipeToRefreshInt, nightModeInt, displayWebpageImagesInt,false);
         }
     }
 
@@ -758,4 +815,13 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo
             deleteMenuItem.setIcon(R.drawable.delete_blue);
         }
     }
+
+    @Override
+    public void onDestroy() {
+        // Close the domains database helper.
+        domainsDatabaseHelper.close();
+
+        // Run the default commands.
+        super.onDestroy();
+    }
 }
\ No newline at end of file