Merge "Speculative fix for BT race condition"
diff --git a/src/com/android/server/telecom/Call.java b/src/com/android/server/telecom/Call.java
index 76eed40..1d5a24b 100644
--- a/src/com/android/server/telecom/Call.java
+++ b/src/com/android/server/telecom/Call.java
@@ -536,12 +536,12 @@
      * @param handle The handle to dial.
      * @param gatewayInfo Gateway information to use for the call.
      * @param connectionManagerPhoneAccountHandle Account to use for the service managing the call.
-*         This account must be one that was registered with the
-*         {@link PhoneAccount#CAPABILITY_CONNECTION_MANAGER} flag.
+     *         This account must be one that was registered with the
+     *           {@link PhoneAccount#CAPABILITY_CONNECTION_MANAGER} flag.
      * @param targetPhoneAccountHandle Account information to use for the call. This account must be
-*         one that was registered with the {@link PhoneAccount#CAPABILITY_CALL_PROVIDER} flag.
+     *         one that was registered with the {@link PhoneAccount#CAPABILITY_CALL_PROVIDER} flag.
      * @param callDirection one of CALL_DIRECTION_INCOMING, CALL_DIRECTION_OUTGOING,
-*         or CALL_DIRECTION_UNKNOWN.
+     *         or CALL_DIRECTION_UNKNOWN.
      * @param shouldAttachToExistingConnection Set to true to attach the call to an existing
      * @param clockProxy
      */
@@ -643,6 +643,10 @@
     }
 
     public void initAnalytics() {
+        initAnalytics(null);
+    }
+
+    public void initAnalytics(String callingPackage) {
         int analyticsDirection;
         switch (mCallDirection) {
             case CALL_DIRECTION_OUTGOING:
@@ -658,7 +662,7 @@
         }
         mAnalytics = Analytics.initiateCallAnalytics(mId, analyticsDirection);
         mAnalytics.setCallIsEmergency(mIsEmergencyCall);
-        Log.addEvent(this, LogUtils.Events.CREATED);
+        Log.addEvent(this, LogUtils.Events.CREATED, callingPackage);
     }
 
     public Analytics.CallInfo getAnalytics() {
diff --git a/src/com/android/server/telecom/CallIntentProcessor.java b/src/com/android/server/telecom/CallIntentProcessor.java
index ff3b7b2..5213364 100644
--- a/src/com/android/server/telecom/CallIntentProcessor.java
+++ b/src/com/android/server/telecom/CallIntentProcessor.java
@@ -28,7 +28,7 @@
 public class CallIntentProcessor {
     public interface Adapter {
         void processOutgoingCallIntent(Context context, CallsManager callsManager,
-                Intent intent);
+                Intent intent, String callingPackage);
         void processIncomingCallIntent(CallsManager callsManager, Intent intent);
         void processUnknownCallIntent(CallsManager callsManager, Intent intent);
     }
@@ -36,8 +36,9 @@
     public static class AdapterImpl implements Adapter {
         @Override
         public void processOutgoingCallIntent(Context context, CallsManager callsManager,
-                Intent intent) {
-            CallIntentProcessor.processOutgoingCallIntent(context, callsManager, intent);
+                Intent intent, String callingPackage) {
+            CallIntentProcessor.processOutgoingCallIntent(context, callsManager, intent,
+                    callingPackage);
         }
 
         @Override
@@ -73,7 +74,7 @@
         this.mCallsManager = callsManager;
     }
 
-    public void processIntent(Intent intent) {
+    public void processIntent(Intent intent, String callingPackage) {
         final boolean isUnknownCall = intent.getBooleanExtra(KEY_IS_UNKNOWN_CALL, false);
         Log.i(this, "onReceive - isUnknownCall: %s", isUnknownCall);
 
@@ -81,7 +82,7 @@
         if (isUnknownCall) {
             processUnknownCallIntent(mCallsManager, intent);
         } else {
-            processOutgoingCallIntent(mContext, mCallsManager, intent);
+            processOutgoingCallIntent(mContext, mCallsManager, intent, callingPackage);
         }
         Trace.endSection();
     }
@@ -91,11 +92,13 @@
      * Processes CALL, CALL_PRIVILEGED, and CALL_EMERGENCY intents.
      *
      * @param intent Call intent containing data about the handle to call.
+     * @param callingPackage The package which initiated the outgoing call (if known).
      */
     static void processOutgoingCallIntent(
             Context context,
             CallsManager callsManager,
-            Intent intent) {
+            Intent intent,
+            String callingPackage) {
 
         Uri handle = intent.getData();
         String scheme = handle.getScheme();
@@ -145,7 +148,7 @@
         // Send to CallsManager to ensure the InCallUI gets kicked off before the broadcast returns
         Call call = callsManager
                 .startOutgoingCall(handle, phoneAccountHandle, clientExtras, initiatingUser,
-                        intent);
+                        intent, callingPackage);
 
         if (call != null) {
             sendNewOutgoingCallIntent(context, call, callsManager, intent);
diff --git a/src/com/android/server/telecom/CallLogManager.java b/src/com/android/server/telecom/CallLogManager.java
index 6e71b73..1d1a010 100755
--- a/src/com/android/server/telecom/CallLogManager.java
+++ b/src/com/android/server/telecom/CallLogManager.java
@@ -39,6 +39,7 @@
 // TODO: Needed for move to system service: import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.CallerInfo;
+import com.android.server.telecom.callfiltering.CallFilteringResult;
 
 import java.util.Arrays;
 import java.util.HashSet;
@@ -83,7 +84,8 @@
                 String postDialDigits, String viaNumber, int presentation, int callType,
                 int features, PhoneAccountHandle accountHandle, long creationDate,
                 long durationInMillis, Long dataUsage, UserHandle initiatingUser, boolean isRead,
-                @Nullable LogCallCompletedListener logCallCompletedListener) {
+                @Nullable LogCallCompletedListener logCallCompletedListener, int callBlockReason,
+                String callScreeningAppName, String callScreeningComponentName) {
             this.context = context;
             this.callerInfo = callerInfo;
             this.number = number;
@@ -99,6 +101,9 @@
             this.initiatingUser = initiatingUser;
             this.isRead = isRead;
             this.logCallCompletedListener = logCallCompletedListener;
+            this.callBockReason = callBlockReason;
+            this.callScreeningAppName = callScreeningAppName;
+            this.callScreeningComponentName = callScreeningComponentName;
         }
         // Since the members are accessed directly, we don't use the
         // mXxxx notation.
@@ -119,6 +124,10 @@
 
         @Nullable
         public final LogCallCompletedListener logCallCompletedListener;
+
+        public final int callBockReason;
+        public final String callScreeningAppName;
+        public final String callScreeningComponentName;
     }
 
     private static final String TAG = CallLogManager.class.getSimpleName();
@@ -182,22 +191,23 @@
             // Always show the notification for managed calls. For self-managed calls, it is up to
             // the app to show the notification, so suppress the notification when logging the call.
             boolean showNotification = !call.isSelfManaged();
-            logCall(call, type, showNotification);
+            logCall(call, type, showNotification, null /*result*/);
         }
     }
 
-    void logCall(Call call, int type, boolean showNotificationForMissedCall) {
-        if (type == Calls.MISSED_TYPE && showNotificationForMissedCall) {
-            logCall(call, Calls.MISSED_TYPE,
-                    new LogCallCompletedListener() {
-                        @Override
-                        public void onLogCompleted(@Nullable Uri uri) {
-                            mMissedCallNotifier.showMissedCallNotification(
-                                    new MissedCallNotifier.CallInfo(call));
-                        }
-                    });
+    void logCall(Call call, int type, boolean showNotificationForMissedCall, CallFilteringResult
+            result) {
+        if ((type == Calls.MISSED_TYPE || type == Calls.BLOCKED_TYPE) &&
+                showNotificationForMissedCall) {
+            logCall(call, type, new LogCallCompletedListener() {
+                @Override
+                public void onLogCompleted(@Nullable Uri uri) {
+                    mMissedCallNotifier.showMissedCallNotification(
+                            new MissedCallNotifier.CallInfo(call));
+                }
+            }, result);
         } else {
-            logCall(call, type, null);
+            logCall(call, type, null, result);
         }
     }
 
@@ -209,10 +219,13 @@
      *     {@link android.provider.CallLog.Calls#INCOMING_TYPE}
      *     {@link android.provider.CallLog.Calls#OUTGOING_TYPE}
      *     {@link android.provider.CallLog.Calls#MISSED_TYPE}
+     *     {@link android.provider.CallLog.Calls#BLOCKED_TYPE}
      * @param logCallCompletedListener optional callback called after the call is logged.
+     * @param result is generated when call type is
+     *     {@link android.provider.CallLog.Calls#BLOCKED_TYPE}.
      */
     void logCall(Call call, int callLogType,
-        @Nullable LogCallCompletedListener logCallCompletedListener) {
+        @Nullable LogCallCompletedListener logCallCompletedListener, CallFilteringResult result) {
         final long creationTime = call.getCreationTimeMillis();
         final long age = call.getAgeMillis();
 
@@ -242,10 +255,22 @@
                 (call.getConnectionProperties() & Connection.PROPERTY_ASSISTED_DIALING_USED) ==
                         Connection.PROPERTY_ASSISTED_DIALING_USED,
                 call.wasEverRttCall());
-        logCall(call.getCallerInfo(), logNumber, call.getPostDialDigits(), formattedViaNumber,
-                call.getHandlePresentation(), callLogType, callFeatures, accountHandle,
-                creationTime, age, callDataUsage, call.isEmergencyCall(), call.getInitiatingUser(),
-                call.isSelfManaged(), logCallCompletedListener);
+
+        if (callLogType == Calls.BLOCKED_TYPE) {
+            logCall(call.getCallerInfo(), logNumber, call.getPostDialDigits(), formattedViaNumber,
+                    call.getHandlePresentation(), callLogType, callFeatures, accountHandle,
+                    creationTime, age, callDataUsage, call.isEmergencyCall(),
+                    call.getInitiatingUser(), call.isSelfManaged(), logCallCompletedListener,
+                    result.mCallBlockReason, result.mCallScreeningAppName,
+                    result.mCallScreeningComponentName);
+        } else {
+            logCall(call.getCallerInfo(), logNumber, call.getPostDialDigits(), formattedViaNumber,
+                    call.getHandlePresentation(), callLogType, callFeatures, accountHandle,
+                    creationTime, age, callDataUsage, call.isEmergencyCall(),
+                    call.getInitiatingUser(), call.isSelfManaged(), logCallCompletedListener,
+                    Calls.BLOCK_REASON_NOT_BLOCKED, null /*callScreeningAppName*/,
+                    null /*callScreeningComponentName*/);
+        }
     }
 
     /**
@@ -265,6 +290,9 @@
      * @param logCallCompletedListener optional callback called after the call is logged.
      * @param initiatingUser The user the call was initiated under.
      * @param isSelfManaged {@code true} if this is a self-managed call, {@code false} otherwise.
+     * @param callBlockReason The reason why the call is blocked.
+     * @param callScreeningAppName The call screening application name which block the call.
+     * @param callScreeningComponentName The call screening component name which block the call.
      */
     private void logCall(
             CallerInfo callerInfo,
@@ -281,7 +309,10 @@
             boolean isEmergency,
             UserHandle initiatingUser,
             boolean isSelfManaged,
-            @Nullable LogCallCompletedListener logCallCompletedListener) {
+            @Nullable LogCallCompletedListener logCallCompletedListener,
+            int callBlockReason,
+            String callScreeningAppName,
+            String callScreeningComponentName) {
 
         // On some devices, to avoid accidental redialing of emergency numbers, we *never* log
         // emergency calls to the Call Log.  (This behavior is set on a per-product basis, based
@@ -314,7 +345,8 @@
             }
             AddCallArgs args = new AddCallArgs(mContext, callerInfo, number, postDialDigits,
                     viaNumber, presentation, callType, features, accountHandle, start, duration,
-                    dataUsage, initiatingUser, isRead, logCallCompletedListener);
+                    dataUsage, initiatingUser, isRead, logCallCompletedListener, callBlockReason,
+                    callScreeningAppName, callScreeningComponentName);
             logCallAsync(args);
         } else {
           Log.d(TAG, "Not adding emergency call to call log.");
@@ -475,7 +507,8 @@
             return Calls.addCall(c.callerInfo, c.context, c.number, c.postDialDigits, c.viaNumber,
                     c.presentation, c.callType, c.features, c.accountHandle, c.timestamp,
                     c.durationInSec, c.dataUsage, userToBeInserted == null,
-                    userToBeInserted, c.isRead);
+                    userToBeInserted, c.isRead, c.callBockReason, c.callScreeningAppName,
+                    c.callScreeningComponentName);
         }
 
 
diff --git a/src/com/android/server/telecom/CallsManager.java b/src/com/android/server/telecom/CallsManager.java
index 1733255..5635699 100644
--- a/src/com/android/server/telecom/CallsManager.java
+++ b/src/com/android/server/telecom/CallsManager.java
@@ -569,7 +569,8 @@
         filters.add(new AsyncBlockCheckFilter(mContext, new BlockCheckerAdapter(),
                 mCallerInfoLookupHelper, null));
         filters.add(new CallScreeningServiceFilter(mContext, this, mPhoneAccountRegistrar,
-                mDefaultDialerCache, new ParcelableCallUtils.Converter(), mLock));
+            mDefaultDialerCache, new ParcelableCallUtils.Converter(), mLock,
+            new TelecomServiceImpl.SettingsSecureAdapterImpl()));
         new IncomingCallFilter(mContext, this, incomingCall, mLock,
                 mTimeoutsAdapter, filters).performFiltering();
     }
@@ -595,7 +596,7 @@
                 } else {
                     Log.i(this, "onCallFilteringCompleted: Call rejected! " +
                             "Exceeds maximum number of ringing calls.");
-                    rejectCallAndLog(incomingCall);
+                    rejectCallAndLog(incomingCall, result);
                 }
             } else if (hasMaximumManagedDialingCalls(incomingCall)) {
                 if (shouldSilenceInsteadOfReject(incomingCall)) {
@@ -604,7 +605,7 @@
 
                     Log.i(this, "onCallFilteringCompleted: Call rejected! Exceeds maximum number of " +
                             "dialing calls.");
-                    rejectCallAndLog(incomingCall);
+                    rejectCallAndLog(incomingCall, result);
                 }
             } else {
                 addCall(incomingCall);
@@ -619,8 +620,8 @@
                 if (result.shouldShowNotification) {
                     Log.w(this, "onCallScreeningCompleted: blocked call, showing notification.");
                 }
-                mCallLogManager.logCall(incomingCall, Calls.MISSED_TYPE,
-                        result.shouldShowNotification);
+                mCallLogManager.logCall(incomingCall, Calls.BLOCKED_TYPE,
+                        result.shouldShowNotification, result);
             } else if (result.shouldShowNotification) {
                 Log.i(this, "onCallScreeningCompleted: blocked call, showing notification.");
                 mMissedCallNotifier.showMissedCallNotification(
@@ -1163,10 +1164,11 @@
      * @param extras The optional extras Bundle passed with the intent used for the incoming call.
      * @param initiatingUser {@link UserHandle} of user that place the outgoing call.
      * @param originalIntent
+     * @param callingPackage the package name of the app which initiated the outgoing call.
      */
     @VisibleForTesting
     public Call startOutgoingCall(Uri handle, PhoneAccountHandle phoneAccountHandle, Bundle extras,
-            UserHandle initiatingUser, Intent originalIntent) {
+            UserHandle initiatingUser, Intent originalIntent, String callingPackage) {
         boolean isReusedCall = true;
         Call call = reuseOutgoingCall(handle);
 
@@ -1192,7 +1194,7 @@
                     false /* forceAttachToExistingConnection */,
                     false, /* isConference */
                     mClockProxy);
-            call.initAnalytics();
+            call.initAnalytics(callingPackage);
 
             // Ensure new calls related to self-managed calls/connections are set as such.  This
             // will be overridden when the actual connection is returned in startCreateConnection,
@@ -2442,7 +2444,7 @@
      * Reject an incoming call and manually add it to the Call Log.
      * @param incomingCall Incoming call that has been rejected
      */
-    private void rejectCallAndLog(Call incomingCall) {
+    private void rejectCallAndLog(Call incomingCall, CallFilteringResult result) {
         if (incomingCall.getConnectionService() != null) {
             // Only reject the call if it has not already been destroyed.  If a call ends while
             // incoming call filtering is taking place, it is possible that the call has already
@@ -2457,7 +2459,7 @@
         // call notifier and the call logger manually.
         // Do we need missed call notification for direct to Voicemail calls?
         mCallLogManager.logCall(incomingCall, Calls.MISSED_TYPE,
-                true /*showNotificationForMissedCall*/);
+                true /*showNotificationForMissedCall*/, result);
     }
 
     /**
@@ -3323,7 +3325,7 @@
 
     /**
      * Used to confirm creation of an outgoing call which was marked as pending confirmation in
-     * {@link #startOutgoingCall(Uri, PhoneAccountHandle, Bundle, UserHandle, Intent)}.
+     * {@link #startOutgoingCall(Uri, PhoneAccountHandle, Bundle, UserHandle, Intent, String)}.
      * Called via {@link TelecomBroadcastIntentProcessor} for a call which was confirmed via
      * {@link ConfirmCallDialogActivity}.
      * @param callId The call ID of the call to confirm.
@@ -3348,7 +3350,7 @@
 
     /**
      * Used to cancel an outgoing call which was marked as pending confirmation in
-     * {@link #startOutgoingCall(Uri, PhoneAccountHandle, Bundle, UserHandle, Intent)}.
+     * {@link #startOutgoingCall(Uri, PhoneAccountHandle, Bundle, UserHandle, Intent, String)}.
      * Called via {@link TelecomBroadcastIntentProcessor} for a call which was confirmed via
      * {@link ConfirmCallDialogActivity}.
      * @param callId The call ID of the call to cancel.
@@ -3364,7 +3366,7 @@
     }
 
     /**
-     * Called from {@link #startOutgoingCall(Uri, PhoneAccountHandle, Bundle, UserHandle, Intent)} when
+     * Called from {@link #startOutgoingCall(Uri, PhoneAccountHandle, Bundle, UserHandle, Intent, String)} when
      * a managed call is added while there are ongoing self-managed calls.  Starts
      * {@link ConfirmCallDialogActivity} to prompt the user to see if they wish to place the
      * outgoing call or not.
@@ -3595,7 +3597,8 @@
         extras.putParcelable(TelecomManager.EXTRA_CALL_AUDIO_STATE,
                 mCallAudioManager.getCallAudioState());
         Call handoverToCall = startOutgoingCall(handoverFromCall.getHandle(), handoverToHandle,
-                extras, getCurrentUserHandle(), null /* originalIntent */);
+                extras, getCurrentUserHandle(), null /* originalIntent */,
+                null /* callingPackage */);
         if (handoverToCall == null) {
             handoverFromCall.sendCallEvent(android.telecom.Call.EVENT_HANDOVER_FAILED, null);
             return;
diff --git a/src/com/android/server/telecom/PhoneAccountRegistrar.java b/src/com/android/server/telecom/PhoneAccountRegistrar.java
index d9398e5..196b8ad 100644
--- a/src/com/android/server/telecom/PhoneAccountRegistrar.java
+++ b/src/com/android/server/telecom/PhoneAccountRegistrar.java
@@ -815,7 +815,7 @@
         sb.append("[").append(account1.getAccountHandle());
         appendDiff(sb, "addr", Log.piiHandle(account1.getAddress()),
                 Log.piiHandle(account2.getAddress()));
-        appendDiff(sb, "cap", account1.getCapabilities(), account2.getCapabilities());
+        appendDiff(sb, "cap", account1.capabilitiesToString(), account2.capabilitiesToString());
         appendDiff(sb, "hl", account1.getHighlightColor(), account2.getHighlightColor());
         appendDiff(sb, "lbl", account1.getLabel(), account2.getLabel());
         appendDiff(sb, "desc", account1.getShortDescription(), account2.getShortDescription());
diff --git a/src/com/android/server/telecom/TelecomServiceImpl.java b/src/com/android/server/telecom/TelecomServiceImpl.java
index 892b5b0..2b2408e 100644
--- a/src/com/android/server/telecom/TelecomServiceImpl.java
+++ b/src/com/android/server/telecom/TelecomServiceImpl.java
@@ -1657,7 +1657,7 @@
                     try {
                         Log.i(this, "handleCallIntent: handling call intent");
                         mCallIntentProcessorAdapter.processOutgoingCallIntent(mContext,
-                                mCallsManager, intent);
+                                mCallsManager, intent, null /* callingPackage */);
                     } finally {
                         Binder.restoreCallingIdentity(token);
                     }
diff --git a/src/com/android/server/telecom/callfiltering/AsyncBlockCheckFilter.java b/src/com/android/server/telecom/callfiltering/AsyncBlockCheckFilter.java
index c63e57c..0abd15d 100644
--- a/src/com/android/server/telecom/callfiltering/AsyncBlockCheckFilter.java
+++ b/src/com/android/server/telecom/callfiltering/AsyncBlockCheckFilter.java
@@ -21,6 +21,7 @@
 import android.os.AsyncTask;
 import android.os.Bundle;
 import android.provider.BlockedNumberContract;
+import android.provider.CallLog;
 import android.telecom.Log;
 import android.telecom.Logging.Session;
 import android.telecom.TelecomManager;
@@ -123,8 +124,11 @@
                 result = new CallFilteringResult(
                         false, // shouldAllowCall
                         true, //shouldReject
-                        false, //shouldAddToCallLog
-                        false // shouldShowNotification
+                        true, //shouldAddToCallLog
+                        false, // shouldShowNotification
+                        convertBlockStatusToReason(), //callBlockReason
+                        null, //callScreeningAppName
+                        null //callScreeningComponentName
                 );
                 if (mCallBlockListener != null) {
                     String number = mIncomingCall.getHandle() == null ? null
@@ -148,4 +152,28 @@
             Log.endSession();
         }
     }
+
+    private int convertBlockStatusToReason() {
+        switch (mBlockStatus) {
+            case BlockedNumberContract.STATUS_BLOCKED_IN_LIST:
+                return CallLog.Calls.BLOCK_REASON_BLOCKED_NUMBER;
+
+            case BlockedNumberContract.STATUS_BLOCKED_UNKNOWN_NUMBER:
+                return CallLog.Calls.BLOCK_REASON_UNKNOWN_NUMBER;
+
+            case BlockedNumberContract.STATUS_BLOCKED_RESTRICTED:
+                return CallLog.Calls.BLOCK_REASON_RESTRICTED_NUMBER;
+
+            case BlockedNumberContract.STATUS_BLOCKED_PAYPHONE:
+                return CallLog.Calls.BLOCK_REASON_PAY_PHONE;
+
+            case BlockedNumberContract.STATUS_BLOCKED_NOT_IN_CONTACTS:
+                return CallLog.Calls.BLOCK_REASON_NOT_IN_CONTACTS;
+
+            default:
+                Log.w(AsyncBlockCheckFilter.class.getSimpleName(),
+                    "There's no call log block reason can be converted");
+                return CallLog.Calls.BLOCK_REASON_BLOCKED_NUMBER;
+        }
+    }
 }
diff --git a/src/com/android/server/telecom/callfiltering/CallFilteringResult.java b/src/com/android/server/telecom/callfiltering/CallFilteringResult.java
index 9e35d86..1213131 100644
--- a/src/com/android/server/telecom/callfiltering/CallFilteringResult.java
+++ b/src/com/android/server/telecom/callfiltering/CallFilteringResult.java
@@ -16,11 +16,18 @@
 
 package com.android.server.telecom.callfiltering;
 
+import android.provider.CallLog;
+import android.provider.CallLog.Calls;
+import android.text.TextUtils;
+
 public class CallFilteringResult {
     public boolean shouldAllowCall;
     public boolean shouldReject;
     public boolean shouldAddToCallLog;
     public boolean shouldShowNotification;
+    public int mCallBlockReason = CallLog.Calls.BLOCK_REASON_NOT_BLOCKED;
+    public String mCallScreeningAppName = null;
+    public String mCallScreeningComponentName = null;
 
     public CallFilteringResult(boolean shouldAllowCall, boolean shouldReject, boolean
             shouldAddToCallLog, boolean shouldShowNotification) {
@@ -30,22 +37,85 @@
         this.shouldShowNotification = shouldShowNotification;
     }
 
+    public CallFilteringResult(boolean shouldAllowCall, boolean shouldReject, boolean
+            shouldAddToCallLog, boolean shouldShowNotification, int callBlockReason, String
+            callScreeningAppName, String callScreeningComponentName) {
+        this.shouldAllowCall = shouldAllowCall;
+        this.shouldReject = shouldReject;
+        this.shouldAddToCallLog = shouldAddToCallLog;
+        this.shouldShowNotification = shouldShowNotification;
+        this.mCallBlockReason = callBlockReason;
+        this.mCallScreeningAppName = callScreeningAppName;
+        this.mCallScreeningComponentName = callScreeningComponentName;
+    }
+
     /**
-     * Combine this CallFilteringResult with another, returning a CallFilteringResult with
-     * the more restrictive properties of the two.
+     * Combine this CallFilteringResult with another, returning a CallFilteringResult with the more
+     * restrictive properties of the two. Where there are multiple call filtering components which
+     * block a call, the first filter from {@link AsyncBlockCheckFilter},
+     * {@link DirectToVoicemailCallFilter}, {@link CallScreeningServiceFilter} which blocked a call
+     * shall be used to populate the call block reason, component name, etc.
      */
     public CallFilteringResult combine(CallFilteringResult other) {
         if (other == null) {
             return this;
         }
 
+        if (isBlockedByProvider(mCallBlockReason)) {
+            return getCombinedCallFilteringResult(other, mCallBlockReason,
+                null /*callScreeningAppName*/, null /*callScreeningComponentName*/);
+        } else if (isBlockedByProvider(other.mCallBlockReason)) {
+            return getCombinedCallFilteringResult(other, other.mCallBlockReason,
+                null /*callScreeningAppName*/, null /*callScreeningComponentName*/);
+        }
+
+        if (mCallBlockReason == Calls.BLOCK_REASON_DIRECT_TO_VOICEMAIL
+            || other.mCallBlockReason == Calls.BLOCK_REASON_DIRECT_TO_VOICEMAIL) {
+            return getCombinedCallFilteringResult(other, Calls.BLOCK_REASON_DIRECT_TO_VOICEMAIL,
+                null /*callScreeningAppName*/, null /*callScreeningComponentName*/);
+        }
+
+        if (shouldReject && mCallBlockReason == CallLog.Calls.BLOCK_REASON_CALL_SCREENING_SERVICE) {
+            return getCombinedCallFilteringResult(other, Calls.BLOCK_REASON_CALL_SCREENING_SERVICE,
+                mCallScreeningAppName, mCallScreeningComponentName);
+        } else if (other.shouldReject && other.mCallBlockReason == CallLog.Calls
+            .BLOCK_REASON_CALL_SCREENING_SERVICE) {
+            return getCombinedCallFilteringResult(other, Calls.BLOCK_REASON_CALL_SCREENING_SERVICE,
+                other.mCallScreeningAppName, other.mCallScreeningComponentName);
+        }
+
         return new CallFilteringResult(
-                shouldAllowCall && other.shouldAllowCall,
-                shouldReject || other.shouldReject,
-                shouldAddToCallLog && other.shouldAddToCallLog,
-                shouldShowNotification && other.shouldShowNotification);
+            shouldAllowCall && other.shouldAllowCall,
+            shouldReject || other.shouldReject,
+            shouldAddToCallLog && other.shouldAddToCallLog,
+            shouldShowNotification && other.shouldShowNotification);
     }
 
+    private boolean isBlockedByProvider(int blockReason) {
+        if (blockReason == Calls.BLOCK_REASON_BLOCKED_NUMBER
+            || blockReason == Calls.BLOCK_REASON_UNKNOWN_NUMBER
+            || blockReason == Calls.BLOCK_REASON_RESTRICTED_NUMBER
+            || blockReason == Calls.BLOCK_REASON_PAY_PHONE
+            || blockReason == Calls.BLOCK_REASON_NOT_IN_CONTACTS) {
+            return true;
+        }
+
+        return false;
+    }
+
+    private CallFilteringResult getCombinedCallFilteringResult(CallFilteringResult other,
+        int callBlockReason, String callScreeningAppName, String callScreeningComponentName) {
+        return new CallFilteringResult(
+            shouldAllowCall && other.shouldAllowCall,
+            shouldReject || other.shouldReject,
+            shouldAddToCallLog && other.shouldAddToCallLog,
+            shouldShowNotification && other.shouldShowNotification,
+            callBlockReason,
+            callScreeningAppName,
+            callScreeningComponentName);
+    }
+
+
     @Override
     public boolean equals(Object o) {
         if (this == o) return true;
@@ -56,7 +126,24 @@
         if (shouldAllowCall != that.shouldAllowCall) return false;
         if (shouldReject != that.shouldReject) return false;
         if (shouldAddToCallLog != that.shouldAddToCallLog) return false;
-        return shouldShowNotification == that.shouldShowNotification;
+        if (shouldShowNotification != that.shouldShowNotification) return false;
+        if (mCallBlockReason != that.mCallBlockReason) return false;
+
+        if ((TextUtils.isEmpty(mCallScreeningAppName) &&
+            TextUtils.isEmpty(that.mCallScreeningAppName)) &&
+            (TextUtils.isEmpty(mCallScreeningComponentName) &&
+            TextUtils.isEmpty(that.mCallScreeningComponentName))) {
+            return true;
+        } else if (!TextUtils.isEmpty(mCallScreeningAppName) &&
+            !TextUtils.isEmpty(that.mCallScreeningAppName) &&
+            mCallScreeningAppName.equals(that.mCallScreeningAppName) &&
+            !TextUtils.isEmpty(mCallScreeningComponentName) &&
+            !TextUtils.isEmpty(that.mCallScreeningComponentName) &&
+            mCallScreeningComponentName.equals(that.mCallScreeningComponentName)) {
+            return true;
+        }
+
+        return false;
     }
 
     @Override
@@ -87,6 +174,21 @@
         if (shouldShowNotification) {
             sb.append(", notified");
         }
+
+        if (mCallBlockReason != 0) {
+            sb.append(", mCallBlockReason = ");
+            sb.append(mCallBlockReason);
+        }
+
+        if (!TextUtils.isEmpty(mCallScreeningAppName)) {
+            sb.append(", mCallScreeningAppName = ");
+            sb.append(mCallScreeningAppName);
+        }
+
+        if (!TextUtils.isEmpty(mCallScreeningComponentName)) {
+            sb.append(", mCallScreeningComponentName = ");
+            sb.append(mCallScreeningComponentName);
+        }
         sb.append("]");
 
         return sb.toString();
diff --git a/src/com/android/server/telecom/callfiltering/CallScreeningServiceFilter.java b/src/com/android/server/telecom/callfiltering/CallScreeningServiceFilter.java
index 4830b31..c89a1a4 100644
--- a/src/com/android/server/telecom/callfiltering/CallScreeningServiceFilter.java
+++ b/src/com/android/server/telecom/callfiltering/CallScreeningServiceFilter.java
@@ -24,10 +24,15 @@
 import android.content.pm.ResolveInfo;
 import android.os.Binder;
 import android.os.IBinder;
+import android.os.PersistableBundle;
 import android.os.RemoteException;
 import android.os.UserHandle;
+import android.provider.CallLog;
+import android.provider.Settings;
 import android.telecom.CallScreeningService;
 import android.telecom.Log;
+import android.telecom.TelecomManager;
+import android.telephony.CarrierConfigManager;
 import android.text.TextUtils;
 
 import com.android.internal.telecom.ICallScreeningAdapter;
@@ -39,6 +44,7 @@
 import com.android.server.telecom.ParcelableCallUtils;
 import com.android.server.telecom.PhoneAccountRegistrar;
 import com.android.server.telecom.TelecomServiceImpl;
+import com.android.server.telecom.TelecomServiceImpl.SettingsSecureAdapter;
 import com.android.server.telecom.TelecomSystem;
 
 import java.util.List;
@@ -108,20 +114,26 @@
                 String callId,
                 boolean shouldReject,
                 boolean shouldAddToCallLog,
-                boolean shouldShowNotification) {
+                boolean shouldShowNotification,
+                ComponentName componentName) {
             Log.startSession("CSCR.dC");
             long token = Binder.clearCallingIdentity();
             try {
                 synchronized (mTelecomLock) {
+                    boolean isServiceRequestingLogging = isLoggable(componentName,
+                        shouldAddToCallLog);
                     Log.i(this, "disallowCall(%s), shouldReject: %b, shouldAddToCallLog: %b, "
-                                    + "shouldShowNotification: %b", callId, shouldReject,
-                            shouldAddToCallLog, shouldShowNotification);
+                            + "shouldShowNotification: %b", callId, shouldReject,
+                        isServiceRequestingLogging, shouldShowNotification);
                     if (mCall != null && mCall.getId().equals(callId)) {
                         mResult = new CallFilteringResult(
-                                false, // shouldAllowCall
-                                shouldReject, //shouldReject
-                                shouldAddToCallLog, //shouldAddToCallLog
-                                shouldShowNotification // shouldShowNotification
+                            false, // shouldAllowCall
+                            shouldReject, //shouldReject
+                            isServiceRequestingLogging, //shouldAddToCallLog
+                            shouldShowNotification, // shouldShowNotification
+                            CallLog.Calls.BLOCK_REASON_CALL_SCREENING_SERVICE, //callBlockReason
+                            componentName.getPackageName(), //callScreeningAppName
+                            componentName.flattenToString() //callScreeningComponentName
                         );
                     } else {
                         Log.w(this, "disallowCall, unknown call id: %s", callId);
@@ -141,6 +153,7 @@
     private final DefaultDialerCache mDefaultDialerCache;
     private final ParcelableCallUtils.Converter mParcelableCallUtilsConverter;
     private final TelecomSystem.SyncRoot mTelecomLock;
+    private final SettingsSecureAdapter mSettingsSecureAdapter;
 
     private Call mCall;
     private CallFilterResultCallback mCallback;
@@ -161,13 +174,15 @@
             PhoneAccountRegistrar phoneAccountRegistrar,
             DefaultDialerCache defaultDialerCache,
             ParcelableCallUtils.Converter parcelableCallUtilsConverter,
-            TelecomSystem.SyncRoot lock) {
+            TelecomSystem.SyncRoot lock,
+            SettingsSecureAdapter settingsSecureAdapter) {
         mContext = context;
         mPhoneAccountRegistrar = phoneAccountRegistrar;
         mCallsManager = callsManager;
         mDefaultDialerCache = defaultDialerCache;
         mParcelableCallUtilsConverter = parcelableCallUtilsConverter;
         mTelecomLock = lock;
+        mSettingsSecureAdapter = settingsSecureAdapter;
     }
 
     @Override
@@ -261,4 +276,56 @@
             finishCallScreening();
         }
     }
+
+    private boolean isLoggable(ComponentName componentName, boolean shouldAddToCallLog) {
+        if (isCarrierCallScreeningApp(componentName)) {
+            return shouldAddToCallLog;
+        } else if (isDefaultDialer(componentName) || isUserChosenCallScreeningApp(componentName)) {
+            return true;
+        }
+
+        return shouldAddToCallLog;
+    }
+
+    private boolean isCarrierCallScreeningApp(ComponentName componentName) {
+        String carrierCallScreeningApp = null;
+        CarrierConfigManager configManager = (CarrierConfigManager) mContext
+            .getSystemService(Context.CARRIER_CONFIG_SERVICE);
+        PersistableBundle configBundle = configManager.getConfig();
+        if (configBundle != null) {
+            carrierCallScreeningApp = configBundle
+                .getString(CarrierConfigManager.KEY_CARRIER_CALL_SCREENING_APP_STRING);
+        }
+
+        if (!TextUtils.isEmpty(carrierCallScreeningApp) && carrierCallScreeningApp
+            .equals(componentName.flattenToString())) {
+            return true;
+        }
+
+        return false;
+    }
+
+    private boolean isDefaultDialer(ComponentName componentName) {
+        String defaultDialer = TelecomManager.from(mContext).getDefaultDialerPackage();
+
+        if (!TextUtils.isEmpty(defaultDialer) && defaultDialer
+            .equals(componentName.getPackageName())) {
+            return true;
+        }
+
+        return false;
+    }
+
+    private boolean isUserChosenCallScreeningApp(ComponentName componentName) {
+        String defaultCallScreeningApplication = mSettingsSecureAdapter
+            .getStringForUser(mContext.getContentResolver(),
+                Settings.Secure.CALL_SCREENING_DEFAULT_COMPONENT, UserHandle.USER_CURRENT);
+
+        if (!TextUtils.isEmpty(defaultCallScreeningApplication) && defaultCallScreeningApplication
+            .equals(componentName.flattenToString())) {
+            return true;
+        }
+
+        return false;
+    }
 }
diff --git a/src/com/android/server/telecom/callfiltering/DirectToVoicemailCallFilter.java b/src/com/android/server/telecom/callfiltering/DirectToVoicemailCallFilter.java
index 2ac82dc..3a8ff7d 100644
--- a/src/com/android/server/telecom/callfiltering/DirectToVoicemailCallFilter.java
+++ b/src/com/android/server/telecom/callfiltering/DirectToVoicemailCallFilter.java
@@ -17,6 +17,7 @@
 package com.android.server.telecom.callfiltering;
 
 import android.net.Uri;
+import android.provider.CallLog;
 import android.telecom.Log;
 
 import com.android.internal.telephony.CallerInfo;
@@ -49,7 +50,11 @@
                                         false, // shouldAllowCall
                                         true, // shouldReject
                                         true, // shouldAddToCallLog
-                                        true // shouldShowNotification
+                                        true, // shouldShowNotification
+                                        CallLog.Calls.BLOCK_REASON_DIRECT_TO_VOICEMAIL,
+                                        //callBlockReason
+                                        null, //callScreeningAppName
+                                        null // callScreeningComponentName
                                 );
                             } else {
                                 result = new CallFilteringResult(
diff --git a/src/com/android/server/telecom/components/UserCallIntentProcessor.java b/src/com/android/server/telecom/components/UserCallIntentProcessor.java
index 6a8f8c8..ae4a7d8 100644
--- a/src/com/android/server/telecom/components/UserCallIntentProcessor.java
+++ b/src/com/android/server/telecom/components/UserCallIntentProcessor.java
@@ -159,7 +159,7 @@
         // Save the user handle of current user before forwarding the intent to primary user.
         intent.putExtra(CallIntentProcessor.KEY_INITIATING_USER, mUserHandle);
 
-        sendIntentToDestination(intent, isLocalInvocation);
+        sendIntentToDestination(intent, isLocalInvocation, callingPackageName);
     }
 
     private boolean isDefaultOrSystemDialer(String callingPackageName) {
@@ -193,7 +193,8 @@
      * If the caller is local to the Telecom service, we send the intent to Telecom without
      * sending it through TelecomServiceImpl.
      */
-    private boolean sendIntentToDestination(Intent intent, boolean isLocalInvocation) {
+    private boolean sendIntentToDestination(Intent intent, boolean isLocalInvocation,
+            String callingPackage) {
         intent.putExtra(CallIntentProcessor.KEY_IS_INCOMING_CALL, false);
         intent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
         if (isLocalInvocation) {
@@ -202,7 +203,8 @@
             // TODO: We should not be using an intent here; this whole flows needs cleanup.
             Log.i(this, "sendIntentToDestination: send intent to Telecom directly.");
             synchronized (TelecomSystem.getInstance().getLock()) {
-                TelecomSystem.getInstance().getCallIntentProcessor().processIntent(intent);
+                TelecomSystem.getInstance().getCallIntentProcessor().processIntent(intent,
+                        callingPackage);
             }
         } else {
             // We're calling from the UserCallActivity, so the TelecomSystem is not in the same
diff --git a/testapps/src/com/android/server/telecom/testapps/CallServiceNotifier.java b/testapps/src/com/android/server/telecom/testapps/CallServiceNotifier.java
index 758ae4f..1c84d29 100644
--- a/testapps/src/com/android/server/telecom/testapps/CallServiceNotifier.java
+++ b/testapps/src/com/android/server/telecom/testapps/CallServiceNotifier.java
@@ -19,6 +19,7 @@
 import com.android.server.telecom.testapps.R;
 
 import android.app.Notification;
+import android.app.NotificationChannel;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
 import android.content.ComponentName;
@@ -26,6 +27,7 @@
 import android.content.Intent;
 import android.graphics.Color;
 import android.graphics.drawable.Icon;
+import android.media.AudioAttributes;
 import android.net.Uri;
 import android.os.Bundle;
 import android.telecom.PhoneAccount;
@@ -45,6 +47,7 @@
  */
 public class CallServiceNotifier {
     private static final CallServiceNotifier INSTANCE = new CallServiceNotifier();
+    private static final String CHANNEL_ID = "channel1";
 
     public static final String CALL_PROVIDER_ID = "testapps_TestConnectionService_CALL_PROVIDER_ID";
     public static final String SIM_SUBSCRIPTION_ID =
@@ -86,6 +89,9 @@
      */
     public void updateNotification(Context context) {
         log("adding the notification ------------");
+        NotificationChannel channel = new NotificationChannel(CHANNEL_ID, "Test Channel",
+                NotificationManager.IMPORTANCE_DEFAULT);
+        getNotificationManager(context).createNotificationChannel(channel);
         getNotificationManager(context).notify(CALL_NOTIFICATION_ID, getMainNotification(context));
         getNotificationManager(context).notify(
                 PHONE_ACCOUNT_NOTIFICATION_ID, getPhoneAccountNotification(context));
@@ -219,7 +225,7 @@
      * Creates a notification object for using the telecom APIs.
      */
     private Notification getPhoneAccountNotification(Context context) {
-        final Notification.Builder builder = new Notification.Builder(context);
+        final Notification.Builder builder = new Notification.Builder(context, CHANNEL_ID);
         // Both notifications have buttons and only the first one with buttons will show its
         // buttons.  Since the phone accounts notification is always first, setting false ensures
         // it can be dismissed to use the other notification.
@@ -244,7 +250,7 @@
      * Creates a notification object out of the current calls state.
      */
     private Notification getMainNotification(Context context) {
-        final Notification.Builder builder = new Notification.Builder(context);
+        final Notification.Builder builder = new Notification.Builder(context, CHANNEL_ID);
         builder.setOngoing(true);
         builder.setPriority(Notification.PRIORITY_HIGH);
         builder.setSmallIcon(android.R.drawable.stat_sys_phone_call);
diff --git a/tests/src/com/android/server/telecom/tests/AsyncBlockCheckFilterTest.java b/tests/src/com/android/server/telecom/tests/AsyncBlockCheckFilterTest.java
index 22c803e..91ddf5a 100644
--- a/tests/src/com/android/server/telecom/tests/AsyncBlockCheckFilterTest.java
+++ b/tests/src/com/android/server/telecom/tests/AsyncBlockCheckFilterTest.java
@@ -23,6 +23,7 @@
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.PersistableBundle;
+import android.provider.CallLog;
 import android.telecom.TelecomManager;
 import android.telephony.CarrierConfigManager;
 import android.test.suitebuilder.annotation.SmallTest;
@@ -62,8 +63,12 @@
     private static final CallFilteringResult BLOCK_RESULT = new CallFilteringResult(
             false, // shouldAllowCall
             true, //shouldReject
-            false, //shouldAddToCallLog
-            false // shouldShowNotification
+            true, //shouldAddToCallLog
+            false, // shouldShowNotification
+            CallLog.Calls.BLOCK_REASON_BLOCKED_NUMBER, //blockReason
+            null, // callScreeningAppName
+            null //callScreeningComponentName
+
     );
 
     private static final CallFilteringResult PASS_RESULT = new CallFilteringResult(
diff --git a/tests/src/com/android/server/telecom/tests/CallScreeningServiceFilterTest.java b/tests/src/com/android/server/telecom/tests/CallScreeningServiceFilterTest.java
index a319fad..f2530af 100644
--- a/tests/src/com/android/server/telecom/tests/CallScreeningServiceFilterTest.java
+++ b/tests/src/com/android/server/telecom/tests/CallScreeningServiceFilterTest.java
@@ -18,6 +18,7 @@
 
 import android.Manifest;
 import android.content.ComponentName;
+import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.ServiceConnection;
@@ -25,10 +26,14 @@
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
 import android.os.IBinder;
+import android.os.PersistableBundle;
 import android.os.RemoteException;
 import android.os.UserHandle;
+import android.provider.CallLog;
 import android.telecom.CallScreeningService;
 import android.telecom.ParcelableCall;
+import android.telecom.TelecomManager;
+import android.telephony.CarrierConfigManager;
 import android.test.suitebuilder.annotation.SmallTest;
 
 import com.android.internal.telecom.ICallScreeningAdapter;
@@ -38,6 +43,7 @@
 import com.android.server.telecom.DefaultDialerCache;
 import com.android.server.telecom.ParcelableCallUtils;
 import com.android.server.telecom.PhoneAccountRegistrar;
+import com.android.server.telecom.TelecomServiceImpl;
 import com.android.server.telecom.callfiltering.CallFilterResultCallback;
 import com.android.server.telecom.callfiltering.CallFilteringResult;
 import com.android.server.telecom.callfiltering.CallScreeningServiceFilter;
@@ -60,6 +66,7 @@
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -78,11 +85,22 @@
     @Mock PackageManager mPackageManager;
     @Mock IBinder mBinder;
     @Mock ICallScreeningService mCallScreeningService;
+    @Mock CarrierConfigManager mCarrierConfigManager;
+    @Mock private TelecomManager mTelecomManager;
+    private TelecomServiceImpl.SettingsSecureAdapter mSettingsSecureAdapter =
+        spy(new SettingsSecureAdapterFake());
 
     private static final String PKG_NAME = "com.android.services.telecom.tests";
     private static final String CLS_NAME = "CallScreeningService";
     private static final ComponentName COMPONENT_NAME = new ComponentName(PKG_NAME, CLS_NAME);
     private static final String CALL_ID = "u89prgt9ps78y5";
+    private static final String DEFAULT_DIALER_PACKAGE = "com.android.dialer";
+    private static final ComponentName CARRIER_DEFINED_CALL_SCREENING = new ComponentName(
+        "com.android.carrier", "com.android.carrier.callscreeningserviceimpl");
+    private static final ComponentName DEFAULT_DIALER_CALL_SCREENING = new ComponentName(
+        "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 ResolveInfo mResolveInfo;
 
@@ -95,6 +113,20 @@
 
     private CallScreeningServiceFilter mFilter;
 
+    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();
+        }
+    }
+
     @Override
     @Before
     public void setUp() throws Exception {
@@ -112,7 +144,7 @@
         }};
 
         mFilter = new CallScreeningServiceFilter(mContext, mCallsManager, mPhoneAccountRegistrar,
-                mDefaultDialerCache, mParcelableCallUtilsConverter, mLock);
+                mDefaultDialerCache, mParcelableCallUtilsConverter, mLock, mSettingsSecureAdapter);
 
         when(mDefaultDialerCache.getDefaultDialerApplication(eq(UserHandle.USER_CURRENT)))
                 .thenReturn(PKG_NAME);
@@ -191,7 +223,11 @@
 
     @SmallTest
     @Test
-    public void testDisallowCall() throws Exception {
+    public void testDisallowCallForCarrierDefined() throws Exception {
+        setCarrierDefinedCallScreeningApplication();
+        when(TelecomManager.from(mContext)).thenReturn(mTelecomManager);
+        when(mTelecomManager.getDefaultDialerPackage()).thenReturn(DEFAULT_DIALER_PACKAGE);
+
         mFilter.startFilterLookup(mCall, mCallback);
         ServiceConnection serviceConnection = verifyBindingIntent();
         serviceConnection.onServiceConnected(COMPONENT_NAME, mBinder);
@@ -199,13 +235,73 @@
         csAdapter.disallowCall(CALL_ID,
                 true, // shouldReject
                 false, // shouldAddToCallLog
-                true // shouldShowNotification
+                true, // shouldShowNotification
+                CARRIER_DEFINED_CALL_SCREENING
         );
         verify(mCallback).onCallFilteringComplete(eq(mCall), eq(new CallFilteringResult(
                 false, // shouldAllowCall
                 true, // shouldReject
                 false, // shouldAddToCallLog
-                true // shouldShowNotification
+                true, // shouldShowNotification
+                CallLog.Calls.BLOCK_REASON_CALL_SCREENING_SERVICE, //callBlockReason
+                CARRIER_DEFINED_CALL_SCREENING.getPackageName(), //callScreeningAppName
+                CARRIER_DEFINED_CALL_SCREENING.flattenToString() //callScreeningComponentName
+        )));
+    }
+
+    @SmallTest
+    @Test
+    public void testDisallowCallForDefaultDialer() throws Exception {
+        setCarrierDefinedCallScreeningApplication();
+        when(TelecomManager.from(mContext)).thenReturn(mTelecomManager);
+        when(mTelecomManager.getDefaultDialerPackage()).thenReturn(DEFAULT_DIALER_PACKAGE);
+
+        mFilter.startFilterLookup(mCall, mCallback);
+        ServiceConnection serviceConnection = verifyBindingIntent();
+        serviceConnection.onServiceConnected(COMPONENT_NAME, mBinder);
+        ICallScreeningAdapter csAdapter = getCallScreeningAdapter();
+        csAdapter.disallowCall(CALL_ID,
+            true, // shouldReject
+            false, // shouldAddToCallLog
+            true, // shouldShowNotification
+            DEFAULT_DIALER_CALL_SCREENING
+        );
+        verify(mCallback).onCallFilteringComplete(eq(mCall), eq(new CallFilteringResult(
+            false, // shouldAllowCall
+            true, // shouldReject
+            true, // shouldAddToCallLog
+            true, // shouldShowNotification
+            CallLog.Calls.BLOCK_REASON_CALL_SCREENING_SERVICE, //callBlockReason
+            DEFAULT_DIALER_CALL_SCREENING.getPackageName(), //callScreeningAppName
+            DEFAULT_DIALER_CALL_SCREENING.flattenToString() //callScreeningComponentName
+        )));
+    }
+
+    @SmallTest
+    @Test
+    public void testDisallowCallForUserChosen() throws Exception {
+        setCarrierDefinedCallScreeningApplication();
+        when(TelecomManager.from(mContext)).thenReturn(mTelecomManager);
+        when(mTelecomManager.getDefaultDialerPackage()).thenReturn(DEFAULT_DIALER_PACKAGE);
+
+        mFilter.startFilterLookup(mCall, mCallback);
+        ServiceConnection serviceConnection = verifyBindingIntent();
+        serviceConnection.onServiceConnected(COMPONENT_NAME, mBinder);
+        ICallScreeningAdapter csAdapter = getCallScreeningAdapter();
+        csAdapter.disallowCall(CALL_ID,
+            true, // shouldReject
+            false, // shouldAddToCallLog
+            true, // shouldShowNotification
+            USER_CHOSEN_CALL_SCREENING
+        );
+        verify(mCallback).onCallFilteringComplete(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.getPackageName(), //callScreeningAppName
+            USER_CHOSEN_CALL_SCREENING.flattenToString() //callScreeningComponentName
         )));
     }
 
@@ -231,4 +327,14 @@
         verify(mCallScreeningService).screenCall(captor.capture(), nullable(ParcelableCall.class));
         return captor.getValue();
     }
+
+    private void setCarrierDefinedCallScreeningApplication() {
+        String carrierDefined = "com.android.carrier/com.android.carrier.callscreeningserviceimpl";
+        PersistableBundle bundle = new PersistableBundle();
+        bundle.putString(CarrierConfigManager.KEY_CARRIER_CALL_SCREENING_APP_STRING,
+            carrierDefined);
+        when(mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE))
+            .thenReturn(mCarrierConfigManager);
+        when(mCarrierConfigManager.getConfig()).thenReturn(bundle);
+    }
 }
diff --git a/tests/src/com/android/server/telecom/tests/DirectToVoicemailCallFilterTest.java b/tests/src/com/android/server/telecom/tests/DirectToVoicemailCallFilterTest.java
index af4c168..a685c5e 100644
--- a/tests/src/com/android/server/telecom/tests/DirectToVoicemailCallFilterTest.java
+++ b/tests/src/com/android/server/telecom/tests/DirectToVoicemailCallFilterTest.java
@@ -17,6 +17,7 @@
 package com.android.server.telecom.tests;
 
 import android.net.Uri;
+import android.provider.CallLog;
 import android.test.suitebuilder.annotation.SmallTest;
 
 import com.android.internal.telephony.CallerInfo;
@@ -65,7 +66,10 @@
                         false, // shouldAllowCall
                         true, // shouldReject
                         true, // shouldAddToCallLog
-                        true // shouldShowNotification
+                        true, // shouldShowNotification
+                        CallLog.Calls.BLOCK_REASON_DIRECT_TO_VOICEMAIL, //callBlockReason
+                        null, //callScreeningAppName
+                        null // callScreeningComponentName
                 ));
     }
 
diff --git a/tests/src/com/android/server/telecom/tests/IncomingCallFilterTest.java b/tests/src/com/android/server/telecom/tests/IncomingCallFilterTest.java
index d975ec2..e399088 100644
--- a/tests/src/com/android/server/telecom/tests/IncomingCallFilterTest.java
+++ b/tests/src/com/android/server/telecom/tests/IncomingCallFilterTest.java
@@ -19,6 +19,7 @@
 import android.content.ContentResolver;
 import android.content.IContentProvider;
 import android.net.Uri;
+import android.provider.CallLog;
 import android.test.suitebuilder.annotation.SmallTest;
 
 import com.android.server.telecom.Call;
@@ -55,6 +56,7 @@
     @Mock private IncomingCallFilter.CallFilter mFilter1;
     @Mock private IncomingCallFilter.CallFilter mFilter2;
     @Mock private IncomingCallFilter.CallFilter mFilter3;
+    @Mock private IncomingCallFilter.CallFilter mFilter4;
 
     @Mock private Timeouts.Adapter mTimeoutsAdapter;
 
@@ -62,7 +64,7 @@
     private static final long LONG_TIMEOUT = 1000000;
     private static final long SHORT_TIMEOUT = 100;
 
-    private static final CallFilteringResult RESULT1 =
+    private static final CallFilteringResult PASS_CALL_RESULT =
             new CallFilteringResult(
                     true, // shouldAllowCall
                     false, // shouldReject
@@ -70,23 +72,41 @@
                     true // shouldShowNotification
             );
 
-    private static final CallFilteringResult RESULT2 =
-            new CallFilteringResult(
-                    false, // shouldAllowCall
-                    true, // shouldReject
-                    false, // shouldAddToCallLog
-                    true // shouldShowNotification
-            );
-
-    private static final CallFilteringResult RESULT3 =
+    private static final CallFilteringResult ASYNC_BLOCK_CHECK_BLOCK_RESULT =
             new CallFilteringResult(
                     false, // shouldAllowCall
                     true, // shouldReject
                     true, // shouldAddToCallLog
-                    false // shouldShowNotification
+                    false, // shouldShowNotification
+                    CallLog.Calls.BLOCK_REASON_BLOCKED_NUMBER, //callBlockReason
+                    null, //callScreeningAppName
+                    null //callScreeningComponentName
             );
 
-    private static final CallFilteringResult DEFAULT_RESULT = RESULT1;
+    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
+            );
+
+    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
+            );
+
+    private static final CallFilteringResult DEFAULT_RESULT = PASS_CALL_RESULT;
 
     @Override
     @Before
@@ -99,20 +119,97 @@
 
     @SmallTest
     @Test
-    public void testSingleFilter() {
+    public void testAsyncBlockCallResultFilter() {
         IncomingCallFilter testFilter = new IncomingCallFilter(mContext, mResultCallback, mCall,
                 mLock, mTimeoutsAdapter, Collections.singletonList(mFilter1));
         testFilter.performFiltering();
         verify(mFilter1).startFilterLookup(mCall, testFilter);
 
-        testFilter.onCallFilteringComplete(mCall, RESULT1);
+        testFilter.onCallFilteringComplete(mCall, ASYNC_BLOCK_CHECK_BLOCK_RESULT);
         waitForHandlerAction(testFilter.getHandler(), SHORT_TIMEOUT * 2);
-        verify(mResultCallback).onCallFilteringComplete(eq(mCall), eq(RESULT1));
+        verify(mResultCallback).onCallFilteringComplete(eq(mCall), eq
+                (ASYNC_BLOCK_CHECK_BLOCK_RESULT));
     }
 
     @SmallTest
     @Test
-    public void testMultipleFilters() {
+    public void testDirectToVoiceMailCallResultFilter() {
+        IncomingCallFilter testFilter = new IncomingCallFilter(mContext, mResultCallback, mCall,
+                mLock, mTimeoutsAdapter, Collections.singletonList(mFilter1));
+        testFilter.performFiltering();
+        verify(mFilter1).startFilterLookup(mCall, testFilter);
+
+        testFilter.onCallFilteringComplete(mCall, DIRECT_TO_VOICEMAIL_CALL_BLOCK_RESULT);
+        waitForHandlerAction(testFilter.getHandler(), SHORT_TIMEOUT * 2);
+        verify(mResultCallback).onCallFilteringComplete(eq(mCall), eq
+                (DIRECT_TO_VOICEMAIL_CALL_BLOCK_RESULT));
+    }
+
+    @SmallTest
+    @Test
+    public void testCallScreeningServiceBlockCallResultFilter() {
+        IncomingCallFilter testFilter = new IncomingCallFilter(mContext, mResultCallback, mCall,
+                mLock, mTimeoutsAdapter, Collections.singletonList(mFilter1));
+        testFilter.performFiltering();
+        verify(mFilter1).startFilterLookup(mCall, testFilter);
+
+        testFilter.onCallFilteringComplete(mCall, CALL_SCREENING_SERVICE_BLOCK_RESULT);
+        waitForHandlerAction(testFilter.getHandler(), SHORT_TIMEOUT * 2);
+        verify(mResultCallback).onCallFilteringComplete(eq(mCall), eq
+                (CALL_SCREENING_SERVICE_BLOCK_RESULT));
+    }
+
+    @SmallTest
+    @Test
+    public void testPassCallResultFilter() {
+        IncomingCallFilter testFilter = new IncomingCallFilter(mContext, mResultCallback, mCall,
+                mLock, mTimeoutsAdapter, Collections.singletonList(mFilter1));
+        testFilter.performFiltering();
+        verify(mFilter1).startFilterLookup(mCall, testFilter);
+
+        testFilter.onCallFilteringComplete(mCall, PASS_CALL_RESULT);
+        waitForHandlerAction(testFilter.getHandler(), SHORT_TIMEOUT * 2);
+        verify(mResultCallback).onCallFilteringComplete(eq(mCall), eq(PASS_CALL_RESULT));
+    }
+
+    @SmallTest
+    @Test
+    public void testMultipleFiltersForAsyncBlockCheckFilter() {
+        List<IncomingCallFilter.CallFilter> filters =
+                new ArrayList<IncomingCallFilter.CallFilter>() {{
+                    add(mFilter1);
+                    add(mFilter2);
+                    add(mFilter3);
+                    add(mFilter4);
+                }};
+        IncomingCallFilter testFilter = new IncomingCallFilter(mContext, mResultCallback, mCall,
+                mLock, mTimeoutsAdapter, filters);
+        testFilter.performFiltering();
+        verify(mFilter1).startFilterLookup(mCall, testFilter);
+        verify(mFilter2).startFilterLookup(mCall, testFilter);
+        verify(mFilter3).startFilterLookup(mCall, testFilter);
+        verify(mFilter4).startFilterLookup(mCall, testFilter);
+
+        testFilter.onCallFilteringComplete(mCall, PASS_CALL_RESULT);
+        testFilter.onCallFilteringComplete(mCall, ASYNC_BLOCK_CHECK_BLOCK_RESULT);
+        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
+                )));
+    }
+
+    @SmallTest
+    @Test
+    public void testMultipleFiltersForDirectToVoicemailCallFilter() {
         List<IncomingCallFilter.CallFilter> filters =
                 new ArrayList<IncomingCallFilter.CallFilter>() {{
                     add(mFilter1);
@@ -126,16 +223,49 @@
         verify(mFilter2).startFilterLookup(mCall, testFilter);
         verify(mFilter3).startFilterLookup(mCall, testFilter);
 
-        testFilter.onCallFilteringComplete(mCall, RESULT1);
-        testFilter.onCallFilteringComplete(mCall, RESULT2);
-        testFilter.onCallFilteringComplete(mCall, RESULT3);
+        testFilter.onCallFilteringComplete(mCall, PASS_CALL_RESULT);
+        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
+                        true, // shouldShowNotification
+                        CallLog.Calls.BLOCK_REASON_DIRECT_TO_VOICEMAIL, //callBlockReason
+                        null, ////callScreeningAppName
+                        null ////callScreeningComponentName
+                )));
+    }
+
+    @SmallTest
+    @Test
+    public void testMultipleFiltersForCallScreeningServiceFilter() {
+        List<IncomingCallFilter.CallFilter> filters =
+                new ArrayList<IncomingCallFilter.CallFilter>() {{
+                    add(mFilter1);
+                    add(mFilter2);
+                }};
+        IncomingCallFilter testFilter = new IncomingCallFilter(mContext, mResultCallback, mCall,
+                mLock, mTimeoutsAdapter, filters);
+        testFilter.performFiltering();
+        verify(mFilter1).startFilterLookup(mCall, testFilter);
+        verify(mFilter2).startFilterLookup(mCall, testFilter);
+
+        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
                 )));
     }
 
@@ -148,7 +278,7 @@
         testFilter.performFiltering();
         verify(mResultCallback, timeout((int) SHORT_TIMEOUT * 2)).onCallFilteringComplete(eq(mCall),
                 eq(DEFAULT_RESULT));
-        testFilter.onCallFilteringComplete(mCall, RESULT1);
+        testFilter.onCallFilteringComplete(mCall, PASS_CALL_RESULT);
         waitForHandlerAction(testFilter.getHandler(), SHORT_TIMEOUT * 2);
         // verify that we don't report back again with the result
         verify(mResultCallback, atMost(1)).onCallFilteringComplete(any(Call.class),
@@ -162,7 +292,7 @@
         IncomingCallFilter testFilter = new IncomingCallFilter(mContext, mResultCallback, mCall,
                 mLock, mTimeoutsAdapter, Collections.singletonList(mFilter1));
         testFilter.performFiltering();
-        testFilter.onCallFilteringComplete(mCall, RESULT1);
+        testFilter.onCallFilteringComplete(mCall, PASS_CALL_RESULT);
         waitForHandlerAction(testFilter.getHandler(), SHORT_TIMEOUT * 2);
         Thread.sleep(SHORT_TIMEOUT);
         verify(mResultCallback, atMost(1)).onCallFilteringComplete(any(Call.class),
@@ -172,9 +302,13 @@
     @SmallTest
     @Test
     public void testToString() {
-        assertEquals("[Allow, logged, notified]", RESULT1.toString());
-        assertEquals("[Reject, notified]", RESULT2.toString());
-        assertEquals("[Reject, logged]", RESULT3.toString());
+        assertEquals("[Allow, logged, notified]", PASS_CALL_RESULT.toString());
+        assertEquals("[Reject, notified, mCallBlockReason = 1, mCallScreeningAppName = com" +
+                ".android.thirdparty, mCallScreeningComponentName = com.android.thirdparty/com" +
+                ".android.thirdparty.callscreeningserviceimpl]",
+            CALL_SCREENING_SERVICE_BLOCK_RESULT.toString());
+        assertEquals("[Reject, logged, mCallBlockReason = 3]",
+            ASYNC_BLOCK_CHECK_BLOCK_RESULT.toString());
     }
 
     private void setTimeoutLength(long length) throws Exception {
diff --git a/tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java b/tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java
index 8905361..a459aac 100644
--- a/tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java
+++ b/tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java
@@ -100,7 +100,7 @@
     public static class CallIntentProcessAdapterFake implements CallIntentProcessor.Adapter {
         @Override
         public void processOutgoingCallIntent(Context context, CallsManager callsManager,
-                Intent intent) {
+                Intent intent, String callingPackage) {
 
         }