• 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.incallui.spam;
18 
19 import android.app.Dialog;
20 import android.app.DialogFragment;
21 import android.content.Context;
22 import android.content.DialogInterface;
23 import android.content.Intent;
24 import android.os.Bundle;
25 import android.provider.CallLog;
26 import android.provider.ContactsContract;
27 import android.support.annotation.Nullable;
28 import android.support.v4.app.FragmentActivity;
29 import android.support.v7.app.AlertDialog;
30 import android.telephony.PhoneNumberUtils;
31 import com.android.dialer.blocking.BlockedNumbersMigrator;
32 import com.android.dialer.blocking.FilteredNumberAsyncQueryHandler;
33 import com.android.dialer.blocking.FilteredNumberCompat;
34 import com.android.dialer.blockreportspam.BlockReportSpamDialogs;
35 import com.android.dialer.blockreportspam.BlockReportSpamDialogs.DialogFragmentForBlockingNumberAndOptionallyReportingAsSpam;
36 import com.android.dialer.blockreportspam.BlockReportSpamDialogs.DialogFragmentForReportingNotSpam;
37 import com.android.dialer.common.LogUtil;
38 import com.android.dialer.location.GeoUtil;
39 import com.android.dialer.logging.ContactLookupResult;
40 import com.android.dialer.logging.DialerImpression;
41 import com.android.dialer.logging.Logger;
42 import com.android.dialer.logging.ReportingLocation;
43 import com.android.dialer.notification.DialerNotificationManager;
44 import com.android.dialer.phonenumberutil.PhoneNumberHelper;
45 import com.android.dialer.spam.SpamComponent;
46 import com.android.dialer.spam.SpamSettings;
47 import com.android.dialer.spam.promo.SpamBlockingPromoHelper;
48 import com.android.incallui.call.DialerCall;
49 
50 /** Creates the after call notification dialogs. */
51 public class SpamNotificationActivity extends FragmentActivity {
52 
53   /** Action to add number to contacts. */
54   static final String ACTION_ADD_TO_CONTACTS = "com.android.incallui.spam.ACTION_ADD_TO_CONTACTS";
55   /** Action to show dialog. */
56   static final String ACTION_SHOW_DIALOG = "com.android.incallui.spam.ACTION_SHOW_DIALOG";
57   /** Action to mark a number as spam. */
58   static final String ACTION_MARK_NUMBER_AS_SPAM =
59       "com.android.incallui.spam.ACTION_MARK_NUMBER_AS_SPAM";
60   /** Action to mark a number as not spam. */
61   static final String ACTION_MARK_NUMBER_AS_NOT_SPAM =
62       "com.android.incallui.spam.ACTION_MARK_NUMBER_AS_NOT_SPAM";
63 
64   static final String ACTION_ENABLE_SPAM_BLOCKING =
65       "com.android.incallui.spam.ACTION_ENABLE_SPAM_BLOCKING";
66 
67   static final String ACTION_SHOW_SPAM_BLOCKING_PROMO_DIALOG =
68       "com.android.incallui.spam.ACTION_SHOW_SPAM_BLOCKING_PROMO_DIALOG";
69 
70   private static final String TAG = "SpamNotifications";
71   private static final String EXTRA_NOTIFICATION_TAG = "notification_tag";
72   private static final String EXTRA_NOTIFICATION_ID = "notification_id";
73   private static final String EXTRA_CALL_INFO = "call_info";
74 
75   private static final String CALL_INFO_KEY_PHONE_NUMBER = "phone_number";
76   private static final String CALL_INFO_KEY_IS_SPAM = "is_spam";
77   private static final String CALL_INFO_KEY_CALL_ID = "call_id";
78   private static final String CALL_INFO_KEY_START_TIME_MILLIS = "call_start_time_millis";
79   private static final String CALL_INFO_CONTACT_LOOKUP_RESULT_TYPE = "contact_lookup_result_type";
80   private final DialogInterface.OnDismissListener dismissListener =
81       new DialogInterface.OnDismissListener() {
82         @Override
83         public void onDismiss(DialogInterface dialog) {
84           if (!isFinishing()) {
85             finish();
86           }
87         }
88       };
89   private FilteredNumberAsyncQueryHandler filteredNumberAsyncQueryHandler;
90   private SpamSettings spamSettings;
91   private SpamBlockingPromoHelper spamBlockingPromoHelper;
92 
93   /**
94    * Creates an intent to start this activity.
95    *
96    * @return Intent intent that starts this activity.
97    */
createActivityIntent( Context context, @Nullable DialerCall call, String action, String notificationTag, int notificationId)98   public static Intent createActivityIntent(
99       Context context,
100       @Nullable DialerCall call,
101       String action,
102       String notificationTag,
103       int notificationId) {
104     Intent intent = new Intent(context, SpamNotificationActivity.class);
105     intent.setAction(action);
106     // This ensures only one activity of this kind exists at a time.
107     intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
108     intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
109     intent.putExtra(EXTRA_NOTIFICATION_TAG, notificationTag);
110     intent.putExtra(EXTRA_NOTIFICATION_ID, notificationId);
111 
112     if (call != null) {
113       intent.putExtra(EXTRA_CALL_INFO, newCallInfoBundle(call));
114     }
115     return intent;
116   }
117 
118   /** Creates the intent to insert a contact. */
createInsertContactsIntent(String number)119   private static Intent createInsertContactsIntent(String number) {
120     Intent intent = new Intent(ContactsContract.Intents.Insert.ACTION);
121     // This ensures that the edit contact number field gets updated if called more than once.
122     intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
123     intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
124     intent.setType(ContactsContract.RawContacts.CONTENT_TYPE);
125     intent.putExtra(ContactsContract.Intents.Insert.PHONE, number);
126     return intent;
127   }
128 
129   /** Returns the formatted version of the given number. */
getFormattedNumber(String number, Context context)130   private static String getFormattedNumber(String number, Context context) {
131     String formattedNumber =
132         PhoneNumberHelper.formatNumber(context, number, GeoUtil.getCurrentCountryIso(context));
133     return PhoneNumberUtils.createTtsSpannable(formattedNumber).toString();
134   }
135 
logCallImpression(DialerImpression.Type impression)136   private void logCallImpression(DialerImpression.Type impression) {
137     logCallImpression(this, getCallInfo(), impression);
138   }
139 
logCallImpression( Context context, Bundle bundle, DialerImpression.Type impression)140   private static void logCallImpression(
141       Context context, Bundle bundle, DialerImpression.Type impression) {
142     Logger.get(context)
143         .logCallImpression(
144             impression,
145             bundle.getString(CALL_INFO_KEY_CALL_ID),
146             bundle.getLong(CALL_INFO_KEY_START_TIME_MILLIS, 0));
147   }
148 
newCallInfoBundle(DialerCall call)149   private static Bundle newCallInfoBundle(DialerCall call) {
150     Bundle bundle = new Bundle();
151     bundle.putString(CALL_INFO_KEY_PHONE_NUMBER, call.getNumber());
152     bundle.putBoolean(CALL_INFO_KEY_IS_SPAM, call.isSpam());
153     bundle.putString(CALL_INFO_KEY_CALL_ID, call.getUniqueCallId());
154     bundle.putLong(CALL_INFO_KEY_START_TIME_MILLIS, call.getTimeAddedMs());
155     bundle.putInt(
156         CALL_INFO_CONTACT_LOOKUP_RESULT_TYPE, call.getLogState().contactLookupResult.getNumber());
157     return bundle;
158   }
159 
160   @Override
onCreate(Bundle savedInstanceState)161   protected void onCreate(Bundle savedInstanceState) {
162     LogUtil.i(TAG, "onCreate");
163     super.onCreate(savedInstanceState);
164     setFinishOnTouchOutside(true);
165     filteredNumberAsyncQueryHandler = new FilteredNumberAsyncQueryHandler(this);
166     spamSettings = SpamComponent.get(this).spamSettings();
167     spamBlockingPromoHelper = new SpamBlockingPromoHelper(getApplicationContext(), spamSettings);
168     cancelNotification();
169   }
170 
171   @Override
onResume()172   protected void onResume() {
173     LogUtil.i(TAG, "onResume");
174     super.onResume();
175     Intent intent = getIntent();
176     String number = getCallInfo().getString(CALL_INFO_KEY_PHONE_NUMBER);
177     boolean isSpam = getCallInfo().getBoolean(CALL_INFO_KEY_IS_SPAM);
178     ContactLookupResult.Type contactLookupResultType =
179         ContactLookupResult.Type.forNumber(
180             getCallInfo().getInt(CALL_INFO_CONTACT_LOOKUP_RESULT_TYPE, 0));
181     switch (intent.getAction()) {
182       case ACTION_ADD_TO_CONTACTS:
183         logCallImpression(DialerImpression.Type.SPAM_AFTER_CALL_NOTIFICATION_ADD_TO_CONTACTS);
184         startActivity(createInsertContactsIntent(number));
185         finish();
186         break;
187       case ACTION_MARK_NUMBER_AS_SPAM:
188         assertDialogsEnabled();
189         maybeShowBlockReportSpamDialog(number, contactLookupResultType);
190         break;
191       case ACTION_MARK_NUMBER_AS_NOT_SPAM:
192         assertDialogsEnabled();
193         maybeShowNotSpamDialog(number, contactLookupResultType);
194         break;
195       case ACTION_SHOW_DIALOG:
196         if (isSpam) {
197           showSpamFullDialog();
198         } else {
199           showNonSpamDialog();
200         }
201         break;
202       case ACTION_SHOW_SPAM_BLOCKING_PROMO_DIALOG:
203         showSpamBlockingPromoDialog();
204         break;
205       default: // fall out
206     }
207   }
208 
209   @Override
onPause()210   protected void onPause() {
211     LogUtil.d(TAG, "onPause");
212     // Finish activity on pause (e.g: orientation change or back button pressed)
213     filteredNumberAsyncQueryHandler = null;
214     if (!isFinishing()) {
215       finish();
216     }
217     super.onPause();
218   }
219 
220   /** Creates and displays the dialog for whitelisting a number. */
maybeShowNotSpamDialog( final String number, final ContactLookupResult.Type contactLookupResultType)221   private void maybeShowNotSpamDialog(
222       final String number, final ContactLookupResult.Type contactLookupResultType) {
223     if (SpamComponent.get(this).spamSettings().isDialogEnabledForSpamNotification()) {
224       DialogFragmentForReportingNotSpam.newInstance(
225               getFormattedNumber(number, this),
226               new BlockReportSpamDialogs.OnConfirmListener() {
227                 @Override
228                 public void onClick() {
229                   reportNotSpamAndFinish(number, contactLookupResultType);
230                 }
231               },
232               dismissListener)
233           .show(getSupportFragmentManager(), BlockReportSpamDialogs.NOT_SPAM_DIALOG_TAG);
234     } else {
235       reportNotSpamAndFinish(number, contactLookupResultType);
236     }
237   }
238 
239   /** Creates and displays the dialog for blocking/reporting a number as spam. */
maybeShowBlockReportSpamDialog( final String number, final ContactLookupResult.Type contactLookupResultType)240   private void maybeShowBlockReportSpamDialog(
241       final String number, final ContactLookupResult.Type contactLookupResultType) {
242     if (SpamComponent.get(this).spamSettings().isDialogEnabledForSpamNotification()) {
243       String displayNumber = getFormattedNumber(number, this);
244       maybeShowBlockNumberMigrationDialog(
245           new BlockedNumbersMigrator.Listener() {
246             @Override
247             public void onComplete() {
248               DialogFragmentForBlockingNumberAndOptionallyReportingAsSpam.newInstance(
249                       displayNumber,
250                       SpamComponent.get(SpamNotificationActivity.this)
251                           .spamSettings()
252                           .isDialogReportSpamCheckedByDefault(),
253                       new BlockReportSpamDialogs.OnSpamDialogClickListener() {
254                         @Override
255                         public void onClick(boolean isSpamChecked) {
256                           blockReportNumber(number, isSpamChecked, contactLookupResultType);
257                         }
258                       },
259                       dismissListener)
260                   .show(
261                       getSupportFragmentManager(),
262                       BlockReportSpamDialogs.BLOCK_REPORT_SPAM_DIALOG_TAG);
263             }
264           });
265     } else {
266       blockReportNumber(number, true, contactLookupResultType);
267     }
268   }
269 
270   /**
271    * Displays the dialog for the first time unknown calls with actions "Add contact", "Block/report
272    * spam", and "Dismiss".
273    */
showNonSpamDialog()274   private void showNonSpamDialog() {
275     logCallImpression(DialerImpression.Type.SPAM_AFTER_CALL_NOTIFICATION_SHOW_NON_SPAM_DIALOG);
276     FirstTimeNonSpamCallDialogFragment.newInstance(getCallInfo())
277         .show(getFragmentManager(), FirstTimeNonSpamCallDialogFragment.TAG);
278   }
279 
280   /**
281    * Displays the dialog for first time spam calls with actions "Not spam", "Block", and "Dismiss".
282    */
showSpamFullDialog()283   private void showSpamFullDialog() {
284     logCallImpression(DialerImpression.Type.SPAM_AFTER_CALL_NOTIFICATION_SHOW_SPAM_DIALOG);
285     FirstTimeSpamCallDialogFragment.newInstance(getCallInfo())
286         .show(getFragmentManager(), FirstTimeSpamCallDialogFragment.TAG);
287   }
288 
289   /** Checks if the user has migrated to the new blocking and display a dialog if necessary. */
maybeShowBlockNumberMigrationDialog(BlockedNumbersMigrator.Listener listener)290   private void maybeShowBlockNumberMigrationDialog(BlockedNumbersMigrator.Listener listener) {
291     if (!FilteredNumberCompat.maybeShowBlockNumberMigrationDialog(
292         this, getFragmentManager(), listener)) {
293       listener.onComplete();
294     }
295   }
296 
297   /** Block and report the number as spam. */
blockReportNumber( String number, boolean reportAsSpam, ContactLookupResult.Type contactLookupResultType)298   private void blockReportNumber(
299       String number, boolean reportAsSpam, ContactLookupResult.Type contactLookupResultType) {
300     if (reportAsSpam) {
301       logCallImpression(DialerImpression.Type.SPAM_AFTER_CALL_NOTIFICATION_MARKED_NUMBER_AS_SPAM);
302       SpamComponent.get(this)
303           .spam()
304           .reportSpamFromAfterCallNotification(
305               number,
306               getCountryIso(),
307               CallLog.Calls.INCOMING_TYPE,
308               ReportingLocation.Type.FEEDBACK_PROMPT,
309               contactLookupResultType);
310     }
311 
312     logCallImpression(DialerImpression.Type.SPAM_AFTER_CALL_NOTIFICATION_BLOCK_NUMBER);
313     filteredNumberAsyncQueryHandler.blockNumber(null, number, getCountryIso());
314   }
315 
316   /** Report the number as not spam. */
reportNotSpamAndFinish( String number, ContactLookupResult.Type contactLookupResultType)317   private void reportNotSpamAndFinish(
318       String number, ContactLookupResult.Type contactLookupResultType) {
319     logCallImpression(DialerImpression.Type.SPAM_AFTER_CALL_NOTIFICATION_REPORT_NUMBER_AS_NOT_SPAM);
320     SpamComponent.get(this)
321         .spam()
322         .reportNotSpamFromAfterCallNotification(
323             number,
324             getCountryIso(),
325             CallLog.Calls.INCOMING_TYPE,
326             ReportingLocation.Type.FEEDBACK_PROMPT,
327             contactLookupResultType);
328     // TODO: DialerCall finish() after async task completes (a bug)
329     finish();
330   }
331 
332   /** Cancels the notification associated with the number. */
cancelNotification()333   private void cancelNotification() {
334     String notificationTag = getIntent().getStringExtra(EXTRA_NOTIFICATION_TAG);
335     int notificationId = getIntent().getIntExtra(EXTRA_NOTIFICATION_ID, 1);
336     DialerNotificationManager.cancel(this, notificationTag, notificationId);
337   }
338 
getCountryIso()339   private String getCountryIso() {
340     return GeoUtil.getCurrentCountryIso(this);
341   }
342 
assertDialogsEnabled()343   private void assertDialogsEnabled() {
344     if (!SpamComponent.get(this).spamSettings().isDialogEnabledForSpamNotification()) {
345       throw new IllegalStateException(
346           "Cannot start this activity with given action because dialogs are not enabled.");
347     }
348   }
349 
getCallInfo()350   private Bundle getCallInfo() {
351     return getIntent().hasExtra(EXTRA_CALL_INFO)
352         ? getIntent().getBundleExtra(EXTRA_CALL_INFO)
353         : new Bundle();
354   }
355 
356   /** Dialog that displays "Not spam", "Block/report spam" and "Dismiss". */
357   public static class FirstTimeSpamCallDialogFragment extends DialogFragment {
358 
359     public static final String TAG = "FirstTimeSpamDialog";
360 
361     private boolean dismissed;
362     private Context applicationContext;
363 
newInstance(Bundle bundle)364     private static DialogFragment newInstance(Bundle bundle) {
365       FirstTimeSpamCallDialogFragment fragment = new FirstTimeSpamCallDialogFragment();
366       fragment.setArguments(bundle);
367       return fragment;
368     }
369 
370     @Override
onPause()371     public void onPause() {
372       dismiss();
373       super.onPause();
374     }
375 
376     @Override
onDismiss(DialogInterface dialog)377     public void onDismiss(DialogInterface dialog) {
378       logCallImpression(
379           applicationContext,
380           getArguments(),
381           DialerImpression.Type.SPAM_AFTER_CALL_NOTIFICATION_ON_DISMISS_SPAM_DIALOG);
382       super.onDismiss(dialog);
383       // If dialog was not dismissed by user pressing one of the buttons, finish activity
384       if (!dismissed && getActivity() != null && !getActivity().isFinishing()) {
385         getActivity().finish();
386       }
387     }
388 
389     @Override
onAttach(Context context)390     public void onAttach(Context context) {
391       super.onAttach(context);
392       applicationContext = context.getApplicationContext();
393     }
394 
395     @Override
onCreateDialog(Bundle savedInstanceState)396     public Dialog onCreateDialog(Bundle savedInstanceState) {
397       super.onCreateDialog(savedInstanceState);
398       final SpamNotificationActivity spamNotificationActivity =
399           (SpamNotificationActivity) getActivity();
400       final String number = getArguments().getString(CALL_INFO_KEY_PHONE_NUMBER);
401       final ContactLookupResult.Type contactLookupResultType =
402           ContactLookupResult.Type.forNumber(
403               getArguments().getInt(CALL_INFO_CONTACT_LOOKUP_RESULT_TYPE, 0));
404 
405       return new AlertDialog.Builder(getActivity())
406           .setCancelable(false)
407           .setTitle(
408               getString(
409                   SpamAlternativeExperimentUtil.getResourceIdByName(
410                       "spam_notification_title", applicationContext),
411                   getFormattedNumber(number, applicationContext)))
412           .setNeutralButton(
413               getString(R.string.spam_notification_action_dismiss),
414               new DialogInterface.OnClickListener() {
415                 @Override
416                 public void onClick(DialogInterface dialog, int which) {
417                   dismiss();
418                 }
419               })
420           .setPositiveButton(
421               getString(R.string.spam_notification_block_spam_action_text),
422               new DialogInterface.OnClickListener() {
423                 @Override
424                 public void onClick(DialogInterface dialog, int which) {
425                   dismissed = true;
426                   dismiss();
427                   spamNotificationActivity.maybeShowBlockReportSpamDialog(
428                       number, contactLookupResultType);
429                   spamNotificationActivity.maybeShowSpamBlockingPromoAndFinish();
430                 }
431               })
432           .setNegativeButton(
433               getString(
434                   SpamAlternativeExperimentUtil.getResourceIdByName(
435                       "spam_notification_was_not_spam_action_text", applicationContext)),
436               new DialogInterface.OnClickListener() {
437                 @Override
438                 public void onClick(DialogInterface dialog, int which) {
439                   dismissed = true;
440                   dismiss();
441                   spamNotificationActivity.maybeShowNotSpamDialog(number, contactLookupResultType);
442                 }
443               })
444           .create();
445     }
446   }
447 
448   /** Dialog that displays "Add contact", "Block/report spam" and "Dismiss". */
449   public static class FirstTimeNonSpamCallDialogFragment extends DialogFragment {
450 
451     public static final String TAG = "FirstTimeNonSpamDialog";
452 
453     private boolean dismissed;
454     private Context context;
455 
456     private static DialogFragment newInstance(Bundle bundle) {
457       FirstTimeNonSpamCallDialogFragment fragment = new FirstTimeNonSpamCallDialogFragment();
458       fragment.setArguments(bundle);
459       return fragment;
460     }
461 
462     @Override
463     public void onPause() {
464       // Dismiss on pause e.g: orientation change
465       dismiss();
466       super.onPause();
467     }
468 
469     @Override
470     public void onDismiss(DialogInterface dialog) {
471       super.onDismiss(dialog);
472       logCallImpression(
473           context,
474           getArguments(),
475           DialerImpression.Type.SPAM_AFTER_CALL_NOTIFICATION_ON_DISMISS_NON_SPAM_DIALOG);
476       // If dialog was not dismissed by user pressing one of the buttons, finish activity
477       if (!dismissed && getActivity() != null && !getActivity().isFinishing()) {
478         getActivity().finish();
479       }
480     }
481 
482     @Override
483     public void onAttach(Context context) {
484       super.onAttach(context);
485       this.context = context.getApplicationContext();
486     }
487 
488     @Override
489     public Dialog onCreateDialog(Bundle savedInstanceState) {
490       super.onCreateDialog(savedInstanceState);
491       final SpamNotificationActivity spamNotificationActivity =
492           (SpamNotificationActivity) getActivity();
493       final String number = getArguments().getString(CALL_INFO_KEY_PHONE_NUMBER);
494       final ContactLookupResult.Type contactLookupResultType =
495           ContactLookupResult.Type.forNumber(
496               getArguments().getInt(CALL_INFO_CONTACT_LOOKUP_RESULT_TYPE, 0));
497       return new AlertDialog.Builder(getActivity())
498           .setTitle(
499               getString(R.string.non_spam_notification_title, getFormattedNumber(number, context)))
500           .setCancelable(false)
501           .setMessage(
502               getString(
503                   SpamAlternativeExperimentUtil.getResourceIdByName(
504                       "spam_notification_non_spam_call_expanded_text", context)))
505           .setNeutralButton(
506               getString(R.string.spam_notification_action_dismiss),
507               new DialogInterface.OnClickListener() {
508                 @Override
509                 public void onClick(DialogInterface dialog, int which) {
510                   dismiss();
511                 }
512               })
513           .setPositiveButton(
514               getString(R.string.spam_notification_dialog_add_contact_action_text),
515               new DialogInterface.OnClickListener() {
516                 @Override
517                 public void onClick(DialogInterface dialog, int which) {
518                   dismissed = true;
519                   dismiss();
520                   startActivity(createInsertContactsIntent(number));
521                 }
522               })
523           .setNegativeButton(
524               getString(
525                   SpamAlternativeExperimentUtil.getResourceIdByName(
526                       "spam_notification_dialog_block_report_spam_action_text", context)),
527               new DialogInterface.OnClickListener() {
528                 @Override
529                 public void onClick(DialogInterface dialog, int which) {
530                   dismissed = true;
531                   dismiss();
532                   spamNotificationActivity.maybeShowBlockReportSpamDialog(
533                       number, contactLookupResultType);
534                   spamNotificationActivity.maybeShowSpamBlockingPromoAndFinish();
535                 }
536               })
537           .create();
538     }
539   }
540 
541   private void maybeShowSpamBlockingPromoAndFinish() {
542     if (!spamBlockingPromoHelper.shouldShowAfterCallSpamBlockingPromo()) {
543       finish();
544       return;
545     }
546     Logger.get(this)
547         .logImpression(DialerImpression.Type.SPAM_BLOCKING_AFTER_CALL_NOTIFICATION_PROMO_SHOWN);
548     showSpamBlockingPromoDialog();
549   }
550 
551   private void showSpamBlockingPromoDialog() {
552     spamBlockingPromoHelper.showSpamBlockingPromoDialog(
553         getSupportFragmentManager(),
554         () -> {
555           Logger.get(this)
556               .logImpression(
557                   DialerImpression.Type
558                       .SPAM_BLOCKING_ENABLED_THROUGH_AFTER_CALL_NOTIFICATION_PROMO);
559           spamSettings.modifySpamBlockingSetting(
560               true,
561               success -> {
562                 if (!success) {
563                   Logger.get(this)
564                       .logImpression(
565                           DialerImpression.Type
566                               .SPAM_BLOCKING_MODIFY_FAILURE_THROUGH_AFTER_CALL_NOTIFICATION_PROMO);
567                 }
568                 spamBlockingPromoHelper.showModifySettingOnCompleteToast(success);
569               });
570         },
571         dialog -> finish());
572   }
573 }
574