2 * Copyright © 2018-2019 Soren Stoutner <soren@stoutner.com>.
4 * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
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.
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.
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/>.
20 package com.stoutner.privacybrowser.dialogs;
22 import android.annotation.SuppressLint;
23 import android.app.AlertDialog;
24 import android.app.Dialog;
25 import android.content.Context;
26 import android.content.DialogInterface;
27 import android.content.SharedPreferences;
28 import android.os.Bundle;
29 import android.preference.PreferenceManager;
30 import android.view.View;
31 import android.view.WindowManager;
32 import android.widget.Button;
33 import android.widget.TextView;
35 import androidx.annotation.NonNull;
36 import androidx.fragment.app.DialogFragment;
38 import com.stoutner.privacybrowser.R;
39 import com.stoutner.privacybrowser.helpers.BlocklistHelper;
41 public class ViewRequestDialog extends DialogFragment {
42 // The public interface is used to send information back to the parent activity.
43 public interface ViewRequestListener {
44 void onPrevious(int id);
49 // `viewRequestListener` is used in `onAttach()` and `onCreateDialog()`.
50 private ViewRequestListener viewRequestListener;
52 public void onAttach(Context context) {
53 // Run the default commands.
54 super.onAttach(context);
56 // Get a handle for the listener from the launching context.
57 viewRequestListener = (ViewRequestListener) context;
60 public static ViewRequestDialog request(int id, boolean isLastRequest, String[] requestDetails) {
62 Bundle bundle = new Bundle();
64 // Store the request details.
65 bundle.putInt("id", id);
66 bundle.putBoolean("is_last_request", isLastRequest);
67 bundle.putStringArray("request_details", requestDetails);
69 // Add the bundle to the dialog.
70 ViewRequestDialog viewRequestDialog = new ViewRequestDialog();
71 viewRequestDialog.setArguments(bundle);
73 // Return the new dialog.
74 return viewRequestDialog;
79 // `@SuppressLing("InflateParams")` removes the warning about using `null` as the parent view group when inflating the `AlertDialog`.
80 @SuppressLint("InflateParams")
81 public Dialog onCreateDialog(Bundle savedInstanceState) {
82 // Get a handle for the shared preferences.
83 SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getContext());
85 // Get the theme and screenshot preferences.
86 boolean darkTheme = sharedPreferences.getBoolean("dark_theme", false);
87 boolean allowScreenshots = sharedPreferences.getBoolean("allow_screenshots", false);
89 // Remove the incorrect lint warning that `getInt()` might be null.
90 assert getArguments() != null;
92 // Get the info from the bundle.
93 int id = getArguments().getInt("id");
94 boolean isLastRequest = getArguments().getBoolean("is_last_request");
95 String[] requestDetails = getArguments().getStringArray("request_details");
97 // Use an alert dialog builder to create the alert dialog.
98 AlertDialog.Builder dialogBuilder;
100 // Set the style and icon according to the theme.
102 dialogBuilder = new AlertDialog.Builder(getActivity(), R.style.PrivacyBrowserAlertDialogDark);
103 dialogBuilder.setIcon(R.drawable.block_ads_enabled_dark);
105 dialogBuilder = new AlertDialog.Builder(getActivity(), R.style.PrivacyBrowserAlertDialogLight);
106 dialogBuilder.setIcon(R.drawable.block_ads_enabled_light);
109 // Create the dialog title.
110 String title = getResources().getString(R.string.request_details) + " - " + id;
113 dialogBuilder.setTitle(title);
115 // Remove the incorrect lint warnings about items being null.
116 assert requestDetails != null;
117 assert getActivity() != null;
119 // Set the view. The parent view is null because it will be assigned by the alert dialog.
120 dialogBuilder.setView(getActivity().getLayoutInflater().inflate(R.layout.view_request_dialog, null));
122 // Set the close button.
123 dialogBuilder.setNeutralButton(R.string.close, (DialogInterface dialog, int which) -> {
124 // Do nothing. The dialog will close automatically.
127 // Set the previous button.
128 dialogBuilder.setNegativeButton(R.string.previous, (DialogInterface dialog, int which) -> {
129 // Load the previous request.
130 viewRequestListener.onPrevious(id);
133 // Set the next button.
134 dialogBuilder.setPositiveButton(R.string.next, (DialogInterface dialog, int which) -> {
135 // Load the next request.
136 viewRequestListener.onNext(id);
139 // Create an alert dialog from the alert dialog builder.
140 final AlertDialog alertDialog = dialogBuilder.create();
142 // Disable screenshots if not allowed.
143 if (!allowScreenshots) {
144 // Remove the warning below that `getWindow()` might be null.
145 assert alertDialog.getWindow() != null;
147 // Disable screenshots.
148 alertDialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
151 //The alert dialog must be shown before the contents can be modified.
154 // Get handles for the dialog views.
155 TextView requestDisposition = alertDialog.findViewById(R.id.request_disposition);
156 TextView requestUrl = alertDialog.findViewById(R.id.request_url);
157 TextView requestBlockListLabel = alertDialog.findViewById(R.id.request_blocklist_label);
158 TextView requestBlockList = alertDialog.findViewById(R.id.request_blocklist);
159 TextView requestSubListLabel = alertDialog.findViewById(R.id.request_sublist_label);
160 TextView requestSubList = alertDialog.findViewById(R.id.request_sublist);
161 TextView requestBlockListEntriesLabel = alertDialog.findViewById(R.id.request_blocklist_entries_label);
162 TextView requestBlockListEntries = alertDialog.findViewById(R.id.request_blocklist_entries);
163 TextView requestBlockListOriginalEntryLabel = alertDialog.findViewById(R.id.request_blocklist_original_entry_label);
164 TextView requestBlockListOriginalEntry = alertDialog.findViewById(R.id.request_blocklist_original_entry);
165 Button previousButton = alertDialog.getButton(DialogInterface.BUTTON_NEGATIVE);
166 Button nextButton = alertDialog.getButton(DialogInterface.BUTTON_POSITIVE);
168 // Disable the previous button if the first resource request is displayed.
169 previousButton.setEnabled(!(id == 1));
171 // Disable the next button if the last resource request is displayed.
172 nextButton.setEnabled(!isLastRequest);
174 // Set the request action text.
175 switch (requestDetails[BlocklistHelper.REQUEST_DISPOSITION]) {
176 case BlocklistHelper.REQUEST_DEFAULT:
178 requestDisposition.setText(R.string.default_allowed);
180 // Set the background color.
181 requestDisposition.setBackgroundColor(getResources().getColor(R.color.transparent));
184 case BlocklistHelper.REQUEST_ALLOWED:
186 requestDisposition.setText(R.string.allowed);
188 // Set the background color.
190 requestDisposition.setBackgroundColor(getResources().getColor(R.color.blue_700_50));
192 requestDisposition.setBackgroundColor(getResources().getColor(R.color.blue_100));
196 case BlocklistHelper.REQUEST_THIRD_PARTY:
198 requestDisposition.setText(R.string.third_party_blocked);
200 // Set the background color.
202 requestDisposition.setBackgroundColor(getResources().getColor(R.color.yellow_700_50));
204 requestDisposition.setBackgroundColor(getResources().getColor(R.color.yellow_100));
208 case BlocklistHelper.REQUEST_BLOCKED:
210 requestDisposition.setText(R.string.blocked);
212 // Set the background color.
214 requestDisposition.setBackgroundColor(getResources().getColor(R.color.red_700_40));
216 requestDisposition.setBackgroundColor(getResources().getColor(R.color.red_100));
221 // Display the request URL.
222 requestUrl.setText(requestDetails[BlocklistHelper.REQUEST_URL]);
224 // Modify the dialog based on the request action.
225 if (requestDetails.length == 2) { // A default request.
226 // Hide the unused views.
227 requestBlockListLabel.setVisibility(View.GONE);
228 requestBlockList.setVisibility(View.GONE);
229 requestSubListLabel.setVisibility(View.GONE);
230 requestSubList.setVisibility(View.GONE);
231 requestBlockListEntriesLabel.setVisibility(View.GONE);
232 requestBlockListEntries.setVisibility(View.GONE);
233 requestBlockListOriginalEntryLabel.setVisibility(View.GONE);
234 requestBlockListOriginalEntry.setVisibility(View.GONE);
235 } else { // A blocked or allowed request.
236 // Set the text on the text views.
237 requestBlockList.setText(requestDetails[BlocklistHelper.REQUEST_BLOCKLIST]);
238 requestBlockListEntries.setText(requestDetails[BlocklistHelper.REQUEST_BLOCKLIST_ENTRIES]);
239 requestBlockListOriginalEntry.setText(requestDetails[BlocklistHelper.REQUEST_BLOCKLIST_ORIGINAL_ENTRY]);
241 // Set the sublist text.
242 switch (requestDetails[BlocklistHelper.REQUEST_SUBLIST]) {
243 case BlocklistHelper.MAIN_WHITELIST:
244 requestSubList.setText(R.string.main_whitelist);
247 case BlocklistHelper.FINAL_WHITELIST:
248 requestSubList.setText(R.string.final_whitelist);
251 case BlocklistHelper.DOMAIN_WHITELIST:
252 requestSubList.setText(R.string.domain_whitelist);
255 case BlocklistHelper.DOMAIN_INITIAL_WHITELIST:
256 requestSubList.setText(R.string.domain_initial_whitelist);
259 case BlocklistHelper.DOMAIN_FINAL_WHITELIST:
260 requestSubList.setText(R.string.domain_final_whitelist);
263 case BlocklistHelper.THIRD_PARTY_WHITELIST:
264 requestSubList.setText(R.string.third_party_whitelist);
267 case BlocklistHelper.THIRD_PARTY_DOMAIN_WHITELIST:
268 requestSubList.setText(R.string.third_party_domain_whitelist);
271 case BlocklistHelper.THIRD_PARTY_DOMAIN_INITIAL_WHITELIST:
272 requestSubList.setText(R.string.third_party_domain_initial_whitelist);
275 case BlocklistHelper.MAIN_BLACKLIST:
276 requestSubList.setText(R.string.main_blacklist);
279 case BlocklistHelper.INITIAL_BLACKLIST:
280 requestSubList.setText(R.string.initial_blacklist);
283 case BlocklistHelper.FINAL_BLACKLIST:
284 requestSubList.setText(R.string.final_blacklist);
287 case BlocklistHelper.DOMAIN_BLACKLIST:
288 requestSubList.setText(R.string.domain_blacklist);
291 case BlocklistHelper.DOMAIN_INITIAL_BLACKLIST:
292 requestSubList.setText(R.string.domain_initial_blacklist);
295 case BlocklistHelper.DOMAIN_FINAL_BLACKLIST:
296 requestSubList.setText(R.string.domain_final_blacklist);
299 case BlocklistHelper.DOMAIN_REGULAR_EXPRESSION_BLACKLIST:
300 requestSubList.setText(R.string.domain_regular_expression_blacklist);
303 case BlocklistHelper.THIRD_PARTY_BLACKLIST:
304 requestSubList.setText(R.string.third_party_blacklist);
307 case BlocklistHelper.THIRD_PARTY_INITIAL_BLACKLIST:
308 requestSubList.setText(R.string.third_party_initial_blacklist);
311 case BlocklistHelper.THIRD_PARTY_DOMAIN_BLACKLIST:
312 requestSubList.setText(R.string.third_party_domain_blacklist);
315 case BlocklistHelper.THIRD_PARTY_DOMAIN_INITIAL_BLACKLIST:
316 requestSubList.setText(R.string.third_party_domain_initial_blacklist);
319 case BlocklistHelper.THIRD_PARTY_REGULAR_EXPRESSION_BLACKLIST:
320 requestSubList.setText(R.string.third_party_regular_expression_blacklist);
323 case BlocklistHelper.THIRD_PARTY_DOMAIN_REGULAR_EXPRESSION_BLACKLIST:
324 requestSubList.setText(R.string.third_party_domain_regular_expression_blacklist);
327 case BlocklistHelper.REGULAR_EXPRESSION_BLACKLIST:
328 requestSubList.setText(R.string.regular_expression_blacklist);
333 // `onCreateDialog` requires the return of an alert dialog.