• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.dialer.blockreportspam;
18 
19 import android.app.Activity;
20 import android.app.Dialog;
21 import android.content.Context;
22 import android.content.DialogInterface;
23 import android.os.Bundle;
24 import android.support.annotation.Nullable;
25 import android.support.v4.app.DialogFragment;
26 import android.support.v7.app.AlertDialog;
27 import android.view.View;
28 import android.widget.CheckBox;
29 import android.widget.TextView;
30 import com.android.dialer.blocking.FilteredNumberCompat;
31 
32 /** Creates dialog fragments to block a number and/or report it as spam/not spam. */
33 public final class BlockReportSpamDialogs {
34 
35   public static final String BLOCK_REPORT_SPAM_DIALOG_TAG = "BlockReportSpamDialog";
36   public static final String BLOCK_DIALOG_TAG = "BlockDialog";
37   public static final String UNBLOCK_DIALOG_TAG = "UnblockDialog";
38   public static final String NOT_SPAM_DIALOG_TAG = "NotSpamDialog";
39 
40   /** Creates a dialog with the default cancel button listener (which dismisses the dialog). */
createDialogBuilder( Activity activity, final DialogFragment fragment)41   private static AlertDialog.Builder createDialogBuilder(
42       Activity activity, final DialogFragment fragment) {
43     return new AlertDialog.Builder(activity)
44         .setCancelable(true)
45         .setNegativeButton(android.R.string.cancel, (dialog, which) -> fragment.dismiss());
46   }
47 
48   /**
49    * Creates a generic click listener which dismisses the fragment and then calls the actual
50    * listener.
51    */
createGenericOnClickListener( final DialogFragment fragment, final OnConfirmListener listener)52   private static DialogInterface.OnClickListener createGenericOnClickListener(
53       final DialogFragment fragment, final OnConfirmListener listener) {
54     return (dialog, which) -> {
55       fragment.dismiss();
56       listener.onClick();
57     };
58   }
59 
getBlockMessage(Context context)60   private static String getBlockMessage(Context context) {
61     String message;
62     if (FilteredNumberCompat.useNewFiltering(context)) {
63       message = context.getString(R.string.block_number_confirmation_message_new_filtering);
64     } else {
65       message = context.getString(R.string.block_report_number_alert_details);
66     }
67     return message;
68   }
69 
70   /**
71    * Positive listener for the "Block/Report spam" dialog {@link
72    * DialogFragmentForBlockingNumberAndOptionallyReportingAsSpam}.
73    */
74   public interface OnSpamDialogClickListener {
75 
76     /**
77      * Called when the user clicks on the positive button of the "Block/Report spam" dialog.
78      *
79      * @param isSpamChecked Whether the spam checkbox is checked.
80      */
onClick(boolean isSpamChecked)81     void onClick(boolean isSpamChecked);
82   }
83 
84   /** Positive listener for dialogs other than the "Block/Report spam" dialog. */
85   public interface OnConfirmListener {
86 
87     /** Called when the user clicks on the positive button of the dialog. */
onClick()88     void onClick();
89   }
90 
91   /** Contains common attributes shared among all dialog fragments. */
92   private abstract static class CommonDialogsFragment extends DialogFragment {
93 
94     /** The number to display in the dialog title. */
95     protected String displayNumber;
96 
97     /** Listener for the positive button. */
98     protected OnConfirmListener positiveListener;
99 
100     /** Listener for when the dialog is dismissed. */
101     @Nullable protected DialogInterface.OnDismissListener dismissListener;
102 
103     @Override
onDismiss(DialogInterface dialog)104     public void onDismiss(DialogInterface dialog) {
105       if (dismissListener != null) {
106         dismissListener.onDismiss(dialog);
107       }
108       super.onDismiss(dialog);
109     }
110 
111     @Override
onPause()112     public void onPause() {
113       // The dialog is dismissed onPause, i.e. rotation.
114       dismiss();
115       dismissListener = null;
116       positiveListener = null;
117       displayNumber = null;
118       super.onPause();
119     }
120   }
121 
122   /**
123    * Dialog for blocking a number and optionally reporting it as spam.
124    *
125    * <p>This dialog is for a number that is neither blocked nor marked as spam. It has a checkbox
126    * that allows the user to report a number as spam when they block it.
127    */
128   public static class DialogFragmentForBlockingNumberAndOptionallyReportingAsSpam
129       extends CommonDialogsFragment {
130 
131     /** Called when dialog positive button is pressed. */
132     private OnSpamDialogClickListener onSpamDialogClickListener;
133 
134     /** Whether the mark as spam checkbox is checked before displaying the dialog. */
135     private boolean spamChecked;
136 
newInstance( String displayNumber, boolean spamChecked, OnSpamDialogClickListener onSpamDialogClickListener, @Nullable DialogInterface.OnDismissListener dismissListener)137     public static DialogFragment newInstance(
138         String displayNumber,
139         boolean spamChecked,
140         OnSpamDialogClickListener onSpamDialogClickListener,
141         @Nullable DialogInterface.OnDismissListener dismissListener) {
142       DialogFragmentForBlockingNumberAndOptionallyReportingAsSpam fragment =
143           new DialogFragmentForBlockingNumberAndOptionallyReportingAsSpam();
144       fragment.spamChecked = spamChecked;
145       fragment.displayNumber = displayNumber;
146       fragment.onSpamDialogClickListener = onSpamDialogClickListener;
147       fragment.dismissListener = dismissListener;
148       return fragment;
149     }
150 
151     @Override
onCreateDialog(Bundle savedInstanceState)152     public Dialog onCreateDialog(Bundle savedInstanceState) {
153       super.onCreateDialog(savedInstanceState);
154       View dialogView = View.inflate(getActivity(), R.layout.block_report_spam_dialog, null);
155       final CheckBox isSpamCheckbox =
156           (CheckBox) dialogView.findViewById(R.id.report_number_as_spam_action);
157       // Listen for changes on the checkbox and update if orientation changes
158       isSpamCheckbox.setChecked(spamChecked);
159       isSpamCheckbox.setOnCheckedChangeListener((buttonView, isChecked) -> spamChecked = isChecked);
160 
161       TextView details = (TextView) dialogView.findViewById(R.id.block_details);
162       details.setText(getBlockMessage(getContext()));
163 
164       AlertDialog.Builder alertDialogBuilder = createDialogBuilder(getActivity(), this);
165       Dialog blockReportSpamDialog =
166           alertDialogBuilder
167               .setView(dialogView)
168               .setTitle(getString(R.string.block_report_number_alert_title, displayNumber))
169               .setPositiveButton(
170                   R.string.block_number_ok,
171                   (dialog, which) -> {
172                     dismiss();
173                     onSpamDialogClickListener.onClick(isSpamCheckbox.isChecked());
174                   })
175               .create();
176       blockReportSpamDialog.setCanceledOnTouchOutside(true);
177       return blockReportSpamDialog;
178     }
179   }
180 
181   /**
182    * Dialog for blocking a number and reporting it as spam.
183    *
184    * <p>This dialog is for the migration of blocked numbers. Its positive action should block a
185    * number, and also marks it as spam if the spam feature is enabled.
186    */
187   public static class DialogFragmentForBlockingNumberAndReportingAsSpam
188       extends CommonDialogsFragment {
189 
190     private boolean isSpamEnabled;
191 
newInstance( String displayNumber, boolean isSpamEnabled, OnConfirmListener positiveListener, @Nullable DialogInterface.OnDismissListener dismissListener)192     public static DialogFragment newInstance(
193         String displayNumber,
194         boolean isSpamEnabled,
195         OnConfirmListener positiveListener,
196         @Nullable DialogInterface.OnDismissListener dismissListener) {
197       DialogFragmentForBlockingNumberAndReportingAsSpam fragment =
198           new DialogFragmentForBlockingNumberAndReportingAsSpam();
199       fragment.displayNumber = displayNumber;
200       fragment.positiveListener = positiveListener;
201       fragment.dismissListener = dismissListener;
202       fragment.isSpamEnabled = isSpamEnabled;
203       return fragment;
204     }
205 
206     @Override
onCreateDialog(Bundle savedInstanceState)207     public Dialog onCreateDialog(Bundle savedInstanceState) {
208       super.onCreateDialog(savedInstanceState);
209       // Return the newly created dialog
210       AlertDialog.Builder alertDialogBuilder = createDialogBuilder(getActivity(), this);
211       Dialog dialog =
212           alertDialogBuilder
213               .setTitle(getString(R.string.block_number_confirmation_title, displayNumber))
214               .setMessage(
215                   isSpamEnabled
216                       ? getString(
217                           R.string.block_number_alert_details, getBlockMessage(getContext()))
218                       : getString(R.string.block_report_number_alert_details))
219               .setPositiveButton(
220                   R.string.block_number_ok, createGenericOnClickListener(this, positiveListener))
221               .create();
222       dialog.setCanceledOnTouchOutside(true);
223       return dialog;
224     }
225   }
226 
227   /**
228    * Dialog for blocking a number.
229    *
230    * <p>This dialog is for a spam number that hasn't been blocked. For example, if the user receives
231    * a spam call, this dialog will be shown if they would like to block the number.
232    */
233   public static class DialogFragmentForBlockingNumber extends CommonDialogsFragment {
234 
newInstance( String displayNumber, OnConfirmListener positiveListener, @Nullable DialogInterface.OnDismissListener dismissListener)235     public static DialogFragment newInstance(
236         String displayNumber,
237         OnConfirmListener positiveListener,
238         @Nullable DialogInterface.OnDismissListener dismissListener) {
239       DialogFragmentForBlockingNumberAndReportingAsSpam fragment =
240           new DialogFragmentForBlockingNumberAndReportingAsSpam();
241       fragment.displayNumber = displayNumber;
242       fragment.positiveListener = positiveListener;
243       fragment.dismissListener = dismissListener;
244       return fragment;
245     }
246 
247     @Override
onCreateDialog(Bundle savedInstanceState)248     public Dialog onCreateDialog(Bundle savedInstanceState) {
249       super.onCreateDialog(savedInstanceState);
250       // Return the newly created dialog
251       AlertDialog.Builder alertDialogBuilder = createDialogBuilder(getActivity(), this);
252       Dialog dialog =
253           alertDialogBuilder
254               .setTitle(getString(R.string.block_number_confirmation_title, displayNumber))
255               .setMessage(getString(R.string.block_report_number_alert_details))
256               .setPositiveButton(
257                   R.string.block_number_ok, createGenericOnClickListener(this, positiveListener))
258               .create();
259       dialog.setCanceledOnTouchOutside(true);
260       return dialog;
261     }
262   }
263 
264   /**
265    * Dialog for unblocking a number and marking it as not spam.
266    *
267    * <p>This dialog is used in the old call log, where unblocking a number will also mark it as not
268    * spam.
269    */
270   public static class DialogFragmentForUnblockingNumberAndReportingAsNotSpam
271       extends CommonDialogsFragment {
272 
273     /** Whether or not the number is spam. */
274     private boolean isSpam;
275 
newInstance( String displayNumber, boolean isSpam, OnConfirmListener positiveListener, @Nullable DialogInterface.OnDismissListener dismissListener)276     public static DialogFragment newInstance(
277         String displayNumber,
278         boolean isSpam,
279         OnConfirmListener positiveListener,
280         @Nullable DialogInterface.OnDismissListener dismissListener) {
281       DialogFragmentForUnblockingNumberAndReportingAsNotSpam fragment =
282           new DialogFragmentForUnblockingNumberAndReportingAsNotSpam();
283       fragment.displayNumber = displayNumber;
284       fragment.isSpam = isSpam;
285       fragment.positiveListener = positiveListener;
286       fragment.dismissListener = dismissListener;
287       return fragment;
288     }
289 
290     @Override
onCreateDialog(Bundle savedInstanceState)291     public Dialog onCreateDialog(Bundle savedInstanceState) {
292       super.onCreateDialog(savedInstanceState);
293       // Return the newly created dialog
294       AlertDialog.Builder alertDialogBuilder = createDialogBuilder(getActivity(), this);
295       if (isSpam) {
296         alertDialogBuilder
297             .setMessage(R.string.unblock_number_alert_details)
298             .setTitle(getString(R.string.unblock_report_number_alert_title, displayNumber));
299       } else {
300         alertDialogBuilder.setMessage(
301             getString(R.string.unblock_report_number_alert_title, displayNumber));
302       }
303       Dialog dialog =
304           alertDialogBuilder
305               .setPositiveButton(
306                   R.string.unblock_number_ok, createGenericOnClickListener(this, positiveListener))
307               .create();
308       dialog.setCanceledOnTouchOutside(true);
309       return dialog;
310     }
311   }
312 
313   /**
314    * Dialog for unblocking a number.
315    *
316    * <p>This dialog is used in the new call log, where unblocking a number will *not* mark it as not
317    * spam.
318    */
319   public static class DialogFragmentForUnblockingNumber extends CommonDialogsFragment {
320 
newInstance( String displayNumber, OnConfirmListener positiveListener, @Nullable DialogInterface.OnDismissListener dismissListener)321     public static DialogFragment newInstance(
322         String displayNumber,
323         OnConfirmListener positiveListener,
324         @Nullable DialogInterface.OnDismissListener dismissListener) {
325       DialogFragmentForUnblockingNumberAndReportingAsNotSpam fragment =
326           new DialogFragmentForUnblockingNumberAndReportingAsNotSpam();
327       fragment.displayNumber = displayNumber;
328       fragment.positiveListener = positiveListener;
329       fragment.dismissListener = dismissListener;
330       return fragment;
331     }
332 
333     @Override
onCreateDialog(Bundle savedInstanceState)334     public Dialog onCreateDialog(Bundle savedInstanceState) {
335       super.onCreateDialog(savedInstanceState);
336       // Return the newly created dialog
337       AlertDialog.Builder alertDialogBuilder = createDialogBuilder(getActivity(), this);
338       alertDialogBuilder.setMessage(
339           getString(R.string.unblock_report_number_alert_title, displayNumber));
340       Dialog dialog =
341           alertDialogBuilder
342               .setPositiveButton(
343                   R.string.unblock_number_ok, createGenericOnClickListener(this, positiveListener))
344               .create();
345       dialog.setCanceledOnTouchOutside(true);
346       return dialog;
347     }
348   }
349 
350   /** Dialog for reporting a number as not spam. */
351   public static class DialogFragmentForReportingNotSpam extends CommonDialogsFragment {
352 
newInstance( String displayNumber, OnConfirmListener positiveListener, @Nullable DialogInterface.OnDismissListener dismissListener)353     public static DialogFragment newInstance(
354         String displayNumber,
355         OnConfirmListener positiveListener,
356         @Nullable DialogInterface.OnDismissListener dismissListener) {
357       DialogFragmentForReportingNotSpam fragment = new DialogFragmentForReportingNotSpam();
358       fragment.displayNumber = displayNumber;
359       fragment.positiveListener = positiveListener;
360       fragment.dismissListener = dismissListener;
361       return fragment;
362     }
363 
364     @Override
onCreateDialog(Bundle savedInstanceState)365     public Dialog onCreateDialog(Bundle savedInstanceState) {
366       super.onCreateDialog(savedInstanceState);
367       // Return the newly created dialog
368       AlertDialog.Builder alertDialogBuilder = createDialogBuilder(getActivity(), this);
369       Dialog dialog =
370           alertDialogBuilder
371               .setTitle(R.string.report_not_spam_alert_title)
372               .setMessage(getString(R.string.report_not_spam_alert_details, displayNumber))
373               .setPositiveButton(
374                   R.string.report_not_spam_alert_button,
375                   createGenericOnClickListener(this, positiveListener))
376               .create();
377       dialog.setCanceledOnTouchOutside(true);
378       return dialog;
379     }
380   }
381 }
382