Implement logic for blocking a number from the new call log's bottom sheet.

Bug: 70989547
Test: ShowBlockReportSpamDialogNotifierEndToEndTest
PiperOrigin-RevId: 188351591
Change-Id: I634fb821592bdc890df291fdf83cdf307c94ffa9
diff --git a/java/com/android/dialer/app/calllog/BlockReportSpamListener.java b/java/com/android/dialer/app/calllog/BlockReportSpamListener.java
index c8f8f0c..ecf629e 100644
--- a/java/com/android/dialer/app/calllog/BlockReportSpamListener.java
+++ b/java/com/android/dialer/app/calllog/BlockReportSpamListener.java
@@ -22,6 +22,8 @@
 import android.support.v7.widget.RecyclerView;
 import com.android.dialer.blocking.FilteredNumberAsyncQueryHandler;
 import com.android.dialer.blockreportspam.BlockReportSpamDialogs;
+import com.android.dialer.blockreportspam.BlockReportSpamDialogs.DialogFragmentForReportingNotSpam;
+import com.android.dialer.blockreportspam.BlockReportSpamDialogs.DialogFragmentForUnblockingNumberAndReportingAsNotSpam;
 import com.android.dialer.common.LogUtil;
 import com.android.dialer.logging.ContactSource;
 import com.android.dialer.logging.DialerImpression;
@@ -58,7 +60,7 @@
       final String countryIso,
       final int callType,
       @NonNull final ContactSource.Type contactSourceType) {
-    BlockReportSpamDialogs.BlockReportSpamDialogFragment.newInstance(
+    BlockReportSpamDialogs.DialogFragmentForBlockingNumberAndOptionallyReportingAsSpam.newInstance(
             displayNumber,
             spam.isDialogReportSpamCheckedByDefault(),
             isSpamChecked -> {
@@ -95,7 +97,7 @@
       final String countryIso,
       final int callType,
       @NonNull final ContactSource.Type contactSourceType) {
-    BlockReportSpamDialogs.BlockDialogFragment.newInstance(
+    BlockReportSpamDialogs.DialogFragmentForBlockingNumberAndReportingAsSpam.newInstance(
             displayNumber,
             spam.isSpamEnabled(),
             () -> {
@@ -134,7 +136,7 @@
       final ContactSource.Type contactSourceType,
       final boolean isSpam,
       final Integer blockId) {
-    BlockReportSpamDialogs.UnblockDialogFragment.newInstance(
+    DialogFragmentForUnblockingNumberAndReportingAsNotSpam.newInstance(
             displayNumber,
             isSpam,
             () -> {
@@ -168,7 +170,7 @@
       final String countryIso,
       final int callType,
       final ContactSource.Type contactSourceType) {
-    BlockReportSpamDialogs.ReportNotSpamDialogFragment.newInstance(
+    DialogFragmentForReportingNotSpam.newInstance(
             displayNumber,
             () -> {
               LogUtil.i("BlockReportSpamListener.onReportNotSpam", "onClick");
diff --git a/java/com/android/dialer/blockreportspam/BlockReportSpamDialogs.java b/java/com/android/dialer/blockreportspam/BlockReportSpamDialogs.java
index b75669f..2ec5dbd 100644
--- a/java/com/android/dialer/blockreportspam/BlockReportSpamDialogs.java
+++ b/java/com/android/dialer/blockreportspam/BlockReportSpamDialogs.java
@@ -29,9 +29,7 @@
 import android.widget.TextView;
 import com.android.dialer.blocking.FilteredNumberCompat;
 
-/**
- * Helper class for creating dialog fragments to block a number and/or report it as spam/not spam.
- */
+/** Creates dialog fragments to block a number and/or report it as spam/not spam. */
 public final class BlockReportSpamDialogs {
 
   public static final String BLOCK_REPORT_SPAM_DIALOG_TAG = "BlockReportSpamDialog";
@@ -39,7 +37,7 @@
   public static final String UNBLOCK_DIALOG_TAG = "UnblockDialog";
   public static final String NOT_SPAM_DIALOG_TAG = "NotSpamDialog";
 
-  /** Creates a dialog with the default cancel button listener (dismisses dialog). */
+  /** Creates a dialog with the default cancel button listener (which dismisses the dialog). */
   private static AlertDialog.Builder createDialogBuilder(
       Activity activity, final DialogFragment fragment) {
     return new AlertDialog.Builder(activity, R.style.AlertDialogTheme)
@@ -70,36 +68,36 @@
   }
 
   /**
-   * Listener passed to block/report spam dialog for positive click in {@link
-   * BlockReportSpamDialogFragment}.
+   * Positive listener for the "Block/Report spam" dialog {@link
+   * DialogFragmentForBlockingNumberAndOptionallyReportingAsSpam}.
    */
   public interface OnSpamDialogClickListener {
 
     /**
-     * Called when user clicks on positive button in block/report spam dialog.
+     * Called when the user clicks on the positive button of the "Block/Report spam" dialog.
      *
      * @param isSpamChecked Whether the spam checkbox is checked.
      */
     void onClick(boolean isSpamChecked);
   }
 
-  /** Listener passed to all dialogs except the block/report spam dialog for positive click. */
+  /** Positive listener for dialogs other than the "Block/Report spam" dialog. */
   public interface OnConfirmListener {
 
-    /** Called when user clicks on positive button in the dialog. */
+    /** Called when the user clicks on the positive button of the dialog. */
     void onClick();
   }
 
-  /** Contains the common attributes between all block/unblock/report spam dialog fragments. */
+  /** Contains common attributes shared among all dialog fragments. */
   private abstract static class CommonDialogsFragment extends DialogFragment {
 
     /** The number to display in the dialog title. */
     protected String displayNumber;
 
-    /** Called when dialog positive button is pressed. */
+    /** Listener for the positive button. */
     protected OnConfirmListener positiveListener;
 
-    /** Called when dialog is dismissed. */
+    /** Listener for when the dialog is dismissed. */
     @Nullable protected DialogInterface.OnDismissListener dismissListener;
 
     @Override
@@ -121,8 +119,14 @@
     }
   }
 
-  /** Dialog for block/report spam with the mark as spam checkbox. */
-  public static class BlockReportSpamDialogFragment extends CommonDialogsFragment {
+  /**
+   * Dialog for blocking a number and optionally reporting it as spam.
+   *
+   * <p>This dialog is for a number that is neither blocked nor marked as spam. It has a checkbox
+   * that allows the user to report a number as spam when they block it.
+   */
+  public static class DialogFragmentForBlockingNumberAndOptionallyReportingAsSpam
+      extends CommonDialogsFragment {
 
     /** Called when dialog positive button is pressed. */
     private OnSpamDialogClickListener onSpamDialogClickListener;
@@ -135,7 +139,8 @@
         boolean spamChecked,
         OnSpamDialogClickListener onSpamDialogClickListener,
         @Nullable DialogInterface.OnDismissListener dismissListener) {
-      BlockReportSpamDialogFragment fragment = new BlockReportSpamDialogFragment();
+      DialogFragmentForBlockingNumberAndOptionallyReportingAsSpam fragment =
+          new DialogFragmentForBlockingNumberAndOptionallyReportingAsSpam();
       fragment.spamChecked = spamChecked;
       fragment.displayNumber = displayNumber;
       fragment.onSpamDialogClickListener = onSpamDialogClickListener;
@@ -173,8 +178,14 @@
     }
   }
 
-  /** Dialog for blocking a number. */
-  public static class BlockDialogFragment extends CommonDialogsFragment {
+  /**
+   * Dialog for blocking a number and reporting it as spam.
+   *
+   * <p>This dialog is for the migration of blocked numbers. Its positive action should block a
+   * number, and also marks it as spam if the spam feature is enabled.
+   */
+  public static class DialogFragmentForBlockingNumberAndReportingAsSpam
+      extends CommonDialogsFragment {
 
     private boolean isSpamEnabled;
 
@@ -183,7 +194,8 @@
         boolean isSpamEnabled,
         OnConfirmListener positiveListener,
         @Nullable DialogInterface.OnDismissListener dismissListener) {
-      BlockDialogFragment fragment = new BlockDialogFragment();
+      DialogFragmentForBlockingNumberAndReportingAsSpam fragment =
+          new DialogFragmentForBlockingNumberAndReportingAsSpam();
       fragment.displayNumber = displayNumber;
       fragment.positiveListener = positiveListener;
       fragment.dismissListener = dismissListener;
@@ -212,8 +224,51 @@
     }
   }
 
-  /** Dialog for unblocking a number. */
-  public static class UnblockDialogFragment extends CommonDialogsFragment {
+  /**
+   * Dialog for blocking a number.
+   *
+   * <p>This dialog is for a spam number that hasn't been blocked. For example, if the user receives
+   * a spam call, this dialog will be shown if they would like to block the number.
+   */
+  public static class DialogFragmentForBlockingNumber extends CommonDialogsFragment {
+
+    public static DialogFragment newInstance(
+        String displayNumber,
+        OnConfirmListener positiveListener,
+        @Nullable DialogInterface.OnDismissListener dismissListener) {
+      DialogFragmentForBlockingNumberAndReportingAsSpam fragment =
+          new DialogFragmentForBlockingNumberAndReportingAsSpam();
+      fragment.displayNumber = displayNumber;
+      fragment.positiveListener = positiveListener;
+      fragment.dismissListener = dismissListener;
+      return fragment;
+    }
+
+    @Override
+    public Dialog onCreateDialog(Bundle savedInstanceState) {
+      super.onCreateDialog(savedInstanceState);
+      // Return the newly created dialog
+      AlertDialog.Builder alertDialogBuilder = createDialogBuilder(getActivity(), this);
+      Dialog dialog =
+          alertDialogBuilder
+              .setTitle(getString(R.string.block_number_confirmation_title, displayNumber))
+              .setMessage(getString(R.string.block_report_number_alert_details))
+              .setPositiveButton(
+                  R.string.block_number_ok, createGenericOnClickListener(this, positiveListener))
+              .create();
+      dialog.setCanceledOnTouchOutside(true);
+      return dialog;
+    }
+  }
+
+  /**
+   * Dialog for unblocking a number and marking it as not spam.
+   *
+   * <p>This dialog is used in the old call log, where unblocking a number will also marking it as
+   * not spam.
+   */
+  public static class DialogFragmentForUnblockingNumberAndReportingAsNotSpam
+      extends CommonDialogsFragment {
 
     /** Whether or not the number is spam. */
     private boolean isSpam;
@@ -223,7 +278,8 @@
         boolean isSpam,
         OnConfirmListener positiveListener,
         @Nullable DialogInterface.OnDismissListener dismissListener) {
-      UnblockDialogFragment fragment = new UnblockDialogFragment();
+      DialogFragmentForUnblockingNumberAndReportingAsNotSpam fragment =
+          new DialogFragmentForUnblockingNumberAndReportingAsNotSpam();
       fragment.displayNumber = displayNumber;
       fragment.isSpam = isSpam;
       fragment.positiveListener = positiveListener;
@@ -255,13 +311,13 @@
   }
 
   /** Dialog for reporting a number as not spam. */
-  public static class ReportNotSpamDialogFragment extends CommonDialogsFragment {
+  public static class DialogFragmentForReportingNotSpam extends CommonDialogsFragment {
 
     public static DialogFragment newInstance(
         String displayNumber,
         OnConfirmListener positiveListener,
         @Nullable DialogInterface.OnDismissListener dismissListener) {
-      ReportNotSpamDialogFragment fragment = new ReportNotSpamDialogFragment();
+      DialogFragmentForReportingNotSpam fragment = new DialogFragmentForReportingNotSpam();
       fragment.displayNumber = displayNumber;
       fragment.positiveListener = positiveListener;
       fragment.dismissListener = dismissListener;
diff --git a/java/com/android/dialer/blockreportspam/ShowBlockReportSpamDialogNotifier.java b/java/com/android/dialer/blockreportspam/ShowBlockReportSpamDialogNotifier.java
index 58e1988..2fccdd1 100644
--- a/java/com/android/dialer/blockreportspam/ShowBlockReportSpamDialogNotifier.java
+++ b/java/com/android/dialer/blockreportspam/ShowBlockReportSpamDialogNotifier.java
@@ -47,6 +47,19 @@
     LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
   }
 
+  /** Notifies that a dialog for blocking a number should be shown. */
+  public static void notifyShowDialogToBlockNumber(
+      Context context, BlockReportSpamDialogInfo blockReportSpamDialogInfo) {
+    LogUtil.enterBlock("ShowBlockReportSpamDialogNotifier.notifyShowDialogToBlockNumber");
+
+    Intent intent = new Intent();
+    intent.setAction(ShowBlockReportSpamDialogReceiver.ACTION_SHOW_DIALOG_TO_BLOCK_NUMBER);
+    ProtoParsers.put(
+        intent, ShowBlockReportSpamDialogReceiver.EXTRA_DIALOG_INFO, blockReportSpamDialogInfo);
+
+    LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
+  }
+
   /** Notifies that a dialog for reporting a number as not spam should be shown. */
   public static void notifyShowDialogToReportNotSpam(
       Context context, BlockReportSpamDialogInfo blockReportSpamDialogInfo) {
diff --git a/java/com/android/dialer/blockreportspam/ShowBlockReportSpamDialogReceiver.java b/java/com/android/dialer/blockreportspam/ShowBlockReportSpamDialogReceiver.java
index f24bb1c..6b8f819 100644
--- a/java/com/android/dialer/blockreportspam/ShowBlockReportSpamDialogReceiver.java
+++ b/java/com/android/dialer/blockreportspam/ShowBlockReportSpamDialogReceiver.java
@@ -21,7 +21,10 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.widget.Toast;
+import com.android.dialer.blocking.FilteredNumberAsyncQueryHandler;
+import com.android.dialer.blockreportspam.BlockReportSpamDialogs.DialogFragmentForBlockingNumber;
+import com.android.dialer.blockreportspam.BlockReportSpamDialogs.DialogFragmentForBlockingNumberAndOptionallyReportingAsSpam;
+import com.android.dialer.blockreportspam.BlockReportSpamDialogs.DialogFragmentForReportingNotSpam;
 import com.android.dialer.blockreportspam.BlockReportSpamDialogs.OnConfirmListener;
 import com.android.dialer.blockreportspam.BlockReportSpamDialogs.OnSpamDialogClickListener;
 import com.android.dialer.common.Assert;
@@ -31,7 +34,6 @@
 import com.android.dialer.protos.ProtoParsers;
 import com.android.dialer.spam.Spam;
 import com.android.dialer.spam.SpamComponent;
-import java.util.Locale;
 
 /**
  * A {@link BroadcastReceiver} that shows an appropriate dialog upon receiving notifications from
@@ -39,6 +41,7 @@
  */
 public final class ShowBlockReportSpamDialogReceiver extends BroadcastReceiver {
 
+  static final String ACTION_SHOW_DIALOG_TO_BLOCK_NUMBER = "show_dialog_to_block_number";
   static final String ACTION_SHOW_DIALOG_TO_BLOCK_NUMBER_AND_OPTIONALLY_REPORT_SPAM =
       "show_dialog_to_block_number_and_optionally_report_spam";
   static final String ACTION_SHOW_DIALOG_TO_REPORT_NOT_SPAM = "show_dialog_to_report_not_spam";
@@ -51,6 +54,7 @@
   public static IntentFilter getIntentFilter() {
     IntentFilter intentFilter = new IntentFilter();
     intentFilter.addAction(ACTION_SHOW_DIALOG_TO_BLOCK_NUMBER_AND_OPTIONALLY_REPORT_SPAM);
+    intentFilter.addAction(ACTION_SHOW_DIALOG_TO_BLOCK_NUMBER);
     intentFilter.addAction(ACTION_SHOW_DIALOG_TO_REPORT_NOT_SPAM);
     return intentFilter;
   }
@@ -66,6 +70,9 @@
     String action = intent.getAction();
 
     switch (Assert.isNotNull(action)) {
+      case ACTION_SHOW_DIALOG_TO_BLOCK_NUMBER:
+        showDialogToBlockNumber(context, intent);
+        break;
       case ACTION_SHOW_DIALOG_TO_BLOCK_NUMBER_AND_OPTIONALLY_REPORT_SPAM:
         showDialogToBlockNumberAndOptionallyReportSpam(context, intent);
         break;
@@ -87,6 +94,8 @@
             intent, EXTRA_DIALOG_INFO, BlockReportSpamDialogInfo.getDefaultInstance());
 
     Spam spam = SpamComponent.get(context).spam();
+    FilteredNumberAsyncQueryHandler filteredNumberAsyncQueryHandler =
+        new FilteredNumberAsyncQueryHandler(context);
 
     // Set up the positive listener for the dialog.
     OnSpamDialogClickListener onSpamDialogClickListener =
@@ -111,19 +120,16 @@
                 dialogInfo.getContactSource());
           }
 
-          // TODO(a bug): Block the number.
-          Toast.makeText(
-                  context,
-                  String.format(
-                      Locale.ENGLISH,
-                      "TODO: " + "Block number %s.",
-                      dialogInfo.getNormalizedNumber()),
-                  Toast.LENGTH_SHORT)
-              .show();
+          filteredNumberAsyncQueryHandler.blockNumber(
+              unused ->
+                  Logger.get(context)
+                      .logImpression(DialerImpression.Type.USER_ACTION_BLOCKED_NUMBER),
+              dialogInfo.getNormalizedNumber(),
+              dialogInfo.getCountryIso());
         };
 
     // Create and show the dialog.
-    BlockReportSpamDialogs.BlockReportSpamDialogFragment.newInstance(
+    DialogFragmentForBlockingNumberAndOptionallyReportingAsSpam.newInstance(
             dialogInfo.getNormalizedNumber(),
             spam.isDialogReportSpamCheckedByDefault(),
             onSpamDialogClickListener,
@@ -131,6 +137,35 @@
         .show(fragmentManager, BlockReportSpamDialogs.BLOCK_REPORT_SPAM_DIALOG_TAG);
   }
 
+  private void showDialogToBlockNumber(Context context, Intent intent) {
+    LogUtil.enterBlock("ShowBlockReportSpamDialogReceiver.showDialogToBlockNumber");
+
+    Assert.checkArgument(intent.hasExtra(EXTRA_DIALOG_INFO));
+    BlockReportSpamDialogInfo dialogInfo =
+        ProtoParsers.getTrusted(
+            intent, EXTRA_DIALOG_INFO, BlockReportSpamDialogInfo.getDefaultInstance());
+
+    FilteredNumberAsyncQueryHandler filteredNumberAsyncQueryHandler =
+        new FilteredNumberAsyncQueryHandler(context);
+
+    // Set up the positive listener for the dialog.
+    OnConfirmListener onConfirmListener =
+        () -> {
+          LogUtil.i("ShowBlockReportSpamDialogReceiver.showDialogToBlockNumber", "block number");
+          filteredNumberAsyncQueryHandler.blockNumber(
+              unused ->
+                  Logger.get(context)
+                      .logImpression(DialerImpression.Type.USER_ACTION_BLOCKED_NUMBER),
+              dialogInfo.getNormalizedNumber(),
+              dialogInfo.getCountryIso());
+        };
+
+    // Create and show the dialog.
+    DialogFragmentForBlockingNumber.newInstance(
+            dialogInfo.getNormalizedNumber(), onConfirmListener, /* dismissListener = */ null)
+        .show(fragmentManager, BlockReportSpamDialogs.BLOCK_DIALOG_TAG);
+  }
+
   private void showDialogToReportNotSpam(Context context, Intent intent) {
     LogUtil.enterBlock("ShowBlockReportSpamDialogReceiver.showDialogToReportNotSpam");
 
@@ -158,7 +193,7 @@
         };
 
     // Create & show the dialog.
-    BlockReportSpamDialogs.ReportNotSpamDialogFragment.newInstance(
+    DialogFragmentForReportingNotSpam.newInstance(
             dialogInfo.getNormalizedNumber(), onConfirmListener, /* dismissListener = */ null)
         .show(fragmentManager, BlockReportSpamDialogs.NOT_SPAM_DIALOG_TAG);
   }
diff --git a/java/com/android/dialer/blockreportspam/res/values/strings.xml b/java/com/android/dialer/blockreportspam/res/values/strings.xml
index e803a16..aface92 100644
--- a/java/com/android/dialer/blockreportspam/res/values/strings.xml
+++ b/java/com/android/dialer/blockreportspam/res/values/strings.xml
@@ -18,7 +18,7 @@
 
   <!-- Confirmation dialog title for blocking a number. [CHAR LIMIT=NONE] -->
   <string name="block_number_confirmation_title">
-    Block<xliff:g example="(555) 555-5555" id="number">%1$s</xliff:g>?
+    Block <xliff:g example="(555) 555-5555" id="number">%1$s</xliff:g>?
   </string>
 
   <!-- Confirmation dialog message for blocking a number with new filtering enabled.
diff --git a/java/com/android/dialer/historyitemactions/SharedModules.java b/java/com/android/dialer/historyitemactions/SharedModules.java
index c046086..1147289 100644
--- a/java/com/android/dialer/historyitemactions/SharedModules.java
+++ b/java/com/android/dialer/historyitemactions/SharedModules.java
@@ -187,15 +187,20 @@
 
       @Override
       public boolean onClick() {
-        // TODO(a bug): implement this method.
-        Toast.makeText(
-                context,
-                String.format(
-                    Locale.ENGLISH,
-                    "TODO: " + (isBlocked ? "Unblock " : "Block ") + " number %s.",
-                    blockReportSpamDialogInfo.getNormalizedNumber()),
-                Toast.LENGTH_SHORT)
-            .show();
+        if (!isBlocked) {
+          ShowBlockReportSpamDialogNotifier.notifyShowDialogToBlockNumber(
+              context, blockReportSpamDialogInfo);
+        } else {
+          // TODO(a bug): implement this method.
+          Toast.makeText(
+                  context,
+                  String.format(
+                      Locale.ENGLISH,
+                      "TODO: Unblock number %s.",
+                      blockReportSpamDialogInfo.getNormalizedNumber()),
+                  Toast.LENGTH_SHORT)
+              .show();
+        }
         return true; // Close the bottom sheet.
       }
     };
diff --git a/java/com/android/incallui/spam/SpamNotificationActivity.java b/java/com/android/incallui/spam/SpamNotificationActivity.java
index 8919dc7..61d04a0 100644
--- a/java/com/android/incallui/spam/SpamNotificationActivity.java
+++ b/java/com/android/incallui/spam/SpamNotificationActivity.java
@@ -31,6 +31,8 @@
 import com.android.dialer.blocking.FilteredNumberAsyncQueryHandler;
 import com.android.dialer.blocking.FilteredNumberCompat;
 import com.android.dialer.blockreportspam.BlockReportSpamDialogs;
+import com.android.dialer.blockreportspam.BlockReportSpamDialogs.DialogFragmentForBlockingNumberAndOptionallyReportingAsSpam;
+import com.android.dialer.blockreportspam.BlockReportSpamDialogs.DialogFragmentForReportingNotSpam;
 import com.android.dialer.common.LogUtil;
 import com.android.dialer.location.GeoUtil;
 import com.android.dialer.logging.ContactLookupResult;
@@ -196,7 +198,7 @@
   private void maybeShowNotSpamDialog(
       final String number, final ContactLookupResult.Type contactLookupResultType) {
     if (SpamComponent.get(this).spam().isDialogEnabledForSpamNotification()) {
-      BlockReportSpamDialogs.ReportNotSpamDialogFragment.newInstance(
+      DialogFragmentForReportingNotSpam.newInstance(
               getFormattedNumber(number, this),
               new BlockReportSpamDialogs.OnConfirmListener() {
                 @Override
@@ -220,7 +222,7 @@
           new BlockedNumbersMigrator.Listener() {
             @Override
             public void onComplete() {
-              BlockReportSpamDialogs.BlockReportSpamDialogFragment.newInstance(
+              DialogFragmentForBlockingNumberAndOptionallyReportingAsSpam.newInstance(
                       displayNumber,
                       SpamComponent.get(SpamNotificationActivity.this)
                           .spam()