/*
- * Copyright © 2018 Soren Stoutner <soren@stoutner.com>.
+ * Copyright © 2018-2020 Soren Stoutner <soren@stoutner.com>.
*
* This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
*
package com.stoutner.privacybrowser.activities;
import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.os.Bundle;
-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.preference.PreferenceManager;
import android.view.View;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.Spinner;
import android.widget.TextView;
+import androidx.annotation.NonNull;
+import androidx.appcompat.app.ActionBar;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.appcompat.widget.Toolbar;
+import androidx.fragment.app.DialogFragment;
+
import com.stoutner.privacybrowser.R;
import com.stoutner.privacybrowser.adapters.RequestsArrayAdapter;
import com.stoutner.privacybrowser.dialogs.ViewRequestDialog;
+import com.stoutner.privacybrowser.helpers.BlocklistHelper;
import java.util.ArrayList;
import java.util.List;
public class RequestsActivity extends AppCompatActivity implements ViewRequestDialog.ViewRequestListener {
- // The list view is used in `onCreate()` and `launchViewRequestDialog()`.
- private ListView resourceRequestsListView;
+ // The resource requests are populated by `MainWebViewActivity` before `RequestsActivity` is launched.
+ public static List<String[]> resourceRequests;
+
+ // Initialize the class constants.
+ private final String LISTVIEW_POSITION = "listview_position";
+
+ // Define the class views.
+ private ListView requestsListView;
@Override
public void onCreate(Bundle savedInstanceState) {
+ // Get a handle for the shared preferences.
+ SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
+
+ // Get the screenshot preference.
+ boolean allowScreenshots = sharedPreferences.getBoolean("allow_screenshots", false);
+
// Disable screenshots if not allowed.
- if (!MainWebViewActivity.allowScreenshots) {
+ if (!allowScreenshots) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
}
- // Set the activity theme.
- if (MainWebViewActivity.darkTheme) {
- setTheme(R.style.PrivacyBrowserDark_SecondaryActivity);
- } else {
- setTheme(R.style.PrivacyBrowserLight_SecondaryActivity);
- }
+ // Set the theme.
+ setTheme(R.style.PrivacyBrowser);
// Run the default commands.
super.onCreate(savedInstanceState);
+ // Get the launching intent
+ Intent intent = getIntent();
+
+ // Get the status of the third-party blocklist.
+ boolean blockAllThirdPartyRequests = intent.getBooleanExtra("block_all_third_party_requests", false);
+
// Set the content view.
setContentView(R.layout.requests_coordinatorlayout);
- // Use the `SupportActionBar` from `android.support.v7.app.ActionBar` until the minimum API is >= 21.
- Toolbar blockListsAppBar = findViewById(R.id.blocklists_toolbar);
- setSupportActionBar(blockListsAppBar);
+ // Use the AndroidX toolbar until the minimum API is >= 21.
+ Toolbar toolbar = findViewById(R.id.requests_toolbar);
+ setSupportActionBar(toolbar);
// Get a handle for the app bar and the list view.
ActionBar appBar = getSupportActionBar();
- resourceRequestsListView = findViewById(R.id.resource_requests_listview);
+ requestsListView = findViewById(R.id.requests_listview);
// Remove the incorrect lint warning that `appBar` might be null.
assert appBar != null;
// Display the spinner and the back arrow in the app bar.
- appBar.setCustomView(R.layout.requests_spinner);
+ appBar.setCustomView(R.layout.spinner);
appBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM | ActionBar.DISPLAY_HOME_AS_UP);
- // Initialize the resource array lists.
+ // Initialize the resource array lists. A list is needed for all the resource requests, or the activity can crash if `MainWebViewActivity.resourceRequests` is modified after the activity loads.
+ List<String[]> allResourceRequests = new ArrayList<>();
List<String[]> defaultResourceRequests = new ArrayList<>();
List<String[]> allowedResourceRequests = new ArrayList<>();
+ List<String[]> thirdPartyResourceRequests = new ArrayList<>();
List<String[]> blockedResourceRequests = new ArrayList<>();
// Populate the resource array lists.
- for (String[] request : MainWebViewActivity.resourceRequests) {
- switch (Integer.valueOf(request[MainWebViewActivity.REQUEST_DISPOSITION])) {
- case MainWebViewActivity.REQUEST_DEFAULT:
+ for (String[] request : resourceRequests) {
+ switch (request[BlocklistHelper.REQUEST_DISPOSITION]) {
+ case BlocklistHelper.REQUEST_DEFAULT:
+ // Add the request to the list of all requests.
+ allResourceRequests.add(request);
+
+ // Add the request to the list of default requests.
defaultResourceRequests.add(request);
break;
- case MainWebViewActivity.REQUEST_ALLOWED:
+ case BlocklistHelper.REQUEST_ALLOWED:
+ // Add the request to the list of all requests.
+ allResourceRequests.add(request);
+
+ // Add the request to the list of allowed requests.
allowedResourceRequests.add(request);
break;
- case MainWebViewActivity.REQUEST_BLOCKED:
+ case BlocklistHelper.REQUEST_THIRD_PARTY:
+ // Add the request to the list of all requests.
+ allResourceRequests.add(request);
+
+ // Add the request to the list of third-party requests.
+ thirdPartyResourceRequests.add(request);
+ break;
+
+ case BlocklistHelper.REQUEST_BLOCKED:
+ // Add the request to the list of all requests.
+ allResourceRequests.add(request);
+
+ // Add the request to the list of blocked requests.
blockedResourceRequests.add(request);
break;
}
// Setup a matrix cursor for the resource lists.
MatrixCursor spinnerCursor = new MatrixCursor(new String[]{"_id", "Requests"});
- spinnerCursor.addRow(new Object[]{0, getString(R.string.all) + " - " + MainWebViewActivity.resourceRequests.size()});
+ spinnerCursor.addRow(new Object[]{0, getString(R.string.all) + " - " + allResourceRequests.size()});
spinnerCursor.addRow(new Object[]{1, getString(R.string.default_label) + " - " + defaultResourceRequests.size()});
- spinnerCursor.addRow(new Object[]{2, getString(R.string.allowed) + " - " + allowedResourceRequests.size()});
- spinnerCursor.addRow(new Object[]{3, getString(R.string.blocked) + " - " + blockedResourceRequests.size()});
+ spinnerCursor.addRow(new Object[]{2, getString(R.string.allowed_plural) + " - " + allowedResourceRequests.size()});
+ if (blockAllThirdPartyRequests) {
+ spinnerCursor.addRow(new Object[]{3, getString(R.string.third_party_plural) + " - " + thirdPartyResourceRequests.size()});
+ }
+ spinnerCursor.addRow(new Object[]{4, getString(R.string.blocked_plural) + " - " + blockedResourceRequests.size()});
// Create a resource cursor adapter for the spinner.
- ResourceCursorAdapter spinnerCursorAdapter = new ResourceCursorAdapter(this, R.layout.requests_spinner_item, spinnerCursor, 0) {
+ ResourceCursorAdapter spinnerCursorAdapter = new ResourceCursorAdapter(this, R.layout.requests_appbar_spinner_item, spinnerCursor, 0) {
@Override
public void bindView(View view, Context context, Cursor cursor) {
// Get a handle for the spinner item text view.
};
// Set the resource cursor adapter drop down view resource.
- spinnerCursorAdapter.setDropDownViewResource(R.layout.requests_spinner_dropdown_item);
+ spinnerCursorAdapter.setDropDownViewResource(R.layout.requests_appbar_spinner_dropdown_item);
// Get a handle for the app bar spinner and set the adapter.
- Spinner appBarSpinner = findViewById(R.id.requests_spinner);
+ Spinner appBarSpinner = findViewById(R.id.spinner);
appBarSpinner.setAdapter(spinnerCursorAdapter);
+ // Get a handle for the context.
+ Context context = this;
+
// Handle clicks on the spinner dropdown.
appBarSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
- switch (position) {
+ switch ((int) id) {
case 0: // All requests.
// Get an adapter for all the request.
- ArrayAdapter<String[]> allResourceRequestsArrayAdapter = new RequestsArrayAdapter(getApplicationContext(), MainWebViewActivity.resourceRequests);
+ ArrayAdapter<String[]> allResourceRequestsArrayAdapter = new RequestsArrayAdapter(context, allResourceRequests);
// Display the adapter in the list view.
- resourceRequestsListView.setAdapter(allResourceRequestsArrayAdapter);
+ requestsListView.setAdapter(allResourceRequestsArrayAdapter);
break;
case 1: // Default requests.
// Get an adapter for the default requests.
- ArrayAdapter<String[]> defaultResourceRequestsArrayAdapter = new RequestsArrayAdapter(getApplicationContext(), defaultResourceRequests);
+ ArrayAdapter<String[]> defaultResourceRequestsArrayAdapter = new RequestsArrayAdapter(context, defaultResourceRequests);
// Display the adapter in the list view.
- resourceRequestsListView.setAdapter(defaultResourceRequestsArrayAdapter);
+ requestsListView.setAdapter(defaultResourceRequestsArrayAdapter);
break;
case 2: // Allowed requests.
// Get an adapter for the allowed requests.
- ArrayAdapter<String[]> allowedResourceRequestsArrayAdapter = new RequestsArrayAdapter(getApplicationContext(), allowedResourceRequests);
+ ArrayAdapter<String[]> allowedResourceRequestsArrayAdapter = new RequestsArrayAdapter(context, allowedResourceRequests);
// Display the adapter in the list view.
- resourceRequestsListView.setAdapter(allowedResourceRequestsArrayAdapter);
+ requestsListView.setAdapter(allowedResourceRequestsArrayAdapter);
break;
- case 3: // Blocked requests.
+ case 3: // Third-party requests.
+ // Get an adapter for the third-party requests.
+ ArrayAdapter<String[]> thirdPartyResourceRequestsArrayAdapter = new RequestsArrayAdapter(context, thirdPartyResourceRequests);
+
+ //Display the adapter in the list view.
+ requestsListView.setAdapter(thirdPartyResourceRequestsArrayAdapter);
+ break;
+
+ case 4: // Blocked requests.
// Get an adapter fo the blocked requests.
- ArrayAdapter<String[]> blockedResourceRequestsArrayAdapter = new RequestsArrayAdapter(getApplicationContext(), blockedResourceRequests);
+ ArrayAdapter<String[]> blockedResourceRequestsArrayAdapter = new RequestsArrayAdapter(context, blockedResourceRequests);
// Display the adapter in the list view.
- resourceRequestsListView.setAdapter(blockedResourceRequestsArrayAdapter);
+ requestsListView.setAdapter(blockedResourceRequestsArrayAdapter);
break;
}
}
});
// Create an array adapter with the list of the resource requests.
- ArrayAdapter<String[]> resourceRequestsArrayAdapter = new RequestsArrayAdapter(getApplicationContext(), MainWebViewActivity.resourceRequests);
+ ArrayAdapter<String[]> resourceRequestsArrayAdapter = new RequestsArrayAdapter(context, allResourceRequests);
// Populate the list view with the resource requests adapter.
- resourceRequestsListView.setAdapter(resourceRequestsArrayAdapter);
+ requestsListView.setAdapter(resourceRequestsArrayAdapter);
// Listen for taps on entries in the list view.
- resourceRequestsListView.setOnItemClickListener((AdapterView<?> parent, View view, int position, long id) -> {
+ requestsListView.setOnItemClickListener((AdapterView<?> parent, View view, int position, long id) -> {
// Display the view request dialog. The list view is 0 based, so the position must be incremented by 1.
launchViewRequestDialog(position + 1);
});
+
+ // Check to see if the activity has been restarted.
+ if (savedInstanceState != null) {
+ // Scroll to the saved position.
+ requestsListView.post(() -> requestsListView.setSelection(savedInstanceState.getInt(LISTVIEW_POSITION)));
+ }
+ }
+
+ @Override
+ public void onSaveInstanceState(@NonNull Bundle savedInstanceState) {
+ // Run the default commands.
+ super.onSaveInstanceState(savedInstanceState);
+
+ // Get the listview position.
+ int listViewPosition = requestsListView.getFirstVisiblePosition();
+
+ // Store the listview position in the bundle.
+ savedInstanceState.putInt(LISTVIEW_POSITION, listViewPosition);
}
@Override
private void launchViewRequestDialog(int id) {
// Determine if this is the last request in the list.
- boolean isLastRequest = (id == resourceRequestsListView.getCount());
+ boolean isLastRequest = (id == requestsListView.getCount());
// Get the string array for the selected resource request. The resource requests list view is zero based.
- String[] selectedRequestStringArray = (String[]) resourceRequestsListView.getItemAtPosition(id - 1);
+ String[] selectedRequestStringArray = (String[]) requestsListView.getItemAtPosition(id - 1);
// Remove the warning that `selectedRequest` might be null.
assert selectedRequestStringArray != null;
// Show the request detail dialog.
- AppCompatDialogFragment viewRequestDialogFragment = ViewRequestDialog.request(id, isLastRequest, selectedRequestStringArray);
+ DialogFragment viewRequestDialogFragment = ViewRequestDialog.request(id, isLastRequest, selectedRequestStringArray);
viewRequestDialogFragment.show(getSupportFragmentManager(), getString(R.string.request_details));
}
}
\ No newline at end of file