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.blocking;
18 
19 import android.app.Activity;
20 import android.app.AlertDialog;
21 import android.app.Dialog;
22 import android.app.DialogFragment;
23 import android.content.Context;
24 import android.content.DialogInterface;
25 import android.os.Bundle;
26 import android.support.annotation.Nullable;
27 import android.view.View;
28 import android.widget.CheckBox;
29 import android.widget.CompoundButton;
30 import android.widget.TextView;
31 
32 /** Helper class for creating block/report dialog fragments. */
33 public 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 (dismisses 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, R.style.AlertDialogTheme)
44         .setCancelable(true)
45         .setNegativeButton(
46             android.R.string.cancel,
47             new DialogInterface.OnClickListener() {
48               @Override
49               public void onClick(DialogInterface dialog, int which) {
50                 fragment.dismiss();
51               }
52             });
53   }
54 
55   /**
56    * Creates a generic click listener which dismisses the fragment and then calls the actual
57    * listener.
58    */
59   private static DialogInterface.OnClickListener createGenericOnClickListener(
60       final DialogFragment fragment, final OnConfirmListener listener) {
61     return new DialogInterface.OnClickListener() {
62       @Override
63       public void onClick(DialogInterface dialog, int which) {
64         fragment.dismiss();
65         listener.onClick();
66       }
67     };
68   }
69 
70   private static String getBlockMessage(Context context) {
71     String message;
72     if (FilteredNumberCompat.useNewFiltering(context)) {
73       message = context.getString(R.string.block_number_confirmation_message_new_filtering);
74     } else {
75       message = context.getString(R.string.block_report_number_alert_details);
76     }
77     return message;
78   }
79 
80   /**
81    * Listener passed to block/report spam dialog for positive click in {@link
82    * BlockReportSpamDialogFragment}.
83    */
84   public interface OnSpamDialogClickListener {
85 
86     /**
87      * Called when user clicks on positive button in block/report spam dialog.
88      *
89      * @param isSpamChecked Whether the spam checkbox is checked.
90      */
91     void onClick(boolean isSpamChecked);
92   }
93 
94   /** Listener passed to all dialogs except the block/report spam dialog for positive click. */
95   public interface OnConfirmListener {
96 
97     /** Called when user clicks on positive button in the dialog. */
98     void onClick();
99   }
100 
101   /** Contains the common attributes between all block/unblock/report dialog fragments. */
102   private static class CommonDialogsFragment extends DialogFragment {
103 
104     /** The number to display in the dialog title. */
105     protected String mDisplayNumber;
106 
107     /** Called when dialog positive button is pressed. */
108     protected OnConfirmListener mPositiveListener;
109 
110     /** Called when dialog is dismissed. */
111     @Nullable protected DialogInterface.OnDismissListener mDismissListener;
112 
113     @Override
114     public void onDismiss(DialogInterface dialog) {
115       if (mDismissListener != null) {
116         mDismissListener.onDismiss(dialog);
117       }
118       super.onDismiss(dialog);
119     }
120 
121     @Override
122     public void onPause() {
123       // The dialog is dismissed onPause, i.e. rotation.
124       dismiss();
125       mDismissListener = null;
126       mPositiveListener = null;
127       mDisplayNumber = null;
128       super.onPause();
129     }
130   }
131 
132   /** Dialog for block/report spam with the mark as spam checkbox. */
133   public static class BlockReportSpamDialogFragment extends CommonDialogsFragment {
134 
135     /** Called when dialog positive button is pressed. */
136     private OnSpamDialogClickListener mPositiveListener;
137 
138     /** Whether the mark as spam checkbox is checked before displaying the dialog. */
139     private boolean mSpamChecked;
140 
141     public static DialogFragment newInstance(
142         String displayNumber,
143         boolean spamChecked,
144         OnSpamDialogClickListener positiveListener,
145         @Nullable DialogInterface.OnDismissListener dismissListener) {
146       BlockReportSpamDialogFragment fragment = new BlockReportSpamDialogFragment();
147       fragment.mSpamChecked = spamChecked;
148       fragment.mDisplayNumber = displayNumber;
149       fragment.mPositiveListener = positiveListener;
150       fragment.mDismissListener = dismissListener;
151       return fragment;
152     }
153 
154     @Override
155     public Dialog onCreateDialog(Bundle savedInstanceState) {
156       super.onCreateDialog(savedInstanceState);
157       View dialogView = View.inflate(getActivity(), R.layout.block_report_spam_dialog, null);
158       final CheckBox isSpamCheckbox =
159           (CheckBox) dialogView.findViewById(R.id.report_number_as_spam_action);
160       // Listen for changes on the checkbox and update if orientation changes
161       isSpamCheckbox.setChecked(mSpamChecked);
162       isSpamCheckbox.setOnCheckedChangeListener(
163           new CompoundButton.OnCheckedChangeListener() {
164             @Override
165             public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
166               mSpamChecked = isChecked;
167             }
168           });
169 
170       TextView details = (TextView) dialogView.findViewById(R.id.block_details);
171       details.setText(getBlockMessage(getContext()));
172 
173       AlertDialog.Builder alertDialogBuilder = createDialogBuilder(getActivity(), this);
174       Dialog dialog =
175           alertDialogBuilder
176               .setView(dialogView)
177               .setTitle(getString(R.string.block_report_number_alert_title, mDisplayNumber))
178               .setPositiveButton(
179                   R.string.block_number_ok,
180                   new DialogInterface.OnClickListener() {
181                     @Override
182                     public void onClick(DialogInterface dialog, int which) {
183                       dismiss();
184                       mPositiveListener.onClick(isSpamCheckbox.isChecked());
185                     }
186                   })
187               .create();
188       dialog.setCanceledOnTouchOutside(true);
189       return dialog;
190     }
191   }
192 
193   /** Dialog for blocking a number. */
194   public static class BlockDialogFragment extends CommonDialogsFragment {
195 
196     private boolean isSpamEnabled;
197 
198     public static DialogFragment newInstance(
199         String displayNumber,
200         boolean isSpamEnabled,
201         OnConfirmListener positiveListener,
202         @Nullable DialogInterface.OnDismissListener dismissListener) {
203       BlockDialogFragment fragment = new BlockDialogFragment();
204       fragment.mDisplayNumber = displayNumber;
205       fragment.mPositiveListener = positiveListener;
206       fragment.mDismissListener = dismissListener;
207       fragment.isSpamEnabled = isSpamEnabled;
208       return fragment;
209     }
210 
211     @Override
212     public Dialog onCreateDialog(Bundle savedInstanceState) {
213       super.onCreateDialog(savedInstanceState);
214       // Return the newly created dialog
215       AlertDialog.Builder alertDialogBuilder = createDialogBuilder(getActivity(), this);
216       Dialog dialog =
217           alertDialogBuilder
218               .setTitle(getString(R.string.block_number_confirmation_title, mDisplayNumber))
219               .setMessage(
220                   isSpamEnabled
221                       ? getString(
222                           R.string.block_number_alert_details, getBlockMessage(getContext()))
223                       : getString(R.string.block_report_number_alert_details))
224               .setPositiveButton(
225                   R.string.block_number_ok, createGenericOnClickListener(this, mPositiveListener))
226               .create();
227       dialog.setCanceledOnTouchOutside(true);
228       return dialog;
229     }
230   }
231 
232   /** Dialog for unblocking a number. */
233   public static class UnblockDialogFragment extends CommonDialogsFragment {
234 
235     /** Whether or not the number is spam. */
236     private boolean mIsSpam;
237 
238     public static DialogFragment newInstance(
239         String displayNumber,
240         boolean isSpam,
241         OnConfirmListener positiveListener,
242         @Nullable DialogInterface.OnDismissListener dismissListener) {
243       UnblockDialogFragment fragment = new UnblockDialogFragment();
244       fragment.mDisplayNumber = displayNumber;
245       fragment.mIsSpam = isSpam;
246       fragment.mPositiveListener = positiveListener;
247       fragment.mDismissListener = dismissListener;
248       return fragment;
249     }
250 
251     @Override
252     public Dialog onCreateDialog(Bundle savedInstanceState) {
253       super.onCreateDialog(savedInstanceState);
254       // Return the newly created dialog
255       AlertDialog.Builder alertDialogBuilder = createDialogBuilder(getActivity(), this);
256       if (mIsSpam) {
257         alertDialogBuilder
258             .setMessage(R.string.unblock_number_alert_details)
259             .setTitle(getString(R.string.unblock_report_number_alert_title, mDisplayNumber));
260       } else {
261         alertDialogBuilder.setMessage(
262             getString(R.string.unblock_report_number_alert_title, mDisplayNumber));
263       }
264       Dialog dialog =
265           alertDialogBuilder
266               .setPositiveButton(
267                   R.string.unblock_number_ok, createGenericOnClickListener(this, mPositiveListener))
268               .create();
269       dialog.setCanceledOnTouchOutside(true);
270       return dialog;
271     }
272   }
273 
274   /** Dialog for reporting a number as not spam. */
275   public static class ReportNotSpamDialogFragment extends CommonDialogsFragment {
276 
277     public static DialogFragment newInstance(
278         String displayNumber,
279         OnConfirmListener positiveListener,
280         @Nullable DialogInterface.OnDismissListener dismissListener) {
281       ReportNotSpamDialogFragment fragment = new ReportNotSpamDialogFragment();
282       fragment.mDisplayNumber = displayNumber;
283       fragment.mPositiveListener = positiveListener;
284       fragment.mDismissListener = dismissListener;
285       return fragment;
286     }
287 
288     @Override
289     public Dialog onCreateDialog(Bundle savedInstanceState) {
290       super.onCreateDialog(savedInstanceState);
291       // Return the newly created dialog
292       AlertDialog.Builder alertDialogBuilder = createDialogBuilder(getActivity(), this);
293       Dialog dialog =
294           alertDialogBuilder
295               .setTitle(R.string.report_not_spam_alert_title)
296               .setMessage(getString(R.string.report_not_spam_alert_details, mDisplayNumber))
297               .setPositiveButton(
298                   R.string.report_not_spam_alert_button,
299                   createGenericOnClickListener(this, mPositiveListener))
300               .create();
301       dialog.setCanceledOnTouchOutside(true);
302       return dialog;
303     }
304   }
305 }
306