Merge "Update Spam module to use Dagger"
diff --git a/java/com/android/dialer/app/calllog/BlockReportSpamListener.java b/java/com/android/dialer/app/calllog/BlockReportSpamListener.java
index 28082df..05fb2b3 100644
--- a/java/com/android/dialer/app/calllog/BlockReportSpamListener.java
+++ b/java/com/android/dialer/app/calllog/BlockReportSpamListener.java
@@ -17,9 +17,7 @@
 package com.android.dialer.app.calllog;
 
 import android.app.FragmentManager;
-import android.content.ContentValues;
 import android.content.Context;
-import android.net.Uri;
 import android.support.annotation.NonNull;
 import android.support.v7.widget.RecyclerView;
 import com.android.dialer.blocking.BlockReportSpamDialogs;
@@ -30,6 +28,7 @@
 import com.android.dialer.logging.Logger;
 import com.android.dialer.logging.ReportingLocation;
 import com.android.dialer.spam.Spam;
+import com.android.dialer.spam.SpamComponent;
 
 /** Listener to show dialogs for block and report spam actions. */
 public class BlockReportSpamListener implements CallLogListItemViewHolder.OnClickListener {
@@ -38,6 +37,7 @@
   private final FragmentManager mFragmentManager;
   private final RecyclerView.Adapter mAdapter;
   private final FilteredNumberAsyncQueryHandler mFilteredNumberAsyncQueryHandler;
+  private final Spam spam;
 
   public BlockReportSpamListener(
       Context context,
@@ -48,6 +48,7 @@
     mFragmentManager = fragmentManager;
     mAdapter = adapter;
     mFilteredNumberAsyncQueryHandler = filteredNumberAsyncQueryHandler;
+    spam = SpamComponent.get(context).spam();
   }
 
   @Override
@@ -59,36 +60,29 @@
       @NonNull final ContactSource.Type contactSourceType) {
     BlockReportSpamDialogs.BlockReportSpamDialogFragment.newInstance(
             displayNumber,
-            Spam.get(mContext).isDialogReportSpamCheckedByDefault(),
-            new BlockReportSpamDialogs.OnSpamDialogClickListener() {
-              @Override
-              public void onClick(boolean isSpamChecked) {
-                LogUtil.i("BlockReportSpamListener.onBlockReportSpam", "onClick");
-                if (isSpamChecked && Spam.get(mContext).isSpamEnabled()) {
-                  Logger.get(mContext)
-                      .logImpression(
-                          DialerImpression.Type
-                              .REPORT_CALL_AS_SPAM_VIA_CALL_LOG_BLOCK_REPORT_SPAM_SENT_VIA_BLOCK_NUMBER_DIALOG);
-                  Spam.get(mContext)
-                      .reportSpamFromCallHistory(
-                          number,
-                          countryIso,
-                          callType,
-                          ReportingLocation.Type.CALL_LOG_HISTORY,
-                          contactSourceType);
-                }
-                mFilteredNumberAsyncQueryHandler.blockNumber(
-                    new FilteredNumberAsyncQueryHandler.OnBlockNumberListener() {
-                      @Override
-                      public void onBlockComplete(Uri uri) {
-                        Logger.get(mContext)
-                            .logImpression(DialerImpression.Type.USER_ACTION_BLOCKED_NUMBER);
-                        mAdapter.notifyDataSetChanged();
-                      }
-                    },
+            spam.isDialogReportSpamCheckedByDefault(),
+            isSpamChecked -> {
+              LogUtil.i("BlockReportSpamListener.onBlockReportSpam", "onClick");
+              if (isSpamChecked && spam.isSpamEnabled()) {
+                Logger.get(mContext)
+                    .logImpression(
+                        DialerImpression.Type
+                            .REPORT_CALL_AS_SPAM_VIA_CALL_LOG_BLOCK_REPORT_SPAM_SENT_VIA_BLOCK_NUMBER_DIALOG);
+                spam.reportSpamFromCallHistory(
                     number,
-                    countryIso);
+                    countryIso,
+                    callType,
+                    ReportingLocation.Type.CALL_LOG_HISTORY,
+                    contactSourceType);
               }
+              mFilteredNumberAsyncQueryHandler.blockNumber(
+                  uri -> {
+                    Logger.get(mContext)
+                        .logImpression(DialerImpression.Type.USER_ACTION_BLOCKED_NUMBER);
+                    mAdapter.notifyDataSetChanged();
+                  },
+                  number,
+                  countryIso);
             },
             null)
         .show(mFragmentManager, BlockReportSpamDialogs.BLOCK_REPORT_SPAM_DIALOG_TAG);
@@ -103,36 +97,29 @@
       @NonNull final ContactSource.Type contactSourceType) {
     BlockReportSpamDialogs.BlockDialogFragment.newInstance(
             displayNumber,
-            Spam.get(mContext).isSpamEnabled(),
-            new BlockReportSpamDialogs.OnConfirmListener() {
-              @Override
-              public void onClick() {
-                LogUtil.i("BlockReportSpamListener.onBlock", "onClick");
-                if (Spam.get(mContext).isSpamEnabled()) {
-                  Logger.get(mContext)
-                      .logImpression(
-                          DialerImpression.Type
-                              .DIALOG_ACTION_CONFIRM_NUMBER_SPAM_INDIRECTLY_VIA_BLOCK_NUMBER);
-                  Spam.get(mContext)
-                      .reportSpamFromCallHistory(
-                          number,
-                          countryIso,
-                          callType,
-                          ReportingLocation.Type.CALL_LOG_HISTORY,
-                          contactSourceType);
-                }
-                mFilteredNumberAsyncQueryHandler.blockNumber(
-                    new FilteredNumberAsyncQueryHandler.OnBlockNumberListener() {
-                      @Override
-                      public void onBlockComplete(Uri uri) {
-                        Logger.get(mContext)
-                            .logImpression(DialerImpression.Type.USER_ACTION_BLOCKED_NUMBER);
-                        mAdapter.notifyDataSetChanged();
-                      }
-                    },
+            spam.isSpamEnabled(),
+            () -> {
+              LogUtil.i("BlockReportSpamListener.onBlock", "onClick");
+              if (spam.isSpamEnabled()) {
+                Logger.get(mContext)
+                    .logImpression(
+                        DialerImpression.Type
+                            .DIALOG_ACTION_CONFIRM_NUMBER_SPAM_INDIRECTLY_VIA_BLOCK_NUMBER);
+                spam.reportSpamFromCallHistory(
                     number,
-                    countryIso);
+                    countryIso,
+                    callType,
+                    ReportingLocation.Type.CALL_LOG_HISTORY,
+                    contactSourceType);
               }
+              mFilteredNumberAsyncQueryHandler.blockNumber(
+                  uri -> {
+                    Logger.get(mContext)
+                        .logImpression(DialerImpression.Type.USER_ACTION_BLOCKED_NUMBER);
+                    mAdapter.notifyDataSetChanged();
+                  },
+                  number,
+                  countryIso);
             },
             null)
         .show(mFragmentManager, BlockReportSpamDialogs.BLOCK_DIALOG_TAG);
@@ -150,32 +137,25 @@
     BlockReportSpamDialogs.UnblockDialogFragment.newInstance(
             displayNumber,
             isSpam,
-            new BlockReportSpamDialogs.OnConfirmListener() {
-              @Override
-              public void onClick() {
-                LogUtil.i("BlockReportSpamListener.onUnblock", "onClick");
-                if (isSpam && Spam.get(mContext).isSpamEnabled()) {
-                  Logger.get(mContext)
-                      .logImpression(DialerImpression.Type.REPORT_AS_NOT_SPAM_VIA_UNBLOCK_NUMBER);
-                  Spam.get(mContext)
-                      .reportNotSpamFromCallHistory(
-                          number,
-                          countryIso,
-                          callType,
-                          ReportingLocation.Type.CALL_LOG_HISTORY,
-                          contactSourceType);
-                }
-                mFilteredNumberAsyncQueryHandler.unblock(
-                    new FilteredNumberAsyncQueryHandler.OnUnblockNumberListener() {
-                      @Override
-                      public void onUnblockComplete(int rows, ContentValues values) {
-                        Logger.get(mContext)
-                            .logImpression(DialerImpression.Type.USER_ACTION_UNBLOCKED_NUMBER);
-                        mAdapter.notifyDataSetChanged();
-                      }
-                    },
-                    blockId);
+            () -> {
+              LogUtil.i("BlockReportSpamListener.onUnblock", "onClick");
+              if (isSpam && spam.isSpamEnabled()) {
+                Logger.get(mContext)
+                    .logImpression(DialerImpression.Type.REPORT_AS_NOT_SPAM_VIA_UNBLOCK_NUMBER);
+                spam.reportNotSpamFromCallHistory(
+                    number,
+                    countryIso,
+                    callType,
+                    ReportingLocation.Type.CALL_LOG_HISTORY,
+                    contactSourceType);
               }
+              mFilteredNumberAsyncQueryHandler.unblock(
+                  (rows, values) -> {
+                    Logger.get(mContext)
+                        .logImpression(DialerImpression.Type.USER_ACTION_UNBLOCKED_NUMBER);
+                    mAdapter.notifyDataSetChanged();
+                  },
+                  blockId);
             },
             null)
         .show(mFragmentManager, BlockReportSpamDialogs.UNBLOCK_DIALOG_TAG);
@@ -190,23 +170,19 @@
       final ContactSource.Type contactSourceType) {
     BlockReportSpamDialogs.ReportNotSpamDialogFragment.newInstance(
             displayNumber,
-            new BlockReportSpamDialogs.OnConfirmListener() {
-              @Override
-              public void onClick() {
-                LogUtil.i("BlockReportSpamListener.onReportNotSpam", "onClick");
-                if (Spam.get(mContext).isSpamEnabled()) {
-                  Logger.get(mContext)
-                      .logImpression(DialerImpression.Type.DIALOG_ACTION_CONFIRM_NUMBER_NOT_SPAM);
-                  Spam.get(mContext)
-                      .reportNotSpamFromCallHistory(
-                          number,
-                          countryIso,
-                          callType,
-                          ReportingLocation.Type.CALL_LOG_HISTORY,
-                          contactSourceType);
-                }
-                mAdapter.notifyDataSetChanged();
+            () -> {
+              LogUtil.i("BlockReportSpamListener.onReportNotSpam", "onClick");
+              if (spam.isSpamEnabled()) {
+                Logger.get(mContext)
+                    .logImpression(DialerImpression.Type.DIALOG_ACTION_CONFIRM_NUMBER_NOT_SPAM);
+                spam.reportNotSpamFromCallHistory(
+                    number,
+                    countryIso,
+                    callType,
+                    ReportingLocation.Type.CALL_LOG_HISTORY,
+                    contactSourceType);
               }
+              mAdapter.notifyDataSetChanged();
             },
             null)
         .show(mFragmentManager, BlockReportSpamDialogs.NOT_SPAM_DIALOG_TAG);
diff --git a/java/com/android/dialer/app/calllog/CallLogAdapter.java b/java/com/android/dialer/app/calllog/CallLogAdapter.java
index f456555..0459519 100644
--- a/java/com/android/dialer/app/calllog/CallLogAdapter.java
+++ b/java/com/android/dialer/app/calllog/CallLogAdapter.java
@@ -89,7 +89,7 @@
 import com.android.dialer.phonenumbercache.ContactInfo;
 import com.android.dialer.phonenumbercache.ContactInfoHelper;
 import com.android.dialer.phonenumberutil.PhoneNumberHelper;
-import com.android.dialer.spam.Spam;
+import com.android.dialer.spam.SpamComponent;
 import com.android.dialer.util.PermissionsUtil;
 import java.util.ArrayList;
 import java.util.Map;
@@ -667,7 +667,7 @@
       mContactInfoCache.start();
     }
     mContactsPreferences.refreshValue(ContactsPreferences.DISPLAY_ORDER_KEY);
-    mIsSpamEnabled = Spam.get(mActivity).isSpamEnabled();
+    mIsSpamEnabled = SpamComponent.get(mActivity).spam().isSpamEnabled();
     getDuo().registerListener(this);
     notifyDataSetChanged();
   }
@@ -862,7 +862,8 @@
               // Call log cards with only outgoing calls should never be displayed as spam.
               viewHolder.isSpam =
                   details.hasIncomingCalls()
-                      && Spam.get(mActivity)
+                      && SpamComponent.get(mActivity)
+                          .spam()
                           .checkSpamStatusSynchronous(viewHolder.number, viewHolder.countryIso);
               details.isSpam = viewHolder.isSpam;
             }
diff --git a/java/com/android/dialer/binary/aosp/AospDialerRootComponent.java b/java/com/android/dialer/binary/aosp/AospDialerRootComponent.java
index 2bba432..c344fad 100644
--- a/java/com/android/dialer/binary/aosp/AospDialerRootComponent.java
+++ b/java/com/android/dialer/binary/aosp/AospDialerRootComponent.java
@@ -29,6 +29,7 @@
 import com.android.dialer.precall.impl.PreCallModule;
 import com.android.dialer.preferredsim.suggestion.stub.StubSimSuggestionModule;
 import com.android.dialer.simulator.impl.SimulatorModule;
+import com.android.dialer.spam.StubSpamModule;
 import com.android.dialer.storage.StorageModule;
 import com.android.dialer.strictmode.impl.SystemStrictModeModule;
 import com.android.incallui.calllocation.stub.StubCallLocationModule;
@@ -58,6 +59,7 @@
     VoicemailModule.class,
     StubSimSuggestionModule.class,
     StubFeedbackModule.class,
+    StubSpamModule.class,
   }
 )
 public interface AospDialerRootComponent extends BaseDialerRootComponent {}
diff --git a/java/com/android/dialer/binary/basecomponent/BaseDialerRootComponent.java b/java/com/android/dialer/binary/basecomponent/BaseDialerRootComponent.java
index 2e13cfb..8973a32 100644
--- a/java/com/android/dialer/binary/basecomponent/BaseDialerRootComponent.java
+++ b/java/com/android/dialer/binary/basecomponent/BaseDialerRootComponent.java
@@ -29,6 +29,7 @@
 import com.android.dialer.precall.PreCallComponent;
 import com.android.dialer.preferredsim.suggestion.SimSuggestionComponent;
 import com.android.dialer.simulator.SimulatorComponent;
+import com.android.dialer.spam.SpamComponent;
 import com.android.dialer.storage.StorageComponent;
 import com.android.dialer.strictmode.StrictModeComponent;
 import com.android.incallui.calllocation.CallLocationComponent;
@@ -57,4 +58,5 @@
         SimulatorComponent.HasComponent,
         StorageComponent.HasComponent,
         StrictModeComponent.HasComponent,
-        VoicemailComponent.HasComponent {}
+        VoicemailComponent.HasComponent,
+        SpamComponent.HasComponent {}
diff --git a/java/com/android/dialer/binary/google/GoogleStubDialerRootComponent.java b/java/com/android/dialer/binary/google/GoogleStubDialerRootComponent.java
index 2801bde..b54e062 100644
--- a/java/com/android/dialer/binary/google/GoogleStubDialerRootComponent.java
+++ b/java/com/android/dialer/binary/google/GoogleStubDialerRootComponent.java
@@ -29,6 +29,7 @@
 import com.android.dialer.precall.impl.PreCallModule;
 import com.android.dialer.preferredsim.suggestion.stub.StubSimSuggestionModule;
 import com.android.dialer.simulator.impl.SimulatorModule;
+import com.android.dialer.spam.StubSpamModule;
 import com.android.dialer.storage.StorageModule;
 import com.android.dialer.strictmode.impl.SystemStrictModeModule;
 import com.android.incallui.calllocation.impl.CallLocationModule;
@@ -61,6 +62,7 @@
     VoicemailModule.class,
     StubDuoModule.class,
     StubFeedbackModule.class,
+    StubSpamModule.class,
   }
 )
 public interface GoogleStubDialerRootComponent extends BaseDialerRootComponent {}
diff --git a/java/com/android/dialer/simulator/impl/SimulatorNotifications.java b/java/com/android/dialer/simulator/impl/SimulatorNotifications.java
index a243c34..bd17b7f 100644
--- a/java/com/android/dialer/simulator/impl/SimulatorNotifications.java
+++ b/java/com/android/dialer/simulator/impl/SimulatorNotifications.java
@@ -35,15 +35,7 @@
     return new SimulatorSubMenu(context)
         .addItem(
             "Missed calls", () -> new SimulatorMissedCallCreator(context).start(NOTIFICATION_COUNT))
-        .addItem("Voicemails", () -> addVoicemailNotifications(context))
-        .addItem(
-            "Non spam",
-            () ->
-                new SimulatorSpamCallCreator(context, false /* isSpam */).start(NOTIFICATION_COUNT))
-        .addItem(
-            "Confirm spam",
-            () ->
-                new SimulatorSpamCallCreator(context, true /* isSpam */).start(NOTIFICATION_COUNT));
+        .addItem("Voicemails", () -> addVoicemailNotifications(context));
   }
 
   private static void addVoicemailNotifications(@NonNull Context context) {
diff --git a/java/com/android/dialer/simulator/impl/SimulatorSpamCallCreator.java b/java/com/android/dialer/simulator/impl/SimulatorSpamCallCreator.java
deleted file mode 100644
index a843ec0..0000000
--- a/java/com/android/dialer/simulator/impl/SimulatorSpamCallCreator.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.dialer.simulator.impl;
-
-import android.content.ContentProviderOperation;
-import android.content.Context;
-import android.content.OperationApplicationException;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.provider.CallLog;
-import android.support.annotation.NonNull;
-import android.telecom.Connection;
-import android.telecom.DisconnectCause;
-import com.android.dialer.common.Assert;
-import com.android.dialer.common.LogUtil;
-import com.android.dialer.common.concurrent.ThreadUtil;
-import com.android.dialer.spam.Spam;
-import com.android.dialer.spam.SpamBindingsStub;
-import java.util.ArrayList;
-
-/**
- * Creates many spam call notifications by adding new incoming calls one at a time and disconnecting
- * them.
- */
-final class SimulatorSpamCallCreator implements SimulatorConnectionService.Listener {
-  private static final String EXTRA_CALL_COUNT = "call_count";
-  private static final String EXTRA_IS_SPAM_CALL_CONNECTION = "is_spam_call_connection";
-  private static final int DISCONNECT_DELAY_MILLIS = 1000;
-
-  private final Context context;
-  private final boolean isSpam;
-
-  SimulatorSpamCallCreator(@NonNull Context context, boolean isSpam) {
-    this.context = Assert.isNotNull(context);
-    this.isSpam = isSpam;
-  }
-
-  public void start(int callCount) {
-    Spam.setForTesting(new SimulatorSpamBindings(isSpam));
-    SimulatorConnectionService.addListener(this);
-    addNextIncomingCall(callCount);
-  }
-
-  @Override
-  public void onNewOutgoingConnection(@NonNull SimulatorConnection connection) {}
-
-  @Override
-  public void onNewIncomingConnection(@NonNull SimulatorConnection connection) {
-    if (!isSpamCallConnection(connection)) {
-      return;
-    }
-    ThreadUtil.postDelayedOnUiThread(
-        () -> {
-          LogUtil.i("SimulatorSpamCallCreator.onNewIncomingConnection", "disconnecting");
-          connection.setActive();
-          connection.setDisconnected(new DisconnectCause(DisconnectCause.LOCAL));
-          ThreadUtil.postDelayedOnUiThread(
-              () -> addNextIncomingCall(getCallCount(connection)), DISCONNECT_DELAY_MILLIS);
-        },
-        DISCONNECT_DELAY_MILLIS);
-  }
-
-  @Override
-  public void onConference(
-      @NonNull SimulatorConnection connection1, @NonNull SimulatorConnection connection2) {}
-
-  private void addNextIncomingCall(int callCount) {
-    if (callCount <= 0) {
-      LogUtil.i("SimulatorSpamCallCreator.addNextIncomingCall", "done adding calls");
-      SimulatorConnectionService.removeListener(this);
-      Spam.setForTesting(null);
-      return;
-    }
-
-    // Caller ID must be e.164 formatted and unique.
-    String callerId = String.format("+1-650-234%04d", callCount);
-    Bundle extras = new Bundle();
-    extras.putInt(EXTRA_CALL_COUNT, callCount - 1);
-    extras.putBoolean(EXTRA_IS_SPAM_CALL_CONNECTION, true);
-
-    // We need to clear the call log because spam notifications are only shown for new calls.
-    clearCallLog(context);
-
-    SimulatorSimCallManager.addNewIncomingCall(context, callerId, false /* isVideo */, extras);
-  }
-
-  private static boolean isSpamCallConnection(@NonNull Connection connection) {
-    return connection.getExtras().getBoolean(EXTRA_IS_SPAM_CALL_CONNECTION);
-  }
-
-  private static int getCallCount(@NonNull Connection connection) {
-    return connection.getExtras().getInt(EXTRA_CALL_COUNT);
-  }
-
-  private static void clearCallLog(@NonNull Context context) {
-    try {
-      ArrayList<ContentProviderOperation> operations = new ArrayList<>();
-      operations.add(ContentProviderOperation.newDelete(CallLog.Calls.CONTENT_URI).build());
-      context.getContentResolver().applyBatch(CallLog.AUTHORITY, operations);
-    } catch (RemoteException | OperationApplicationException e) {
-      Assert.fail("failed to clear call log: " + e);
-    }
-  }
-
-  /**
-   * Custom spam bindings that allow us to override which phone numbers are considered to be spam.
-   * Also disables throttling of spam notifications.
-   */
-  private static class SimulatorSpamBindings extends SpamBindingsStub {
-    private final boolean isSpam;
-
-    SimulatorSpamBindings(boolean isSpam) {
-      this.isSpam = isSpam;
-    }
-
-    @Override
-    public boolean isSpamEnabled() {
-      return true;
-    }
-
-    @Override
-    public boolean isSpamNotificationEnabled() {
-      return true;
-    }
-
-    @Override
-    public int percentOfSpamNotificationsToShow() {
-      return 100;
-    }
-
-    @Override
-    public int percentOfNonSpamNotificationsToShow() {
-      return 100;
-    }
-
-    @Override
-    public void checkSpamStatus(String number, String countryIso, Listener listener) {
-      listener.onComplete(isSpam);
-    }
-  }
-}
diff --git a/java/com/android/dialer/spam/Spam.java b/java/com/android/dialer/spam/Spam.java
index 692a1a0..b1240c6 100644
--- a/java/com/android/dialer/spam/Spam.java
+++ b/java/com/android/dialer/spam/Spam.java
@@ -16,34 +16,150 @@
 
 package com.android.dialer.spam;
 
-import android.content.Context;
-import java.util.Objects;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import com.android.dialer.logging.ContactLookupResult;
+import com.android.dialer.logging.ContactSource;
+import com.android.dialer.logging.ReportingLocation;
 
-/** Accessor for the spam bindings. */
-public class Spam {
+/** Allows the container application to mark calls as spam. */
+public interface Spam {
 
-  private static SpamBindings spamBindings;
+  boolean isSpamEnabled();
 
-  private Spam() {}
+  boolean isSpamNotificationEnabled();
 
-  public static SpamBindings get(Context context) {
-    Objects.requireNonNull(context);
-    if (spamBindings != null) {
-      return spamBindings;
-    }
+  boolean isDialogEnabledForSpamNotification();
 
-    Context application = context.getApplicationContext();
-    if (application instanceof SpamBindingsFactory) {
-      spamBindings = ((SpamBindingsFactory) application).newSpamBindings();
-    }
+  boolean isDialogReportSpamCheckedByDefault();
 
-    if (spamBindings == null) {
-      spamBindings = new SpamBindingsStub();
-    }
-    return spamBindings;
-  }
+  /** @return what percentage of aftercall notifications to show to the user */
+  int percentOfSpamNotificationsToShow();
 
-  public static void setForTesting(SpamBindings spamBindings) {
-    Spam.spamBindings = spamBindings;
+  int percentOfNonSpamNotificationsToShow();
+
+  /**
+   * Checks if the given number is suspected of being a spamer.
+   *
+   * @param number The phone number of the call.
+   * @param countryIso The country ISO of the call.
+   * @param listener The callback to be invoked after {@code Info} is fetched.
+   */
+  void checkSpamStatus(String number, String countryIso, Listener listener);
+
+  /**
+   * @param number The number to check if the number is in the user's white list (non spam list)
+   * @param countryIso The country ISO of the call.
+   * @param listener The callback to be invoked after {@code Info} is fetched.
+   */
+  void checkUserMarkedNonSpamStatus(
+      String number, @Nullable String countryIso, @NonNull Listener listener);
+
+  /**
+   * @param number The number to check if it is in user's spam list
+   * @param countryIso The country ISO of the call.
+   * @param listener The callback to be invoked after {@code Info} is fetched.
+   */
+  void checkUserMarkedSpamStatus(
+      String number, @Nullable String countryIso, @NonNull Listener listener);
+
+  /**
+   * @param number The number to check if it is in the global spam list
+   * @param countryIso The country ISO of the call.
+   * @param listener The callback to be invoked after {@code Info} is fetched.
+   */
+  void checkGlobalSpamListStatus(
+      String number, @Nullable String countryIso, @NonNull Listener listener);
+
+  /**
+   * Synchronously checks if the given number is suspected of being a spamer.
+   *
+   * @param number The phone number of the call.
+   * @param countryIso The country ISO of the call.
+   * @return True if the number is spam.
+   */
+  boolean checkSpamStatusSynchronous(String number, String countryIso);
+
+  /**
+   * Reports number as spam.
+   *
+   * @param number The number to be reported.
+   * @param countryIso The country ISO of the number.
+   * @param callType Whether the type of call is missed, voicemail, etc. Example of this is {@link
+   *     android.provider.CallLog.Calls#VOICEMAIL_TYPE}.
+   * @param from Where in the dialer this was reported from. Must be one of {@link
+   *     com.android.dialer.logging.ReportingLocation}.
+   * @param contactLookupResultType The result of the contact lookup for this phone number. Must be
+   *     one of {@link com.android.dialer.logging.ContactLookupResult}.
+   */
+  void reportSpamFromAfterCallNotification(
+      String number,
+      String countryIso,
+      int callType,
+      ReportingLocation.Type from,
+      ContactLookupResult.Type contactLookupResultType);
+
+  /**
+   * Reports number as spam.
+   *
+   * @param number The number to be reported.
+   * @param countryIso The country ISO of the number.
+   * @param callType Whether the type of call is missed, voicemail, etc. Example of this is {@link
+   *     android.provider.CallLog.Calls#VOICEMAIL_TYPE}.
+   * @param from Where in the dialer this was reported from. Must be one of {@link
+   *     com.android.dialer.logging.ReportingLocation}.
+   * @param contactSourceType If we have cached contact information for the phone number, this
+   *     indicates its source. Must be one of {@link com.android.dialer.logging.ContactSource}.
+   */
+  void reportSpamFromCallHistory(
+      String number,
+      String countryIso,
+      int callType,
+      ReportingLocation.Type from,
+      ContactSource.Type contactSourceType);
+
+  /**
+   * Reports number as not spam.
+   *
+   * @param number The number to be reported.
+   * @param countryIso The country ISO of the number.
+   * @param callType Whether the type of call is missed, voicemail, etc. Example of this is {@link
+   *     android.provider.CallLog.Calls#VOICEMAIL_TYPE}.
+   * @param from Where in the dialer this was reported from. Must be one of {@link
+   *     com.android.dialer.logging.ReportingLocation}.
+   * @param contactLookupResultType The result of the contact lookup for this phone number. Must be
+   *     one of {@link com.android.dialer.logging.ContactLookupResult}.
+   */
+  void reportNotSpamFromAfterCallNotification(
+      String number,
+      String countryIso,
+      int callType,
+      ReportingLocation.Type from,
+      ContactLookupResult.Type contactLookupResultType);
+
+  /**
+   * Reports number as not spam.
+   *
+   * @param number The number to be reported.
+   * @param countryIso The country ISO of the number.
+   * @param callType Whether the type of call is missed, voicemail, etc. Example of this is {@link
+   *     android.provider.CallLog.Calls#VOICEMAIL_TYPE}.
+   * @param from Where in the dialer this was reported from. Must be one of {@link
+   *     com.android.dialer.logging.ReportingLocation}.
+   * @param contactSourceType If we have cached contact information for the phone number, this
+   *     indicates its source. Must be one of {@link com.android.dialer.logging.ContactSource}.
+   */
+  void reportNotSpamFromCallHistory(
+      String number,
+      String countryIso,
+      int callType,
+      ReportingLocation.Type from,
+      ContactSource.Type contactSourceType);
+
+  /** Callback to be invoked when data is fetched. */
+  interface Listener {
+
+    /** Called when data is fetched. */
+    void onComplete(boolean isSpam);
   }
 }
diff --git a/java/com/android/dialer/spam/SpamBindings.java b/java/com/android/dialer/spam/SpamBindings.java
deleted file mode 100644
index 5631da6..0000000
--- a/java/com/android/dialer/spam/SpamBindings.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dialer.spam;
-
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import com.android.dialer.logging.ContactLookupResult;
-import com.android.dialer.logging.ContactSource;
-import com.android.dialer.logging.ReportingLocation;
-
-/** Allows the container application to mark calls as spam. */
-public interface SpamBindings {
-
-  boolean isSpamEnabled();
-
-  boolean isSpamNotificationEnabled();
-
-  boolean isDialogEnabledForSpamNotification();
-
-  boolean isDialogReportSpamCheckedByDefault();
-
-  /** @return what percentage of aftercall notifications to show to the user */
-  int percentOfSpamNotificationsToShow();
-
-  int percentOfNonSpamNotificationsToShow();
-
-  /**
-   * Checks if the given number is suspected of being a spamer.
-   *
-   * @param number The phone number of the call.
-   * @param countryIso The country ISO of the call.
-   * @param listener The callback to be invoked after {@code Info} is fetched.
-   */
-  void checkSpamStatus(String number, String countryIso, Listener listener);
-
-  /**
-   * @param number The number to check if the number is in the user's white list (non spam list)
-   * @param countryIso The country ISO of the call.
-   * @param listener The callback to be invoked after {@code Info} is fetched.
-   */
-  void checkUserMarkedNonSpamStatus(
-      String number, @Nullable String countryIso, @NonNull Listener listener);
-
-  /**
-   * @param number The number to check if it is in user's spam list
-   * @param countryIso The country ISO of the call.
-   * @param listener The callback to be invoked after {@code Info} is fetched.
-   */
-  void checkUserMarkedSpamStatus(
-      String number, @Nullable String countryIso, @NonNull Listener listener);
-
-  /**
-   * @param number The number to check if it is in the global spam list
-   * @param countryIso The country ISO of the call.
-   * @param listener The callback to be invoked after {@code Info} is fetched.
-   */
-  void checkGlobalSpamListStatus(
-      String number, @Nullable String countryIso, @NonNull Listener listener);
-
-  /**
-   * Synchronously checks if the given number is suspected of being a spamer.
-   *
-   * @param number The phone number of the call.
-   * @param countryIso The country ISO of the call.
-   * @return True if the number is spam.
-   */
-  boolean checkSpamStatusSynchronous(String number, String countryIso);
-
-  /**
-   * Reports number as spam.
-   *
-   * @param number The number to be reported.
-   * @param countryIso The country ISO of the number.
-   * @param callType Whether the type of call is missed, voicemail, etc. Example of this is {@link
-   *     android.provider.CallLog.Calls#VOICEMAIL_TYPE}.
-   * @param from Where in the dialer this was reported from. Must be one of {@link
-   *     com.android.dialer.logging.ReportingLocation}.
-   * @param contactLookupResultType The result of the contact lookup for this phone number. Must be
-   *     one of {@link com.android.dialer.logging.ContactLookupResult}.
-   */
-  void reportSpamFromAfterCallNotification(
-      String number,
-      String countryIso,
-      int callType,
-      ReportingLocation.Type from,
-      ContactLookupResult.Type contactLookupResultType);
-
-  /**
-   * Reports number as spam.
-   *
-   * @param number The number to be reported.
-   * @param countryIso The country ISO of the number.
-   * @param callType Whether the type of call is missed, voicemail, etc. Example of this is {@link
-   *     android.provider.CallLog.Calls#VOICEMAIL_TYPE}.
-   * @param from Where in the dialer this was reported from. Must be one of {@link
-   *     com.android.dialer.logging.ReportingLocation}.
-   * @param contactSourceType If we have cached contact information for the phone number, this
-   *     indicates its source. Must be one of {@link com.android.dialer.logging.ContactSource}.
-   */
-  void reportSpamFromCallHistory(
-      String number,
-      String countryIso,
-      int callType,
-      ReportingLocation.Type from,
-      ContactSource.Type contactSourceType);
-
-  /**
-   * Reports number as not spam.
-   *
-   * @param number The number to be reported.
-   * @param countryIso The country ISO of the number.
-   * @param callType Whether the type of call is missed, voicemail, etc. Example of this is {@link
-   *     android.provider.CallLog.Calls#VOICEMAIL_TYPE}.
-   * @param from Where in the dialer this was reported from. Must be one of {@link
-   *     com.android.dialer.logging.ReportingLocation}.
-   * @param contactLookupResultType The result of the contact lookup for this phone number. Must be
-   *     one of {@link com.android.dialer.logging.ContactLookupResult}.
-   */
-  void reportNotSpamFromAfterCallNotification(
-      String number,
-      String countryIso,
-      int callType,
-      ReportingLocation.Type from,
-      ContactLookupResult.Type contactLookupResultType);
-
-  /**
-   * Reports number as not spam.
-   *
-   * @param number The number to be reported.
-   * @param countryIso The country ISO of the number.
-   * @param callType Whether the type of call is missed, voicemail, etc. Example of this is {@link
-   *     android.provider.CallLog.Calls#VOICEMAIL_TYPE}.
-   * @param from Where in the dialer this was reported from. Must be one of {@link
-   *     com.android.dialer.logging.ReportingLocation}.
-   * @param contactSourceType If we have cached contact information for the phone number, this
-   *     indicates its source. Must be one of {@link com.android.dialer.logging.ContactSource}.
-   */
-  void reportNotSpamFromCallHistory(
-      String number,
-      String countryIso,
-      int callType,
-      ReportingLocation.Type from,
-      ContactSource.Type contactSourceType);
-
-  /** Callback to be invoked when data is fetched. */
-  interface Listener {
-
-    /** Called when data is fetched. */
-    void onComplete(boolean isSpam);
-  }
-}
diff --git a/java/com/android/dialer/spam/SpamComponent.java b/java/com/android/dialer/spam/SpamComponent.java
new file mode 100644
index 0000000..0bcdafa
--- /dev/null
+++ b/java/com/android/dialer/spam/SpamComponent.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.dialer.spam;
+
+import android.content.Context;
+import com.android.dialer.inject.HasRootComponent;
+import dagger.Subcomponent;
+
+/** Dagger component to get Spam. */
+@Subcomponent
+public abstract class SpamComponent {
+
+  public abstract Spam spam();
+
+  public static SpamComponent get(Context context) {
+    return ((SpamComponent.HasComponent)
+            ((HasRootComponent) context.getApplicationContext()).component())
+        .spamComponent();
+  }
+
+  /** Used to refer to the root application component. */
+  public interface HasComponent {
+    SpamComponent spamComponent();
+  }
+}
diff --git a/java/com/android/dialer/spam/SpamBindingsStub.java b/java/com/android/dialer/spam/SpamStub.java
similarity index 95%
rename from java/com/android/dialer/spam/SpamBindingsStub.java
rename to java/com/android/dialer/spam/SpamStub.java
index b815dc9..daa475c 100644
--- a/java/com/android/dialer/spam/SpamBindingsStub.java
+++ b/java/com/android/dialer/spam/SpamStub.java
@@ -19,9 +19,13 @@
 import com.android.dialer.logging.ContactLookupResult;
 import com.android.dialer.logging.ContactSource;
 import com.android.dialer.logging.ReportingLocation;
+import javax.inject.Inject;
 
-/** Default implementation of SpamBindings. */
-public class SpamBindingsStub implements SpamBindings {
+/** Default implementation of Spam. */
+public class SpamStub implements Spam {
+
+  @Inject
+  public SpamStub() {}
 
   @Override
   public boolean isSpamEnabled() {
diff --git a/java/com/android/dialer/spam/SpamBindingsFactory.java b/java/com/android/dialer/spam/StubSpamModule.java
similarity index 75%
rename from java/com/android/dialer/spam/SpamBindingsFactory.java
rename to java/com/android/dialer/spam/StubSpamModule.java
index 41144e1..0d3b917 100644
--- a/java/com/android/dialer/spam/SpamBindingsFactory.java
+++ b/java/com/android/dialer/spam/StubSpamModule.java
@@ -16,11 +16,13 @@
 
 package com.android.dialer.spam;
 
-/**
- * This interface should be implementated by the Application subclass. It allows this module to get
- * references to the SpamBindings.
- */
-public interface SpamBindingsFactory {
+import dagger.Binds;
+import dagger.Module;
 
-  SpamBindings newSpamBindings();
+/** Module which binds {@link SpamStub}. */
+@Module
+public abstract class StubSpamModule {
+
+  @Binds
+  public abstract Spam bindSpam(SpamStub stub);
 }
diff --git a/java/com/android/incallui/call/CallList.java b/java/com/android/incallui/call/CallList.java
index fd43a4a..d2ac483 100644
--- a/java/com/android/incallui/call/CallList.java
+++ b/java/com/android/incallui/call/CallList.java
@@ -39,7 +39,7 @@
 import com.android.dialer.logging.LoggingBindings;
 import com.android.dialer.shortcuts.ShortcutUsageReporter;
 import com.android.dialer.spam.Spam;
-import com.android.dialer.spam.SpamBindings;
+import com.android.dialer.spam.SpamComponent;
 import com.android.incallui.call.DialerCall.State;
 import com.android.incallui.latencyreport.LatencyReport;
 import com.android.incallui.util.TelecomCallUtil;
@@ -141,13 +141,14 @@
     Trace.beginSection("checkSpam");
     call.addListener(new DialerCallListenerImpl(call));
     LogUtil.d("CallList.onCallAdded", "callState=" + call.getState());
-    if (Spam.get(context).isSpamEnabled()) {
+    if (SpamComponent.get(context).spam().isSpamEnabled()) {
       String number = TelecomCallUtil.getNumber(telecomCall);
-      Spam.get(context)
+      SpamComponent.get(context)
+          .spam()
           .checkSpamStatus(
               number,
               call.getCountryIso(),
-              new SpamBindings.Listener() {
+              new Spam.Listener() {
                 @Override
                 public void onComplete(boolean isSpam) {
                   boolean isIncomingCall =
@@ -262,33 +263,36 @@
   private void updateUserMarkedSpamStatus(
       final DialerCall call, final Context context, String number) {
 
-    Spam.get(context)
+    SpamComponent.get(context)
+        .spam()
         .checkUserMarkedNonSpamStatus(
             number,
             call.getCountryIso(),
-            new SpamBindings.Listener() {
+            new Spam.Listener() {
               @Override
               public void onComplete(boolean isInUserWhiteList) {
                 call.setIsInUserWhiteList(isInUserWhiteList);
               }
             });
 
-    Spam.get(context)
+    SpamComponent.get(context)
+        .spam()
         .checkGlobalSpamListStatus(
             number,
             call.getCountryIso(),
-            new SpamBindings.Listener() {
+            new Spam.Listener() {
               @Override
               public void onComplete(boolean isInGlobalSpamList) {
                 call.setIsInGlobalSpamList(isInGlobalSpamList);
               }
             });
 
-    Spam.get(context)
+    SpamComponent.get(context)
+        .spam()
         .checkUserMarkedSpamStatus(
             number,
             call.getCountryIso(),
-            new SpamBindings.Listener() {
+            new Spam.Listener() {
               @Override
               public void onComplete(boolean isInUserSpamList) {
                 call.setIsInUserSpamList(isInUserSpamList);
diff --git a/java/com/android/incallui/spam/SpamCallListListener.java b/java/com/android/incallui/spam/SpamCallListListener.java
index cf545c0..fa3dd6e 100644
--- a/java/com/android/incallui/spam/SpamCallListListener.java
+++ b/java/com/android/incallui/spam/SpamCallListListener.java
@@ -47,7 +47,7 @@
 import com.android.dialer.logging.Logger;
 import com.android.dialer.notification.DialerNotificationManager;
 import com.android.dialer.notification.NotificationChannelId;
-import com.android.dialer.spam.Spam;
+import com.android.dialer.spam.SpamComponent;
 import com.android.dialer.telecom.TelecomUtil;
 import com.android.dialer.util.PermissionsUtil;
 import com.android.incallui.call.CallList;
@@ -205,7 +205,7 @@
 
   /** Determines if the after call notification should be shown for the specified call. */
   private boolean shouldShowAfterCallNotification(DialerCall call) {
-    if (!Spam.get(context).isSpamNotificationEnabled()) {
+    if (!SpamComponent.get(context).spam().isSpamNotificationEnabled()) {
       return false;
     }
 
@@ -304,7 +304,7 @@
 
   private boolean shouldThrottleSpamNotification() {
     int randomNumber = random.nextInt(100);
-    int thresholdForShowing = Spam.get(context).percentOfSpamNotificationsToShow();
+    int thresholdForShowing = SpamComponent.get(context).spam().percentOfSpamNotificationsToShow();
     if (thresholdForShowing == 0) {
       LogUtil.d(
           "SpamCallListListener.shouldThrottleSpamNotification",
@@ -327,7 +327,8 @@
 
   private boolean shouldThrottleNonSpamNotification() {
     int randomNumber = random.nextInt(100);
-    int thresholdForShowing = Spam.get(context).percentOfNonSpamNotificationsToShow();
+    int thresholdForShowing =
+        SpamComponent.get(context).spam().percentOfNonSpamNotificationsToShow();
     if (thresholdForShowing == 0) {
       LogUtil.d(
           "SpamCallListListener.shouldThrottleNonSpamNotification",
@@ -419,7 +420,7 @@
    */
   private PendingIntent createBlockReportSpamPendingIntent(DialerCall call) {
     String action = SpamNotificationActivity.ACTION_MARK_NUMBER_AS_SPAM;
-    return Spam.get(context).isDialogEnabledForSpamNotification()
+    return SpamComponent.get(context).spam().isDialogEnabledForSpamNotification()
         ? createActivityPendingIntent(call, action)
         : createServicePendingIntent(call, action);
   }
@@ -430,7 +431,7 @@
    */
   private PendingIntent createNotSpamPendingIntent(DialerCall call) {
     String action = SpamNotificationActivity.ACTION_MARK_NUMBER_AS_NOT_SPAM;
-    return Spam.get(context).isDialogEnabledForSpamNotification()
+    return SpamComponent.get(context).spam().isDialogEnabledForSpamNotification()
         ? createActivityPendingIntent(call, action)
         : createServicePendingIntent(call, action);
   }
diff --git a/java/com/android/incallui/spam/SpamNotificationActivity.java b/java/com/android/incallui/spam/SpamNotificationActivity.java
index f5ea73c..ceb9ebb 100644
--- a/java/com/android/incallui/spam/SpamNotificationActivity.java
+++ b/java/com/android/incallui/spam/SpamNotificationActivity.java
@@ -38,7 +38,7 @@
 import com.android.dialer.logging.Logger;
 import com.android.dialer.logging.ReportingLocation;
 import com.android.dialer.notification.DialerNotificationManager;
-import com.android.dialer.spam.Spam;
+import com.android.dialer.spam.SpamComponent;
 import com.android.incallui.call.DialerCall;
 
 /** Creates the after call notification dialogs. */
@@ -188,7 +188,7 @@
   /** Creates and displays the dialog for whitelisting a number. */
   private void maybeShowNotSpamDialog(
       final String number, final ContactLookupResult.Type contactLookupResultType) {
-    if (Spam.get(this).isDialogEnabledForSpamNotification()) {
+    if (SpamComponent.get(this).spam().isDialogEnabledForSpamNotification()) {
       BlockReportSpamDialogs.ReportNotSpamDialogFragment.newInstance(
               getFormattedNumber(number),
               new BlockReportSpamDialogs.OnConfirmListener() {
@@ -207,14 +207,16 @@
   /** Creates and displays the dialog for blocking/reporting a number as spam. */
   private void maybeShowBlockReportSpamDialog(
       final String number, final ContactLookupResult.Type contactLookupResultType) {
-    if (Spam.get(this).isDialogEnabledForSpamNotification()) {
+    if (SpamComponent.get(this).spam().isDialogEnabledForSpamNotification()) {
       maybeShowBlockNumberMigrationDialog(
           new BlockedNumbersMigrator.Listener() {
             @Override
             public void onComplete() {
               BlockReportSpamDialogs.BlockReportSpamDialogFragment.newInstance(
                       getFormattedNumber(number),
-                      Spam.get(SpamNotificationActivity.this).isDialogReportSpamCheckedByDefault(),
+                      SpamComponent.get(SpamNotificationActivity.this)
+                          .spam()
+                          .isDialogReportSpamCheckedByDefault(),
                       new BlockReportSpamDialogs.OnSpamDialogClickListener() {
                         @Override
                         public void onClick(boolean isSpamChecked) {
@@ -263,7 +265,8 @@
       String number, boolean reportAsSpam, ContactLookupResult.Type contactLookupResultType) {
     if (reportAsSpam) {
       logCallImpression(DialerImpression.Type.SPAM_AFTER_CALL_NOTIFICATION_MARKED_NUMBER_AS_SPAM);
-      Spam.get(this)
+      SpamComponent.get(this)
+          .spam()
           .reportSpamFromAfterCallNotification(
               number,
               getCountryIso(),
@@ -282,7 +285,8 @@
   private void reportNotSpamAndFinish(
       String number, ContactLookupResult.Type contactLookupResultType) {
     logCallImpression(DialerImpression.Type.SPAM_AFTER_CALL_NOTIFICATION_REPORT_NUMBER_AS_NOT_SPAM);
-    Spam.get(this)
+    SpamComponent.get(this)
+        .spam()
         .reportNotSpamFromAfterCallNotification(
             number,
             getCountryIso(),
@@ -305,7 +309,7 @@
   }
 
   private void assertDialogsEnabled() {
-    if (!Spam.get(this).isDialogEnabledForSpamNotification()) {
+    if (!SpamComponent.get(this).spam().isDialogEnabledForSpamNotification()) {
       throw new IllegalStateException(
           "Cannot start this activity with given action because dialogs are not enabled.");
     }
diff --git a/java/com/android/incallui/spam/SpamNotificationService.java b/java/com/android/incallui/spam/SpamNotificationService.java
index 3c1061a..b85ab11 100644
--- a/java/com/android/incallui/spam/SpamNotificationService.java
+++ b/java/com/android/incallui/spam/SpamNotificationService.java
@@ -30,7 +30,7 @@
 import com.android.dialer.logging.Logger;
 import com.android.dialer.logging.ReportingLocation;
 import com.android.dialer.notification.DialerNotificationManager;
-import com.android.dialer.spam.Spam;
+import com.android.dialer.spam.SpamComponent;
 import com.android.incallui.call.DialerCall;
 
 /**
@@ -95,7 +95,8 @@
       case SpamNotificationActivity.ACTION_MARK_NUMBER_AS_SPAM:
         logCallImpression(
             intent, DialerImpression.Type.SPAM_NOTIFICATION_SERVICE_ACTION_MARK_NUMBER_AS_SPAM);
-        Spam.get(this)
+        SpamComponent.get(this)
+            .spam()
             .reportSpamFromAfterCallNotification(
                 number,
                 countryIso,
@@ -107,7 +108,8 @@
       case SpamNotificationActivity.ACTION_MARK_NUMBER_AS_NOT_SPAM:
         logCallImpression(
             intent, DialerImpression.Type.SPAM_NOTIFICATION_SERVICE_ACTION_MARK_NUMBER_AS_NOT_SPAM);
-        Spam.get(this)
+        SpamComponent.get(this)
+            .spam()
             .reportNotSpamFromAfterCallNotification(
                 number,
                 countryIso,