diff --git a/InCallUI/tests/src/com/android/incallui/ExternalCallListTest.java b/InCallUI/tests/src/com/android/incallui/ExternalCallListTest.java
new file mode 100644
index 0000000..070bdf5
--- /dev/null
+++ b/InCallUI/tests/src/com/android/incallui/ExternalCallListTest.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.incallui;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.net.Uri;
+import android.os.Bundle;
+import android.telecom.*;
+import android.telecom.Call;
+import android.test.AndroidTestCase;
+
+import java.lang.reflect.Constructor;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+public class ExternalCallListTest extends AndroidTestCase {
+
+    private static class Listener implements ExternalCallList.ExternalCallListener {
+        private CountDownLatch mCallAddedLatch = new CountDownLatch(1);
+        private CountDownLatch mCallRemovedLatch = new CountDownLatch(1);
+        private CountDownLatch mCallUpdatedLatch = new CountDownLatch(1);
+
+        @Override
+        public void onExternalCallAdded(Call call) {
+            mCallAddedLatch.countDown();
+        }
+
+        @Override
+        public void onExternalCallRemoved(Call call) {
+            mCallRemovedLatch.countDown();
+        }
+
+        @Override
+        public void onExternalCallUpdated(Call call) {
+            mCallUpdatedLatch.countDown();
+        }
+
+        public boolean awaitCallAdded() {
+            try {
+                return mCallAddedLatch.await(WAIT_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
+            } catch (InterruptedException e) {
+                return false;
+            }
+        }
+
+        public boolean awaitCallRemoved() {
+            try {
+                return mCallRemovedLatch.await(WAIT_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
+            } catch (InterruptedException e) {
+                return false;
+            }
+        }
+
+        public boolean awaitCallUpdated() {
+            try {
+                return mCallUpdatedLatch.await(WAIT_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
+            } catch (InterruptedException e) {
+                return false;
+            }
+        }
+    }
+
+    private static final int WAIT_TIMEOUT_MILLIS = 5000;
+
+    private ExternalCallList mExternalCallList = new ExternalCallList();
+    private Listener mExternalCallListener = new Listener();
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        mExternalCallList.addExternalCallListener(mExternalCallListener);
+    }
+
+    public void testAddCallSuccess() {
+        TestTelecomCall call = getTestCall(Call.Details.PROPERTY_IS_EXTERNAL_CALL);
+        mExternalCallList.onCallAdded(call.getCall());
+        assertTrue(mExternalCallListener.awaitCallAdded());
+    }
+
+    public void testAddCallFail() {
+        TestTelecomCall call = getTestCall(0 /* no properties */);
+        try {
+            mExternalCallList.onCallAdded(call.getCall());
+            fail();
+        } catch (IllegalArgumentException e) {
+        }
+    }
+
+    public void testUpdateCall() {
+        TestTelecomCall call = getTestCall(Call.Details.PROPERTY_IS_EXTERNAL_CALL);
+        mExternalCallList.onCallAdded(call.getCall());
+        assertTrue(mExternalCallListener.awaitCallAdded());
+
+        call.forceDetailsUpdate();
+        assertTrue(mExternalCallListener.awaitCallUpdated());
+    }
+
+    public void testRemoveCall() {
+        TestTelecomCall call = getTestCall(Call.Details.PROPERTY_IS_EXTERNAL_CALL);
+        mExternalCallList.onCallAdded(call.getCall());
+        assertTrue(mExternalCallListener.awaitCallAdded());
+
+        mExternalCallList.onCallRemoved(call.getCall());
+        assertTrue(mExternalCallListener.awaitCallRemoved());
+    }
+
+    private TestTelecomCall getTestCall(int properties) {
+        TestTelecomCall testCall = TestTelecomCall.createInstance(
+                "1",
+                Uri.parse("tel:650-555-1212"), /* handle */
+                TelecomManager.PRESENTATION_ALLOWED, /* handlePresentation */
+                "Joe", /* callerDisplayName */
+                TelecomManager.PRESENTATION_ALLOWED, /* callerDisplayNamePresentation */
+                new PhoneAccountHandle(new ComponentName("test", "class"),
+                        "handle"), /* accountHandle */
+                Call.Details.CAPABILITY_CAN_PULL_CALL, /* capabilities */
+                properties, /* properties */
+                null, /* disconnectCause */
+                0, /* connectTimeMillis */
+                null, /* GatewayInfo */
+                VideoProfile.STATE_AUDIO_ONLY, /* videoState */
+                null, /* statusHints */
+                null, /* extras */
+                null /* intentExtras */);
+        return testCall;
+    }
+}
diff --git a/InCallUI/tests/src/com/android/incallui/ExternalCallNotifierTest.java b/InCallUI/tests/src/com/android/incallui/ExternalCallNotifierTest.java
new file mode 100644
index 0000000..e57efef
--- /dev/null
+++ b/InCallUI/tests/src/com/android/incallui/ExternalCallNotifierTest.java
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.incallui;
+
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyBoolean;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import com.android.contacts.common.preference.ContactsPreferences;
+
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.Spy;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.res.Resources;
+import android.net.Uri;
+import android.telecom.*;
+import android.telecom.Call;
+import android.telephony.TelephonyManager;
+import android.test.AndroidTestCase;
+import android.test.mock.MockContext;
+
+/**
+ * Unit tests for {@link ExternalCallNotifier}.
+ */
+public class ExternalCallNotifierTest extends AndroidTestCase {
+    private static final int TIMEOUT_MILLIS = 5000;
+    private static final String NAME_PRIMARY = "Full Name";
+    private static final String NAME_ALTERNATIVE = "Name, Full";
+    private static final String LOCATION = "US";
+    private static final String NUMBER = "6505551212";
+
+    @Mock private ContactsPreferences mContactsPreferences;
+    @Mock private NotificationManager mNotificationManager;
+    @Mock private MockContext mMockContext;
+    @Mock private Resources mResources;
+    @Mock private StatusBarNotifier mStatusBarNotifier;
+    @Mock private ContactInfoCache mContactInfoCache;
+    @Mock private TelecomManager mTelecomManager;
+    @Mock private TelephonyManager mTelephonyManager;
+    @Mock private ProximitySensor mProximitySensor;
+    @Mock private CallList mCallList;
+    private InCallPresenter mInCallPresenter;
+    private ExternalCallNotifier mExternalCallNotifier;
+    private ContactInfoCache.ContactCacheEntry mContactInfo;
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        MockitoAnnotations.initMocks(this);
+
+        when(mContactsPreferences.getDisplayOrder())
+                .thenReturn(ContactsPreferences.DISPLAY_ORDER_PRIMARY);
+
+        // Setup the mock context to return mocks for some of the needed services; the notification
+        // service is especially important as we want to be able to intercept calls into it and
+        // validate the notifcations.
+        when(mMockContext.getSystemService(eq(Context.NOTIFICATION_SERVICE)))
+                .thenReturn(mNotificationManager);
+        when(mMockContext.getSystemService(eq(Context.TELECOM_SERVICE)))
+                .thenReturn(mTelecomManager);
+        when(mMockContext.getSystemService(eq(Context.TELEPHONY_SERVICE)))
+                .thenReturn(mTelephonyManager);
+
+        // These aspects of the context are used by the notification builder to build the actual
+        // notification; we will rely on the actual implementations of these.
+        when(mMockContext.getPackageManager()).thenReturn(mContext.getPackageManager());
+        when(mMockContext.getResources()).thenReturn(mContext.getResources());
+        when(mMockContext.getApplicationInfo()).thenReturn(mContext.getApplicationInfo());
+        when(mMockContext.getContentResolver()).thenReturn(mContext.getContentResolver());
+        when(mMockContext.getPackageName()).thenReturn(mContext.getPackageName());
+
+        ContactsPreferencesFactory.setTestInstance(null);
+        mExternalCallNotifier = new ExternalCallNotifier(mMockContext, mContactInfoCache);
+
+        // We don't directly use the InCallPresenter in the test, or even in ExternalCallNotifier
+        // itself.  However, ExternalCallNotifier needs to make instances of
+        // com.android.incallui.Call for the purpose of performing contact cache lookups.  The
+        // Call class depends on the static InCallPresenter for a number of things, so we need to
+        // set it up here to prevent crashes.
+        mInCallPresenter = InCallPresenter.getInstance();
+        mInCallPresenter.setUp(mMockContext, mCallList, new ExternalCallList(),
+                null, mStatusBarNotifier, mExternalCallNotifier, mContactInfoCache,
+                mProximitySensor);
+
+        // Unlocked all contact info is available
+        mContactInfo = new ContactInfoCache.ContactCacheEntry();
+        mContactInfo.namePrimary = NAME_PRIMARY;
+        mContactInfo.nameAlternative = NAME_ALTERNATIVE;
+        mContactInfo.location = LOCATION;
+        mContactInfo.number = NUMBER;
+
+        // Given the mock ContactInfoCache cache, we need to mock out what happens when the
+        // ExternalCallNotifier calls into the contact info cache to do a lookup.  We will always
+        // return mock info stored in mContactInfo.
+        doAnswer(new Answer() {
+            @Override
+            public Object answer(InvocationOnMock invocation) throws Throwable {
+                Object[] args = invocation.getArguments();
+                com.android.incallui.Call call = (com.android.incallui.Call) args[0];
+                ContactInfoCache.ContactInfoCacheCallback callback
+                        = (ContactInfoCache.ContactInfoCacheCallback) args[2];
+                callback.onContactInfoComplete(call.getId(), mContactInfo);
+                return null;
+            }
+        }).when(mContactInfoCache).findInfo(any(com.android.incallui.Call.class), anyBoolean(),
+                any(ContactInfoCache.ContactInfoCacheCallback.class));
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        super.tearDown();
+        ContactsPreferencesFactory.setTestInstance(null);
+        mInCallPresenter.tearDown();
+    }
+
+    public void testPostNonPullable() {
+        TestTelecomCall call = getTestCall(false);
+        mExternalCallNotifier.onExternalCallAdded(call.getCall());
+        Notification notification = verifyNotificationPosted();
+        assertNull(notification.actions);
+    }
+
+    public void testPostPullable() {
+        TestTelecomCall call = getTestCall(true);
+        mExternalCallNotifier.onExternalCallAdded(call.getCall());
+        Notification notification = verifyNotificationPosted();
+        assertEquals(1, notification.actions.length);
+    }
+
+    public void testNotificationDismissed() {
+        TestTelecomCall call = getTestCall(false);
+        mExternalCallNotifier.onExternalCallAdded(call.getCall());
+        verifyNotificationPosted();
+
+        mExternalCallNotifier.onExternalCallRemoved(call.getCall());
+        verify(mNotificationManager, timeout(TIMEOUT_MILLIS)).cancel(eq("EXTERNAL_CALL"), eq(0));
+    }
+
+    public void testNotificationUpdated() {
+        TestTelecomCall call = getTestCall(false);
+        mExternalCallNotifier.onExternalCallAdded(call.getCall());
+        verifyNotificationPosted();
+
+        call.setCapabilities(android.telecom.Call.Details.CAPABILITY_CAN_PULL_CALL);
+        mExternalCallNotifier.onExternalCallUpdated(call.getCall());
+
+        ArgumentCaptor<Notification> notificationCaptor =
+                ArgumentCaptor.forClass(Notification.class);
+        verify(mNotificationManager, timeout(TIMEOUT_MILLIS).times(2))
+                .notify(eq("EXTERNAL_CALL"), eq(0), notificationCaptor.capture());
+        Notification notification1 = notificationCaptor.getAllValues().get(0);
+        assertNull(notification1.actions);
+        Notification notification2 = notificationCaptor.getAllValues().get(1);
+        assertEquals(1, notification2.actions.length);
+    }
+
+    private Notification verifyNotificationPosted() {
+        ArgumentCaptor<Notification> notificationCaptor =
+                ArgumentCaptor.forClass(Notification.class);
+        verify(mNotificationManager, timeout(TIMEOUT_MILLIS))
+                .notify(eq("EXTERNAL_CALL"), eq(0), notificationCaptor.capture());
+        return notificationCaptor.getValue();
+    }
+
+    private TestTelecomCall getTestCall(boolean canPull) {
+        TestTelecomCall testCall = TestTelecomCall.createInstance(
+                "1",
+                Uri.parse("tel:650-555-1212"), /* handle */
+                TelecomManager.PRESENTATION_ALLOWED, /* handlePresentation */
+                "Joe", /* callerDisplayName */
+                TelecomManager.PRESENTATION_ALLOWED, /* callerDisplayNamePresentation */
+                new PhoneAccountHandle(new ComponentName("test", "class"),
+                        "handle"), /* accountHandle */
+                canPull ? android.telecom.Call.Details.CAPABILITY_CAN_PULL_CALL : 0, /* capabilities */
+                Call.Details.PROPERTY_IS_EXTERNAL_CALL, /* properties */
+                null, /* disconnectCause */
+                0, /* connectTimeMillis */
+                null, /* GatewayInfo */
+                VideoProfile.STATE_AUDIO_ONLY, /* videoState */
+                null, /* statusHints */
+                null, /* extras */
+                null /* intentExtras */);
+        return testCall;
+    }
+}
diff --git a/InCallUI/tests/src/com/android/incallui/TestTelecomCall.java b/InCallUI/tests/src/com/android/incallui/TestTelecomCall.java
new file mode 100644
index 0000000..48ac6e1
--- /dev/null
+++ b/InCallUI/tests/src/com/android/incallui/TestTelecomCall.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.incallui;
+
+import com.google.common.base.Preconditions;
+
+import android.content.Context;
+import android.net.Uri;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.telecom.DisconnectCause;
+import android.telecom.GatewayInfo;
+import android.telecom.PhoneAccountHandle;
+import android.telecom.StatusHints;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * Wrapper class which uses reflection to create instances of {@link android.telecom.Call} for use
+ * with unit testing.  Since {@link android.telecom.Call} is final, it cannot be mocked using
+ * mockito, and since all setter methods are hidden, it is necessary to use reflection.  In the
+ * future, it would be desirable to replace this if a different mocking solution is used.
+ */
+public class TestTelecomCall {
+
+    private android.telecom.Call mCall;
+
+    public static @Nullable TestTelecomCall createInstance(String callId,
+            Uri handle,
+            int handlePresentation,
+            String callerDisplayName,
+            int callerDisplayNamePresentation,
+            PhoneAccountHandle accountHandle,
+            int capabilities,
+            int properties,
+            DisconnectCause disconnectCause,
+            long connectTimeMillis,
+            GatewayInfo gatewayInfo,
+            int videoState,
+            StatusHints statusHints,
+            Bundle extras,
+            Bundle intentExtras) {
+
+        try {
+            // Phone and InCall adapter are @hide, so we cannot refer to them directly.
+            Class<?> phoneClass = Class.forName("android.telecom.Phone");
+            Class<?> incallAdapterClass = Class.forName("android.telecom.InCallAdapter");
+            Class<?> callClass = android.telecom.Call.class;
+            Constructor<?> cons = callClass
+                    .getDeclaredConstructor(phoneClass, String.class, incallAdapterClass);
+            cons.setAccessible(true);
+
+            android.telecom.Call call = (android.telecom.Call) cons.newInstance(null, callId, null);
+
+            // Create an instance of the call details.
+            Class<?> callDetailsClass = android.telecom.Call.Details.class;
+            Constructor<?> detailsCons = callDetailsClass.getDeclaredConstructor(
+                    String.class, /* telecomCallId */
+                    Uri.class, /* handle */
+                    int.class, /* handlePresentation */
+                    String.class, /* callerDisplayName */
+                    int.class, /* callerDisplayNamePresentation */
+                    PhoneAccountHandle.class, /* accountHandle */
+                    int.class, /* capabilities */
+                    int.class, /* properties */
+                    DisconnectCause.class, /* disconnectCause */
+                    long.class, /* connectTimeMillis */
+                    GatewayInfo.class, /* gatewayInfo */
+                    int.class, /* videoState */
+                    StatusHints.class, /* statusHints */
+                    Bundle.class, /* extras */
+                    Bundle.class /* intentExtras */);
+            detailsCons.setAccessible(true);
+
+            android.telecom.Call.Details details = (android.telecom.Call.Details)
+                    detailsCons.newInstance(callId, handle, handlePresentation, callerDisplayName,
+                            callerDisplayNamePresentation, accountHandle, capabilities, properties,
+                            disconnectCause, connectTimeMillis, gatewayInfo, videoState,
+                            statusHints,
+                            extras, intentExtras);
+
+            // Finally, set this as the details of the call.
+            Field detailsField = call.getClass().getDeclaredField("mDetails");
+            detailsField.setAccessible(true);
+            detailsField.set(call, details);
+
+            return new TestTelecomCall(call);
+        } catch (NoSuchMethodException nsm) {
+            return null;
+        } catch (ClassNotFoundException cnf) {
+            return null;
+        } catch (IllegalAccessException e) {
+            return null;
+        } catch (InstantiationException e) {
+            return null;
+        } catch (InvocationTargetException e) {
+            return null;
+        } catch (NoSuchFieldException e) {
+            return null;
+        }
+    }
+
+    private TestTelecomCall(android.telecom.Call call) {
+        mCall = call;
+    }
+
+    public android.telecom.Call getCall() {
+        return mCall;
+    }
+
+    public void forceDetailsUpdate() {
+        Preconditions.checkNotNull(mCall);
+
+        try {
+            Method method = mCall.getClass().getDeclaredMethod("fireDetailsChanged",
+                    android.telecom.Call.Details.class);
+            method.setAccessible(true);
+            method.invoke(mCall, mCall.getDetails());
+        } catch (NoSuchMethodException e) {
+            Log.e(this, "forceDetailsUpdate", e);
+        } catch (InvocationTargetException e) {
+            Log.e(this, "forceDetailsUpdate", e);
+        } catch (IllegalAccessException e) {
+            Log.e(this, "forceDetailsUpdate", e);
+        }
+    }
+
+    public void setCapabilities(int capabilities) {
+        Preconditions.checkNotNull(mCall);
+        try {
+            Field field = mCall.getDetails().getClass().getDeclaredField("mCallCapabilities");
+            field.setAccessible(true);
+            field.set(mCall.getDetails(), capabilities);
+        } catch (IllegalAccessException e) {
+            Log.e(this, "setProperties", e);
+        } catch (NoSuchFieldException e) {
+            Log.e(this, "setProperties", e);
+        }
+    }
+
+    public void setCall(android.telecom.Call call) {
+        mCall = call;
+    }
+}
