diff --git a/src/com/android/server/telecom/callfiltering/CallFilteringResult.java b/src/com/android/server/telecom/callfiltering/CallFilteringResult.java
index 4bad7b3..3f64f2c 100644
--- a/src/com/android/server/telecom/callfiltering/CallFilteringResult.java
+++ b/src/com/android/server/telecom/callfiltering/CallFilteringResult.java
@@ -28,6 +28,7 @@
         private boolean mShouldShowNotification;
         private boolean mShouldSilence = false;
         private boolean mShouldScreenViaAudio = false;
+        private boolean mContactExists = false;
         private int mCallBlockReason = Calls.BLOCK_REASON_NOT_BLOCKED;
         private CharSequence mCallScreeningAppName = null;
         private String mCallScreeningComponentName = null;
@@ -77,11 +78,30 @@
             return this;
         }
 
+        public Builder setContactExists(boolean contactExists) {
+            mContactExists = contactExists;
+            return this;
+        }
+
+        public static Builder from(CallFilteringResult result) {
+            return new Builder()
+                    .setShouldAllowCall(result.shouldAllowCall)
+                    .setShouldReject(result.shouldReject)
+                    .setShouldAddToCallLog(result.shouldAddToCallLog)
+                    .setShouldShowNotification(result.shouldShowNotification)
+                    .setShouldSilence(result.shouldSilence)
+                    .setCallBlockReason(result.mCallBlockReason)
+                    .setShouldScreenViaAudio(result.shouldScreenViaAudio)
+                    .setCallScreeningAppName(result.mCallScreeningAppName)
+                    .setCallScreeningComponentName(result.mCallScreeningComponentName)
+                    .setContactExists(result.contactExists);
+        }
+
         public CallFilteringResult build() {
             return new CallFilteringResult(mShouldAllowCall, mShouldReject, mShouldSilence,
                     mShouldAddToCallLog, mShouldShowNotification, mCallBlockReason,
-                    mCallScreeningAppName, mCallScreeningComponentName,
-                    mShouldScreenViaAudio);
+                    mCallScreeningAppName, mCallScreeningComponentName, mShouldScreenViaAudio,
+                    mContactExists);
         }
     }
 
@@ -94,11 +114,12 @@
     public int mCallBlockReason;
     public CharSequence mCallScreeningAppName;
     public String mCallScreeningComponentName;
+    public boolean contactExists;
 
     private CallFilteringResult(boolean shouldAllowCall, boolean shouldReject, boolean
             shouldSilence, boolean shouldAddToCallLog, boolean shouldShowNotification, int
             callBlockReason, CharSequence callScreeningAppName, String callScreeningComponentName,
-            boolean shouldScreenViaAudio) {
+            boolean shouldScreenViaAudio, boolean contactExists) {
         this.shouldAllowCall = shouldAllowCall;
         this.shouldReject = shouldReject;
         this.shouldSilence = shouldSilence;
@@ -108,6 +129,7 @@
         this.mCallBlockReason = callBlockReason;
         this.mCallScreeningAppName = callScreeningAppName;
         this.mCallScreeningComponentName = callScreeningComponentName;
+        this.contactExists = contactExists;
     }
 
     /**
@@ -187,6 +209,7 @@
                 .setCallBlockReason(callBlockReason)
                 .setCallScreeningAppName(callScreeningAppName)
                 .setCallScreeningComponentName(callScreeningComponentName)
+                .setContactExists(contactExists || other.contactExists)
                 .build();
     }
 
@@ -204,6 +227,7 @@
         if (shouldAddToCallLog != that.shouldAddToCallLog) return false;
         if (shouldShowNotification != that.shouldShowNotification) return false;
         if (mCallBlockReason != that.mCallBlockReason) return false;
+        if (contactExists != that.contactExists) return false;
 
         if ((TextUtils.isEmpty(mCallScreeningAppName) &&
             TextUtils.isEmpty(that.mCallScreeningAppName)) &&
@@ -258,6 +282,10 @@
             sb.append(", notified");
         }
 
+        if (contactExists) {
+            sb.append(", contact exists");
+        }
+
         if (mCallBlockReason != 0) {
             sb.append(", mCallBlockReason = ");
             sb.append(mCallBlockReason);
diff --git a/src/com/android/server/telecom/callfiltering/IncomingCallFilterGraph.java b/src/com/android/server/telecom/callfiltering/IncomingCallFilterGraph.java
index fededed..99f4e5d 100644
--- a/src/com/android/server/telecom/callfiltering/IncomingCallFilterGraph.java
+++ b/src/com/android/server/telecom/callfiltering/IncomingCallFilterGraph.java
@@ -33,7 +33,7 @@
 public class IncomingCallFilterGraph {
     //TODO: Add logging for control flow.
     public static final String TAG = "IncomingCallFilterGraph";
-    public static final CallFilteringResult DEFAULT_SCREENING_RESULT =
+    public static final CallFilteringResult DEFAULT_RESULT =
             new CallFilteringResult.Builder()
                     .setShouldAllowCall(true)
                     .setShouldReject(false)
@@ -92,8 +92,8 @@
         mFinished = false;
         mContext = context;
         mTimeoutsAdapter = timeoutsAdapter;
-        mCurrentResult = DEFAULT_SCREENING_RESULT;
         mLock = lock;
+        mCurrentResult = DEFAULT_RESULT;
     }
 
     public void addFilter(CallFilter filter) {
diff --git a/src/com/android/server/telecom/callfiltering/NewCallScreeningServiceFilter.java b/src/com/android/server/telecom/callfiltering/NewCallScreeningServiceFilter.java
new file mode 100644
index 0000000..aa81a49
--- /dev/null
+++ b/src/com/android/server/telecom/callfiltering/NewCallScreeningServiceFilter.java
@@ -0,0 +1,271 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.telecom.callfiltering;
+
+import static com.android.server.telecom.callfiltering.IncomingCallFilterGraph.DEFAULT_RESULT;
+
+import android.Manifest;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.ServiceConnection;
+import android.content.pm.PackageManager;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.provider.CallLog;
+import android.telecom.Log;
+import android.telecom.TelecomManager;
+
+import com.android.internal.telecom.ICallScreeningAdapter;
+import com.android.internal.telecom.ICallScreeningService;
+import com.android.server.telecom.Call;
+import com.android.server.telecom.CallScreeningServiceHelper;
+import com.android.server.telecom.CallsManager;
+import com.android.server.telecom.ParcelableCallUtils;
+
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionStage;
+
+public class NewCallScreeningServiceFilter extends CallFilter {
+    //TODO: Change the name of this class with CallScreeningServiceFilter
+    public static final int PACKAGE_TYPE_CARRIER = 0;
+    public static final int PACKAGE_TYPE_DEFAULT_DIALER = 1;
+    public static final int PACKAGE_TYPE_USER_CHOSEN = 2;
+    public static final long CALL_SCREENING_FILTER_TIMEOUT = 5000;
+
+    private final Call mCall;
+    private final String mPackageName;
+    private final int mPackagetype;
+    private PackageManager mPackageManager;
+    private Context mContext;
+    private CallScreeningServiceConnection mConnection;
+    private final CallsManager mCallsManager;
+    private CharSequence mAppName;
+    private final ParcelableCallUtils.Converter mParcelableCallUtilsConverter;
+
+    private class CallScreeningAdapter extends ICallScreeningAdapter.Stub {
+        private CompletableFuture<CallFilteringResult> mResultFuture;
+
+        public CallScreeningAdapter(CompletableFuture<CallFilteringResult> resultFuture) {
+            mResultFuture = resultFuture;
+        }
+
+        @Override
+        public void allowCall(String callId) {
+            Long token = Binder.clearCallingIdentity();
+            if (mCall == null || (!mCall.getId().equals(callId))) {
+                Log.w(this, "allowCall, unknown call id: %s", callId);
+            }
+            mResultFuture.complete(DEFAULT_RESULT);
+            Binder.restoreCallingIdentity(token);
+            unbindCallScreeningService();
+        }
+
+        @Override
+        public void disallowCall(String callId, boolean shouldReject,
+                boolean shouldAddToCallLog, boolean shouldShowNotification,
+                ComponentName componentName) {
+            long token = Binder.clearCallingIdentity();
+            if (mCall != null && mCall.getId().equals(callId)) {
+                mResultFuture.complete(new CallFilteringResult.Builder()
+                        .setShouldAllowCall(false)
+                        .setShouldReject(shouldReject)
+                        .setShouldSilence(false)
+                        .setShouldAddToCallLog(shouldAddToCallLog
+                                || packageTypeShouldAdd(mPackagetype))
+                        .setShouldShowNotification(shouldShowNotification)
+                        .setCallBlockReason(CallLog.Calls.BLOCK_REASON_CALL_SCREENING_SERVICE)
+                        .setCallScreeningAppName(mAppName)
+                        .setCallScreeningComponentName(componentName.flattenToString())
+                        .build());
+            } else {
+                Log.w(this, "disallowCall, unknown call id: %s", callId);
+                mResultFuture.complete(DEFAULT_RESULT);
+            }
+            Binder.restoreCallingIdentity(token);
+            unbindCallScreeningService();
+        }
+
+        @Override
+        public void silenceCall(String callId) {
+            long token = Binder.clearCallingIdentity();
+            if (mCall != null && mCall.getId().equals(callId)) {
+                mResultFuture.complete(new CallFilteringResult.Builder()
+                        .setShouldAllowCall(true)
+                        .setShouldReject(false)
+                        .setShouldSilence(true)
+                        .setShouldAddToCallLog(true)
+                        .setShouldShowNotification(true)
+                        .build());
+            } else {
+                Log.w(this, "silenceCall, unknown call id: %s" , callId);
+                mResultFuture.complete(DEFAULT_RESULT);
+            }
+            Binder.restoreCallingIdentity(token);
+            unbindCallScreeningService();
+        }
+
+        @Override
+        public void screenCallFurther(String callId) {
+            long token = Binder.clearCallingIdentity();
+            if (mPackagetype != PACKAGE_TYPE_DEFAULT_DIALER) {
+                throw new SecurityException("Only the default/system dialer may request screen via"
+                    + "background call audio");
+            }
+            // TODO: add permission check for the additional role-based permission
+
+            if (mCall != null && mCall.getId().equals(callId)) {
+                mResultFuture.complete(new CallFilteringResult.Builder()
+                        .setShouldAllowCall(true)
+                        .setShouldReject(false)
+                        .setShouldSilence(false)
+                        .setShouldScreenViaAudio(true)
+                        .build());
+            } else {
+                Log.w(this, "screenCallFurther, unknown call id: %s", callId);
+                mResultFuture.complete(DEFAULT_RESULT);
+            }
+            Binder.restoreCallingIdentity(token);
+            unbindCallScreeningService();
+        }
+    }
+
+    private class CallScreeningServiceConnection implements ServiceConnection {
+        private CompletableFuture<CallFilteringResult> mResultFuture;
+
+        public CallScreeningServiceConnection(CompletableFuture<CallFilteringResult> resultFuture) {
+            mResultFuture = resultFuture;
+        }
+
+        @Override
+        public void onServiceConnected(ComponentName componentName, IBinder service) {
+            ICallScreeningService callScreeningService =
+                    ICallScreeningService.Stub.asInterface(service);
+
+            try {
+                callScreeningService.screenCall(new CallScreeningAdapter(mResultFuture),
+                        mParcelableCallUtilsConverter.
+                                toParcelableCallForScreening(mCall, isSystemDialer()));
+            } catch (RemoteException e) {
+                Log.e(this, e, "Failed to set the call screening adapter");
+                mResultFuture.complete(DEFAULT_RESULT);
+            }
+            Log.i(this, "Binding completed.");
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName componentName) {
+            mResultFuture.complete(DEFAULT_RESULT);
+            Log.i(this, "Service disconnected.");
+        }
+
+        @Override
+        public void onBindingDied(ComponentName name) {
+            mResultFuture.complete(DEFAULT_RESULT);
+            Log.i(this, "Binding died.");
+        }
+
+        @Override
+        public void onNullBinding(ComponentName name) {
+            mResultFuture.complete(DEFAULT_RESULT);
+            Log.i(this, "Null binding.");
+        }
+    }
+
+    public NewCallScreeningServiceFilter(
+            Call call,
+            String packageName,
+            int packageType,
+            Context context,
+            CallsManager callsManager,
+            CallScreeningServiceHelper.AppLabelProxy appLabelProxy,
+            ParcelableCallUtils.Converter parcelableCallUtilsConverter) {
+        super();
+        mCall = call;
+        mPackageName = packageName;
+        mPackagetype = packageType;
+        mContext = context;
+        mPackageManager = mContext.getPackageManager();
+        mCallsManager = callsManager;
+        mAppName = appLabelProxy.getAppLabel(mPackageName);
+        mParcelableCallUtilsConverter = parcelableCallUtilsConverter;
+    }
+
+    @Override
+    public CompletionStage<CallFilteringResult> startFilterLookup(CallFilteringResult priorStageResult) {
+        if (mPackageName == null) {
+            return CompletableFuture.completedFuture(DEFAULT_RESULT);
+        }
+
+        if (!priorStageResult.shouldAllowCall) {
+            // Call already blocked by other filters, no need to bind to call screening service.
+            return CompletableFuture.completedFuture(DEFAULT_RESULT);
+        }
+
+        if (priorStageResult.contactExists && (!hasReadContactsPermission())) {
+            // Binding to the call screening service will be skipped if it does NOT hold
+            // READ_CONTACTS permission and the number is in the user’s contacts
+            return CompletableFuture.completedFuture(DEFAULT_RESULT);
+        }
+
+        CompletableFuture<CallFilteringResult> resultFuture = new CompletableFuture<>();
+
+        bindCallScreeningService(resultFuture);
+        return resultFuture;
+    }
+
+    private boolean hasReadContactsPermission() {
+        int permission = PackageManager.PERMISSION_DENIED;
+        if (mPackagetype == PACKAGE_TYPE_CARRIER || mPackagetype == PACKAGE_TYPE_DEFAULT_DIALER) {
+            permission = PackageManager.PERMISSION_GRANTED;
+        } else if (mPackageManager != null) {
+            permission = mPackageManager.checkPermission(Manifest.permission.READ_CONTACTS,
+                    mPackageName);
+        }
+        return permission == PackageManager.PERMISSION_GRANTED;
+    }
+
+    private void bindCallScreeningService(
+            CompletableFuture<CallFilteringResult> resultFuture) {
+        mConnection = new CallScreeningServiceConnection(resultFuture);
+        if (!CallScreeningServiceHelper.bindCallScreeningService(mContext,
+                mCallsManager.getCurrentUserHandle(), mPackageName, mConnection)) {
+            Log.i(this, "Call screening service binding failed.");
+            resultFuture.complete(DEFAULT_RESULT);
+        }
+    }
+
+    private void unbindCallScreeningService() {
+        if (mConnection != null) {
+            mContext.unbindService(mConnection);
+        }
+        mConnection = null;
+    }
+
+    private boolean isSystemDialer() {
+        if (mPackagetype != PACKAGE_TYPE_DEFAULT_DIALER) {
+            return false;
+        } else {
+            return mPackageName.equals(TelecomManager.from(mContext).getSystemDialerPackage());
+        }
+    }
+
+    private boolean packageTypeShouldAdd(int packageType) {
+        return packageType == PACKAGE_TYPE_CARRIER;
+    }
+
+}
diff --git a/tests/src/com/android/server/telecom/tests/NewCallScreeningServiceFilterTest.java b/tests/src/com/android/server/telecom/tests/NewCallScreeningServiceFilterTest.java
new file mode 100644
index 0000000..3c6552d
--- /dev/null
+++ b/tests/src/com/android/server/telecom/tests/NewCallScreeningServiceFilterTest.java
@@ -0,0 +1,320 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.telecom.tests;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.nullable;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.Manifest;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+import android.os.IBinder;
+import android.os.UserHandle;
+import android.provider.CallLog;
+import android.telecom.CallScreeningService;
+import android.telecom.ParcelableCall;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import com.android.internal.telecom.ICallScreeningAdapter;
+import com.android.internal.telecom.ICallScreeningService;
+import com.android.server.telecom.Call;
+import com.android.server.telecom.CallScreeningServiceHelper;
+import com.android.server.telecom.CallsManager;
+import com.android.server.telecom.ParcelableCallUtils;
+import com.android.server.telecom.PhoneAccountRegistrar;
+import com.android.server.telecom.callfiltering.CallFilteringResult;
+import com.android.server.telecom.callfiltering.NewCallScreeningServiceFilter;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+
+import java.util.Collections;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionStage;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+@RunWith(JUnit4.class)
+public class NewCallScreeningServiceFilterTest extends TelecomTestCase {
+    //TODO: Change the name of this class to CallScreeningServiceFilterTest
+    static @Mock Call mCall;
+    @Mock Context mContext;
+    @Mock PackageManager mPackageManager;
+    @Mock CallsManager mCallsManager;
+    @Mock CallScreeningServiceHelper.AppLabelProxy mAppLabelProxy;
+    @Mock ParcelableCallUtils.Converter mParcelableCallUtilsConverter;
+    @Mock PhoneAccountRegistrar mPhoneAccountRegistrar;
+    @Mock ICallScreeningService mCallScreeningService;
+    @Mock IBinder mBinder;
+
+    private static final String CALL_ID = "u89prgt9ps78y5";
+    private static final String PKG_NAME = "com.android.services.telecom.tests";
+    private static final String APP_NAME = "TeleTestApp";
+    private static final String CLS_NAME = "CallScreeningService";
+    private static final ComponentName COMPONENT_NAME = new ComponentName(PKG_NAME, CLS_NAME);
+    private ResolveInfo mResolveInfo;
+    private CallFilteringResult inputResult;
+
+    private static final CallFilteringResult PASS_RESULT = new CallFilteringResult.Builder()
+            .setShouldAllowCall(true)
+            .setShouldReject(false)
+            .setShouldAddToCallLog(true)
+            .setShouldShowNotification(true)
+            .build();
+
+    @Override
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+
+        mResolveInfo =  new ResolveInfo() {{
+            serviceInfo = new ServiceInfo();
+            serviceInfo.packageName = PKG_NAME;
+            serviceInfo.name = CLS_NAME;
+            serviceInfo.permission = Manifest.permission.BIND_SCREENING_SERVICE;
+        }};
+        inputResult = new CallFilteringResult.Builder()
+                .setShouldAllowCall(true)
+                .setShouldReject(false)
+                .setShouldAddToCallLog(true)
+                .setShouldShowNotification(true)
+                .build();
+
+        when(mCallsManager.getCurrentUserHandle()).thenReturn(UserHandle.CURRENT);
+        when(mCall.getId()).thenReturn(CALL_ID);
+        when(mContext.getPackageManager()).thenReturn(mPackageManager);
+        when(mAppLabelProxy.getAppLabel(PKG_NAME)).thenReturn(APP_NAME);
+        when(mParcelableCallUtilsConverter.toParcelableCall(
+                eq(mCall), anyBoolean(), eq(mPhoneAccountRegistrar))).thenReturn(null);
+        when(mContext.bindServiceAsUser(nullable(Intent.class), nullable(ServiceConnection.class),
+                anyInt(), eq(UserHandle.CURRENT))).thenReturn(true);
+        when(mPackageManager.queryIntentServicesAsUser(nullable(Intent.class), anyInt(), anyInt()))
+                .thenReturn(Collections.singletonList(mResolveInfo));
+        doReturn(mCallScreeningService).when(mBinder).queryLocalInterface(anyString());
+    }
+
+    @SmallTest
+    @Test
+    public void testNoPackageName() throws Exception {
+        NewCallScreeningServiceFilter filter = new NewCallScreeningServiceFilter(mCall, null,
+                NewCallScreeningServiceFilter.PACKAGE_TYPE_CARRIER, mContext, mCallsManager,
+                mAppLabelProxy, mParcelableCallUtilsConverter);
+        assertEquals(PASS_RESULT,
+                filter.startFilterLookup(inputResult).toCompletableFuture().get(
+                        NewCallScreeningServiceFilter.CALL_SCREENING_FILTER_TIMEOUT,
+                        TimeUnit.MILLISECONDS));
+    }
+
+    @SmallTest
+    @Test
+    public void testContextFailToBind() throws Exception {
+        when(mContext.bindServiceAsUser(nullable(Intent.class), nullable(ServiceConnection.class),
+                anyInt(), eq(UserHandle.CURRENT))).thenReturn(false);
+        NewCallScreeningServiceFilter filter = new NewCallScreeningServiceFilter(mCall, PKG_NAME,
+                NewCallScreeningServiceFilter.PACKAGE_TYPE_CARRIER, mContext, mCallsManager,
+                mAppLabelProxy, mParcelableCallUtilsConverter);
+        assertEquals(PASS_RESULT,
+                filter.startFilterLookup(inputResult).toCompletableFuture().get(
+                        NewCallScreeningServiceFilter.CALL_SCREENING_FILTER_TIMEOUT,
+                        TimeUnit.MILLISECONDS));
+    }
+
+    @SmallTest
+    @Test
+    public void testNoResolveEntries() throws Exception {
+        when(mPackageManager.queryIntentServicesAsUser(nullable(Intent.class), anyInt(), anyInt()))
+                .thenReturn(Collections.emptyList());
+        NewCallScreeningServiceFilter filter = new NewCallScreeningServiceFilter(mCall, PKG_NAME,
+                NewCallScreeningServiceFilter.PACKAGE_TYPE_CARRIER, mContext, mCallsManager,
+                mAppLabelProxy, mParcelableCallUtilsConverter);
+        assertEquals(PASS_RESULT,
+                filter.startFilterLookup(inputResult).toCompletableFuture().get(
+                        NewCallScreeningServiceFilter.CALL_SCREENING_FILTER_TIMEOUT,
+                        TimeUnit.MILLISECONDS));
+    }
+
+    @SmallTest
+    @Test
+    public void testBadResolveEntry() throws Exception {
+        mResolveInfo.serviceInfo = null;
+        NewCallScreeningServiceFilter filter = new NewCallScreeningServiceFilter(mCall, PKG_NAME,
+                NewCallScreeningServiceFilter.PACKAGE_TYPE_CARRIER, mContext, mCallsManager,
+                mAppLabelProxy, mParcelableCallUtilsConverter);
+        assertEquals(PASS_RESULT,
+                filter.startFilterLookup(inputResult).toCompletableFuture().get(
+                        NewCallScreeningServiceFilter.CALL_SCREENING_FILTER_TIMEOUT,
+                        TimeUnit.MILLISECONDS));
+    }
+
+    @SmallTest
+    @Test
+    public void testNoBindingCondition() {
+        // Make sure there will be no binding if the package has no READ_CONTACT permission and
+        // contact exist.
+        when(mPackageManager.checkPermission(Manifest.permission.READ_CONTACTS, PKG_NAME))
+                .thenReturn(PackageManager.PERMISSION_DENIED);
+        when(mContext.bindServiceAsUser(nullable(Intent.class), nullable(ServiceConnection.class),
+                anyInt(), eq(UserHandle.CURRENT))).thenThrow(new SecurityException());
+        inputResult.contactExists = true;
+        NewCallScreeningServiceFilter filter = new NewCallScreeningServiceFilter(mCall, PKG_NAME,
+                NewCallScreeningServiceFilter.PACKAGE_TYPE_USER_CHOSEN, mContext, mCallsManager,
+                mAppLabelProxy, mParcelableCallUtilsConverter);
+        filter.startFilterLookup(inputResult);
+    }
+
+    @SmallTest
+    @Test
+    public void testBindingCondition() {
+        // Make sure there will be binding if the package has READ_CONTACT permission and contact
+        // exist.
+        inputResult.contactExists = true;
+        NewCallScreeningServiceFilter filter = new NewCallScreeningServiceFilter(mCall, PKG_NAME,
+                NewCallScreeningServiceFilter.PACKAGE_TYPE_CARRIER, mContext, mCallsManager,
+                mAppLabelProxy, mParcelableCallUtilsConverter);
+        filter.startFilterLookup(inputResult);
+        ServiceConnection connection = verifyBindingIntent();
+        connection.onServiceDisconnected(COMPONENT_NAME);
+    }
+
+    @SmallTest
+    @Test
+    public void testAllowCall() throws Exception {
+        NewCallScreeningServiceFilter filter = new NewCallScreeningServiceFilter(mCall, PKG_NAME,
+                NewCallScreeningServiceFilter.PACKAGE_TYPE_CARRIER, mContext, mCallsManager,
+                mAppLabelProxy, mParcelableCallUtilsConverter);
+        CompletionStage<CallFilteringResult> resultFuture = filter.startFilterLookup(inputResult);
+
+        ServiceConnection serviceConnection = verifyBindingIntent();
+
+        serviceConnection.onServiceConnected(COMPONENT_NAME, mBinder);
+        ICallScreeningAdapter csAdapter = getCallScreeningAdapter();
+        csAdapter.allowCall(CALL_ID);
+        assertEquals(PASS_RESULT,
+                resultFuture.toCompletableFuture().get(
+                        NewCallScreeningServiceFilter.CALL_SCREENING_FILTER_TIMEOUT,
+                        TimeUnit.MILLISECONDS));
+        serviceConnection.onServiceDisconnected(COMPONENT_NAME);
+    }
+
+    @SmallTest
+    @Test
+    public void testDisallowCall() throws Exception {
+        CallFilteringResult expectedResult = new CallFilteringResult.Builder()
+                .setShouldAllowCall(false)
+                .setShouldReject(true)
+                .setShouldSilence(false)
+                .setShouldAddToCallLog(true)
+                .setShouldShowNotification(true)
+                .setCallBlockReason(CallLog.Calls.BLOCK_REASON_CALL_SCREENING_SERVICE)
+                .setCallScreeningAppName(APP_NAME)
+                .setCallScreeningComponentName(COMPONENT_NAME.flattenToString())
+                .build();
+        NewCallScreeningServiceFilter filter = new NewCallScreeningServiceFilter(mCall, PKG_NAME,
+                NewCallScreeningServiceFilter.PACKAGE_TYPE_CARRIER, mContext, mCallsManager,
+                mAppLabelProxy, mParcelableCallUtilsConverter);
+        CompletionStage<CallFilteringResult> resultFuture = filter.startFilterLookup(inputResult);
+
+        ServiceConnection serviceConnection = verifyBindingIntent();
+
+        serviceConnection.onServiceConnected(COMPONENT_NAME, mBinder);
+        ICallScreeningAdapter csAdapter = getCallScreeningAdapter();
+        csAdapter.disallowCall(CALL_ID,
+                true, // shouldReject
+                true, //shouldAddToCallLog
+                true, // shouldShowNotification
+                COMPONENT_NAME);
+        assertEquals(expectedResult,
+                resultFuture.toCompletableFuture().get(
+                        NewCallScreeningServiceFilter.CALL_SCREENING_FILTER_TIMEOUT,
+                        TimeUnit.MILLISECONDS));
+        serviceConnection.onServiceDisconnected(COMPONENT_NAME);
+    }
+
+    @SmallTest
+    @Test
+    public void testSilenceCall() throws Exception {
+        CallFilteringResult expectedResult = new CallFilteringResult.Builder()
+                .setShouldAllowCall(true)
+                .setShouldReject(false)
+                .setShouldSilence(true)
+                .setShouldAddToCallLog(true)
+                .setShouldShowNotification(true)
+                .build();
+        NewCallScreeningServiceFilter filter = new NewCallScreeningServiceFilter(mCall, PKG_NAME,
+                NewCallScreeningServiceFilter.PACKAGE_TYPE_CARRIER, mContext, mCallsManager,
+                mAppLabelProxy, mParcelableCallUtilsConverter);
+        CompletionStage<CallFilteringResult> resultFuture = filter.startFilterLookup(inputResult);
+
+        ServiceConnection serviceConnection = verifyBindingIntent();
+
+        serviceConnection.onServiceConnected(COMPONENT_NAME, mBinder);
+        ICallScreeningAdapter csAdapter = getCallScreeningAdapter();
+        csAdapter.silenceCall(CALL_ID);
+        assertEquals(expectedResult,
+                resultFuture.toCompletableFuture().get(
+                        NewCallScreeningServiceFilter.CALL_SCREENING_FILTER_TIMEOUT,
+                        TimeUnit.MILLISECONDS));
+
+        serviceConnection.onServiceDisconnected(COMPONENT_NAME);
+    }
+
+    private ServiceConnection verifyBindingIntent() {
+        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+        ArgumentCaptor<ServiceConnection> serviceCaptor = ArgumentCaptor
+                .forClass(ServiceConnection.class);
+        verify(mContext, timeout(NewCallScreeningServiceFilter.CALL_SCREENING_FILTER_TIMEOUT))
+                .bindServiceAsUser(intentCaptor.capture(), serviceCaptor.capture(),
+                eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
+                eq(UserHandle.CURRENT));
+
+        Intent capturedIntent = intentCaptor.getValue();
+        assertEquals(CallScreeningService.SERVICE_INTERFACE, capturedIntent.getAction());
+        assertEquals(mResolveInfo.serviceInfo.packageName, capturedIntent.getPackage());
+        assertEquals(new ComponentName(mResolveInfo.serviceInfo.packageName,
+                mResolveInfo.serviceInfo.name), capturedIntent.getComponent());
+
+        return serviceCaptor.getValue();
+    }
+
+    private ICallScreeningAdapter getCallScreeningAdapter() throws Exception {
+        ArgumentCaptor<ICallScreeningAdapter> captor =
+                ArgumentCaptor.forClass(ICallScreeningAdapter.class);
+        verify(mCallScreeningService,
+                timeout(NewCallScreeningServiceFilter.CALL_SCREENING_FILTER_TIMEOUT))
+                .screenCall(captor.capture(), nullable(ParcelableCall.class));
+        return captor.getValue();
+    }
+}
