2 * Copyright 2018-2022 Soren Stoutner <soren@stoutner.com>.
4 * This file is part of Privacy Browser Android <https://www.stoutner.com/privacy-browser-android>.
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.
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.
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/>.
20 package com.stoutner.privacybrowser.dialogs
22 import android.app.Dialog
23 import android.content.Context
24 import android.content.DialogInterface
25 import android.os.Bundle
26 import android.view.View
27 import android.view.WindowManager
28 import android.widget.TextView
30 import androidx.appcompat.app.AlertDialog
31 import androidx.core.content.ContextCompat.getColor
32 import androidx.fragment.app.DialogFragment
33 import androidx.preference.PreferenceManager
35 import com.stoutner.privacybrowser.R
36 import com.stoutner.privacybrowser.helpers.BlocklistHelper
38 // Define the class constants.
39 private const val ID = "id"
40 private const val IS_LAST_REQUEST = "is_last_request"
41 private const val REQUEST_DETAILS = "request_details"
43 class ViewRequestDialog : DialogFragment() {
44 // Define the class variables.
45 private lateinit var viewRequestListener: ViewRequestListener
47 // The public interface is used to send information back to the parent activity.
48 interface ViewRequestListener {
49 // Show the previous request.
50 fun onPrevious(currentId: Int)
52 // Show the next request.
53 fun onNext(currentId: Int)
56 override fun onAttach(context: Context) {
57 // Run the default commands.
58 super.onAttach(context)
60 // Get a handle for the listener from the launching context.
61 viewRequestListener = context as ViewRequestListener
65 // `@JvmStatic` will no longer be required once all the code has transitioned to Kotlin.
67 fun request(id: Int, isLastRequest: Boolean, requestDetails: Array<String>): ViewRequestDialog {
71 // Store the request details.
73 bundle.putBoolean(IS_LAST_REQUEST, isLastRequest)
74 bundle.putStringArray(REQUEST_DETAILS, requestDetails)
76 // Create a new instance of the view request dialog.
77 val viewRequestDialog = ViewRequestDialog()
79 // Add the arguments to the new dialog.
80 viewRequestDialog.arguments = bundle
82 // Return the new dialog.
83 return viewRequestDialog
87 override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
88 // Get the arguments from the bundle.
89 val id = requireArguments().getInt(ID)
90 val isLastRequest = requireArguments().getBoolean(IS_LAST_REQUEST)
91 val requestDetails = requireArguments().getStringArray(REQUEST_DETAILS)!!
93 // Use an alert dialog builder to create the alert dialog.
94 val dialogBuilder = AlertDialog.Builder(requireContext(), R.style.PrivacyBrowserAlertDialog)
97 dialogBuilder.setIcon(R.drawable.block_ads_enabled)
100 dialogBuilder.setTitle(resources.getString(R.string.request_details) + " - " + id)
103 dialogBuilder.setView(R.layout.view_request_dialog)
105 // Set the close button. Using `null` as the listener closes the dialog without doing anything else.
106 dialogBuilder.setNeutralButton(R.string.close, null)
108 // Set the previous button.
109 dialogBuilder.setNegativeButton(R.string.previous) { _: DialogInterface?, _: Int ->
110 // Load the previous request.
111 viewRequestListener.onPrevious(id)
114 // Set the next button.
115 dialogBuilder.setPositiveButton(R.string.next) { _: DialogInterface?, _: Int ->
116 // Load the next request.
117 viewRequestListener.onNext(id)
120 // Create an alert dialog from the alert dialog builder.
121 val alertDialog = dialogBuilder.create()
123 // Get a handle for the shared preferences.
124 val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
126 // Get the screenshot preference.
127 val allowScreenshots = sharedPreferences.getBoolean(getString(R.string.allow_screenshots_key), false)
129 // Disable screenshots if not allowed.
130 if (!allowScreenshots) {
131 // Disable screenshots.
132 alertDialog.window!!.addFlags(WindowManager.LayoutParams.FLAG_SECURE)
135 //The alert dialog must be shown before the contents can be modified.
138 // Get handles for the dialog views.
139 val requestDisposition = alertDialog.findViewById<TextView>(R.id.request_disposition)!!
140 val requestUrl = alertDialog.findViewById<TextView>(R.id.request_url)!!
141 val requestBlockListLabel = alertDialog.findViewById<TextView>(R.id.request_blocklist_label)!!
142 val requestBlockList = alertDialog.findViewById<TextView>(R.id.request_blocklist)!!
143 val requestSubListLabel = alertDialog.findViewById<TextView>(R.id.request_sublist_label)!!
144 val requestSubList = alertDialog.findViewById<TextView>(R.id.request_sublist)!!
145 val requestBlockListEntriesLabel = alertDialog.findViewById<TextView>(R.id.request_blocklist_entries_label)!!
146 val requestBlockListEntries = alertDialog.findViewById<TextView>(R.id.request_blocklist_entries)!!
147 val requestBlockListOriginalEntryLabel = alertDialog.findViewById<TextView>(R.id.request_blocklist_original_entry_label)!!
148 val requestBlockListOriginalEntry = alertDialog.findViewById<TextView>(R.id.request_blocklist_original_entry)!!
149 val previousButton = alertDialog.getButton(DialogInterface.BUTTON_NEGATIVE)
150 val nextButton = alertDialog.getButton(DialogInterface.BUTTON_POSITIVE)
152 // Disable the previous button if the first resource request is displayed.
153 previousButton.isEnabled = (id != 1)
155 // Disable the next button if the last resource request is displayed.
156 nextButton.isEnabled = !isLastRequest
158 // Set the request action text.
159 when (requestDetails[BlocklistHelper.REQUEST_DISPOSITION]) {
160 BlocklistHelper.REQUEST_DEFAULT -> {
162 requestDisposition.setText(R.string.default_allowed)
164 // Set the background color to be transparent.
165 requestDisposition.setBackgroundColor(getColor(requireContext(), R.color.transparent))
168 BlocklistHelper.REQUEST_ALLOWED -> {
170 requestDisposition.setText(R.string.allowed)
172 // Set the background color to be blue.
173 requestDisposition.setBackgroundColor(getColor(requireContext(), R.color.blue_background))
176 BlocklistHelper.REQUEST_THIRD_PARTY -> {
178 requestDisposition.setText(R.string.third_party_blocked)
180 // Set the background color to be yellow.
181 requestDisposition.setBackgroundColor(getColor(requireContext(), R.color.yellow_background))
183 BlocklistHelper.REQUEST_BLOCKED -> {
185 requestDisposition.setText(R.string.blocked)
187 // Set the background color to be red.
188 requestDisposition.setBackgroundColor(getColor(requireContext(), R.color.red_background))
192 // Display the request URL.
193 requestUrl.text = requestDetails[BlocklistHelper.REQUEST_URL]
195 // Modify the dialog based on the request action.
196 if (requestDetails.size == 2) { // A default request.
197 // Hide the unused views.
198 requestBlockListLabel.visibility = View.GONE
199 requestBlockList.visibility = View.GONE
200 requestSubListLabel.visibility = View.GONE
201 requestSubList.visibility = View.GONE
202 requestBlockListEntriesLabel.visibility = View.GONE
203 requestBlockListEntries.visibility = View.GONE
204 requestBlockListOriginalEntryLabel.visibility = View.GONE
205 requestBlockListOriginalEntry.visibility = View.GONE
206 } else { // A blocked or allowed request.
207 // Set the text on the text views.
208 requestBlockList.text = requestDetails[BlocklistHelper.REQUEST_BLOCKLIST]
209 requestBlockListEntries.text = requestDetails[BlocklistHelper.REQUEST_BLOCKLIST_ENTRIES]
210 requestBlockListOriginalEntry.text = requestDetails[BlocklistHelper.REQUEST_BLOCKLIST_ORIGINAL_ENTRY]
211 when (requestDetails[BlocklistHelper.REQUEST_SUBLIST]) {
212 BlocklistHelper.MAIN_WHITELIST -> requestSubList.setText(R.string.main_whitelist)
213 BlocklistHelper.FINAL_WHITELIST -> requestSubList.setText(R.string.final_whitelist)
214 BlocklistHelper.DOMAIN_WHITELIST -> requestSubList.setText(R.string.domain_whitelist)
215 BlocklistHelper.DOMAIN_INITIAL_WHITELIST -> requestSubList.setText(R.string.domain_initial_whitelist)
216 BlocklistHelper.DOMAIN_FINAL_WHITELIST -> requestSubList.setText(R.string.domain_final_whitelist)
217 BlocklistHelper.THIRD_PARTY_WHITELIST -> requestSubList.setText(R.string.third_party_whitelist)
218 BlocklistHelper.THIRD_PARTY_DOMAIN_WHITELIST -> requestSubList.setText(R.string.third_party_domain_whitelist)
219 BlocklistHelper.THIRD_PARTY_DOMAIN_INITIAL_WHITELIST -> requestSubList.setText(R.string.third_party_domain_initial_whitelist)
220 BlocklistHelper.MAIN_BLACKLIST -> requestSubList.setText(R.string.main_blacklist)
221 BlocklistHelper.INITIAL_BLACKLIST -> requestSubList.setText(R.string.initial_blacklist)
222 BlocklistHelper.FINAL_BLACKLIST -> requestSubList.setText(R.string.final_blacklist)
223 BlocklistHelper.DOMAIN_BLACKLIST -> requestSubList.setText(R.string.domain_blacklist)
224 BlocklistHelper.DOMAIN_INITIAL_BLACKLIST -> requestSubList.setText(R.string.domain_initial_blacklist)
225 BlocklistHelper.DOMAIN_FINAL_BLACKLIST -> requestSubList.setText(R.string.domain_final_blacklist)
226 BlocklistHelper.DOMAIN_REGULAR_EXPRESSION_BLACKLIST -> requestSubList.setText(R.string.domain_regular_expression_blacklist)
227 BlocklistHelper.THIRD_PARTY_BLACKLIST -> requestSubList.setText(R.string.third_party_blacklist)
228 BlocklistHelper.THIRD_PARTY_INITIAL_BLACKLIST -> requestSubList.setText(R.string.third_party_initial_blacklist)
229 BlocklistHelper.THIRD_PARTY_DOMAIN_BLACKLIST -> requestSubList.setText(R.string.third_party_domain_blacklist)
230 BlocklistHelper.THIRD_PARTY_DOMAIN_INITIAL_BLACKLIST -> requestSubList.setText(R.string.third_party_domain_initial_blacklist)
231 BlocklistHelper.THIRD_PARTY_REGULAR_EXPRESSION_BLACKLIST -> requestSubList.setText(R.string.third_party_regular_expression_blacklist)
232 BlocklistHelper.THIRD_PARTY_DOMAIN_REGULAR_EXPRESSION_BLACKLIST -> requestSubList.setText(R.string.third_party_domain_regular_expression_blacklist)
233 BlocklistHelper.REGULAR_EXPRESSION_BLACKLIST -> requestSubList.setText(R.string.regular_expression_blacklist)
237 // Return the alert dialog.