diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
index fecfffb..bbc3292 100644
--- a/tests/AndroidManifest.xml
+++ b/tests/AndroidManifest.xml
@@ -15,10 +15,13 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-        package="com.android.telecomm.tests">
+          coreApp="true"
+          package="com.android.telecomm.tests">
 
     <!-- Test connection service outgoing video preview. -->
     <uses-permission android:name="android.permission.CAMERA" />
+    <uses-permission
+            android:name="com.android.telecomm.permission.REGISTER_PROVIDER_OR_SUBSCRIPTION" />
 
     <application android:label="@string/app_name">
         <uses-library android:name="android.test.runner" />
@@ -31,6 +34,12 @@
             </intent-filter>
         </service>
 
+        <service android:name="com.android.telecomm.testapps.TestConnectionManager">
+            <intent-filter>
+                <action android:name="android.telecomm.ConnectionService" />
+            </intent-filter>
+        </service>
+
         <activity android:name="com.android.telecomm.testapps.TestCallActivity"
                 android:label="@string/testCallActivityLabel">
             <intent-filter>
diff --git a/tests/res/drawable-xhdpi/stat_sys_phone_call.png b/tests/res/drawable-xhdpi/stat_sys_phone_call.png
new file mode 100644
index 0000000..1bb4340
--- /dev/null
+++ b/tests/res/drawable-xhdpi/stat_sys_phone_call.png
Binary files differ
diff --git a/tests/src/com/android/telecomm/testapps/CallServiceNotifier.java b/tests/src/com/android/telecomm/testapps/CallServiceNotifier.java
index 0dbb0b1..debfc9b 100644
--- a/tests/src/com/android/telecomm/testapps/CallServiceNotifier.java
+++ b/tests/src/com/android/telecomm/testapps/CallServiceNotifier.java
@@ -16,6 +16,8 @@
 
 package com.android.telecomm.testapps;
 
+import com.android.telecomm.tests.R;
+
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
@@ -88,19 +90,28 @@
      * Registers a phone account with telecomm.
      */
     public void registerPhoneAccount(Context context) {
-        PhoneAccount account = new PhoneAccount(
+        TelecommManager telecommManager =
+                (TelecommManager) context.getSystemService(Context.TELECOMM_SERVICE);
+        telecommManager.registerPhoneAccount(new PhoneAccount(
                 new PhoneAccountHandle(
                         new ComponentName(context, TestConnectionService.class),
                         PHONE_ACCOUNT_ID),
                 Uri.parse("tel:555-TEST"),
                 "555-TEST",
                 PhoneAccount.CAPABILITY_CALL_PROVIDER,
-                0,  // iconResId
+                R.drawable.stat_sys_phone_call,
                 "Dummy Service",
-                "a short description for the dummy service");
-        TelecommManager telecommManager =
-                (TelecommManager) context.getSystemService(Context.TELECOMM_SERVICE);
-        telecommManager.registerPhoneAccount(account);
+                "a short description for the dummy service"));
+        telecommManager.registerPhoneAccount(new PhoneAccount(
+                new PhoneAccountHandle(
+                        new ComponentName(context, TestConnectionManager.class),
+                        PHONE_ACCOUNT_ID),
+                Uri.parse("tel:555-CMGR"),
+                "555-CMGR",
+                PhoneAccount.CAPABILITY_CONNECTION_MANAGER,
+                R.drawable.stat_sys_phone_call,
+                "Dummy Connection Manager",
+                "a short description for the dummy connection manager"));
     }
 
     /**
diff --git a/tests/src/com/android/telecomm/testapps/TestConnectionManager.java b/tests/src/com/android/telecomm/testapps/TestConnectionManager.java
new file mode 100644
index 0000000..6a8433a
--- /dev/null
+++ b/tests/src/com/android/telecomm/testapps/TestConnectionManager.java
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2013 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.telecomm.testapps;
+
+import android.app.PendingIntent;
+import android.net.Uri;
+import android.telecomm.CallAudioState;
+import android.telecomm.Connection;
+import android.telecomm.ConnectionRequest;
+import android.telecomm.ConnectionService;
+import android.telecomm.PhoneAccountHandle;
+import android.telecomm.RemoteConnection;
+import android.telecomm.StatusHints;
+import android.util.Log;
+
+import java.util.Random;
+
+/**
+ * Service which acts as a fake ConnectionManager if so configured.
+ * TODO(santoscordon): Rename all classes in the directory to Dummy* (e.g., DummyConnectionService).
+ */
+public class TestConnectionManager extends ConnectionService {
+    /**
+     * Random number generator used to generate phone numbers.
+     */
+    private Random mRandom = new Random();
+
+    private final class TestManagedConnection extends Connection {
+        private final RemoteConnection.Listener mProxyListener = new RemoteConnection.Listener() {
+            @Override
+            public void onStateChanged(RemoteConnection connection, int state) {
+                setState(state);
+            }
+
+            @Override
+            public void onDisconnected(RemoteConnection connection, int cause, String message) {
+                setDisconnected(cause, message);
+                destroy();
+            }
+
+            @Override
+            public void onRequestingRingback(RemoteConnection connection, boolean ringback) {
+                setRequestingRingback(ringback);
+            }
+
+            @Override
+            public void onCallCapabilitiesChanged(RemoteConnection connection,
+                    int callCapabilities) {
+                setCallCapabilities(callCapabilities);
+            }
+
+            @Override
+            public void onPostDialWait(RemoteConnection connection, String remainingDigits) {
+                setPostDialWait(remainingDigits);
+            }
+
+            @Override
+            public void onAudioModeIsVoipChanged(RemoteConnection connection, boolean isVoip) {
+                setAudioModeIsVoip(isVoip);
+            }
+
+            @Override
+            public void onStatusHintsChanged(RemoteConnection connection, StatusHints statusHints) {
+                setStatusHints(statusHints);
+            }
+
+            @Override
+            public void onVideoStateChanged(RemoteConnection connection, int videoState) {
+                setVideoState(videoState);
+            }
+
+            @Override
+            public void onHandleChanged(RemoteConnection connection, Uri handle, int presentation) {
+                setHandle(handle, presentation);
+            }
+
+            @Override
+            public void onCallerDisplayNameChanged(
+                    RemoteConnection connection, String callerDisplayName, int presentation) {
+                setCallerDisplayName(callerDisplayName, presentation);
+            }
+
+            @Override
+            public void onStartActivityFromInCall(
+                    RemoteConnection connection, PendingIntent intent) {
+                startActivityFromInCall(intent);
+            }
+
+            @Override
+            public void onDestroyed(RemoteConnection connection) {
+                destroy();
+            }
+        };
+
+        private final RemoteConnection mRemoteConnection;
+        private final boolean mIsIncoming;
+
+        TestManagedConnection(RemoteConnection remoteConnection, boolean isIncoming) {
+            mRemoteConnection = remoteConnection;
+            mIsIncoming = isIncoming;
+            mRemoteConnection.addListener(mProxyListener);
+            setState(mRemoteConnection.getState());
+        }
+
+        @Override
+        public void onAbort() {
+            mRemoteConnection.abort();
+        }
+
+        /** ${inheritDoc} */
+        @Override
+        public void onAnswer(int videoState) {
+            mRemoteConnection.answer(videoState);
+        }
+
+        /** ${inheritDoc} */
+        @Override
+        public void onDisconnect() {
+            mRemoteConnection.disconnect();
+        }
+
+        /** ${inheritDoc} */
+        @Override
+        public void onHold() {
+            mRemoteConnection.hold();
+        }
+
+        /** ${inheritDoc} */
+        @Override
+        public void onReject() {
+            mRemoteConnection.reject();
+        }
+
+        /** ${inheritDoc} */
+        @Override
+        public void onUnhold() {
+            mRemoteConnection.unhold();
+        }
+
+        @Override
+        public void onSetAudioState(CallAudioState state) {
+            mRemoteConnection.setAudioState(state);
+        }
+
+        private void setState(int state) {
+            log("setState: " + state);
+            switch (state) {
+                case State.ACTIVE:
+                    setActive();
+                    break;
+                case State.HOLDING:
+                    setOnHold();
+                    break;
+                case State.DIALING:
+                    setDialing();
+                    break;
+                case State.RINGING:
+                    setRinging();
+                    break;
+            }
+        }
+    }
+
+    private static void log(String msg) {
+        Log.w("telecomtestcs", "[TestConnectionService] " + msg);
+    }
+
+    @Override
+    public Connection onCreateOutgoingConnection(
+            PhoneAccountHandle connectionManagerAccount,
+            final ConnectionRequest request) {
+        return new TestManagedConnection(
+                createRemoteOutgoingConnection(
+                        request.getAccountHandle(),
+                        request),
+                false);
+    }
+
+    @Override
+    public Connection onCreateIncomingConnection(
+            PhoneAccountHandle connectionManagerAccount,
+            final ConnectionRequest request) {
+        return new TestManagedConnection(
+                createRemoteOutgoingConnection(
+                        request.getAccountHandle(),
+                        request),
+                true);
+    }
+}
