From b3b4105e9acd9cf8e202abef3b811d49c6c36bec Mon Sep 17 00:00:00 2001 From: Soren Stoutner Date: Mon, 13 Mar 2017 17:54:50 -0700 Subject: [PATCH] Populate and save the domain `Switches` and `Spinners`. --- .idea/dictionaries/soren.xml | 1 + .../activities/BookmarksActivity.java | 15 +-- .../activities/DomainSettingsActivity.java | 92 ++++++++++++- .../activities/DomainsActivity.java | 113 +++++++++++++++- .../activities/MainWebViewActivity.java | 2 +- .../fragments/DomainSettingsFragment.java | 121 +++++++++++++++++- .../fragments/SettingsFragment.java | 9 +- .../helpers/BookmarksDatabaseHelper.java | 4 +- .../helpers/DomainsDatabaseHelper.java | 70 +++++++--- app/src/main/res/layout/domain_settings.xml | 55 ++++++-- .../domain_settings_coordinatorlayout.xml | 7 +- .../main/res/menu/domains_options_menu.xml | 39 ++++++ app/src/main/res/values/strings.xml | 2 +- 13 files changed, 458 insertions(+), 72 deletions(-) create mode 100644 app/src/main/res/menu/domains_options_menu.xml diff --git a/.idea/dictionaries/soren.xml b/.idea/dictionaries/soren.xml index 4833f591..7734ed66 100644 --- a/.idea/dictionaries/soren.xml +++ b/.idea/dictionaries/soren.xml @@ -28,6 +28,7 @@ displayorder dname doesn + domainname downloadfile drawerlayout dwallach diff --git a/app/src/main/java/com/stoutner/privacybrowser/activities/BookmarksActivity.java b/app/src/main/java/com/stoutner/privacybrowser/activities/BookmarksActivity.java index b6f9bc61..dcb603ff 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/activities/BookmarksActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/activities/BookmarksActivity.java @@ -505,32 +505,27 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma @Override public boolean onCreateOptionsMenu(Menu menu) { - //Inflate the menu. + // Inflate the menu. getMenuInflater().inflate(R.menu.bookmarks_options_menu, menu); - return true; - } - - @Override - public boolean onPrepareOptionsMenu(Menu menu) { - super.onPrepareOptionsMenu(menu); - + // Success. return true; } @Override public boolean onOptionsItemSelected(MenuItem menuItem) { + // Get the ID of the `MenuItem` that was selected. int menuItemId = menuItem.getItemId(); switch (menuItemId) { - case android.R.id.home: + case android.R.id.home: // The home arrow is identified as `android.R.id.home`, not just `R.id.home`. if (currentFolder.isEmpty()) { // Exit BookmarksActivity if currently in the home folder. NavUtils.navigateUpFromSameTask(this); } else { // Navigate up one folder. // Place the former parent folder in `currentFolder`. currentFolder = bookmarksDatabaseHelper.getParentFolder(currentFolder); - // Exit BookmarksActivity if currently in the home folder. + // Update `bookmarksListView`. updateBookmarksListView(currentFolder); } break; diff --git a/app/src/main/java/com/stoutner/privacybrowser/activities/DomainSettingsActivity.java b/app/src/main/java/com/stoutner/privacybrowser/activities/DomainSettingsActivity.java index eba5f321..65546068 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/activities/DomainSettingsActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/activities/DomainSettingsActivity.java @@ -21,14 +21,24 @@ package com.stoutner.privacybrowser.activities; import android.content.Intent; import android.os.Bundle; +import android.support.v4.app.NavUtils; import android.support.v7.app.ActionBar; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; +import android.view.Menu; +import android.view.MenuItem; +import android.widget.EditText; +import android.widget.Spinner; +import android.widget.Switch; import com.stoutner.privacybrowser.R; import com.stoutner.privacybrowser.fragments.DomainSettingsFragment; +import com.stoutner.privacybrowser.helpers.DomainsDatabaseHelper; public class DomainSettingsActivity extends AppCompatActivity { + // `databaseId` is used in `onCreate()` and `onOptionsItemSelected()`. + int databaseId; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -47,7 +57,7 @@ public class DomainSettingsActivity extends AppCompatActivity { final Intent launchingIntent = getIntent(); // Extract the `databaseID`. The default value is `1`. - int databaseId = launchingIntent.getIntExtra(DomainSettingsFragment.DATABASE_ID, 1); + databaseId = launchingIntent.getIntExtra(DomainSettingsFragment.DATABASE_ID, 1); // Store `databaseId` in `argumentsBundle`. Bundle argumentsBundle = new Bundle(); @@ -58,6 +68,84 @@ public class DomainSettingsActivity extends AppCompatActivity { domainSettingsFragment.setArguments(argumentsBundle); // Display `domainSettingsFragment`. - getSupportFragmentManager().beginTransaction().replace(R.id.domain_settings_linearlayout, domainSettingsFragment).commit(); + getSupportFragmentManager().beginTransaction().replace(R.id.domain_settings_scrollview, domainSettingsFragment).commit(); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // Inflate the menu. + getMenuInflater().inflate(R.menu.domains_options_menu, menu); + + // Show the `MenuItems`. + menu.findItem(R.id.save_domain).setVisible(true); + menu.findItem(R.id.delete_domain).setVisible(true); + + // Success! + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem menuItem) { + // Get the ID of the `MenuItem` that was selected. + int menuItemID = menuItem.getItemId(); + + // Initialize the database handler. `this` specifies the context. 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`. + DomainsDatabaseHelper domainsDatabaseHelper = new DomainsDatabaseHelper(getApplicationContext(), null, null, 0); + + switch (menuItemID) { + case android.R.id.home: // The home arrow is identified as `android.R.id.home`, not just `R.id.home`. + // Go home. + NavUtils.navigateUpFromSameTask(this); + break; + + case R.id.save_domain: + // Get handles for the domain settings. + EditText domainNameEditText = (EditText) findViewById(R.id.domain_settings_name_edittext); + Switch javaScriptEnabledSwitch = (Switch) findViewById(R.id.domain_settings_javascript_switch); + Switch firstPartyCookiesEnabledSwitch = (Switch) findViewById(R.id.domain_settings_first_party_cookies_switch); + Switch thirdPartyCookiesEnabledSwitch = (Switch) findViewById(R.id.domain_settings_third_party_cookies_switch); + Switch domStorageEnabledSwitch = (Switch) findViewById(R.id.domain_settings_dom_storage_switch); + Switch formDataEnabledSwitch = (Switch) findViewById(R.id.domain_settings_form_data_switch); + Spinner userAgentSpinner = (Spinner) findViewById(R.id.domain_settings_user_agent_spinner); + EditText customUserAgentEditText = (EditText) findViewById(R.id.domain_settings_custom_user_agent_edittext); + Spinner fontSizeSpinner = (Spinner) findViewById(R.id.domain_settings_font_size_spinner); + + // Extract the data for the domain settings. + String domainNameString = domainNameEditText.getText().toString(); + boolean javaScriptEnabled = javaScriptEnabledSwitch.isChecked(); + boolean firstPartyCookiesEnabled = firstPartyCookiesEnabledSwitch.isChecked(); + boolean thirdPartyCookiesEnabled = thirdPartyCookiesEnabledSwitch.isChecked(); + boolean domStorageEnabledEnabled = domStorageEnabledSwitch.isChecked(); + boolean formDataEnabled = formDataEnabledSwitch.isChecked(); + int userAgentPosition = userAgentSpinner.getSelectedItemPosition(); + int fontSizePosition = fontSizeSpinner.getSelectedItemPosition(); + + // Get the data for the `Spinners` from the entry values string arrays. + String userAgentString = getResources().getStringArray(R.array.user_agent_entry_values)[userAgentPosition]; + int fontSizeInt = Integer.parseInt(getResources().getStringArray(R.array.default_font_size_entry_values)[fontSizePosition]); + + // 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(); + } + + // Save the domain settings. + domainsDatabaseHelper.saveDomain(databaseId, domainNameString, javaScriptEnabled, firstPartyCookiesEnabled, thirdPartyCookiesEnabled, domStorageEnabledEnabled, formDataEnabled, userAgentString, fontSizeInt); + + // Navigate to `DomainsActivity`. + NavUtils.navigateUpFromSameTask(this); + break; + + case R.id.delete_domain: + // Delete the selected domain. + domainsDatabaseHelper.deleteDomain(databaseId); + + // Navigate to `DomainsActivity`. + NavUtils.navigateUpFromSameTask(this); + break; + } + return true; } } diff --git a/app/src/main/java/com/stoutner/privacybrowser/activities/DomainsActivity.java b/app/src/main/java/com/stoutner/privacybrowser/activities/DomainsActivity.java index 7cbe8d05..78fbfb53 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/activities/DomainsActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/activities/DomainsActivity.java @@ -24,16 +24,21 @@ import android.content.Intent; import android.database.Cursor; import android.os.Bundle; import android.support.design.widget.FloatingActionButton; +import android.support.v4.app.NavUtils; import android.support.v7.app.ActionBar; import android.support.v7.app.AppCompatActivity; import android.support.v7.app.AppCompatDialogFragment; import android.support.v7.widget.Toolbar; +import android.view.Menu; +import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.CursorAdapter; import android.widget.EditText; import android.widget.ListView; +import android.widget.Spinner; +import android.widget.Switch; import android.widget.TextView; import com.stoutner.privacybrowser.R; @@ -42,17 +47,32 @@ import com.stoutner.privacybrowser.fragments.DomainSettingsFragment; import com.stoutner.privacybrowser.helpers.DomainsDatabaseHelper; public class DomainsActivity extends AppCompatActivity implements AddDomainDialog.AddDomainListener { - // `domainsDatabaseHelper` is used in `onCreate()`, `onAddDomain()`, and `updateDomainsRecyclerView()`. + // `context` is used in `onCreate()` and `onOptionsItemSelected()`. + Context context; + + // `domainsDatabaseHelper` is used in `onCreate()`, `onOptionsItemSelected()`, `onAddDomain()`, and `updateDomainsRecyclerView()`. private static DomainsDatabaseHelper domainsDatabaseHelper; // `domainsRecyclerView` is used in `onCreate()` and `updateDomainsListView()`. private ListView domainsListView; + // `databaseId` is used in `onCreate()` and `onOptionsItemSelected()`. + private int databaseId; + + // `saveMenuItem` is used in `onCreate()`, `onOptionsItemSelected()`, and `onCreateOptionsMenu()`. + private MenuItem saveMenuItem; + + // `deleteMenuItem` is used in `onCreate()`, `onOptionsItemSelected()`, and `onCreateOptionsMenu()`. + private MenuItem deleteMenuItem; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.domains_coordinatorlayout); + // Get a handle for the context. + context = this; + // We need to use the `SupportActionBar` from `android.support.v7.app.ActionBar` until the minimum API is >= 21. final Toolbar bookmarksAppBar = (Toolbar) findViewById(R.id.domains_toolbar); setSupportActionBar(bookmarksAppBar); @@ -75,11 +95,15 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo domainsListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView parent, View view, int position, long id) { - // Convert the id from long to int to match the format of the domains database. - int databaseId = (int) id; + // Convert the id from `long` to `int` to match the format of the domains database. + databaseId = (int) id; // Display the Domain Settings. if (twoPaneMode) { // Display a fragment in two paned mode. + // Display the options `MenuItems`. + saveMenuItem.setVisible(true); + deleteMenuItem.setVisible(true); + // Store `databaseId` in `argumentsBundle`. Bundle argumentsBundle = new Bundle(); argumentsBundle.putInt(DomainSettingsFragment.DATABASE_ID, databaseId); @@ -91,9 +115,6 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo // Display `domainSettingsFragment`. getSupportFragmentManager().beginTransaction().replace(R.id.domain_settings_scrollview, domainSettingsFragment).commit(); } else { // Load the second activity on smaller screens. - // Get a handle for the context. - Context context = view.getContext(); - // Create `domainSettingsActivityIntent` with the `databaseId`. Intent domainSettingsActivityIntent = new Intent(context, DomainSettingsActivity.class); domainSettingsActivityIntent.putExtra(DomainSettingsFragment.DATABASE_ID, databaseId); @@ -118,6 +139,84 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo updateDomainsListView(); } + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // Inflate the menu. + getMenuInflater().inflate(R.menu.domains_options_menu, menu); + + // Store the `MenuItems` for future use. + saveMenuItem = menu.findItem(R.id.save_domain); + deleteMenuItem = menu.findItem(R.id.delete_domain); + + // Success! + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem menuItem) { + // Get the ID of the `MenuItem` that was selected. + int menuItemID = menuItem.getItemId(); + + switch (menuItemID) { + case android.R.id.home: // The home arrow is identified as `android.R.id.home`, not just `R.id.home`. + // Go home. + NavUtils.navigateUpFromSameTask(this); + break; + + case R.id.save_domain: + // Get handles for the domain settings. + EditText domainNameEditText = (EditText) findViewById(R.id.domain_settings_name_edittext); + Switch javaScriptEnabledSwitch = (Switch) findViewById(R.id.domain_settings_javascript_switch); + Switch firstPartyCookiesEnabledSwitch = (Switch) findViewById(R.id.domain_settings_first_party_cookies_switch); + Switch thirdPartyCookiesEnabledSwitch = (Switch) findViewById(R.id.domain_settings_third_party_cookies_switch); + Switch domStorageEnabledSwitch = (Switch) findViewById(R.id.domain_settings_dom_storage_switch); + Switch formDataEnabledSwitch = (Switch) findViewById(R.id.domain_settings_form_data_switch); + Spinner userAgentSpinner = (Spinner) findViewById(R.id.domain_settings_user_agent_spinner); + EditText customUserAgentEditText = (EditText) findViewById(R.id.domain_settings_custom_user_agent_edittext); + Spinner fontSizeSpinner = (Spinner) findViewById(R.id.domain_settings_font_size_spinner); + + // Extract the data for the domain settings. + String domainNameString = domainNameEditText.getText().toString(); + boolean javaScriptEnabled = javaScriptEnabledSwitch.isChecked(); + boolean firstPartyCookiesEnabled = firstPartyCookiesEnabledSwitch.isChecked(); + boolean thirdPartyCookiesEnabled = thirdPartyCookiesEnabledSwitch.isChecked(); + boolean domStorageEnabledEnabled = domStorageEnabledSwitch.isChecked(); + boolean formDataEnabled = formDataEnabledSwitch.isChecked(); + int userAgentPosition = userAgentSpinner.getSelectedItemPosition(); + int fontSizePosition = fontSizeSpinner.getSelectedItemPosition(); + + // Get the data for the `Spinners` from the entry values string arrays. + String userAgentString = getResources().getStringArray(R.array.user_agent_entry_values)[userAgentPosition]; + int fontSizeInt = Integer.parseInt(getResources().getStringArray(R.array.default_font_size_entry_values)[fontSizePosition]); + + // 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(); + } + + // Save the domain settings. + domainsDatabaseHelper.saveDomain(databaseId, domainNameString, javaScriptEnabled, firstPartyCookiesEnabled, thirdPartyCookiesEnabled, domStorageEnabledEnabled, formDataEnabled, userAgentString, fontSizeInt); + break; + + case R.id.delete_domain: + // Delete the selected domain. + domainsDatabaseHelper.deleteDomain(databaseId); + + // Detach the domain settings fragment. + getSupportFragmentManager().beginTransaction().detach(getSupportFragmentManager().findFragmentById(R.id.domain_settings_scrollview)).commit(); + + // Hide the options `MenuItems`. + saveMenuItem.setVisible(false); + deleteMenuItem.setVisible(false); + + // Update the `ListView`. + updateDomainsListView(); + break; + } + return true; + } + @Override public void onAddDomain(AppCompatDialogFragment dialogFragment) { // Get the `domainNameEditText` from `dialogFragment` and extract the string. @@ -146,7 +245,7 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo @Override public void bindView(View view, Context context, Cursor cursor) { // Set the domain name. - String domainNameString = cursor.getString(cursor.getColumnIndex(DomainsDatabaseHelper.DOMAIN)); + String domainNameString = cursor.getString(cursor.getColumnIndex(DomainsDatabaseHelper.DOMAIN_NAME)); TextView domainNameTextView = (TextView) view.findViewById(R.id.domain_name_textview); domainNameTextView.setText(domainNameString); } diff --git a/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java b/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java index 2cad4b6d..0457af74 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java @@ -1926,7 +1926,7 @@ public class MainWebViewActivity extends AppCompatActivity implements Navigation // Set the user agent initial status. switch (userAgentString) { - case "Default user agent": + case "WebView default user agent": // Set the user agent to `""`, which uses the default value. mainWebView.getSettings().setUserAgentString(""); break; diff --git a/app/src/main/java/com/stoutner/privacybrowser/fragments/DomainSettingsFragment.java b/app/src/main/java/com/stoutner/privacybrowser/fragments/DomainSettingsFragment.java index a6214174..2c415dac 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/fragments/DomainSettingsFragment.java +++ b/app/src/main/java/com/stoutner/privacybrowser/fragments/DomainSettingsFragment.java @@ -19,6 +19,7 @@ package com.stoutner.privacybrowser.fragments; +import android.annotation.SuppressLint; import android.content.Context; import android.database.Cursor; import android.os.Bundle; @@ -27,9 +28,13 @@ import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.webkit.WebView; +import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.EditText; import android.widget.Spinner; +import android.widget.Switch; +import android.widget.TextView; import com.stoutner.privacybrowser.R; import com.stoutner.privacybrowser.helpers.DomainsDatabaseHelper; @@ -59,7 +64,14 @@ public class DomainSettingsFragment extends Fragment { // Get handles for the views in the fragment. EditText domainNameEditText = (EditText) domainSettingsView.findViewById(R.id.domain_settings_name_edittext); + Switch javaScriptEnabledSwitch = (Switch) domainSettingsView.findViewById(R.id.domain_settings_javascript_switch); + Switch firstPartyCookiesEnabledSwitch = (Switch) domainSettingsView.findViewById(R.id.domain_settings_first_party_cookies_switch); + Switch thirdPartyCookiesEnabledSwitch = (Switch) domainSettingsView.findViewById(R.id.domain_settings_third_party_cookies_switch); + Switch domStorageEnabledSwitch = (Switch) domainSettingsView.findViewById(R.id.domain_settings_dom_storage_switch); + Switch formDataEnabledSwitch = (Switch) domainSettingsView.findViewById(R.id.domain_settings_form_data_switch); Spinner userAgentSpinner = (Spinner) domainSettingsView.findViewById(R.id.domain_settings_user_agent_spinner); + final TextView userAgentTextView = (TextView) domainSettingsView.findViewById(R.id.domain_settings_user_agent_textview); + final EditText customUserAgentEditText = (EditText) domainSettingsView.findViewById(R.id.domain_settings_custom_user_agent_edittext); Spinner fontSizeSpinner = (Spinner) domainSettingsView.findViewById(R.id.domain_settings_font_size_spinner); // Initialize the database handler. `this` specifies the context. The two `nulls` do not specify the database name or a `CursorFactory`. @@ -71,12 +83,18 @@ public class DomainSettingsFragment extends Fragment { domainCursor.moveToFirst(); // Save the `Cursor` entries as variables. - String domainNameString = domainCursor.getString(domainCursor.getColumnIndex(DomainsDatabaseHelper.DOMAIN)); + String domainNameString = domainCursor.getString(domainCursor.getColumnIndex(DomainsDatabaseHelper.DOMAIN_NAME)); + int javaScriptEnabledInt = domainCursor.getInt(domainCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_JAVASCRIPT)); + int firstPartyCookiesEnabledInt = domainCursor.getInt(domainCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_FIRST_PARTY_COOKIES)); + int thirdPartyCookiesEnabledInt = domainCursor.getInt(domainCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_THIRD_PARTY_COOKIES)); + int domStorageEnabledInt = domainCursor.getInt(domainCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_DOM_STORAGE)); + int formDataEnabledInt = domainCursor.getInt(domainCursor.getColumnIndex(DomainsDatabaseHelper.ENABLE_FORM_DATA)); + final String currentUserAgentString = domainCursor.getString(domainCursor.getColumnIndex(DomainsDatabaseHelper.USER_AGENT)); int fontSizeInt = domainCursor.getInt(domainCursor.getColumnIndex(DomainsDatabaseHelper.FONT_SIZE)); // Create `ArrayAdapters` for the `Spinners`and their `entry values`. ArrayAdapter userAgentArrayAdapter = ArrayAdapter.createFromResource(context, R.array.user_agent_entries, android.R.layout.simple_spinner_item); - ArrayAdapter userAgentEntryValuesArrayAdapter = ArrayAdapter.createFromResource(context, R.array.user_agent_entry_values, android.R.layout.simple_spinner_item); + final ArrayAdapter userAgentEntryValuesArrayAdapter = ArrayAdapter.createFromResource(context, R.array.user_agent_entry_values, android.R.layout.simple_spinner_item); ArrayAdapter fontSizeArrayAdapter = ArrayAdapter.createFromResource(context, R.array.default_font_size_entries, android.R.layout.simple_spinner_item); ArrayAdapter fontSizeEntryValuesArrayAdapter = ArrayAdapter.createFromResource(context, R.array.default_font_size_entry_values, android.R.layout.simple_spinner_item); @@ -88,16 +106,105 @@ public class DomainSettingsFragment extends Fragment { userAgentSpinner.setAdapter(userAgentArrayAdapter); fontSizeSpinner.setAdapter(fontSizeArrayAdapter); - // - // int userAgentArrayPosition = + // Set the domain name from the the database cursor. + domainNameEditText.setText(domainNameString); + + // Set the status of the `Switches` from the database cursor. + javaScriptEnabledSwitch.setChecked(javaScriptEnabledInt == 1); + firstPartyCookiesEnabledSwitch.setChecked(firstPartyCookiesEnabledInt == 1); + thirdPartyCookiesEnabledSwitch.setChecked(thirdPartyCookiesEnabledInt == 1); + domStorageEnabledSwitch.setChecked(domStorageEnabledInt == 1); + formDataEnabledSwitch.setChecked(formDataEnabledInt == 1); + + // We need to inflated a `WebView` to get the default user agent. + // `@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. + @SuppressLint("InflateParams") View bareWebViewLayout = inflater.inflate(R.layout.bare_webview, null, false); + WebView bareWebView = (WebView) bareWebViewLayout.findViewById(R.id.bare_webview); + final String webViewDefaultUserAgentString = bareWebView.getSettings().getUserAgentString(); + + // Get the position of the user agent in `userAgentEntryValuesArrayAdapter`. + int userAgentArrayPosition = userAgentEntryValuesArrayAdapter.getPosition(currentUserAgentString); + + // Set the user agent. + if (userAgentArrayPosition == -1) { // We are using a custom `userAgentString`. + // Set `userAgentSpinner` to `Custom`. + userAgentSpinner.setSelection(userAgentEntryValuesArrayAdapter.getPosition("Custom user agent")); + + // Hide `userAgentTextView`. + userAgentTextView.setVisibility(View.GONE); + + // Show `customUserAgentEditText` and set `userAgentString` as the text. + customUserAgentEditText.setVisibility(View.VISIBLE); + customUserAgentEditText.setText(currentUserAgentString); + } else if (currentUserAgentString.equals("WebView default user agent")) { // We are using the `WebView` default user agent. + // Set the `userAgentSpinner` selection. + userAgentSpinner.setSelection(userAgentArrayPosition); + + // Show `userAgentTextView` and set the text. + userAgentTextView.setVisibility(View.VISIBLE); + userAgentTextView.setText(webViewDefaultUserAgentString); + + // Hide `customUserAgentEditText`. + customUserAgentEditText.setVisibility(View.GONE); + } else { // We are using a standard user agent. + // Set the `userAgentSpinner` selection. + userAgentSpinner.setSelection(userAgentArrayPosition); + + // Show `userAgentTextView` and set the text. + userAgentTextView.setVisibility(View.VISIBLE); + userAgentTextView.setText(currentUserAgentString); + + // Hide `customUserAgentEditText`. + customUserAgentEditText.setVisibility(View.GONE); + } // Set the selected font size. int fontSizeArrayPosition = fontSizeEntryValuesArrayAdapter.getPosition(String.valueOf(fontSizeInt)); fontSizeSpinner.setSelection(fontSizeArrayPosition); - - // Set the text from the database cursor. - domainNameEditText.setText(domainNameString); + // Set the `userAgentSpinner` `onItemClickListener()`. + userAgentSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView parent, View view, int position, long id) { + // Store the new user agent string. + String newUserAgentString = getResources().getStringArray(R.array.user_agent_entry_values)[position]; + + // Set the new user agent. + switch (newUserAgentString) { + case "Custom user agent": + // Hide `userAgentTextView`. + userAgentTextView.setVisibility(View.GONE); + + // Show `customUserAgentEditText` and set `userAgentString` as the text. + customUserAgentEditText.setVisibility(View.VISIBLE); + customUserAgentEditText.setText(currentUserAgentString); + break; + + case "WebView default user agent": + // Show `userAgentTextView` and set the text. + userAgentTextView.setVisibility(View.VISIBLE); + userAgentTextView.setText(webViewDefaultUserAgentString); + + // Hide `customUserAgentEditText`. + customUserAgentEditText.setVisibility(View.GONE); + break; + + default: + // Show `userAgentTextView` and set the text. + userAgentTextView.setVisibility(View.VISIBLE); + userAgentTextView.setText(getResources().getStringArray(R.array.user_agent_entry_values)[position]); + + // Hide `customUserAgentEditText`. + customUserAgentEditText.setVisibility(View.GONE); + break; + } + } + + @Override + public void onNothingSelected(AdapterView parent) { + // Do nothing. + } + }); return domainSettingsView; } diff --git a/app/src/main/java/com/stoutner/privacybrowser/fragments/SettingsFragment.java b/app/src/main/java/com/stoutner/privacybrowser/fragments/SettingsFragment.java index 0f7330bb..bda6dc82 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/fragments/SettingsFragment.java +++ b/app/src/main/java/com/stoutner/privacybrowser/fragments/SettingsFragment.java @@ -79,16 +79,15 @@ public class SettingsFragment extends PreferenceFragment { thirdPartyCookiesEnabled.setEnabled(savedPreferences.getBoolean("first_party_cookies_enabled", false)); - // We need an inflated `WebView` to get the default user agent. + // We need to inflated a `WebView` to get the default user agent. LayoutInflater inflater = getActivity().getLayoutInflater(); - // `@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. + // `@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. @SuppressLint("InflateParams") View bareWebViewLayout = inflater.inflate(R.layout.bare_webview, null, false); final WebView bareWebView = (WebView) bareWebViewLayout.findViewById(R.id.bare_webview); // Set the current user-agent as the summary text for the "user_agent" preference when the preference screen is loaded. switch (savedPreferences.getString("user_agent", "PrivacyBrowser/1.0")) { - case "Default user agent": + case "WebView default user agent": // Get the user agent text from the webview (which changes based on the version of Android and WebView installed). userAgentPreference.setSummary(bareWebView.getSettings().getUserAgentString()); break; @@ -219,7 +218,7 @@ public class SettingsFragment extends PreferenceFragment { String userAgentString = sharedPreferences.getString("user_agent", "PrivacyBrowser/1.0"); switch (userAgentString) { - case "Default user agent": + case "WebView default user agent": // Display the user agent as the summary text for `userAgentPreference`, and disable `customUserAgent`. userAgentPreference.setSummary(bareWebView.getSettings().getUserAgentString()); customUserAgent.setEnabled(false); diff --git a/app/src/main/java/com/stoutner/privacybrowser/helpers/BookmarksDatabaseHelper.java b/app/src/main/java/com/stoutner/privacybrowser/helpers/BookmarksDatabaseHelper.java index ccd420e1..0daf7f6a 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/helpers/BookmarksDatabaseHelper.java +++ b/app/src/main/java/com/stoutner/privacybrowser/helpers/BookmarksDatabaseHelper.java @@ -428,7 +428,7 @@ public class BookmarksDatabaseHelper extends SQLiteOpenHelper { bookmarkContentValues.put(DISPLAY_ORDER, displayOrder); bookmarkContentValues.put(PARENT_FOLDER, newFolder); - // Update the database. The last argument is 'null' because there are no 'whereArgs'. + // Update the database. The last argument is `null` because there are no `whereArgs`. bookmarksDatabase.update(BOOKMARKS_TABLE, bookmarkContentValues, _ID + " = " + databaseId, null); // Close the database handle. @@ -439,7 +439,7 @@ public class BookmarksDatabaseHelper extends SQLiteOpenHelper { // Get a writable database handle. SQLiteDatabase bookmarksDatabase = this.getWritableDatabase(); - // Deletes the row with the given databaseId. The last argument is null because we don't need additional parameters. + // Deletes the row with the given `databaseId`. The last argument is `null` because we don't need additional parameters. bookmarksDatabase.delete(BOOKMARKS_TABLE, _ID + " = " + databaseId, null); // Close the database handle. diff --git a/app/src/main/java/com/stoutner/privacybrowser/helpers/DomainsDatabaseHelper.java b/app/src/main/java/com/stoutner/privacybrowser/helpers/DomainsDatabaseHelper.java index 5e792678..d30839fa 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/helpers/DomainsDatabaseHelper.java +++ b/app/src/main/java/com/stoutner/privacybrowser/helpers/DomainsDatabaseHelper.java @@ -31,18 +31,15 @@ public class DomainsDatabaseHelper extends SQLiteOpenHelper { private static final String DOMAINS_TABLE = "domains"; private static final String _ID = "_id"; - public static final String DOMAIN = "domain"; + public static final String DOMAIN_NAME = "domainname"; + public static final String ENABLE_JAVASCRIPT = "enablejavascript"; + public static final String ENABLE_FIRST_PARTY_COOKIES = "enablefirstpartycookies"; + public static final String ENABLE_THIRD_PARTY_COOKIES = "enablethirdpartycookies"; + public static final String ENABLE_DOM_STORAGE = "enabledomstorage"; + public static final String ENABLE_FORM_DATA = "enableformdata"; + public static final String USER_AGENT = "useragent"; public static final String FONT_SIZE = "fontsize"; - private static final String ENABLE_JAVASCRIPT = "enablejavascript"; - private static final String ENABLE_FIRST_PARTY_COOKIES = "enablefirstpartycookies"; - private static final String ENABLE_THIRD_PARTY_COOKIES = "enablethirdpartycookies"; - private static final String ENABLE_DOM_STORAGE = "enabledomstorage"; - private static final String ENABLE_FORM_DATA = "enableformdata"; - private static final String USER_AGENT_NAME = "useragentname"; - private static final String USER_AGENT_STRING = "useragentstring"; - private static final String CUSTOM_USER_AGENT_STRING = "customuseragent"; - // Initialize the database. The lint warnings for the unused parameters are suppressed. public DomainsDatabaseHelper(Context context, @SuppressWarnings("UnusedParameters") String name, SQLiteDatabase.CursorFactory cursorFactory, @SuppressWarnings("UnusedParameters") int version) { super(context, DOMAINS_DATABASE, cursorFactory, SCHEMA_VERSION); @@ -53,15 +50,13 @@ public class DomainsDatabaseHelper extends SQLiteOpenHelper { // Setup the SQL string to create the `domains` table. final String CREATE_DOMAINS_TABLE = "CREATE TABLE " + DOMAINS_TABLE + " (" + _ID + " integer primary key, " + - DOMAIN + " text, " + + DOMAIN_NAME + " text, " + ENABLE_JAVASCRIPT + " boolean, " + ENABLE_FIRST_PARTY_COOKIES + " boolean, " + ENABLE_THIRD_PARTY_COOKIES + " boolean, " + ENABLE_DOM_STORAGE + " boolean, " + ENABLE_FORM_DATA + " boolean, " + - USER_AGENT_NAME + " text, " + - USER_AGENT_STRING + " text, " + - CUSTOM_USER_AGENT_STRING + " text, " + + USER_AGENT + " text, " + FONT_SIZE + " integer);"; // Create the `domains` table if it doesn't exist. @@ -77,9 +72,9 @@ public class DomainsDatabaseHelper extends SQLiteOpenHelper { // Get a readable database handle. SQLiteDatabase domainsDatabase = this.getReadableDatabase(); - // Get everything in `DOMAINS_TABLE` ordered by `DOMAIN`. + // Get everything in `DOMAINS_TABLE` ordered by `DOMAIN_NAME`. final String GET_CURSOR_SORTED_BY_DOMAIN = "Select * FROM " + DOMAINS_TABLE + - " ORDER BY " + DOMAIN + " ASC"; + " ORDER BY " + DOMAIN_NAME + " ASC"; // Return the results as a `Cursor`. The second argument is `null` because there are no `selectionArgs`. We can't close the `Cursor` because we need to use it in the parent activity. return domainsDatabase.rawQuery(GET_CURSOR_SORTED_BY_DOMAIN, null); @@ -98,19 +93,17 @@ public class DomainsDatabaseHelper extends SQLiteOpenHelper { } public void addDomain(String domainName) { - // We need to store the domain data in a `ContentValues`. + // Store the domain data in a `ContentValues`. ContentValues domainContentValues = new ContentValues(); // Create entries for each field in the database. The ID is created automatically. - domainContentValues.put(DOMAIN, domainName); + domainContentValues.put(DOMAIN_NAME, domainName); domainContentValues.put(ENABLE_JAVASCRIPT, false); domainContentValues.put(ENABLE_FIRST_PARTY_COOKIES, false); domainContentValues.put(ENABLE_THIRD_PARTY_COOKIES, false); domainContentValues.put(ENABLE_DOM_STORAGE, false); domainContentValues.put(ENABLE_FORM_DATA, false); - domainContentValues.put(USER_AGENT_NAME, "Privacy Browser 1.0"); - domainContentValues.put(USER_AGENT_STRING, "PrivacyBrowser/1.0"); - domainContentValues.put(CUSTOM_USER_AGENT_STRING, "PrivacyBrowser/1.0"); + domainContentValues.put(USER_AGENT, "PrivacyBrowser/1.0"); domainContentValues.put(FONT_SIZE, "100"); // Get a writable database handle. @@ -122,4 +115,39 @@ public class DomainsDatabaseHelper extends SQLiteOpenHelper { // Close the database handle. domainsDatabase.close(); } + + public void saveDomain(int databaseId, String domainName, boolean javaScriptEnabled, boolean firstPartyCookiesEnabled, boolean thirdPartyCookiesEnabled, boolean domStorageEnabled, boolean formDataEnabled, String userAgent, int fontSize) { + // Store the domain data in a `ContentValues`. + ContentValues domainContentValues = new ContentValues(); + + // Add entries for each field in the database. + domainContentValues.put(DOMAIN_NAME, domainName); + domainContentValues.put(ENABLE_JAVASCRIPT, javaScriptEnabled); + domainContentValues.put(ENABLE_FIRST_PARTY_COOKIES, firstPartyCookiesEnabled); + domainContentValues.put(ENABLE_THIRD_PARTY_COOKIES, thirdPartyCookiesEnabled); + domainContentValues.put(ENABLE_DOM_STORAGE, domStorageEnabled); + domainContentValues.put(ENABLE_FORM_DATA, formDataEnabled); + domainContentValues.put(USER_AGENT, userAgent); + domainContentValues.put(FONT_SIZE, fontSize); + + // Get a writable database handle. + SQLiteDatabase domainsDatabase = this.getWritableDatabase(); + + // Update the row for `databaseId`. The last argument is `null` because there are no `whereArgs`. + domainsDatabase.update(DOMAINS_TABLE, domainContentValues, _ID + " = " + databaseId, null); + + // Close the database handle. + domainsDatabase.close(); + } + + public void deleteDomain(int databaseId) { + // Get a writable database handle. + SQLiteDatabase domainsDatabase = this.getWritableDatabase(); + + // Delete the row for `databaseId`. The last argument is `null` because we don't need additional parameters. + domainsDatabase.delete(DOMAINS_TABLE, _ID + " = " + databaseId, null); + + // Close the database handle. + domainsDatabase.close(); + } } diff --git a/app/src/main/res/layout/domain_settings.xml b/app/src/main/res/layout/domain_settings.xml index 725041ea..d550386e 100644 --- a/app/src/main/res/layout/domain_settings.xml +++ b/app/src/main/res/layout/domain_settings.xml @@ -46,6 +46,7 @@ android:layout_height="wrap_content" android:layout_width="wrap_content" android:layout_marginBottom="26dp" + android:layout_marginEnd="10dp" android:layout_gravity="bottom" android:src="@drawable/domains" android:tint="@color/blue_800" @@ -77,6 +78,7 @@ @@ -102,6 +104,7 @@ android:layout_height="wrap_content" android:layout_width="wrap_content" android:layout_marginTop="1dp" + android:layout_marginEnd="10dp" android:layout_gravity="center_vertical" android:src="@drawable/cookies_enabled" android:tint="@color/blue_800" @@ -128,6 +131,7 @@ android:layout_height="wrap_content" android:layout_width="wrap_content" android:layout_marginTop="1dp" + android:layout_marginEnd="10dp" android:layout_gravity="center_vertical" android:src="@drawable/cookies_enabled" android:tint="@color/blue_800" @@ -154,6 +158,7 @@ android:layout_height="wrap_content" android:layout_width="wrap_content" android:layout_marginTop="1dp" + android:layout_marginEnd="10dp" android:layout_gravity="center_vertical" android:src="@drawable/dom_storage_enabled" android:tint="@color/blue_800" @@ -180,6 +185,7 @@ android:layout_height="wrap_content" android:layout_width="wrap_content" android:layout_marginTop="1dp" + android:layout_marginEnd="10dp" android:layout_gravity="center_vertical" android:src="@drawable/form_data_enabled" android:tint="@color/blue_800" @@ -200,23 +206,47 @@ + android:orientation="vertical" + android:layout_marginTop="14dp" + android:layout_marginBottom="14dp" > - + android:layout_width="match_parent" + android:orientation="horizontal"> - + + + + + + + + android:layout_marginStart="38dp" + android:layout_marginEnd="60dp" + android:inputType="textUri" /> @@ -231,6 +261,7 @@ android:layout_height="wrap_content" android:layout_width="wrap_content" android:layout_marginTop="1dp" + android:layout_marginEnd="10dp" android:layout_gravity="center_vertical" android:src="@drawable/font_size" android:tint="@color/blue_800" diff --git a/app/src/main/res/layout/domain_settings_coordinatorlayout.xml b/app/src/main/res/layout/domain_settings_coordinatorlayout.xml index 7c47eba9..ceb1beac 100644 --- a/app/src/main/res/layout/domain_settings_coordinatorlayout.xml +++ b/app/src/main/res/layout/domain_settings_coordinatorlayout.xml @@ -47,10 +47,9 @@ app:popupTheme="@style/LightPopupOverlay" /> - + android:layout_width="match_parent" /> \ No newline at end of file diff --git a/app/src/main/res/menu/domains_options_menu.xml b/app/src/main/res/menu/domains_options_menu.xml new file mode 100644 index 00000000..641dfd81 --- /dev/null +++ b/app/src/main/res/menu/domains_options_menu.xml @@ -0,0 +1,39 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9dbfc3bf..cca1c042 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -228,7 +228,7 @@ PrivacyBrowser/1.0 - Default user agent + WebView default user agent Mozilla/5.0 (Android 7.1.1; Mobile; rv:50.0) Gecko/50.0 Firefox/50.0 Mozilla/5.0 (Linux; Android 7.1.1; Nexus 6P Build/N4F26I) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36 Mozilla/5.0 (iPhone; CPU iPhone OS 10_2_1 like Mac OS X) AppleWebKit/602.4.6 (KHTML, like Gecko) Version/10.0 Mobile/14D27 Safari/602.1 -- 2.43.0