Fix closing of tabs.
[PrivacyBrowser.git] / app / src / main / java / com / stoutner / privacybrowser / activities / RequestsActivity.java
1 /*
2  * Copyright © 2018-2019 Soren Stoutner <soren@stoutner.com>.
3  *
4  * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
5  *
6  * Privacy Browser 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 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.  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.database.Cursor;
24 import android.database.MatrixCursor;
25 import android.os.Bundle;
26 import android.view.View;
27 import android.view.WindowManager;
28 import android.widget.AdapterView;
29 import android.widget.ArrayAdapter;
30 import android.widget.ListView;
31 import android.widget.ResourceCursorAdapter;
32 import android.widget.Spinner;
33 import android.widget.TextView;
34
35 import androidx.appcompat.app.ActionBar;
36 import androidx.appcompat.app.AppCompatActivity;
37 import androidx.appcompat.widget.Toolbar;  // The AndroidX toolbar must be used until the minimum API >= 21.
38 import androidx.fragment.app.DialogFragment;
39
40 import com.stoutner.privacybrowser.R;
41 import com.stoutner.privacybrowser.adapters.RequestsArrayAdapter;
42 import com.stoutner.privacybrowser.dialogs.ViewRequestDialog;
43
44 import java.util.ArrayList;
45 import java.util.List;
46
47 public class RequestsActivity extends AppCompatActivity implements ViewRequestDialog.ViewRequestListener {
48     // The list view is used in `onCreate()` and `launchViewRequestDialog()`.
49     private ListView requestsListView;
50
51     @Override
52     public void onCreate(Bundle savedInstanceState) {
53         // Disable screenshots if not allowed.
54         if (!MainWebViewActivity.allowScreenshots) {
55             getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
56         }
57
58         // Set the activity theme.
59         if (MainWebViewActivity.darkTheme) {
60             setTheme(R.style.PrivacyBrowserDark_SecondaryActivity);
61         } else {
62             setTheme(R.style.PrivacyBrowserLight_SecondaryActivity);
63         }
64
65         // Run the default commands.
66         super.onCreate(savedInstanceState);
67
68         // Set the content view.
69         setContentView(R.layout.requests_coordinatorlayout);
70
71         // Use the AndroidX toolbar from until the minimum API is >= 21.
72         Toolbar toolbar = findViewById(R.id.requests_toolbar);
73         setSupportActionBar(toolbar);
74
75         // Get a handle for the app bar and the list view.
76         ActionBar appBar = getSupportActionBar();
77         requestsListView = findViewById(R.id.requests_listview);
78
79         // Remove the incorrect lint warning that `appBar` might be null.
80         assert appBar != null;
81
82         // Display the spinner and the back arrow in the app bar.
83         appBar.setCustomView(R.layout.spinner);
84         appBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM | ActionBar.DISPLAY_HOME_AS_UP);
85
86         // 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.
87         List<String[]> allResourceRequests = new ArrayList<>();
88         List<String[]> defaultResourceRequests = new ArrayList<>();
89         List<String[]> allowedResourceRequests = new ArrayList<>();
90         List<String[]> thirdPartyResourceRequests = new ArrayList<>();
91         List<String[]> blockedResourceRequests = new ArrayList<>();
92
93         // Populate the resource array lists.
94         for (String[] request : MainWebViewActivity.resourceRequests) {
95             switch (Integer.valueOf(request[MainWebViewActivity.REQUEST_DISPOSITION])) {
96                 case MainWebViewActivity.REQUEST_DEFAULT:
97                     // Add the request to the list of all requests.
98                     allResourceRequests.add(request);
99
100                     // Add the request to the list of default requests.
101                     defaultResourceRequests.add(request);
102                     break;
103
104                 case MainWebViewActivity.REQUEST_ALLOWED:
105                     // Add the request to the list of all requests.
106                     allResourceRequests.add(request);
107
108                     // Add the request to the list of allowed requests.
109                     allowedResourceRequests.add(request);
110                     break;
111
112                 case MainWebViewActivity.REQUEST_THIRD_PARTY:
113                     // Add the request to the list of all requests.
114                     allResourceRequests.add(request);
115
116                     // Add the request to the list of third-party requests.
117                     thirdPartyResourceRequests.add(request);
118                     break;
119
120                 case MainWebViewActivity.REQUEST_BLOCKED:
121                     // Add the request to the list of all requests.
122                     allResourceRequests.add(request);
123
124                     // Add the request to the list of blocked requests.
125                     blockedResourceRequests.add(request);
126                     break;
127             }
128         }
129
130         // Setup a matrix cursor for the resource lists.
131         MatrixCursor spinnerCursor = new MatrixCursor(new String[]{"_id", "Requests"});
132         spinnerCursor.addRow(new Object[]{0, getString(R.string.all) + " - " + allResourceRequests.size()});
133         spinnerCursor.addRow(new Object[]{1, getString(R.string.default_label) + " - " + defaultResourceRequests.size()});
134         spinnerCursor.addRow(new Object[]{2, getString(R.string.allowed_plural) + " - " + allowedResourceRequests.size()});
135         if (MainWebViewActivity.blockAllThirdPartyRequests) {
136             spinnerCursor.addRow(new Object[]{3, getString(R.string.third_party_plural) + " - " + thirdPartyResourceRequests.size()});
137         }
138         spinnerCursor.addRow(new Object[]{4, getString(R.string.blocked_plural) + " - " + blockedResourceRequests.size()});
139
140         // Create a resource cursor adapter for the spinner.
141         ResourceCursorAdapter spinnerCursorAdapter = new ResourceCursorAdapter(this, R.layout.requests_appbar_spinner_item, spinnerCursor, 0) {
142             @Override
143             public void bindView(View view, Context context, Cursor cursor) {
144                 // Get a handle for the spinner item text view.
145                 TextView spinnerItemTextView = view.findViewById(R.id.spinner_item_textview);
146
147                 // Set the text view to display the resource list.
148                 spinnerItemTextView.setText(cursor.getString(1));
149             }
150         };
151
152         // Set the resource cursor adapter drop down view resource.
153         spinnerCursorAdapter.setDropDownViewResource(R.layout.requests_appbar_spinner_dropdown_item);
154
155         // Get a handle for the app bar spinner and set the adapter.
156         Spinner appBarSpinner = findViewById(R.id.spinner);
157         appBarSpinner.setAdapter(spinnerCursorAdapter);
158
159         // Handle clicks on the spinner dropdown.
160         appBarSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
161             @Override
162             public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
163                 switch ((int) id) {
164                     case 0:  // All requests.
165                         // Get an adapter for all the request.
166                         ArrayAdapter<String[]> allResourceRequestsArrayAdapter = new RequestsArrayAdapter(getApplicationContext(), allResourceRequests);
167
168                         // Display the adapter in the list view.
169                         requestsListView.setAdapter(allResourceRequestsArrayAdapter);
170                         break;
171
172                     case 1:  // Default requests.
173                         // Get an adapter for the default requests.
174                         ArrayAdapter<String[]> defaultResourceRequestsArrayAdapter = new RequestsArrayAdapter(getApplicationContext(), defaultResourceRequests);
175
176                         // Display the adapter in the list view.
177                         requestsListView.setAdapter(defaultResourceRequestsArrayAdapter);
178                         break;
179
180                     case 2:  // Allowed requests.
181                         // Get an adapter for the allowed requests.
182                         ArrayAdapter<String[]> allowedResourceRequestsArrayAdapter = new RequestsArrayAdapter(getApplicationContext(), allowedResourceRequests);
183
184                         // Display the adapter in the list view.
185                         requestsListView.setAdapter(allowedResourceRequestsArrayAdapter);
186                         break;
187
188                     case 3:  // Third-party requests.
189                         // Get an adapter for the third-party requests.
190                         ArrayAdapter<String[]> thirdPartyResourceRequestsArrayAdapter = new RequestsArrayAdapter(getApplicationContext(), thirdPartyResourceRequests);
191
192                         //Display the adapter in the list view.
193                         requestsListView.setAdapter(thirdPartyResourceRequestsArrayAdapter);
194                         break;
195
196                     case 4:  // Blocked requests.
197                         // Get an adapter fo the blocked requests.
198                         ArrayAdapter<String[]> blockedResourceRequestsArrayAdapter = new RequestsArrayAdapter(getApplicationContext(), blockedResourceRequests);
199
200                         // Display the adapter in the list view.
201                         requestsListView.setAdapter(blockedResourceRequestsArrayAdapter);
202                         break;
203                 }
204             }
205
206             @Override
207             public void onNothingSelected(AdapterView<?> parent) {
208                 // Do nothing.
209             }
210         });
211
212         // Create an array adapter with the list of the resource requests.
213         ArrayAdapter<String[]> resourceRequestsArrayAdapter = new RequestsArrayAdapter(getApplicationContext(), allResourceRequests);
214
215         // Populate the list view with the resource requests adapter.
216         requestsListView.setAdapter(resourceRequestsArrayAdapter);
217
218         // Listen for taps on entries in the list view.
219         requestsListView.setOnItemClickListener((AdapterView<?> parent, View view, int position, long id) -> {
220             // Display the view request dialog.  The list view is 0 based, so the position must be incremented by 1.
221             launchViewRequestDialog(position + 1);
222         });
223     }
224
225     @Override
226     public void onPrevious(int id) {
227         // Show the previous dialog.
228         launchViewRequestDialog(id -1);
229     }
230
231     @Override
232     public void onNext(int id) {
233         // Show the next dialog.
234         launchViewRequestDialog(id + 1);
235     }
236
237     private void launchViewRequestDialog(int id) {
238         // Determine if this is the last request in the list.
239         boolean isLastRequest = (id == requestsListView.getCount());
240
241         // Get the string array for the selected resource request.  The resource requests list view is zero based.
242         String[] selectedRequestStringArray = (String[]) requestsListView.getItemAtPosition(id - 1);
243
244         // Remove the warning that `selectedRequest` might be null.
245         assert selectedRequestStringArray != null;
246
247         // Show the request detail dialog.
248         DialogFragment viewRequestDialogFragment = ViewRequestDialog.request(id, isLastRequest, selectedRequestStringArray);
249         viewRequestDialogFragment.show(getSupportFragmentManager(), getString(R.string.request_details));
250     }
251 }