]> gitweb.stoutner.com Git - PrivacyBrowserAndroid.git/blob - app/src/main/java/com/stoutner/privacybrowser/activities/RequestsActivity.java
Move the theme assignments to the manifest file. https://redmine.stoutner.com/issues/761
[PrivacyBrowserAndroid.git] / app / src / main / java / com / stoutner / privacybrowser / activities / RequestsActivity.java
1 /*
2  * Copyright © 2018-2022 Soren Stoutner <soren@stoutner.com>.
3  *
4  * This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android>.
5  *
6  * Privacy Browser Android is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Privacy Browser Android is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Privacy Browser Android.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 package com.stoutner.privacybrowser.activities;
21
22 import android.content.Context;
23 import android.content.Intent;
24 import android.content.SharedPreferences;
25 import android.database.Cursor;
26 import android.database.MatrixCursor;
27 import android.os.Bundle;
28 import android.preference.PreferenceManager;
29 import android.view.View;
30 import android.view.WindowManager;
31 import android.widget.AdapterView;
32 import android.widget.ArrayAdapter;
33 import android.widget.ListView;
34 import android.widget.ResourceCursorAdapter;
35 import android.widget.Spinner;
36 import android.widget.TextView;
37
38 import androidx.annotation.NonNull;
39 import androidx.appcompat.app.ActionBar;
40 import androidx.appcompat.app.AppCompatActivity;
41 import androidx.appcompat.widget.Toolbar;
42 import androidx.fragment.app.DialogFragment;
43
44 import com.stoutner.privacybrowser.R;
45 import com.stoutner.privacybrowser.adapters.RequestsArrayAdapter;
46 import com.stoutner.privacybrowser.dialogs.ViewRequestDialog;
47 import com.stoutner.privacybrowser.helpers.BlocklistHelper;
48
49 import java.util.ArrayList;
50 import java.util.List;
51
52 public class RequestsActivity extends AppCompatActivity implements ViewRequestDialog.ViewRequestListener {
53     // The resource requests are populated by `MainWebViewActivity` before `RequestsActivity` is launched.
54     public static List<String[]> resourceRequests;
55
56     // Initialize the class constants.
57     private final String LISTVIEW_POSITION = "listview_position";
58
59     // Define the class views.
60     private ListView requestsListView;
61
62     @Override
63     public void onCreate(Bundle savedInstanceState) {
64         // Get a handle for the shared preferences.
65         SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
66
67         // Get the preferences.
68         boolean allowScreenshots = sharedPreferences.getBoolean(getString(R.string.allow_screenshots_key), false);
69         boolean bottomAppBar = sharedPreferences.getBoolean(getString(R.string.bottom_app_bar_key), false);
70
71         // Disable screenshots if not allowed.
72         if (!allowScreenshots) {
73             getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
74         }
75
76         // Run the default commands.
77         super.onCreate(savedInstanceState);
78
79         // Get the launching intent
80         Intent intent = getIntent();
81
82         // Get the status of the third-party blocklist.
83         boolean blockAllThirdPartyRequests = intent.getBooleanExtra("block_all_third_party_requests", false);
84
85         // Set the content view.
86         if (bottomAppBar) {
87             setContentView(R.layout.requests_bottom_appbar);
88         } else {
89             setContentView(R.layout.requests_top_appbar);
90         }
91
92         // Use the AndroidX toolbar until the minimum API is >= 21.
93         Toolbar toolbar = findViewById(R.id.requests_toolbar);
94         setSupportActionBar(toolbar);
95
96         // Get a handle for the app bar and the list view.
97         ActionBar appBar = getSupportActionBar();
98         requestsListView = findViewById(R.id.requests_listview);
99
100         // Remove the incorrect lint warning that `appBar` might be null.
101         assert appBar != null;
102
103         // Display the spinner and the back arrow in the app bar.
104         appBar.setCustomView(R.layout.spinner);
105         appBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM | ActionBar.DISPLAY_HOME_AS_UP);
106
107         // 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.
108         List<String[]> allResourceRequests = new ArrayList<>();
109         List<String[]> defaultResourceRequests = new ArrayList<>();
110         List<String[]> allowedResourceRequests = new ArrayList<>();
111         List<String[]> thirdPartyResourceRequests = new ArrayList<>();
112         List<String[]> blockedResourceRequests = new ArrayList<>();
113
114         // Populate the resource array lists.
115         for (String[] request : resourceRequests) {
116             switch (request[BlocklistHelper.REQUEST_DISPOSITION]) {
117                 case BlocklistHelper.REQUEST_DEFAULT:
118                     // Add the request to the list of all requests.
119                     allResourceRequests.add(request);
120
121                     // Add the request to the list of default requests.
122                     defaultResourceRequests.add(request);
123                     break;
124
125                 case BlocklistHelper.REQUEST_ALLOWED:
126                     // Add the request to the list of all requests.
127                     allResourceRequests.add(request);
128
129                     // Add the request to the list of allowed requests.
130                     allowedResourceRequests.add(request);
131                     break;
132
133                 case BlocklistHelper.REQUEST_THIRD_PARTY:
134                     // Add the request to the list of all requests.
135                     allResourceRequests.add(request);
136
137                     // Add the request to the list of third-party requests.
138                     thirdPartyResourceRequests.add(request);
139                     break;
140
141                 case BlocklistHelper.REQUEST_BLOCKED:
142                     // Add the request to the list of all requests.
143                     allResourceRequests.add(request);
144
145                     // Add the request to the list of blocked requests.
146                     blockedResourceRequests.add(request);
147                     break;
148             }
149         }
150
151         // Setup a matrix cursor for the resource lists.
152         MatrixCursor spinnerCursor = new MatrixCursor(new String[]{"_id", "Requests"});
153         spinnerCursor.addRow(new Object[]{0, getString(R.string.all) + " - " + allResourceRequests.size()});
154         spinnerCursor.addRow(new Object[]{1, getString(R.string.default_label) + " - " + defaultResourceRequests.size()});
155         spinnerCursor.addRow(new Object[]{2, getString(R.string.allowed_plural) + " - " + allowedResourceRequests.size()});
156         if (blockAllThirdPartyRequests) {
157             spinnerCursor.addRow(new Object[]{3, getString(R.string.third_party_plural) + " - " + thirdPartyResourceRequests.size()});
158         }
159         spinnerCursor.addRow(new Object[]{4, getString(R.string.blocked_plural) + " - " + blockedResourceRequests.size()});
160
161         // Create a resource cursor adapter for the spinner.
162         ResourceCursorAdapter spinnerCursorAdapter = new ResourceCursorAdapter(this, R.layout.requests_appbar_spinner_item, spinnerCursor, 0) {
163             @Override
164             public void bindView(View view, Context context, Cursor cursor) {
165                 // Get a handle for the spinner item text view.
166                 TextView spinnerItemTextView = view.findViewById(R.id.spinner_item_textview);
167
168                 // Set the text view to display the resource list.
169                 spinnerItemTextView.setText(cursor.getString(1));
170             }
171         };
172
173         // Set the resource cursor adapter drop down view resource.
174         spinnerCursorAdapter.setDropDownViewResource(R.layout.requests_appbar_spinner_dropdown_item);
175
176         // Get a handle for the app bar spinner and set the adapter.
177         Spinner appBarSpinner = findViewById(R.id.spinner);
178         appBarSpinner.setAdapter(spinnerCursorAdapter);
179
180         // Get a handle for the context.
181         Context context = this;
182
183         // Handle clicks on the spinner dropdown.
184         appBarSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
185             @Override
186             public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
187                 switch ((int) id) {
188                     case 0:  // All requests.
189                         // Get an adapter for all the request.
190                         ArrayAdapter<String[]> allResourceRequestsArrayAdapter = new RequestsArrayAdapter(context, allResourceRequests);
191
192                         // Display the adapter in the list view.
193                         requestsListView.setAdapter(allResourceRequestsArrayAdapter);
194                         break;
195
196                     case 1:  // Default requests.
197                         // Get an adapter for the default requests.
198                         ArrayAdapter<String[]> defaultResourceRequestsArrayAdapter = new RequestsArrayAdapter(context, defaultResourceRequests);
199
200                         // Display the adapter in the list view.
201                         requestsListView.setAdapter(defaultResourceRequestsArrayAdapter);
202                         break;
203
204                     case 2:  // Allowed requests.
205                         // Get an adapter for the allowed requests.
206                         ArrayAdapter<String[]> allowedResourceRequestsArrayAdapter = new RequestsArrayAdapter(context, allowedResourceRequests);
207
208                         // Display the adapter in the list view.
209                         requestsListView.setAdapter(allowedResourceRequestsArrayAdapter);
210                         break;
211
212                     case 3:  // Third-party requests.
213                         // Get an adapter for the third-party requests.
214                         ArrayAdapter<String[]> thirdPartyResourceRequestsArrayAdapter = new RequestsArrayAdapter(context, thirdPartyResourceRequests);
215
216                         //Display the adapter in the list view.
217                         requestsListView.setAdapter(thirdPartyResourceRequestsArrayAdapter);
218                         break;
219
220                     case 4:  // Blocked requests.
221                         // Get an adapter fo the blocked requests.
222                         ArrayAdapter<String[]> blockedResourceRequestsArrayAdapter = new RequestsArrayAdapter(context, blockedResourceRequests);
223
224                         // Display the adapter in the list view.
225                         requestsListView.setAdapter(blockedResourceRequestsArrayAdapter);
226                         break;
227                 }
228             }
229
230             @Override
231             public void onNothingSelected(AdapterView<?> parent) {
232                 // Do nothing.
233             }
234         });
235
236         // Create an array adapter with the list of the resource requests.
237         ArrayAdapter<String[]> resourceRequestsArrayAdapter = new RequestsArrayAdapter(context, allResourceRequests);
238
239         // Populate the list view with the resource requests adapter.
240         requestsListView.setAdapter(resourceRequestsArrayAdapter);
241
242         // Listen for taps on entries in the list view.
243         requestsListView.setOnItemClickListener((AdapterView<?> parent, View view, int position, long id) -> {
244             // Display the view request dialog.  The list view is 0 based, so the position must be incremented by 1.
245             launchViewRequestDialog(position + 1);
246         });
247
248         // Check to see if the activity has been restarted.
249         if (savedInstanceState != null) {
250             // Scroll to the saved position.
251             requestsListView.post(() -> requestsListView.setSelection(savedInstanceState.getInt(LISTVIEW_POSITION)));
252         }
253     }
254
255     @Override
256     public void onSaveInstanceState(@NonNull Bundle savedInstanceState) {
257         // Run the default commands.
258         super.onSaveInstanceState(savedInstanceState);
259
260         // Get the listview position.
261         int listViewPosition = requestsListView.getFirstVisiblePosition();
262
263         // Store the listview position in the bundle.
264         savedInstanceState.putInt(LISTVIEW_POSITION, listViewPosition);
265     }
266
267     @Override
268     public void onPrevious(int currentId) {
269         // Show the previous dialog.
270         launchViewRequestDialog(currentId -1);
271     }
272
273     @Override
274     public void onNext(int currentId) {
275         // Show the next dialog.
276         launchViewRequestDialog(currentId + 1);
277     }
278
279     private void launchViewRequestDialog(int id) {
280         // Determine if this is the last request in the list.
281         boolean isLastRequest = (id == requestsListView.getCount());
282
283         // Get the string array for the selected resource request.  The resource requests list view is zero based.
284         String[] selectedRequestStringArray = (String[]) requestsListView.getItemAtPosition(id - 1);
285
286         // Remove the warning that `selectedRequest` might be null.
287         assert selectedRequestStringArray != null;
288
289         // Show the request detail dialog.
290         DialogFragment viewRequestDialogFragment = ViewRequestDialog.request(id, isLastRequest, selectedRequestStringArray);
291         viewRequestDialogFragment.show(getSupportFragmentManager(), getString(R.string.request_details));
292     }
293 }