]> gitweb.stoutner.com Git - PrivacyBrowserAndroid.git/blob - app/src/main/java/com/stoutner/privacybrowser/activities/RequestsActivity.kt
Migrate the remaining classes to Kotlin. https://redmine.stoutner.com/issues/989
[PrivacyBrowserAndroid.git] / app / src / main / java / com / stoutner / privacybrowser / activities / RequestsActivity.kt
1 /*
2  * Copyright 2018-2023 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.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.Spinner
32 import android.widget.TextView
33
34 import androidx.appcompat.app.ActionBar
35 import androidx.appcompat.app.AppCompatActivity
36 import androidx.appcompat.widget.Toolbar
37 import androidx.cursoradapter.widget.ResourceCursorAdapter
38 import androidx.fragment.app.DialogFragment
39 import androidx.preference.PreferenceManager
40
41 import com.stoutner.privacybrowser.R
42 import com.stoutner.privacybrowser.adapters.RequestsArrayAdapter
43 import com.stoutner.privacybrowser.dialogs.ViewRequestDialog.Companion.request
44 import com.stoutner.privacybrowser.dialogs.ViewRequestDialog.ViewRequestListener
45 import com.stoutner.privacybrowser.helpers.BlocklistHelper
46
47 // Define the public constants.
48 const val BLOCK_ALL_THIRD_PARTY_REQUESTS = "block_all_third_party_requests"
49
50 // Define the private class constants.
51 private const val LISTVIEW_POSITION = "listview_position"
52
53 class RequestsActivity : AppCompatActivity(), ViewRequestListener {
54     companion object {
55         // The resource requests are populated by `MainWebViewActivity` before `RequestsActivity` is launched.
56         var resourceRequests: List<Array<String>>? = null
57     }
58
59     // Define the class views.
60     private lateinit var requestsListView: ListView
61
62     public override fun onCreate(savedInstanceState: Bundle?) {
63         // Get a handle for the shared preferences.
64         val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(applicationContext)
65
66         // Get the preferences.
67         val allowScreenshots = sharedPreferences.getBoolean(getString(R.string.allow_screenshots_key), false)
68         val bottomAppBar = sharedPreferences.getBoolean(getString(R.string.bottom_app_bar_key), false)
69
70         // Disable screenshots if not allowed.
71         if (!allowScreenshots) {
72             window.addFlags(WindowManager.LayoutParams.FLAG_SECURE)
73         }
74
75         // Run the default commands.
76         super.onCreate(savedInstanceState)
77
78         // Get the launching intent
79         val intent = intent
80
81         // Get the status of the third-party blocklist.
82         val blockAllThirdPartyRequests = intent.getBooleanExtra(BLOCK_ALL_THIRD_PARTY_REQUESTS, false)
83
84         // Set the content view.
85         if (bottomAppBar) {
86             setContentView(R.layout.requests_bottom_appbar)
87         } else {
88             setContentView(R.layout.requests_top_appbar)
89         }
90
91         // Get a handle for the toolbar.
92         val toolbar = findViewById<Toolbar>(R.id.requests_toolbar)
93
94         // Set the support action bar.
95         setSupportActionBar(toolbar)
96
97         // Get a handle for the app bar.
98         val appBar = supportActionBar!!
99
100         // Set the app bar custom view.
101         appBar.setCustomView(R.layout.spinner)
102
103         // Display the back arrow in the app bar.
104         appBar.displayOptions = ActionBar.DISPLAY_SHOW_CUSTOM or ActionBar.DISPLAY_HOME_AS_UP
105
106         // Get handles for the views.
107         val appBarSpinner = findViewById<Spinner>(R.id.spinner)
108         requestsListView = findViewById(R.id.requests_listview)
109
110         // 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.
111         val allResourceRequests: MutableList<Array<String>> = ArrayList()
112         val defaultResourceRequests: MutableList<Array<String>> = ArrayList()
113         val allowedResourceRequests: MutableList<Array<String>> = ArrayList()
114         val thirdPartyResourceRequests: MutableList<Array<String>> = ArrayList()
115         val blockedResourceRequests: MutableList<Array<String>> = ArrayList()
116
117         // Populate the resource array lists.
118         for (request in resourceRequests!!) {
119             // Add the request to the list of all requests.
120             allResourceRequests.add(request)
121
122             when (request[BlocklistHelper.REQUEST_DISPOSITION]) {
123                 BlocklistHelper.REQUEST_DEFAULT -> {
124                     // Add the request to the list of default requests.
125                     defaultResourceRequests.add(request)
126                 }
127
128                 BlocklistHelper.REQUEST_ALLOWED -> {
129                     // Add the request to the list of allowed requests.
130                     allowedResourceRequests.add(request)
131                 }
132
133                 BlocklistHelper.REQUEST_THIRD_PARTY -> {
134                     // Add the request to the list of third-party requests.
135                     thirdPartyResourceRequests.add(request)
136                 }
137
138                 BlocklistHelper.REQUEST_BLOCKED -> {
139                     // Add the request to the list of blocked requests.
140                     blockedResourceRequests.add(request)
141                 }
142             }
143         }
144
145         // Setup a matrix cursor for the resource lists.
146         val spinnerCursor = MatrixCursor(arrayOf("_id", "Requests"))
147         spinnerCursor.addRow(arrayOf<Any>(0, getString(R.string.all) + " - " + allResourceRequests.size))
148         spinnerCursor.addRow(arrayOf<Any>(1, getString(R.string.default_label) + " - " + defaultResourceRequests.size))
149         spinnerCursor.addRow(arrayOf<Any>(2, getString(R.string.allowed_plural) + " - " + allowedResourceRequests.size))
150         if (blockAllThirdPartyRequests)
151             spinnerCursor.addRow(arrayOf<Any>(3, getString(R.string.third_party_plural) + " - " + thirdPartyResourceRequests.size))
152         spinnerCursor.addRow(arrayOf<Any>(4, getString(R.string.blocked_plural) + " - " + blockedResourceRequests.size))
153
154         // Create a resource cursor adapter for the spinner.
155         val spinnerCursorAdapter: ResourceCursorAdapter = object : ResourceCursorAdapter(this, R.layout.requests_appbar_spinner_item, spinnerCursor, 0) {
156             override fun bindView(view: View, context: Context, cursor: Cursor) {
157                 // Get a handle for the spinner item text view.
158                 val spinnerItemTextView = view.findViewById<TextView>(R.id.spinner_item_textview)
159
160                 // Set the text view to display the resource list.
161                 spinnerItemTextView.text = cursor.getString(1)
162             }
163         }
164
165         // Set the resource cursor adapter drop down view resource.
166         spinnerCursorAdapter.setDropDownViewResource(R.layout.requests_appbar_spinner_dropdown_item)
167
168         // Set the app bar spinner adapter.
169         appBarSpinner.adapter = spinnerCursorAdapter
170
171         // Get a handle for the context.
172         val context: Context = this
173
174         // Handle clicks on the spinner dropdown.
175         appBarSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
176             override fun onItemSelected(parent: AdapterView<*>?, view: View, position: Int, id: Long) {
177                 when (id.toInt()) {
178                     0 -> {
179                         // Get an adapter for all the requests.
180                         val allResourceRequestsArrayAdapter: ArrayAdapter<Array<String>> = RequestsArrayAdapter(context, allResourceRequests)
181
182                         // Display the adapter in the list view.
183                         requestsListView.adapter = allResourceRequestsArrayAdapter
184                     }
185
186                     1 -> {
187                         // Get an adapter for the default requests.
188                         val defaultResourceRequestsArrayAdapter: ArrayAdapter<Array<String>> = RequestsArrayAdapter(context, defaultResourceRequests)
189
190                         // Display the adapter in the list view.
191                         requestsListView.adapter = defaultResourceRequestsArrayAdapter
192                     }
193
194                     2 -> {
195                         // Get an adapter for the allowed requests.
196                         val allowedResourceRequestsArrayAdapter: ArrayAdapter<Array<String>> = RequestsArrayAdapter(context, allowedResourceRequests)
197
198                         // Display the adapter in the list view.
199                         requestsListView.adapter = allowedResourceRequestsArrayAdapter
200                     }
201
202                     3 -> {
203                         // Get an adapter for the third-party requests.
204                         val thirdPartyResourceRequestsArrayAdapter: ArrayAdapter<Array<String>> = RequestsArrayAdapter(context, thirdPartyResourceRequests)
205
206                         //Display the adapter in the list view.
207                         requestsListView.adapter = thirdPartyResourceRequestsArrayAdapter
208                     }
209
210                     4 -> {
211                         // Get an adapter for the blocked requests.
212                         val blockedResourceRequestsArrayAdapter: ArrayAdapter<Array<String>> = RequestsArrayAdapter(context, blockedResourceRequests)
213
214                         // Display the adapter in the list view.
215                         requestsListView.adapter = blockedResourceRequestsArrayAdapter
216                     }
217                 }
218             }
219
220             override fun onNothingSelected(parent: AdapterView<*>?) {
221                 // Do nothing.
222             }
223         }
224
225         // Create an array adapter with the list of the resource requests.
226         val resourceRequestsArrayAdapter: ArrayAdapter<Array<String>> = RequestsArrayAdapter(context, allResourceRequests)
227
228         // Populate the list view with the resource requests adapter.
229         requestsListView.adapter = resourceRequestsArrayAdapter
230
231         // Listen for taps on entries in the list view.
232         requestsListView.onItemClickListener = AdapterView.OnItemClickListener { _: AdapterView<*>?, _: View?, position: Int, _: Long ->
233             // Display the view request dialog.  The list view is 0 based, so the position must be incremented by 1.
234             launchViewRequestDialog(position + 1)
235         }
236
237         // Check to see if the activity has been restarted.
238         if (savedInstanceState != null) {
239             // Scroll to the saved position.
240             requestsListView.post { requestsListView.setSelection(savedInstanceState.getInt(LISTVIEW_POSITION)) }
241         }
242     }
243
244     public override fun onSaveInstanceState(savedInstanceState: Bundle) {
245         // Run the default commands.
246         super.onSaveInstanceState(savedInstanceState)
247
248         // Get the listview position.
249         val listViewPosition = requestsListView.firstVisiblePosition
250
251         // Store the listview position in the bundle.
252         savedInstanceState.putInt(LISTVIEW_POSITION, listViewPosition)
253     }
254
255     override fun onPrevious(currentId: Int) {
256         // Show the previous dialog.
257         launchViewRequestDialog(currentId - 1)
258     }
259
260     override fun onNext(currentId: Int) {
261         // Show the next dialog.
262         launchViewRequestDialog(currentId + 1)
263     }
264
265     private fun launchViewRequestDialog(id: Int) {
266         // Determine if this is the last request in the list.
267         val isLastRequest = (id == requestsListView.count)
268
269         // Get the string array for the selected resource request.  The resource requests list view is zero based.  There is no need to check to make sure each string is not null because
270         @Suppress("UNCHECKED_CAST") val selectedRequestStringArray = (requestsListView.getItemAtPosition(id - 1) as Array<String>)
271
272         // Create a view request dialog.
273         val viewRequestDialogFragment: DialogFragment = request(id, isLastRequest, selectedRequestStringArray)
274
275         // Make it so.
276         viewRequestDialogFragment.show(supportFragmentManager, getString(R.string.request_details))
277     }
278 }