/*
- * Copyright © 2017-2020 Soren Stoutner <soren@stoutner.com>.
+ * Copyright © 2017-2022 Soren Stoutner <soren@stoutner.com>.
*
- * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
+ * This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android>.
*
- * Privacy Browser is free software: you can redistribute it and/or modify
+ * Privacy Browser Android is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
- * Privacy Browser is distributed in the hope that it will be useful,
+ * Privacy Browser Android is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with Privacy Browser. If not, see <http://www.gnu.org/licenses/>.
+ * along with Privacy Browser Android. If not, see <http://www.gnu.org/licenses/>.
*/
package com.stoutner.privacybrowser.activities;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
-import android.content.res.Configuration;
import android.content.res.Resources;
import android.database.Cursor;
import android.os.Bundle;
// Get a handle for the shared preferences.
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
- // Get the screenshot preference.
- boolean allowScreenshots = sharedPreferences.getBoolean("allow_screenshots", false);
+ // Get the preferences.
+ boolean allowScreenshots = sharedPreferences.getBoolean(getString(R.string.allow_screenshots_key), false);
+ boolean bottomAppBar = sharedPreferences.getBoolean(getString(R.string.bottom_app_bar_key), false);
// Disable screenshots if not allowed.
if (!allowScreenshots) {
sslEndDateLong = intent.getLongExtra("ssl_end_date", 0);
currentIpAddresses = intent.getStringExtra("current_ip_addresses");
- // Set the content view.
- setContentView(R.layout.domains_coordinatorlayout);
+ // Set the view.
+ if (bottomAppBar) {
+ setContentView(R.layout.domains_bottom_appbar);
+ } else {
+ setContentView(R.layout.domains_top_appbar);
+ }
// Populate the class variables.
coordinatorLayout = findViewById(R.id.domains_coordinatorlayout);
// Set the back arrow on the action bar.
actionBar.setDisplayHomeAsUpEnabled(true);
- // 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(this, null, null, 0);
+ // Initialize the database handler.
+ domainsDatabaseHelper = new DomainsDatabaseHelper(this);
// Determine if we are in two pane mode. `domain_settings_fragment_container` does not exist on devices with a width less than 900dp.
twoPanedMode = (findViewById(R.id.domain_settings_fragment_container) != null);
@Override
public boolean onOptionsItemSelected(MenuItem menuItem) {
// Get the ID of the menu item that was selected.
- int menuItemID = menuItem.getItemId();
+ int menuItemId = menuItem.getItemId();
// Get a handle for the fragment manager.
FragmentManager fragmentManager = getSupportFragmentManager();
- switch (menuItemID) {
- case android.R.id.home: // The home arrow is identified as `android.R.id.home`, not just `R.id.home`.
- 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(coordinatorLayout, resources);
- }
-
- // Dismiss the undo delete `SnackBar` if it is shown.
- if (undoDeleteSnackbar != null && undoDeleteSnackbar.isShown()) {
- // Set the close flag.
- closeActivityAfterDismissingSnackbar = true;
-
- // Dismiss the snackbar.
- undoDeleteSnackbar.dismiss();
- } else {
- // Go home.
- NavUtils.navigateUpFromSameTask(this);
- }
- } 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.
+ // Run the command according to the selected menu item.
+ if (menuItemId == android.R.id.home) { // The home arrow is identified as `android.R.id.home`, not just `R.id.home`.
+ // Check if the device is in two-paned mode.
+ 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(coordinatorLayout, resources);
+ }
+
+ // Dismiss the undo delete snackbar if it is shown.
+ if (undoDeleteSnackbar != null && undoDeleteSnackbar.isShown()) {
+ // Set the close flag.
+ closeActivityAfterDismissingSnackbar = true;
+ // 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 the domain settings fragment is displayed.
- // Save the current domain settings.
- saveDomainSettings(coordinatorLayout, resources);
+ }
+ } 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(coordinatorLayout, resources);
- // Display the domains list fragment.
- DomainsListFragment domainsListFragment = new DomainsListFragment();
- fragmentManager.beginTransaction().replace(R.id.domains_listview_fragment_container, domainsListFragment).commit();
- fragmentManager.executePendingTransactions();
+ // 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);
- // 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, domainsListViewPosition);
+ // Display the domains list fragment.
+ DomainsListFragment domainsListFragment = new DomainsListFragment();
+ fragmentManager.beginTransaction().replace(R.id.domains_listview_fragment_container, domainsListFragment).commit();
+ fragmentManager.executePendingTransactions();
- // Show the add domain floating action button.
- addDomainFAB.show();
+ // 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, domainsListViewPosition);
- // 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()) {
- // Set the close flag.
- closeActivityAfterDismissingSnackbar = true;
-
- // Dismiss the snackbar.
- undoDeleteSnackbar.dismiss();
- } else {
- // Go home.
- NavUtils.navigateUpFromSameTask(this);
- }
- }
- break;
+ // Show the add domain floating action button.
+ addDomainFAB.show();
+
+ // Hide the delete menu item.
+ deleteMenuItem.setVisible(false);
+ } else { // The device is in single-paned mode and domains list fragment is displayed.
+ // Dismiss the undo delete `SnackBar` if it is shown.
+ if (undoDeleteSnackbar != null && undoDeleteSnackbar.isShown()) {
+ // Set the close flag.
+ closeActivityAfterDismissingSnackbar = true;
- case R.id.delete_domain:
+ // Dismiss the snackbar.
+ undoDeleteSnackbar.dismiss();
+ } else {
+ // Go home.
+ NavUtils.navigateUpFromSameTask(this);
+ }
+ }
+ } else if (menuItemId == R.id.delete_domain) { // Delete.
+ // Get a handle for the activity.
+ Activity activity = this;
+
+ // Check to see if the domain settings were loaded directly for editing of this app in single-paned mode.
+ if (closeOnBack && !twoPanedMode) { // The activity should delete the domain settings and exit straight to the the main WebView activity.
+ // Delete the selected domain.
+ domainsDatabaseHelper.deleteDomain(currentDomainDatabaseId);
+
+ // Go home.
+ NavUtils.navigateUpFromSameTask(activity);
+ } else { // A snackbar should be shown before deleting the domain settings.
// 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.
+ // Store a copy of the current domain database ID because it could change while the snackbar is displayed.
final int databaseIdToDelete = currentDomainDatabaseId;
// Update the fragments and menu items.
if (twoPanedMode) { // Two-paned mode.
- // Store the deleted domain position, which is needed if `Undo` is selected in the `Snackbar`.
+ // Store the deleted domain position, which is needed if undo is selected in the snackbar.
deletedDomainPosition = domainsListView.getCheckedItemPosition();
- // Disable the options `MenuItems`.
+ // Disable the options menu items.
deleteMenuItem.setEnabled(false);
deleteMenuItem.setIcon(R.drawable.delete_disabled);
// Remove the domain settings fragment.
fragmentManager.beginTransaction().remove(Objects.requireNonNull(fragmentManager.findFragmentById(R.id.domain_settings_fragment_container))).commit();
} else { // Single-paned mode.
- // Display `DomainsListFragment`.
+ // Display the domains list fragment.
DomainsListFragment domainsListFragment = new DomainsListFragment();
fragmentManager.beginTransaction().replace(R.id.domains_listview_fragment_container, domainsListFragment).commit();
fragmentManager.executePendingTransactions();
deleteMenuItem.setVisible(false);
}
- // Get a `Cursor` that does not show the domain to be deleted.
+ // Get a cursor that does not show the domain to be deleted.
Cursor domainsPendingDeleteCursor = domainsDatabaseHelper.getDomainNameCursorOrderedByDomainExcept(databaseIdToDelete);
- // Setup `domainsPendingDeleteCursorAdapter` with `this` context. `false` disables `autoRequery`.
+ // Setup the domains pending delete cursor adapter.
CursorAdapter domainsPendingDeleteCursorAdapter = new CursorAdapter(this, domainsPendingDeleteCursor, false) {
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
- // Inflate the individual item layout. `false` does not attach it to the root.
+ // Inflate the individual item layout.
return getLayoutInflater().inflate(R.layout.domain_name_linearlayout, parent, false);
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
- // Set the domain name.
- String domainNameString = cursor.getString(cursor.getColumnIndex(DomainsDatabaseHelper.DOMAIN_NAME));
+ // Get the domain name string.
+ String domainNameString = cursor.getString(cursor.getColumnIndexOrThrow(DomainsDatabaseHelper.DOMAIN_NAME));
+
+ // Get a handle for the domain name text view.
TextView domainNameTextView = view.findViewById(R.id.domain_name_textview);
+
+ // Display the domain name.
domainNameTextView.setText(domainNameString);
}
};
- // Update the handle for the current `domains_listview`.
+ // Update the handle for the current domains list view.
domainsListView = findViewById(R.id.domains_listview);
- // Update the `ListView`.
+ // Update the list view.
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) -> {
// Display the correct fragments.
if (twoPanedMode) { // The device in in two-paned mode.
- // Get a `Cursor` with the current contents of the domains database.
+ // Get a cursor with the current contents of the domains database.
Cursor undoDeleteDomainsCursor = domainsDatabaseHelper.getDomainNameCursorOrderedByDomain();
- // Setup `domainsCursorAdapter` with `this` context. `false` disables `autoRequery`.
+ // Setup the domains cursor adapter.
CursorAdapter undoDeleteDomainsCursorAdapter = new CursorAdapter(getApplicationContext(), undoDeleteDomainsCursor, false) {
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
- // Inflate the individual item layout. `false` does not attach it to the root.
+ // Inflate the individual item layout.
return getLayoutInflater().inflate(R.layout.domain_name_linearlayout, parent, false);
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
- // Set the domain name.
- String domainNameString = cursor.getString(cursor.getColumnIndex(DomainsDatabaseHelper.DOMAIN_NAME));
+ /// Get the domain name string.
+ String domainNameString = cursor.getString(cursor.getColumnIndexOrThrow(DomainsDatabaseHelper.DOMAIN_NAME));
+
+ // Get a handle for the domain name text view.
TextView domainNameTextView = view.findViewById(R.id.domain_name_textview);
+
+ // Display the domain name.
domainNameTextView.setText(domainNameString);
}
};
// Enable the options delete menu item.
deleteMenuItem.setEnabled(true);
- // Get the current theme status.
- int currentThemeStatus = getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
-
- // Set the delete menu item icon according to the theme.
- if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
- deleteMenuItem.setIcon(R.drawable.delete_night);
- } else {
- deleteMenuItem.setIcon(R.drawable.delete_day);
- }
+ // Set the delete menu item icon.
+ deleteMenuItem.setIcon(R.drawable.delete_enabled);
} else { // The device in in one-paned mode.
// Display the domain settings fragment.
fragmentManager.beginTransaction().replace(R.id.domains_listview_fragment_container, domainSettingsFragment).commit();
// Enable the delete menu item.
deleteMenuItem.setEnabled(true);
- // Get the current theme status.
- int currentThemeStatus = getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
-
- // Set the delete menu item icon according to the theme.
- if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
- deleteMenuItem.setIcon(R.drawable.delete_night);
- } else {
- deleteMenuItem.setIcon(R.drawable.delete_day);
- }
+ // Set the delete menu item icon.
+ deleteMenuItem.setIcon(R.drawable.delete_enabled);
} else { // Single-paned mode.
// Show the delete menu item.
deleteMenuItem.setVisible(true);
// Show the Snackbar.
undoDeleteSnackbar.show();
- break;
+ }
}
// Consume the event.
// Get handles for the domain settings.
EditText domainNameEditText = view.findViewById(R.id.domain_settings_name_edittext);
SwitchCompat javaScriptSwitch = view.findViewById(R.id.javascript_switch);
- SwitchCompat firstPartyCookiesSwitch = view.findViewById(R.id.first_party_cookies_switch);
- SwitchCompat thirdPartyCookiesSwitch = view.findViewById(R.id.third_party_cookies_switch);
+ SwitchCompat cookiesSwitch = view.findViewById(R.id.cookies_switch);
SwitchCompat domStorageSwitch = view.findViewById(R.id.dom_storage_switch);
SwitchCompat formDataSwitch = view.findViewById(R.id.form_data_switch); // Form data can be removed once the minimum API >= 26.
SwitchCompat easyListSwitch = view.findViewById(R.id.easylist_switch);
// Extract the data for the domain settings.
String domainNameString = domainNameEditText.getText().toString();
boolean javaScript = javaScriptSwitch.isChecked();
- boolean firstPartyCookies = firstPartyCookiesSwitch.isChecked();
- boolean thirdPartyCookies = thirdPartyCookiesSwitch.isChecked();
+ boolean cookies = cookiesSwitch.isChecked();
boolean domStorage = domStorageSwitch.isChecked();
boolean formData = formDataSwitch.isChecked(); // Form data can be removed once the minimum API >= 26.
boolean easyList = easyListSwitch.isChecked();
}
// Save the domain settings.
- domainsDatabaseHelper.updateDomain(DomainsActivity.currentDomainDatabaseId, domainNameString, javaScript, firstPartyCookies, thirdPartyCookies, domStorage, formData, easyList, easyPrivacy,
+ domainsDatabaseHelper.updateDomain(DomainsActivity.currentDomainDatabaseId, domainNameString, javaScript, cookies, domStorage, formData, easyList, easyPrivacy,
fanboysAnnoyance, fanboysSocialBlocking, ultraList, ultraPrivacy, blockAllThirdPartyRequests, userAgentName, fontSizeInt, swipeToRefreshInt, webViewThemeInt, wideViewportInt,
displayWebpageImagesInt, pinnedSslCertificate, pinnedIpAddress);
@Override
public void bindView(View view, Context context, Cursor cursor) {
// Set the domain name.
- String domainNameString = cursor.getString(cursor.getColumnIndex(DomainsDatabaseHelper.DOMAIN_NAME));
+ String domainNameString = cursor.getString(cursor.getColumnIndexOrThrow(DomainsDatabaseHelper.DOMAIN_NAME));
TextView domainNameTextView = view.findViewById(R.id.domain_name_textview);
domainNameTextView.setText(domainNameString);
}
domainsCursor.moveToPosition(i);
// Get the database ID for this position.
- int currentDatabaseId = domainsCursor.getInt(domainsCursor.getColumnIndex(DomainsDatabaseHelper._ID));
+ int currentDatabaseId = domainsCursor.getInt(domainsCursor.getColumnIndexOrThrow(DomainsDatabaseHelper.ID));
// Set `highlightedDomainPosition` if the database ID for this matches `highlightedDomainDatabaseId`.
if (highlightedDomainDatabaseId == currentDatabaseId) {
// Get the database ID for the highlighted domain.
domainsCursor.moveToPosition(highlightedDomainPosition);
- currentDomainDatabaseId = domainsCursor.getInt(domainsCursor.getColumnIndex(DomainsDatabaseHelper._ID));
+ currentDomainDatabaseId = domainsCursor.getInt(domainsCursor.getColumnIndexOrThrow(DomainsDatabaseHelper.ID));
// Create an arguments bundle.
Bundle argumentsBundle = new Bundle();
// Enable the delete options menu items.
deleteMenuItem.setEnabled(true);
- // Get the current theme status.
- int currentThemeStatus = getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
-
- // Set the delete icon according to the theme.
- if (currentThemeStatus == Configuration.UI_MODE_NIGHT_YES) {
- deleteMenuItem.setIcon(R.drawable.delete_night);
- } else {
- deleteMenuItem.setIcon(R.drawable.delete_day);
- }
+ // Set the delete icon.
+ deleteMenuItem.setIcon(R.drawable.delete_enabled);
} else if (twoPanedMode) { // Two-paned mode is enabled but there are no domains.
// Disable the options `MenuItems`.
deleteMenuItem.setEnabled(false);