Merge commit '8b1c13424270cbe4f0b6bc426f0ff80888b87114' into manual_merge_8b1c13424270cbe4f0b6bc426f0ff80888b87114 am: d85a75b72d am: 431ecaf792
am: 575f33da7d

Change-Id: I62b9fc39e1d586ac0308e787ecbe6a578b2efc3e
diff --git a/src/com/android/server/telecom/CallsManager.java b/src/com/android/server/telecom/CallsManager.java
index 02ad6a5..a2953fc 100644
--- a/src/com/android/server/telecom/CallsManager.java
+++ b/src/com/android/server/telecom/CallsManager.java
@@ -79,6 +79,7 @@
 import com.android.server.telecom.callfiltering.BlockCheckerAdapter;
 import com.android.server.telecom.callfiltering.CallFilterResultCallback;
 import com.android.server.telecom.callfiltering.CallFilteringResult;
+import com.android.server.telecom.callfiltering.CallFilteringResult.Builder;
 import com.android.server.telecom.callfiltering.CallScreeningServiceController;
 import com.android.server.telecom.callfiltering.DirectToVoicemailCallFilter;
 import com.android.server.telecom.callfiltering.IncomingCallFilter;
@@ -610,7 +611,12 @@
                     incomingCall.hasProperty(Connection.PROPERTY_EMERGENCY_CALLBACK_MODE),
                     incomingCall.isSelfManaged(),
                     extras.getBoolean(PhoneAccount.EXTRA_SKIP_CALL_FILTERING));
-            onCallFilteringComplete(incomingCall, new CallFilteringResult(true, false, true, true));
+            onCallFilteringComplete(incomingCall, new Builder()
+                    .setShouldAllowCall(true)
+                    .setShouldReject(false)
+                    .setShouldAddToCallLog(true)
+                    .setShouldShowNotification(true)
+                    .build());
             incomingCall.setIsUsingCallFiltering(false);
             return;
         }
diff --git a/src/com/android/server/telecom/LogUtils.java b/src/com/android/server/telecom/LogUtils.java
index 1e82fc0..f55fa2c 100644
--- a/src/com/android/server/telecom/LogUtils.java
+++ b/src/com/android/server/telecom/LogUtils.java
@@ -137,6 +137,7 @@
         public static final String BIND_SCREENING = "BIND_SCREENING";
         public static final String SCREENING_BOUND = "SCREENING_BOUND";
         public static final String SCREENING_SENT = "SCREENING_SENT";
+        public static final String SCREENING_SKIPPED = "SCREENING_SKIPPED";
         public static final String CONTROLLER_SCREENING_COMPLETED =
                 "CONTROLLER_SCREENING_COMPLETED";
         public static final String SCREENING_COMPLETED = "SCREENING_COMPLETED";
diff --git a/src/com/android/server/telecom/callfiltering/AsyncBlockCheckFilter.java b/src/com/android/server/telecom/callfiltering/AsyncBlockCheckFilter.java
index a594af5..fbc79e6 100644
--- a/src/com/android/server/telecom/callfiltering/AsyncBlockCheckFilter.java
+++ b/src/com/android/server/telecom/callfiltering/AsyncBlockCheckFilter.java
@@ -30,6 +30,7 @@
 import com.android.server.telecom.Call;
 import com.android.server.telecom.CallerInfoLookupHelper;
 import com.android.server.telecom.LogUtils;
+import com.android.server.telecom.callfiltering.CallFilteringResult.Builder;
 import com.android.server.telecom.settings.BlockedNumbersUtil;
 
 /**
@@ -121,15 +122,15 @@
         try {
             CallFilteringResult result;
             if (isBlocked) {
-                result = new CallFilteringResult(
-                        false, // shouldAllowCall
-                        true, //shouldReject
-                        true, //shouldAddToCallLog
-                        false, // shouldShowNotification
-                        convertBlockStatusToReason(), //callBlockReason
-                        null, //callScreeningAppName
-                        null //callScreeningComponentName
-                );
+                result = new Builder()
+                        .setShouldAllowCall(false)
+                        .setShouldReject(true)
+                        .setShouldAddToCallLog(true)
+                        .setShouldShowNotification(false)
+                        .setCallBlockReason(convertBlockStatusToReason())
+                        .setCallScreeningAppName(null)
+                        .setCallScreeningComponentName(null)
+                        .build();
                 if (mCallBlockListener != null) {
                     String number = mIncomingCall.getHandle() == null ? null
                             : mIncomingCall.getHandle().getSchemeSpecificPart();
@@ -137,12 +138,12 @@
                             mIncomingCall.getInitiatingUser());
                 }
             } else {
-                result = new CallFilteringResult(
-                        true, // shouldAllowCall
-                        false, // shouldReject
-                        true, // shouldAddToCallLog
-                        true // shouldShowNotification
-                );
+                result = new Builder()
+                        .setShouldAllowCall(true)
+                        .setShouldReject(false)
+                        .setShouldAddToCallLog(true)
+                        .setShouldShowNotification(true)
+                        .build();
             }
             Log.addEvent(mIncomingCall, LogUtils.Events.BLOCK_CHECK_FINISHED,
                     BlockedNumberContract.SystemContract.blockStatusToString(mBlockStatus) + " "
diff --git a/src/com/android/server/telecom/callfiltering/CallFilteringResult.java b/src/com/android/server/telecom/callfiltering/CallFilteringResult.java
index af3ee1e..028fbf5 100644
--- a/src/com/android/server/telecom/callfiltering/CallFilteringResult.java
+++ b/src/com/android/server/telecom/callfiltering/CallFilteringResult.java
@@ -21,47 +21,73 @@
 import android.text.TextUtils;
 
 public class CallFilteringResult {
+    public static class Builder {
+        private boolean mShouldAllowCall;
+        private boolean mShouldReject;
+        private boolean mShouldAddToCallLog;
+        private boolean mShouldShowNotification;
+        private boolean mShouldSilence = false;
+        private int mCallBlockReason = Calls.BLOCK_REASON_NOT_BLOCKED;
+        private CharSequence mCallScreeningAppName = null;
+        private String mCallScreeningComponentName = null;
+
+        public Builder setShouldAllowCall(boolean shouldAllowCall) {
+            mShouldAllowCall = shouldAllowCall;
+            return this;
+        }
+
+        public Builder setShouldReject(boolean shouldReject) {
+            mShouldReject = shouldReject;
+            return this;
+        }
+
+        public Builder setShouldAddToCallLog(boolean shouldAddToCallLog) {
+            mShouldAddToCallLog = shouldAddToCallLog;
+            return this;
+        }
+
+        public Builder setShouldShowNotification(boolean shouldShowNotification) {
+            mShouldShowNotification = shouldShowNotification;
+            return this;
+        }
+
+        public Builder setShouldSilence(boolean shouldSilence) {
+            mShouldSilence = shouldSilence;
+            return this;
+        }
+
+        public Builder setCallBlockReason(int callBlockReason) {
+            mCallBlockReason = callBlockReason;
+            return this;
+        }
+
+        public Builder setCallScreeningAppName(CharSequence callScreeningAppName) {
+            mCallScreeningAppName = callScreeningAppName;
+            return this;
+        }
+
+        public Builder setCallScreeningComponentName(String callScreeningComponentName) {
+            mCallScreeningComponentName = callScreeningComponentName;
+            return this;
+        }
+
+        public CallFilteringResult build() {
+            return new CallFilteringResult(mShouldAllowCall, mShouldReject, mShouldSilence,
+                    mShouldAddToCallLog, mShouldShowNotification, mCallBlockReason,
+                    mCallScreeningAppName, mCallScreeningComponentName);
+        }
+    }
+
     public boolean shouldAllowCall;
     public boolean shouldReject;
     public boolean shouldSilence;
     public boolean shouldAddToCallLog;
     public boolean shouldShowNotification;
-    public int mCallBlockReason = CallLog.Calls.BLOCK_REASON_NOT_BLOCKED;
-    public CharSequence mCallScreeningAppName = null;
-    public String mCallScreeningComponentName = null;
+    public int mCallBlockReason;
+    public CharSequence mCallScreeningAppName;
+    public String mCallScreeningComponentName;
 
-    public CallFilteringResult(boolean shouldAllowCall, boolean shouldReject, boolean
-            shouldAddToCallLog, boolean shouldShowNotification) {
-        this.shouldAllowCall = shouldAllowCall;
-        this.shouldReject = shouldReject;
-        this.shouldSilence = false;
-        this.shouldAddToCallLog = shouldAddToCallLog;
-        this.shouldShowNotification = shouldShowNotification;
-    }
-
-    public CallFilteringResult(boolean shouldAllowCall, boolean shouldReject, boolean
-            shouldAddToCallLog, boolean shouldShowNotification, int callBlockReason,
-            CharSequence callScreeningAppName, String callScreeningComponentName) {
-        this.shouldAllowCall = shouldAllowCall;
-        this.shouldReject = shouldReject;
-        this.shouldSilence = false;
-        this.shouldAddToCallLog = shouldAddToCallLog;
-        this.shouldShowNotification = shouldShowNotification;
-        this.mCallBlockReason = callBlockReason;
-        this.mCallScreeningAppName = callScreeningAppName;
-        this.mCallScreeningComponentName = callScreeningComponentName;
-    }
-
-    public CallFilteringResult(boolean shouldAllowCall, boolean shouldReject, boolean
-            shouldSilence, boolean shouldAddToCallLog, boolean shouldShowNotification) {
-        this.shouldAllowCall = shouldAllowCall;
-        this.shouldReject = shouldReject;
-        this.shouldSilence = shouldSilence;
-        this.shouldAddToCallLog = shouldAddToCallLog;
-        this.shouldShowNotification = shouldShowNotification;
-    }
-
-    public CallFilteringResult(boolean shouldAllowCall, boolean shouldReject, boolean
+    private CallFilteringResult(boolean shouldAllowCall, boolean shouldReject, boolean
             shouldSilence, boolean shouldAddToCallLog, boolean shouldShowNotification, int
             callBlockReason, CharSequence callScreeningAppName, String callScreeningComponentName) {
         this.shouldAllowCall = shouldAllowCall;
@@ -109,12 +135,13 @@
                 other.mCallScreeningAppName, other.mCallScreeningComponentName);
         }
 
-        return new CallFilteringResult(
-            shouldAllowCall && other.shouldAllowCall,
-            shouldReject || other.shouldReject,
-            shouldSilence || other.shouldSilence,
-            shouldAddToCallLog && other.shouldAddToCallLog,
-            shouldShowNotification && other.shouldShowNotification);
+        return new Builder()
+                .setShouldAllowCall(shouldAllowCall && other.shouldAllowCall)
+                .setShouldReject(shouldReject || other.shouldReject)
+                .setShouldSilence(shouldSilence || other.shouldSilence)
+                .setShouldAddToCallLog(shouldAddToCallLog && other.shouldAddToCallLog)
+                .setShouldShowNotification(shouldShowNotification && other.shouldShowNotification)
+                .build();
     }
 
     private boolean isBlockedByProvider(int blockReason) {
@@ -131,15 +158,16 @@
 
     private CallFilteringResult getCombinedCallFilteringResult(CallFilteringResult other,
         int callBlockReason, CharSequence callScreeningAppName, String callScreeningComponentName) {
-        return new CallFilteringResult(
-            shouldAllowCall && other.shouldAllowCall,
-            shouldReject || other.shouldReject,
-            shouldSilence|| other.shouldSilence,
-            shouldAddToCallLog && other.shouldAddToCallLog,
-            shouldShowNotification && other.shouldShowNotification,
-            callBlockReason,
-            callScreeningAppName,
-            callScreeningComponentName);
+        return new Builder()
+                .setShouldAllowCall(shouldAllowCall && other.shouldAllowCall)
+                .setShouldReject(shouldReject || other.shouldReject)
+                .setShouldSilence(shouldSilence || other.shouldSilence)
+                .setShouldAddToCallLog(shouldAddToCallLog && other.shouldAddToCallLog)
+                .setShouldShowNotification(shouldShowNotification && other.shouldShowNotification)
+                .setCallBlockReason(callBlockReason)
+                .setCallScreeningAppName(callScreeningAppName)
+                .setCallScreeningComponentName(callScreeningComponentName)
+                .build();
     }
 
 
diff --git a/src/com/android/server/telecom/callfiltering/CallScreeningServiceController.java b/src/com/android/server/telecom/callfiltering/CallScreeningServiceController.java
index c8cc2f7..249d878 100644
--- a/src/com/android/server/telecom/callfiltering/CallScreeningServiceController.java
+++ b/src/com/android/server/telecom/callfiltering/CallScreeningServiceController.java
@@ -39,6 +39,7 @@
 import com.android.server.telecom.PhoneAccountRegistrar;
 import com.android.server.telecom.TelecomServiceImpl;
 import com.android.server.telecom.TelecomSystem;
+import com.android.server.telecom.callfiltering.CallFilteringResult.Builder;
 
 /**
  * This class supports binding to the various {@link android.telecom.CallScreeningService}:
@@ -66,12 +67,12 @@
     private Call mCall;
     private CallFilterResultCallback mCallback;
 
-    private CallFilteringResult mResult = new CallFilteringResult(
-            true, // shouldAllowCall
-            false, // shouldReject
-            true, // shouldAddToCallLog
-            true // shouldShowNotification
-    );
+    private CallFilteringResult mResult = new Builder()
+            .setShouldAllowCall(true)
+            .setShouldReject(false)
+            .setShouldAddToCallLog(true)
+            .setShouldShowNotification(true)
+            .build();
 
     private boolean mIsFinished;
     private boolean mIsCarrierFinished;
@@ -195,10 +196,18 @@
             if (TextUtils.isEmpty(userChosenPackageName)) {
                 mIsUserChosenFinished = true;
             } else {
-                createCallScreeningServiceFilter().startCallScreeningFilter(mCall,
-                        CallScreeningServiceController.this, userChosenPackageName,
-                        mAppLabelProxy.getAppLabel(userChosenPackageName),
-                        CallScreeningServiceFilter.CALL_SCREENING_FILTER_TYPE_USER_SELECTED);
+                // If the user chosen call screening service is the same as the default dialer, then
+                // we have already bound to it above and don't need to do so again here.
+                if (userChosenPackageName.equals(dialerPackageName)) {
+                    Log.addEvent(mCall, LogUtils.Events.SCREENING_SKIPPED,
+                            "user pkg same as dialer: " + userChosenPackageName);
+                    mIsUserChosenFinished = true;
+                } else {
+                    createCallScreeningServiceFilter().startCallScreeningFilter(mCall,
+                            CallScreeningServiceController.this, userChosenPackageName,
+                            mAppLabelProxy.getAppLabel(userChosenPackageName),
+                            CallScreeningServiceFilter.CALL_SCREENING_FILTER_TYPE_USER_SELECTED);
+                }
             }
 
             if (mIsDefaultDialerFinished && mIsUserChosenFinished) {
diff --git a/src/com/android/server/telecom/callfiltering/CallScreeningServiceFilter.java b/src/com/android/server/telecom/callfiltering/CallScreeningServiceFilter.java
index 2a0e338..9ea8d70 100644
--- a/src/com/android/server/telecom/callfiltering/CallScreeningServiceFilter.java
+++ b/src/com/android/server/telecom/callfiltering/CallScreeningServiceFilter.java
@@ -24,7 +24,7 @@
 import android.os.PersistableBundle;
 import android.os.RemoteException;
 import android.os.UserHandle;
-import android.provider.CallLog;
+import android.provider.CallLog.Calls;
 import android.provider.Settings;
 import android.telecom.Log;
 import android.telecom.TelecomManager;
@@ -41,6 +41,7 @@
 import com.android.server.telecom.PhoneAccountRegistrar;
 import com.android.server.telecom.TelecomServiceImpl.SettingsSecureAdapter;
 import com.android.server.telecom.TelecomSystem;
+import com.android.server.telecom.callfiltering.CallFilteringResult.Builder;
 
 /**
  * Binds to {@link ICallScreeningService} to allow call blocking. A single instance of this class
@@ -96,13 +97,13 @@
                 synchronized (mTelecomLock) {
                     Log.d(this, "allowCall(%s)", callId);
                     if (mCall != null && mCall.getId().equals(callId)) {
-                        mResult = new CallFilteringResult(
-                                true, // shouldAllowCall
-                                false, //shouldReject
-                                false, //shouldSilence
-                                true, //shouldAddToCallLog
-                                true // shouldShowNotification
-                        );
+                        mResult = new Builder()
+                                .setShouldAllowCall(true)
+                                .setShouldReject(false)
+                                .setShouldSilence(false)
+                                .setShouldAddToCallLog(true)
+                                .setShouldShowNotification(true)
+                                .build();
                     } else {
                         Log.w(this, "allowCall, unknown call id: %s", callId);
                     }
@@ -131,16 +132,16 @@
                                     + "shouldShowNotification: %b", callId, shouldReject,
                             isServiceRequestingLogging, shouldShowNotification);
                     if (mCall != null && mCall.getId().equals(callId)) {
-                        mResult = new CallFilteringResult(
-                                false, // shouldAllowCall
-                                shouldReject, //shouldReject
-                                false, // shouldSilenceCall
-                                isServiceRequestingLogging, //shouldAddToCallLog
-                                shouldShowNotification, // shouldShowNotification
-                                CallLog.Calls.BLOCK_REASON_CALL_SCREENING_SERVICE, //callBlockReason
-                                mAppName, //callScreeningAppName
-                                componentName.flattenToString() //callScreeningComponentName
-                        );
+                        mResult = new Builder()
+                                .setShouldAllowCall(false)
+                                .setShouldReject(shouldReject)
+                                .setShouldSilence(false)
+                                .setShouldAddToCallLog(isServiceRequestingLogging)
+                                .setShouldShowNotification(shouldShowNotification)
+                                .setCallBlockReason(Calls.BLOCK_REASON_CALL_SCREENING_SERVICE)
+                                .setCallScreeningAppName(mAppName)
+                                .setCallScreeningComponentName(componentName.flattenToString())
+                                .build();
                     } else {
                         Log.w(this, "disallowCall, unknown call id: %s", callId);
                     }
@@ -160,13 +161,13 @@
                 synchronized (mTelecomLock) {
                     Log.d(this, "silenceCall(%s)", callId);
                     if (mCall != null && mCall.getId().equals(callId)) {
-                        mResult = new CallFilteringResult(
-                                true, // shouldAllowCall
-                                false, //shouldReject
-                                true, //shouldSilence
-                                true, //shouldAddToCallLog
-                                true // shouldShowNotification
-                        );
+                        mResult = new Builder()
+                                .setShouldAllowCall(true)
+                                .setShouldReject(false)
+                                .setShouldSilence(true)
+                                .setShouldAddToCallLog(true)
+                                .setShouldShowNotification(true)
+                                .build();
                     } else {
                         Log.w(this, "silenceCall, unknown call id: %s", callId);
                     }
@@ -199,12 +200,12 @@
     private boolean mHasFinished = false;
     private int mCallScreeningServiceType;
 
-    private CallFilteringResult mResult = new CallFilteringResult(
-            true, // shouldAllowCall
-            false, //shouldReject
-            true, //shouldAddToCallLog
-            true // shouldShowNotification
-    );
+    private CallFilteringResult mResult = new Builder()
+            .setShouldAllowCall(true)
+            .setShouldReject(false)
+            .setShouldAddToCallLog(true)
+            .setShouldShowNotification(true)
+            .build();
 
     public CallScreeningServiceFilter(
             Context context,
diff --git a/src/com/android/server/telecom/callfiltering/DirectToVoicemailCallFilter.java b/src/com/android/server/telecom/callfiltering/DirectToVoicemailCallFilter.java
index 419e2ba..8992a3b 100644
--- a/src/com/android/server/telecom/callfiltering/DirectToVoicemailCallFilter.java
+++ b/src/com/android/server/telecom/callfiltering/DirectToVoicemailCallFilter.java
@@ -17,13 +17,14 @@
 package com.android.server.telecom.callfiltering;
 
 import android.net.Uri;
-import android.provider.CallLog;
+import android.provider.CallLog.Calls;
 import android.telecom.Log;
 
 import android.telephony.CallerInfo;
 import com.android.server.telecom.Call;
 import com.android.server.telecom.CallerInfoLookupHelper;
 import com.android.server.telecom.LogUtils;
+import com.android.server.telecom.callfiltering.CallFilteringResult.Builder;
 
 import java.util.Objects;
 
@@ -46,33 +47,32 @@
                         CallFilteringResult result;
                         if ((handle != null) && Objects.equals(callHandle, handle)) {
                             if (info != null && info.shouldSendToVoicemail) {
-                                result = new CallFilteringResult(
-                                        false, // shouldAllowCall
-                                        true, // shouldReject
-                                        true, // shouldAddToCallLog
-                                        true, // shouldShowNotification
-                                        CallLog.Calls.BLOCK_REASON_DIRECT_TO_VOICEMAIL,
-                                        //callBlockReason
-                                        null, //callScreeningAppName
-                                        null // callScreeningComponentName
-                                );
+                                result = new Builder()
+                                        .setShouldAllowCall(false)
+                                        .setShouldReject(true)
+                                        .setShouldAddToCallLog(true)
+                                        .setShouldShowNotification(true)
+                                        .setCallBlockReason(Calls.BLOCK_REASON_DIRECT_TO_VOICEMAIL)
+                                        .setCallScreeningAppName(null)
+                                        .setCallScreeningComponentName(null)
+                                        .build();
                             } else {
-                                result = new CallFilteringResult(
-                                        true, // shouldAllowCall
-                                        false, // shouldReject
-                                        true, // shouldAddToCallLog
-                                        true // shouldShowNotification
-                                );
+                                result = new Builder()
+                                        .setShouldAllowCall(true)
+                                        .setShouldReject(false)
+                                        .setShouldAddToCallLog(true)
+                                        .setShouldShowNotification(true)
+                                        .build();
                             }
                             Log.addEvent(call, LogUtils.Events.DIRECT_TO_VM_FINISHED, result);
                             callback.onCallFilteringComplete(call, result);
                         } else {
-                            result = new CallFilteringResult(
-                                true, // shouldAllowCall
-                                false, // shouldReject
-                                true, // shouldAddToCallLog
-                                true // shouldShowNotification
-                            );
+                            result = new Builder()
+                                    .setShouldAllowCall(true)
+                                    .setShouldReject(false)
+                                    .setShouldAddToCallLog(true)
+                                    .setShouldShowNotification(true)
+                                    .build();
                             Log.addEvent(call, LogUtils.Events.DIRECT_TO_VM_FINISHED, result);
                             Log.w(this, "CallerInfo lookup returned with a different handle than " +
                                     "what was passed in. Was %s, should be %s", handle, callHandle);
diff --git a/src/com/android/server/telecom/callfiltering/IncomingCallFilter.java b/src/com/android/server/telecom/callfiltering/IncomingCallFilter.java
index cc686ab..860de1f 100644
--- a/src/com/android/server/telecom/callfiltering/IncomingCallFilter.java
+++ b/src/com/android/server/telecom/callfiltering/IncomingCallFilter.java
@@ -27,6 +27,7 @@
 import com.android.server.telecom.LogUtils;
 import com.android.server.telecom.TelecomSystem;
 import com.android.server.telecom.Timeouts;
+import com.android.server.telecom.callfiltering.CallFilteringResult.Builder;
 
 import java.util.List;
 
@@ -53,12 +54,12 @@
     private final CallFilterResultCallback mListener;
     private final Timeouts.Adapter mTimeoutsAdapter;
 
-    private CallFilteringResult mResult = new CallFilteringResult(
-            true, // shouldAllowCall
-            false, // shouldReject
-            true, // shouldAddToCallLog
-            true // shouldShowNotification
-    );
+    private CallFilteringResult mResult = new Builder()
+            .setShouldAllowCall(true)
+            .setShouldReject(false)
+            .setShouldAddToCallLog(true)
+            .setShouldShowNotification(true)
+            .build();
 
     private boolean mIsPending = true;
     private int mNumPendingFilters;
diff --git a/tests/src/com/android/server/telecom/tests/AsyncBlockCheckFilterTest.java b/tests/src/com/android/server/telecom/tests/AsyncBlockCheckFilterTest.java
index ebc2826..ee34b0c 100644
--- a/tests/src/com/android/server/telecom/tests/AsyncBlockCheckFilterTest.java
+++ b/tests/src/com/android/server/telecom/tests/AsyncBlockCheckFilterTest.java
@@ -23,7 +23,7 @@
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.PersistableBundle;
-import android.provider.CallLog;
+import android.provider.CallLog.Calls;
 import android.telecom.TelecomManager;
 import android.telephony.CarrierConfigManager;
 import android.test.suitebuilder.annotation.SmallTest;
@@ -34,6 +34,7 @@
 import com.android.server.telecom.callfiltering.BlockCheckerAdapter;
 import com.android.server.telecom.callfiltering.CallFilterResultCallback;
 import com.android.server.telecom.callfiltering.CallFilteringResult;
+import com.android.server.telecom.callfiltering.CallFilteringResult.Builder;
 
 import org.junit.After;
 import org.junit.Before;
@@ -61,23 +62,22 @@
     @Mock private CarrierConfigManager mCarrierConfigManager;
 
     private AsyncBlockCheckFilter mFilter;
-    private static final CallFilteringResult BLOCK_RESULT = new CallFilteringResult(
-            false, // shouldAllowCall
-            true, //shouldReject
-            true, //shouldAddToCallLog
-            false, // shouldShowNotification
-            CallLog.Calls.BLOCK_REASON_BLOCKED_NUMBER, //blockReason
-            null, // callScreeningAppName
-            null //callScreeningComponentName
+    private static final CallFilteringResult BLOCK_RESULT = new Builder()
+            .setShouldAllowCall(false)
+            .setShouldReject(true)
+            .setShouldAddToCallLog(true)
+            .setShouldShowNotification(false)
+            .setCallBlockReason(Calls.BLOCK_REASON_BLOCKED_NUMBER)
+            .setCallScreeningAppName(null)
+            .setCallScreeningComponentName(null)
+            .build();
 
-    );
-
-    private static final CallFilteringResult PASS_RESULT = new CallFilteringResult(
-            true, // shouldAllowCall
-            false, // shouldReject
-            true, // shouldAddToCallLog
-            true // shouldShowNotification
-    );
+    private static final CallFilteringResult PASS_RESULT = new Builder()
+            .setShouldAllowCall(true)
+            .setShouldReject(false)
+            .setShouldAddToCallLog(true)
+            .setShouldShowNotification(true)
+            .build();
 
     private static final Uri TEST_HANDLE = Uri.parse("tel:1235551234");
     private static final int TEST_TIMEOUT = 1000;
diff --git a/tests/src/com/android/server/telecom/tests/CallScreeningServiceControllerTest.java b/tests/src/com/android/server/telecom/tests/CallScreeningServiceControllerTest.java
index 67439de..59ea094 100644
--- a/tests/src/com/android/server/telecom/tests/CallScreeningServiceControllerTest.java
+++ b/tests/src/com/android/server/telecom/tests/CallScreeningServiceControllerTest.java
@@ -29,6 +29,7 @@
 import android.os.PersistableBundle;
 import android.os.UserHandle;
 import android.provider.CallLog;
+import android.provider.CallLog.Calls;
 import android.telecom.TelecomManager;
 import android.telephony.CarrierConfigManager;
 import android.test.suitebuilder.annotation.SmallTest;
@@ -45,6 +46,7 @@
 import com.android.server.telecom.TelecomSystem;
 import com.android.server.telecom.callfiltering.CallFilterResultCallback;
 import com.android.server.telecom.callfiltering.CallFilteringResult;
+import com.android.server.telecom.callfiltering.CallFilteringResult.Builder;
 import com.android.server.telecom.callfiltering.CallScreeningServiceController;
 
 import org.junit.After;
@@ -70,31 +72,6 @@
 @RunWith(JUnit4.class)
 public class CallScreeningServiceControllerTest extends TelecomTestCase {
 
-    @Mock Context mContext;
-    @Mock Call mCall;
-    @Mock private CallFilterResultCallback mCallback;
-    @Mock CallsManager mCallsManager;
-    @Mock RoleManagerAdapter mRoleManagerAdapter;
-    @Mock CarrierConfigManager mCarrierConfigManager;
-    @Mock private TelecomManager mTelecomManager;
-    @Mock PackageManager mPackageManager;
-    @Mock ParcelableCallUtils.Converter mParcelableCallUtilsConverter;
-    @Mock PhoneAccountRegistrar mPhoneAccountRegistrar;
-    @Mock private CallerInfoLookupHelper mCallerInfoLookupHelper;
-
-    CallScreeningServiceHelper.AppLabelProxy mAppLabelProxy =
-            new CallScreeningServiceHelper.AppLabelProxy() {
-        @Override
-        public CharSequence getAppLabel(String packageName) {
-            return APP_NAME;
-        }
-    };
-
-    private ResolveInfo mResolveInfo;
-    private TelecomServiceImpl.SettingsSecureAdapter mSettingsSecureAdapter =
-            spy(new CallScreeningServiceFilterTest.SettingsSecureAdapterFake());
-    private TelecomSystem.SyncRoot mLock = new TelecomSystem.SyncRoot() { };
-
     private static final String CALL_ID = "u89prgt9ps78y5";
     private static final Uri TEST_HANDLE = Uri.parse("tel:1235551234");
     private static final String DEFAULT_DIALER_PACKAGE = "com.android.dialer";
@@ -107,27 +84,46 @@
             "com.android.dialer", "com.android.dialer.callscreeningserviceimpl");
     private static final ComponentName USER_CHOSEN_CALL_SCREENING = new ComponentName(
             "com.android.userchosen", "com.android.userchosen.callscreeningserviceimpl");
-
-    private static final CallFilteringResult PASS_RESULT = new CallFilteringResult(
-            true, // shouldAllowCall
-            false, // shouldReject
-            true, // shouldAddToCallLog
-            true // shouldShowNotification
-    );
-
-    public static class SettingsSecureAdapterFake implements
-            TelecomServiceImpl.SettingsSecureAdapter {
-        @Override
-        public void putStringForUser(ContentResolver resolver, String name, String value,
-                                     int userHandle) {
-
-        }
-
-        @Override
-        public String getStringForUser(ContentResolver resolver, String name, int userHandle) {
-            return USER_CHOSEN_CALL_SCREENING.flattenToString();
-        }
-    }
+    private static final CallFilteringResult PASS_RESULT = new Builder()
+            .setShouldAllowCall(true)
+            .setShouldReject(false)
+            .setShouldAddToCallLog(true)
+            .setShouldShowNotification(true)
+            .build();
+    @Mock
+    Context mContext;
+    @Mock
+    Call mCall;
+    @Mock
+    CallsManager mCallsManager;
+    @Mock
+    RoleManagerAdapter mRoleManagerAdapter;
+    @Mock
+    CarrierConfigManager mCarrierConfigManager;
+    @Mock
+    PackageManager mPackageManager;
+    @Mock
+    ParcelableCallUtils.Converter mParcelableCallUtilsConverter;
+    @Mock
+    PhoneAccountRegistrar mPhoneAccountRegistrar;
+    CallScreeningServiceHelper.AppLabelProxy mAppLabelProxy =
+            new CallScreeningServiceHelper.AppLabelProxy() {
+                @Override
+                public CharSequence getAppLabel(String packageName) {
+                    return APP_NAME;
+                }
+            };
+    @Mock
+    private CallFilterResultCallback mCallback;
+    @Mock
+    private TelecomManager mTelecomManager;
+    @Mock
+    private CallerInfoLookupHelper mCallerInfoLookupHelper;
+    private ResolveInfo mResolveInfo;
+    private TelecomServiceImpl.SettingsSecureAdapter mSettingsSecureAdapter =
+            spy(new CallScreeningServiceFilterTest.SettingsSecureAdapterFake());
+    private TelecomSystem.SyncRoot mLock = new TelecomSystem.SyncRoot() {
+    };
 
     @Override
     @Before
@@ -145,7 +141,7 @@
         when(TelecomManager.from(mContext)).thenReturn(mTelecomManager);
         when(mTelecomManager.getDefaultDialerPackage()).thenReturn(DEFAULT_DIALER_PACKAGE);
 
-        mResolveInfo =  new ResolveInfo() {{
+        mResolveInfo = new ResolveInfo() {{
             serviceInfo = new ServiceInfo();
             serviceInfo.packageName = PKG_NAME;
             serviceInfo.name = CLS_NAME;
@@ -236,30 +232,27 @@
 
         controller.startFilterLookup(mCall, mCallback);
 
-        controller.onCallScreeningFilterComplete(mCall, new CallFilteringResult(
-                false, // shouldAllowCall
-                true, // shouldReject
-                false, // shouldAddToCallLog
-                true, // shouldShowNotification
-                CallLog.Calls.BLOCK_REASON_CALL_SCREENING_SERVICE,
-                APP_NAME,
-                CARRIER_DEFINED_CALL_SCREENING.flattenToString()
-        ), CARRIER_DEFINED_CALL_SCREENING.getPackageName());
+        CallFilteringResult expectedResult = new Builder()
+                .setShouldAllowCall(false)
+                .setShouldReject(true)
+                .setShouldAddToCallLog(false)
+                .setShouldShowNotification(true)
+                .setCallBlockReason(Calls.BLOCK_REASON_CALL_SCREENING_SERVICE)
+                .setCallScreeningAppName(APP_NAME)
+                .setCallScreeningComponentName(
+                        CARRIER_DEFINED_CALL_SCREENING.flattenToString())
+                .build();
+
+        controller.onCallScreeningFilterComplete(mCall, expectedResult,
+                CARRIER_DEFINED_CALL_SCREENING.getPackageName());
 
         verify(mContext, times(1)).bindServiceAsUser(any(Intent.class),
                 any(ServiceConnection.class),
                 eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
                 eq(UserHandle.CURRENT));
 
-        verify(mCallback).onCallFilteringComplete(eq(mCall), eq(new CallFilteringResult(
-                false, // shouldAllowCall
-                true, // shouldReject
-                false, // shouldAddToCallLog
-                true, // shouldShowNotification
-                CallLog.Calls.BLOCK_REASON_CALL_SCREENING_SERVICE, //callBlockReason
-                APP_NAME, //callScreeningAppName
-                CARRIER_DEFINED_CALL_SCREENING.flattenToString() //callScreeningComponentName
-        )));
+        verify(mCallback)
+                .onCallFilteringComplete(eq(mCall), eq(expectedResult));
     }
 
     @SmallTest
@@ -282,30 +275,31 @@
         callerInfo.contactExists = false;
         queryListener.onCallerInfoQueryComplete(TEST_HANDLE, callerInfo);
 
-        controller.onCallScreeningFilterComplete(mCall, new CallFilteringResult(
-                false, // shouldAllowCall
-                true, // shouldReject
-                false, // shouldAddToCallLog
-                true, // shouldShowNotification
-                CallLog.Calls.BLOCK_REASON_CALL_SCREENING_SERVICE,
-                APP_NAME,
-                DEFAULT_DIALER_CALL_SCREENING.flattenToString()
-        ), DEFAULT_DIALER_CALL_SCREENING.getPackageName());
+        CallFilteringResult.Builder resultBuilder = new Builder()
+                .setShouldAllowCall(false)
+                .setShouldReject(true)
+                .setShouldShowNotification(true)
+                .setCallBlockReason(Calls.BLOCK_REASON_CALL_SCREENING_SERVICE)
+                .setCallScreeningAppName(APP_NAME)
+                .setCallScreeningComponentName(DEFAULT_DIALER_CALL_SCREENING.flattenToString());
+
+        CallFilteringResult providedResult = resultBuilder
+                .setShouldAddToCallLog(false)
+                .build();
+
+        controller.onCallScreeningFilterComplete(mCall, providedResult,
+                DEFAULT_DIALER_CALL_SCREENING.getPackageName());
 
         verify(mContext, times(3)).bindServiceAsUser(any(Intent.class),
                 any(ServiceConnection.class),
                 eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
                 eq(UserHandle.CURRENT));
 
-        verify(mCallback).onCallFilteringComplete(eq(mCall), eq(new CallFilteringResult(
-                false, // shouldAllowCall
-                true, // shouldReject
-                true, // shouldAddToCallLog (we don't allow services to skip call log)
-                true, // shouldShowNotification
-                CallLog.Calls.BLOCK_REASON_CALL_SCREENING_SERVICE, //callBlockReason
-                APP_NAME, //callScreeningAppName
-                DEFAULT_DIALER_CALL_SCREENING.flattenToString() //callScreeningComponentName
-        )));
+        CallFilteringResult expectedResult = resultBuilder
+                .setShouldAddToCallLog(true)
+                .build();
+
+        verify(mCallback).onCallFilteringComplete(eq(mCall), eq(expectedResult));
     }
 
     @SmallTest
@@ -330,30 +324,99 @@
 
         controller.onCallScreeningFilterComplete(mCall, PASS_RESULT,
                 DEFAULT_DIALER_CALL_SCREENING.getPackageName());
-        controller.onCallScreeningFilterComplete(mCall, new CallFilteringResult(
-                false, // shouldAllowCall
-                true, // shouldReject
-                false, // shouldAddToCallLog
-                true, // shouldShowNotification
-                CallLog.Calls.BLOCK_REASON_CALL_SCREENING_SERVICE,
-                APP_NAME,
-                USER_CHOSEN_CALL_SCREENING.flattenToString()
-        ), USER_CHOSEN_CALL_SCREENING.getPackageName());
+
+        CallFilteringResult.Builder resultBuilder = new Builder()
+                .setShouldAllowCall(false)
+                .setShouldReject(true)
+                .setShouldShowNotification(true)
+                .setCallBlockReason(Calls.BLOCK_REASON_CALL_SCREENING_SERVICE)
+                .setCallScreeningAppName(APP_NAME)
+                .setCallScreeningComponentName(DEFAULT_DIALER_CALL_SCREENING.flattenToString());
+        CallFilteringResult providedResult = resultBuilder
+                .setShouldAddToCallLog(false)
+                .build();
+
+        controller.onCallScreeningFilterComplete(mCall, providedResult,
+                USER_CHOSEN_CALL_SCREENING.getPackageName());
 
         verify(mContext, times(3)).bindServiceAsUser(any(Intent.class),
                 any(ServiceConnection.class),
                 eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
                 eq(UserHandle.CURRENT));
 
-        verify(mCallback).onCallFilteringComplete(eq(mCall), eq(new CallFilteringResult(
-                false, // shouldAllowCall
-                true, // shouldReject
-                true, // shouldAddToCallLog (we don't allow services to skip call log)
-                true, // shouldShowNotification
-                CallLog.Calls.BLOCK_REASON_CALL_SCREENING_SERVICE, //callBlockReason
-                APP_NAME, //callScreeningAppName
-                USER_CHOSEN_CALL_SCREENING.flattenToString() //callScreeningComponentName
-        )));
+        CallFilteringResult expectedResult = resultBuilder
+                .setShouldAddToCallLog(true)
+                .build();
+
+        verify(mCallback).onCallFilteringComplete(eq(mCall), eq(expectedResult));
+    }
+
+    /**
+     * This test verifies that where the default dialer role is filled by the same app as the caller
+     * id and spam role, we will only bind to that call screening service once.
+     */
+    @SmallTest
+    @Test
+    public void testOnlyBindOnce() {
+        // Assume the user chose the default dialer to also fill the caller id and spam role.
+        when(mRoleManagerAdapter.getDefaultCallScreeningApp()).thenReturn(
+                DEFAULT_DIALER_CALL_SCREENING.getPackageName());
+        CallScreeningServiceController controller = new CallScreeningServiceController(mContext,
+                mCallsManager,
+                mPhoneAccountRegistrar, mParcelableCallUtilsConverter, mLock,
+                mSettingsSecureAdapter, mCallerInfoLookupHelper, mAppLabelProxy);
+
+        controller.startFilterLookup(mCall, mCallback);
+
+        controller.onCallScreeningFilterComplete(mCall, PASS_RESULT,
+                CARRIER_DEFINED_CALL_SCREENING.getPackageName());
+
+        CallerInfoLookupHelper.OnQueryCompleteListener queryListener = verifyLookupStart();
+        CallerInfo callerInfo = new CallerInfo();
+        callerInfo.contactExists = false;
+        queryListener.onCallerInfoQueryComplete(TEST_HANDLE, callerInfo);
+
+        controller.onCallScreeningFilterComplete(mCall, new CallFilteringResult.Builder()
+                        .setShouldAllowCall(false)
+                        .setShouldReject(true)
+                        .setShouldAddToCallLog(false)
+                        .setShouldShowNotification(true)
+                        .setCallBlockReason(CallLog.Calls.BLOCK_REASON_CALL_SCREENING_SERVICE)
+                        .setCallScreeningAppName(APP_NAME)
+                        .setCallScreeningComponentName(
+                                DEFAULT_DIALER_CALL_SCREENING.flattenToString())
+                        .build(),
+                DEFAULT_DIALER_CALL_SCREENING.getPackageName());
+
+        controller.onCallScreeningFilterComplete(mCall, new CallFilteringResult.Builder()
+                .setShouldAllowCall(false)
+                .setShouldReject(true)
+                .setShouldAddToCallLog(false)
+                .setShouldShowNotification(true)
+                .setCallBlockReason(CallLog.Calls.BLOCK_REASON_CALL_SCREENING_SERVICE)
+                .setCallScreeningAppName(APP_NAME)
+                .setCallScreeningComponentName(DEFAULT_DIALER_CALL_SCREENING.flattenToString())
+                .build(), USER_CHOSEN_CALL_SCREENING.getPackageName());
+
+        // Expect to bind twice; once to the carrier defined service, and then again to the default
+        // dialer.
+        verify(mContext, times(2)).bindServiceAsUser(any(Intent.class),
+                any(ServiceConnection.class),
+                eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
+                eq(UserHandle.CURRENT));
+
+        // Expect filtering to complete only a single time from the default dialer service.
+        verify(mCallback, times(1)).onCallFilteringComplete(eq(mCall),
+                eq(new CallFilteringResult.Builder()
+                        .setShouldAllowCall(false)
+                        .setShouldReject(true)
+                        .setShouldAddToCallLog(true)
+                        .setShouldShowNotification(true)
+                        .setCallBlockReason(CallLog.Calls.BLOCK_REASON_CALL_SCREENING_SERVICE)
+                        .setCallScreeningAppName(APP_NAME)
+                        .setCallScreeningComponentName(
+                                DEFAULT_DIALER_CALL_SCREENING.flattenToString())
+                        .build()));
     }
 
     private CallerInfoLookupHelper.OnQueryCompleteListener verifyLookupStart() {
@@ -377,4 +440,18 @@
                 .thenReturn(mCarrierConfigManager);
         when(mCarrierConfigManager.getConfig()).thenReturn(bundle);
     }
+
+    public static class SettingsSecureAdapterFake implements
+            TelecomServiceImpl.SettingsSecureAdapter {
+        @Override
+        public void putStringForUser(ContentResolver resolver, String name, String value,
+                int userHandle) {
+
+        }
+
+        @Override
+        public String getStringForUser(ContentResolver resolver, String name, int userHandle) {
+            return USER_CHOSEN_CALL_SCREENING.flattenToString();
+        }
+    }
 }
diff --git a/tests/src/com/android/server/telecom/tests/CallScreeningServiceFilterTest.java b/tests/src/com/android/server/telecom/tests/CallScreeningServiceFilterTest.java
index b11b397..7b3a499 100644
--- a/tests/src/com/android/server/telecom/tests/CallScreeningServiceFilterTest.java
+++ b/tests/src/com/android/server/telecom/tests/CallScreeningServiceFilterTest.java
@@ -29,7 +29,7 @@
 import android.os.PersistableBundle;
 import android.os.RemoteException;
 import android.os.UserHandle;
-import android.provider.CallLog;
+import android.provider.CallLog.Calls;
 import android.telecom.CallScreeningService;
 import android.telecom.ParcelableCall;
 import android.telecom.TelecomManager;
@@ -44,6 +44,7 @@
 import com.android.server.telecom.PhoneAccountRegistrar;
 import com.android.server.telecom.TelecomServiceImpl;
 import com.android.server.telecom.callfiltering.CallFilteringResult;
+import com.android.server.telecom.callfiltering.CallFilteringResult.Builder;
 import com.android.server.telecom.callfiltering.CallScreeningServiceFilter;
 import com.android.server.telecom.TelecomSystem;
 
@@ -105,20 +106,20 @@
     private static final String USER_CHOSEN_CALL_SCREENING_APP_NAME = "UserChosen";
     private ResolveInfo mResolveInfo;
 
-    private static final CallFilteringResult PASS_RESULT = new CallFilteringResult(
-            true, // shouldAllowCall
-            false, // shouldReject
-            true, // shouldAddToCallLog
-            true // shouldShowNotification
-    );
+    private static final CallFilteringResult PASS_RESULT = new Builder()
+            .setShouldAllowCall(true)
+            .setShouldReject(false)
+            .setShouldAddToCallLog(true)
+            .setShouldShowNotification(true)
+            .build();
 
-    private static final CallFilteringResult PASS_RESULT_WITH_SILENCE = new CallFilteringResult(
-            true, // shouldAllowCall
-            false, // shouldReject
-            true, // shouldSilence
-            true, // shouldAddToCallLog
-            true // shouldShowNotification
-    );
+    private static final CallFilteringResult PASS_RESULT_WITH_SILENCE = new Builder()
+            .setShouldAllowCall(true)
+            .setShouldReject(false)
+            .setShouldSilence(true)
+            .setShouldAddToCallLog(true)
+            .setShouldShowNotification(true)
+            .build();
 
     private CallScreeningServiceFilter mFilter;
 
@@ -274,15 +275,17 @@
                 true, // shouldShowNotification
                 CARRIER_DEFINED_CALL_SCREENING
         );
-        verify(mCallback).onCallScreeningFilterComplete(eq(mCall), eq(new CallFilteringResult(
-                false, // shouldAllowCall
-                true, // shouldReject
-                false, // shouldAddToCallLog
-                true, // shouldShowNotification
-                CallLog.Calls.BLOCK_REASON_CALL_SCREENING_SERVICE, //callBlockReason
-                CARRIER_DEFINED_CALL_SCREENING_APP_NAME, //callScreeningAppName
-                CARRIER_DEFINED_CALL_SCREENING.flattenToString() //callScreeningComponentName
-        )), eq(CARRIER_DEFINED_CALL_SCREENING.getPackageName()));
+        verify(mCallback).onCallScreeningFilterComplete(eq(mCall), eq(new Builder()
+                        .setShouldAllowCall(false)
+                        .setShouldReject(true)
+                        .setShouldAddToCallLog(false)
+                        .setShouldShowNotification(true)
+                        .setCallBlockReason(Calls.BLOCK_REASON_CALL_SCREENING_SERVICE)
+                        .setCallScreeningAppName(CARRIER_DEFINED_CALL_SCREENING_APP_NAME)
+                        .setCallScreeningComponentName(
+                                CARRIER_DEFINED_CALL_SCREENING.flattenToString())
+                        .build()),
+                eq(CARRIER_DEFINED_CALL_SCREENING.getPackageName()));
     }
 
     @SmallTest
@@ -307,15 +310,16 @@
             true, // shouldShowNotification
             DEFAULT_DIALER_CALL_SCREENING
         );
-        verify(mCallback).onCallScreeningFilterComplete(eq(mCall), eq(new CallFilteringResult(
-            false, // shouldAllowCall
-            true, // shouldReject
-            true, // shouldAddToCallLog
-            true, // shouldShowNotification
-            CallLog.Calls.BLOCK_REASON_CALL_SCREENING_SERVICE, //callBlockReason
-            DEFAULT_DIALER_APP_NAME, //callScreeningAppName
-            DEFAULT_DIALER_CALL_SCREENING.flattenToString() //callScreeningComponentName
-        )), eq(DEFAULT_DIALER_CALL_SCREENING.getPackageName()));
+        verify(mCallback).onCallScreeningFilterComplete(eq(mCall), eq(new Builder()
+                .setShouldAllowCall(false)
+                .setShouldReject(true)
+                .setShouldAddToCallLog(true)
+                .setShouldShowNotification(true)
+                .setCallBlockReason(Calls.BLOCK_REASON_CALL_SCREENING_SERVICE)
+                .setCallScreeningAppName(DEFAULT_DIALER_APP_NAME)
+                .setCallScreeningComponentName(DEFAULT_DIALER_CALL_SCREENING.flattenToString())
+                .build()),
+                eq(DEFAULT_DIALER_CALL_SCREENING.getPackageName()));
     }
 
     @SmallTest
@@ -340,15 +344,16 @@
             true, // shouldShowNotification
             USER_CHOSEN_CALL_SCREENING
         );
-        verify(mCallback).onCallScreeningFilterComplete(eq(mCall), eq(new CallFilteringResult(
-            false, // shouldAllowCall
-            true, // shouldReject
-            true, // shouldAddToCallLog
-            true, // shouldShowNotification
-            CallLog.Calls.BLOCK_REASON_CALL_SCREENING_SERVICE, //callBlockReason
-            USER_CHOSEN_CALL_SCREENING_APP_NAME, //callScreeningAppName
-            USER_CHOSEN_CALL_SCREENING.flattenToString() //callScreeningComponentName
-        )), eq(USER_CHOSEN_CALL_SCREENING.getPackageName()));
+        verify(mCallback).onCallScreeningFilterComplete(eq(mCall), eq(new Builder()
+                        .setShouldAllowCall(false)
+                        .setShouldReject(true)
+                        .setShouldAddToCallLog(true)
+                        .setShouldShowNotification(true)
+                        .setCallBlockReason(Calls.BLOCK_REASON_CALL_SCREENING_SERVICE)
+                        .setCallScreeningAppName(USER_CHOSEN_CALL_SCREENING_APP_NAME)
+                        .setCallScreeningComponentName(USER_CHOSEN_CALL_SCREENING.flattenToString())
+                        .build()),
+                eq(USER_CHOSEN_CALL_SCREENING.getPackageName()));
     }
 
     private ServiceConnection verifyBindingIntent() {
diff --git a/tests/src/com/android/server/telecom/tests/DirectToVoicemailCallFilterTest.java b/tests/src/com/android/server/telecom/tests/DirectToVoicemailCallFilterTest.java
index 7fc4369..4502da7 100644
--- a/tests/src/com/android/server/telecom/tests/DirectToVoicemailCallFilterTest.java
+++ b/tests/src/com/android/server/telecom/tests/DirectToVoicemailCallFilterTest.java
@@ -17,14 +17,14 @@
 package com.android.server.telecom.tests;
 
 import android.net.Uri;
-import android.provider.CallLog;
+import android.provider.CallLog.Calls;
 import android.test.suitebuilder.annotation.SmallTest;
 
 import android.telephony.CallerInfo;
 import com.android.server.telecom.Call;
 import com.android.server.telecom.callfiltering.CallFilterResultCallback;
 import com.android.server.telecom.CallerInfoLookupHelper;
-import com.android.server.telecom.callfiltering.CallFilteringResult;
+import com.android.server.telecom.callfiltering.CallFilteringResult.Builder;
 import com.android.server.telecom.callfiltering.DirectToVoicemailCallFilter;
 
 import org.junit.After;
@@ -68,16 +68,15 @@
         callerInfo.shouldSendToVoicemail = true;
 
         queryListener.onCallerInfoQueryComplete(TEST_HANDLE, callerInfo);
-        verify(mCallback).onCallFilteringComplete(mCall,
-                new CallFilteringResult(
-                        false, // shouldAllowCall
-                        true, // shouldReject
-                        true, // shouldAddToCallLog
-                        true, // shouldShowNotification
-                        CallLog.Calls.BLOCK_REASON_DIRECT_TO_VOICEMAIL, //callBlockReason
-                        null, //callScreeningAppName
-                        null // callScreeningComponentName
-                ));
+        verify(mCallback).onCallFilteringComplete(mCall, new Builder()
+                .setShouldAllowCall(false)
+                .setShouldReject(true)
+                .setShouldAddToCallLog(true)
+                .setShouldShowNotification(true)
+                .setCallBlockReason(Calls.BLOCK_REASON_DIRECT_TO_VOICEMAIL)
+                .setCallScreeningAppName(null)
+                .setCallScreeningComponentName(null)
+                .build());
     }
 
     @SmallTest
@@ -89,13 +88,12 @@
         callerInfo.shouldSendToVoicemail = false;
 
         queryListener.onCallerInfoQueryComplete(TEST_HANDLE, callerInfo);
-        verify(mCallback).onCallFilteringComplete(mCall,
-                new CallFilteringResult(
-                        true, // shouldAllowCall
-                        false, // shouldReject
-                        true, // shouldAddToCallLog
-                        true // shouldShowNotification
-                ));
+        verify(mCallback).onCallFilteringComplete(mCall, new Builder()
+                .setShouldAllowCall(true)
+                .setShouldReject(false)
+                .setShouldAddToCallLog(true)
+                .setShouldShowNotification(true)
+                .build());
     }
 
     @SmallTest
@@ -104,13 +102,12 @@
         CallerInfoLookupHelper.OnQueryCompleteListener queryListener = verifyLookupStart(null);
 
         queryListener.onCallerInfoQueryComplete(null, null);
-        verify(mCallback).onCallFilteringComplete(mCall,
-                new CallFilteringResult(
-                        true, // shouldAllowCall
-                        false, // shouldReject
-                        true, // shouldAddToCallLog
-                        true // shouldShowNotification
-                ));
+        verify(mCallback).onCallFilteringComplete(mCall, new Builder()
+                .setShouldAllowCall(true)
+                .setShouldReject(false)
+                .setShouldAddToCallLog(true)
+                .setShouldShowNotification(true)
+                .build());
     }
 
     private CallerInfoLookupHelper.OnQueryCompleteListener verifyLookupStart() {
diff --git a/tests/src/com/android/server/telecom/tests/IncomingCallFilterTest.java b/tests/src/com/android/server/telecom/tests/IncomingCallFilterTest.java
index 76341b2..8e2d11e 100644
--- a/tests/src/com/android/server/telecom/tests/IncomingCallFilterTest.java
+++ b/tests/src/com/android/server/telecom/tests/IncomingCallFilterTest.java
@@ -17,17 +17,17 @@
 package com.android.server.telecom.tests;
 
 import android.content.ContentResolver;
-import android.content.IContentProvider;
 import android.net.Uri;
 import android.os.Handler;
 import android.os.Looper;
-import android.provider.CallLog;
+import android.provider.CallLog.Calls;
 import android.test.suitebuilder.annotation.SmallTest;
 
 import com.android.server.telecom.Call;
 import com.android.server.telecom.Timeouts;
 import com.android.server.telecom.callfiltering.CallFilterResultCallback;
 import com.android.server.telecom.callfiltering.CallFilteringResult;
+import com.android.server.telecom.callfiltering.CallFilteringResult.Builder;
 import com.android.server.telecom.callfiltering.IncomingCallFilter;
 import com.android.server.telecom.TelecomSystem;
 
@@ -68,46 +68,47 @@
     private static final long SHORT_TIMEOUT = 100;
 
     private static final CallFilteringResult PASS_CALL_RESULT =
-            new CallFilteringResult(
-                    true, // shouldAllowCall
-                    false, // shouldReject
-                    true, // shouldAddToCallLog
-                    true // shouldShowNotification
-            );
+            new Builder()
+                    .setShouldAllowCall(true)
+                    .setShouldReject(false)
+                    .setShouldAddToCallLog(true)
+                    .setShouldShowNotification(true)
+                    .build();
 
     private static final CallFilteringResult ASYNC_BLOCK_CHECK_BLOCK_RESULT =
-            new CallFilteringResult(
-                    false, // shouldAllowCall
-                    true, // shouldReject
-                    true, // shouldAddToCallLog
-                    false, // shouldShowNotification
-                    CallLog.Calls.BLOCK_REASON_BLOCKED_NUMBER, //callBlockReason
-                    null, //callScreeningAppName
-                    null //callScreeningComponentName
-            );
+            new Builder()
+                    .setShouldAllowCall(false)
+                    .setShouldReject(true)
+                    .setShouldAddToCallLog(true)
+                    .setShouldShowNotification(false)
+                    .setCallBlockReason(Calls.BLOCK_REASON_BLOCKED_NUMBER)
+                    .setCallScreeningAppName(null)
+                    .setCallScreeningComponentName(null)
+                    .build();
 
     private static final CallFilteringResult DIRECT_TO_VOICEMAIL_CALL_BLOCK_RESULT =
-            new CallFilteringResult(
-                    false, // shouldAllowCall
-                    true, // shouldReject
-                    true, // shouldAddToCallLog
-                    true, // shouldShowNotification
-                    CallLog.Calls.BLOCK_REASON_DIRECT_TO_VOICEMAIL, //callBlockReason
-                    null, //callScreeningAppName
-                    null //callScreeningComponentName
-            );
+            new Builder()
+                    .setShouldAllowCall(false)
+                    .setShouldReject(true)
+                    .setShouldAddToCallLog(true)
+                    .setShouldShowNotification(true)
+                    .setCallBlockReason(Calls.BLOCK_REASON_DIRECT_TO_VOICEMAIL)
+                    .setCallScreeningAppName(null)
+                    .setCallScreeningComponentName(null)
+                    .build();
 
     private static final CallFilteringResult CALL_SCREENING_SERVICE_BLOCK_RESULT =
-            new CallFilteringResult(
-                    false, // shouldAllowCall
-                    true, // shouldReject
-                    false, // shouldAddToCallLog
-                    true, // shouldShowNotification
-                    CallLog.Calls.BLOCK_REASON_CALL_SCREENING_SERVICE, //callBlockReason
-                    "com.android.thirdparty", //callScreeningAppName
-                    "com.android.thirdparty/com.android.thirdparty.callscreeningserviceimpl"
-                    //callScreeningComponentName
-            );
+            new Builder()
+                    .setShouldAllowCall(false)
+                    .setShouldReject(true)
+                    .setShouldAddToCallLog(false)
+                    .setShouldShowNotification(true)
+                    .setCallBlockReason(Calls.BLOCK_REASON_CALL_SCREENING_SERVICE)
+                    .setCallScreeningAppName("com.android.thirdparty")
+                    .setCallScreeningComponentName(
+                            "com.android.thirdparty/"
+                                    + "com.android.thirdparty.callscreeningserviceimpl")
+                    .build();
 
     private static final CallFilteringResult DEFAULT_RESULT = PASS_CALL_RESULT;
     private Handler mHandler = new Handler(Looper.getMainLooper());
@@ -207,16 +208,15 @@
         testFilter.onCallFilteringComplete(mCall, DIRECT_TO_VOICEMAIL_CALL_BLOCK_RESULT);
         testFilter.onCallFilteringComplete(mCall, CALL_SCREENING_SERVICE_BLOCK_RESULT);
         waitForHandlerAction(testFilter.getHandler(), SHORT_TIMEOUT * 2);
-        verify(mResultCallback).onCallFilteringComplete(eq(mCall), eq(
-                new CallFilteringResult(
-                        false, // shouldAllowCall
-                        true, // shouldReject
-                        false, // shouldAddToCallLog
-                        false, // shouldShowNotification
-                        CallLog.Calls.BLOCK_REASON_BLOCKED_NUMBER, //callBlockReason
-                        null, //callScreeningAppName
-                        null //callScreeningComponentName
-                )));
+        verify(mResultCallback).onCallFilteringComplete(eq(mCall), eq(new Builder()
+                .setShouldAllowCall(false)
+                .setShouldReject(true)
+                .setShouldAddToCallLog(false)
+                .setShouldShowNotification(false)
+                .setCallBlockReason(Calls.BLOCK_REASON_BLOCKED_NUMBER)
+                .setCallScreeningAppName(null)
+                .setCallScreeningComponentName(null)
+                .build()));
     }
 
     @SmallTest
@@ -239,16 +239,15 @@
         testFilter.onCallFilteringComplete(mCall, DIRECT_TO_VOICEMAIL_CALL_BLOCK_RESULT);
         testFilter.onCallFilteringComplete(mCall, CALL_SCREENING_SERVICE_BLOCK_RESULT);
         waitForHandlerAction(testFilter.getHandler(), SHORT_TIMEOUT * 2);
-        verify(mResultCallback).onCallFilteringComplete(eq(mCall), eq(
-                new CallFilteringResult(
-                        false, // shouldAllowCall
-                        true, // shouldReject
-                        false, // shouldAddToCallLog
-                        true, // shouldShowNotification
-                        CallLog.Calls.BLOCK_REASON_DIRECT_TO_VOICEMAIL, //callBlockReason
-                        null, ////callScreeningAppName
-                        null ////callScreeningComponentName
-                )));
+        verify(mResultCallback).onCallFilteringComplete(eq(mCall), eq(new Builder()
+                .setShouldAllowCall(false)
+                .setShouldReject(true)
+                .setShouldAddToCallLog(false)
+                .setShouldShowNotification(true)
+                .setCallBlockReason(Calls.BLOCK_REASON_DIRECT_TO_VOICEMAIL)
+                .setCallScreeningAppName(null)
+                .setCallScreeningComponentName(null)
+                .build()));
     }
 
     @SmallTest
@@ -268,17 +267,16 @@
         testFilter.onCallFilteringComplete(mCall, PASS_CALL_RESULT);
         testFilter.onCallFilteringComplete(mCall, CALL_SCREENING_SERVICE_BLOCK_RESULT);
         waitForHandlerAction(testFilter.getHandler(), SHORT_TIMEOUT * 2);
-        verify(mResultCallback).onCallFilteringComplete(eq(mCall), eq(
-                new CallFilteringResult(
-                        false, // shouldAllowCall
-                        true, // shouldReject
-                        false, // shouldAddToCallLog
-                        true, // shouldShowNotification
-                        CallLog.Calls.BLOCK_REASON_CALL_SCREENING_SERVICE, //callBlockReason
-                        "com.android.thirdparty", //callScreeningAppName
-                        "com.android.thirdparty/com.android.thirdparty.callscreeningserviceimpl"
-                        //callScreeningComponentName
-                )));
+        verify(mResultCallback).onCallFilteringComplete(eq(mCall), eq(new Builder()
+                .setShouldAllowCall(false)
+                .setShouldReject(true)
+                .setShouldAddToCallLog(false)
+                .setShouldShowNotification(true)
+                .setCallBlockReason(Calls.BLOCK_REASON_CALL_SCREENING_SERVICE)
+                .setCallScreeningAppName("com.android.thirdparty")
+                .setCallScreeningComponentName(
+                        "com.android.thirdparty/com.android.thirdparty.callscreeningserviceimpl")
+                .build()));
     }
 
     @SmallTest