diff --git a/testapps/Android.mk b/testapps/Android.mk
new file mode 100644
index 0000000..9c11d34
--- /dev/null
+++ b/testapps/Android.mk
@@ -0,0 +1,31 @@
+#
+# 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.
+#
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+        android-ex-camera2 \
+        guava
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := TelecomTestApps
+LOCAL_CERTIFICATE := platform
+
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_PACKAGE)
diff --git a/testapps/AndroidManifest.xml b/testapps/AndroidManifest.xml
new file mode 100644
index 0000000..747d377
--- /dev/null
+++ b/testapps/AndroidManifest.xml
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          coreApp="true"
+          package="com.android.server.telecom.testapps">
+
+    <uses-permission android:name="android.permission.CAMERA" />
+    <uses-permission android:name="android.permission.CONTROL_INCALL_EXPERIENCE" />
+    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
+    <uses-permission android:name="android.permission.REGISTER_CALL_PROVIDER" />
+    <uses-permission android:name="android.permission.REGISTER_CONNECTION_MANAGER" />
+    <uses-permission android:name="android.permission.REGISTER_SIM_SUBSCRIPTION" />
+
+    <application android:label="@string/app_name">
+        <uses-library android:name="android.test.runner" />
+
+        <!-- Miscellaneous telecom app-related test activities. -->
+
+        <service android:name="com.android.server.telecom.testapps.TestConnectionService"
+                 android:permission="android.permission.BIND_CONNECTION_SERVICE" >
+            <intent-filter>
+                <action android:name="android.telecom.ConnectionService" />
+            </intent-filter>
+        </service>
+
+        <service android:name="com.android.server.telecom.testapps.TestConnectionManager"
+                 android:permission="android.permission.BIND_CONNECTION_SERVICE" >
+            <intent-filter>
+                <action android:name="android.telecom.ConnectionService" />
+            </intent-filter>
+        </service>
+
+        <service android:name="com.android.server.telecom.testapps.TestInCallServiceImpl"
+                 android:process="com.android.server.telecom.testapps.TestInCallService"
+                 android:permission="android.permission.BIND_INCALL_SERVICE" >
+            <intent-filter>
+                <action android:name="android.telecom.InCallService"/>
+            </intent-filter>
+        </service>
+
+        <activity android:name="com.android.server.telecom.testapps.TestCallActivity"
+                  android:label="@string/testCallActivityLabel">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+            <intent-filter>
+                <action android:name="android.telecom.testapps.ACTION_START_INCOMING_CALL" />
+                <action android:name="android.telecom.testapps.ACTION_NEW_UNKNOWN_CALL" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <data android:scheme="tel" />
+                <data android:scheme="sip" />
+            </intent-filter>
+        </activity>
+
+        <receiver android:name="com.android.server.telecom.testapps.CallNotificationReceiver"
+                  android:exported="false">
+            <intent-filter>
+                <action android:name="com.android.server.telecom.testapps.ACTION_CALL_SERVICE_EXIT" />
+            </intent-filter>
+        </receiver>
+
+        <activity android:name="com.android.server.telecom.testapps.TestDialerActivity"
+                  android:label="@string/testDialerActivityLabel"
+                  android:process="com.android.server.telecom.testapps.TestInCallService">
+            <intent-filter>
+                <action android:name="android.intent.action.DIAL" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.BROWSABLE" />
+                <data android:mimeType="vnd.android.cursor.item/phone" />
+                <data android:mimeType="vnd.android.cursor.item/person" />
+            </intent-filter>
+            <intent-filter>
+                <action android:name="android.intent.action.DIAL" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.BROWSABLE" />
+                <data android:scheme="voicemail" />
+            </intent-filter>
+            <intent-filter>
+                <action android:name="android.intent.action.DIAL" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+            <intent-filter>
+                <action android:name="android.intent.action.VIEW" />
+                <action android:name="android.intent.action.DIAL" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.BROWSABLE" />
+                <data android:scheme="tel" />
+            </intent-filter>
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
diff --git a/testapps/res/drawable-xhdpi/stat_sys_phone_call.png b/testapps/res/drawable-xhdpi/stat_sys_phone_call.png
new file mode 100644
index 0000000..1bb4340
--- /dev/null
+++ b/testapps/res/drawable-xhdpi/stat_sys_phone_call.png
Binary files differ
diff --git a/testapps/res/layout/testdialer_main.xml b/testapps/res/layout/testdialer_main.xml
new file mode 100644
index 0000000..a5453fc
--- /dev/null
+++ b/testapps/res/layout/testdialer_main.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical" >
+    <EditText
+        android:id="@+id/number"
+        android:inputType="number"
+        android:layout_width="200dp"
+        android:layout_height="wrap_content" />
+    <Button
+        android:id="@+id/place_call_button"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/placeCallButton" />
+    <Button
+        android:id="@+id/set_default_button"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/defaultDialerButton" />
+</LinearLayout>
diff --git a/testapps/res/raw/beep_boop.ogg b/testapps/res/raw/beep_boop.ogg
new file mode 100644
index 0000000..83148f0
--- /dev/null
+++ b/testapps/res/raw/beep_boop.ogg
Binary files differ
diff --git a/testapps/res/raw/outgoing_video.mp4 b/testapps/res/raw/outgoing_video.mp4
new file mode 100644
index 0000000..3e4f1cb
--- /dev/null
+++ b/testapps/res/raw/outgoing_video.mp4
Binary files differ
diff --git a/testapps/res/raw/test_pattern.mp4 b/testapps/res/raw/test_pattern.mp4
new file mode 100644
index 0000000..401066f
--- /dev/null
+++ b/testapps/res/raw/test_pattern.mp4
Binary files differ
diff --git a/testapps/res/raw/test_video.mp4 b/testapps/res/raw/test_video.mp4
new file mode 100644
index 0000000..1a454b3
--- /dev/null
+++ b/testapps/res/raw/test_video.mp4
Binary files differ
diff --git a/testapps/res/values/donottranslate_strings.xml b/testapps/res/values/donottranslate_strings.xml
new file mode 100644
index 0000000..91d8628
--- /dev/null
+++ b/testapps/res/values/donottranslate_strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<resources>
+    <!-- Application label -->
+    <string name="app_name">TelecommTests</string>
+
+    <!-- String for the TestCallActivity -->
+    <string name="testCallActivityLabel">Test Connection Service App</string>
+
+    <!-- String for the TestDialerActivity -->
+    <string name="testDialerActivityLabel">Test Dialer</string>
+
+    <!-- String for button in TestDialerActivity that reassigns the default Dialer -->
+    <string name="defaultDialerButton">Default dialer request</string>
+
+    <!-- String for button in TestDialerActivity that places a test call -->
+    <string name="placeCallButton">Place call</string>
+</resources>
diff --git a/testapps/src/com/android/server/telecom/testapps/CallNotificationReceiver.java b/testapps/src/com/android/server/telecom/testapps/CallNotificationReceiver.java
new file mode 100644
index 0000000..a835bf1
--- /dev/null
+++ b/testapps/src/com/android/server/telecom/testapps/CallNotificationReceiver.java
@@ -0,0 +1,108 @@
+/*
+ * 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.server.telecom.testapps;
+
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.telecom.CallState;
+import android.telecom.PhoneAccountHandle;
+import android.telecom.TelecomManager;
+import android.util.Log;
+
+/**
+ * This class receives the notification callback intents used to update call states for
+ * {@link TestConnectionService}.
+ */
+public class CallNotificationReceiver extends BroadcastReceiver {
+
+    static final String TAG = CallNotificationReceiver.class.getSimpleName();
+    /**
+     * Exit intent action is sent when the user clicks the "exit" action of the
+     * TestConnectionService notification. Used to cancel (remove) the notification.
+     */
+    static final String ACTION_CALL_SERVICE_EXIT =
+            "com.android.server.telecom.testapps.ACTION_CALL_SERVICE_EXIT";
+    static final String ACTION_REGISTER_PHONE_ACCOUNT =
+            "com.android.server.telecom.testapps.ACTION_REGISTER_PHONE_ACCOUNT";
+    static final String ACTION_SHOW_ALL_PHONE_ACCOUNTS =
+            "com.android.server.telecom.testapps.ACTION_SHOW_ALL_PHONE_ACCOUNTS";
+    static final String ACTION_VIDEO_CALL =
+            "com.android.server.telecom.testapps.ACTION_VIDEO_CALL";
+    static final String ACTION_AUDIO_CALL =
+            "com.android.server.telecom.testapps.ACTION_AUDIO_CALL";
+
+    /** {@inheritDoc} */
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        String action = intent.getAction();
+        if (ACTION_CALL_SERVICE_EXIT.equals(action)) {
+            CallServiceNotifier.getInstance().cancelNotifications(context);
+        } else if (ACTION_REGISTER_PHONE_ACCOUNT.equals(action)) {
+            CallServiceNotifier.getInstance().registerPhoneAccount(context);
+        } else if (ACTION_SHOW_ALL_PHONE_ACCOUNTS.equals(action)) {
+            CallServiceNotifier.getInstance().showAllPhoneAccounts(context);
+        } else if (ACTION_VIDEO_CALL.equals(action)) {
+            sendIncomingCallIntent(context, null, true);
+        } else if (ACTION_AUDIO_CALL.equals(action)) {
+            sendIncomingCallIntent(context, null, false);
+        }
+    }
+
+    /**
+     * Creates and sends the intent to add an incoming call through Telecom.
+     *
+     * @param context The current context.
+     * @param isVideoCall {@code True} if this is a video call.
+     */
+    public static void sendIncomingCallIntent(Context context, Uri handle, boolean isVideoCall) {
+        PhoneAccountHandle phoneAccount = new PhoneAccountHandle(
+                new ComponentName(context, TestConnectionService.class),
+                CallServiceNotifier.SIM_SUBSCRIPTION_ID);
+
+        // For the purposes of testing, indicate whether the incoming call is a video call by
+        // stashing an indicator in the EXTRA_INCOMING_CALL_EXTRAS.
+        Bundle extras = new Bundle();
+        extras.putBoolean(TestConnectionService.EXTRA_IS_VIDEO_CALL, isVideoCall);
+        if (handle != null) {
+            extras.putParcelable(TestConnectionService.EXTRA_HANDLE, handle);
+        }
+
+        TelecomManager.from(context).addNewIncomingCall(phoneAccount, extras);
+    }
+
+    public static void addNewUnknownCall(Context context, Uri handle, Bundle extras) {
+        Log.i(TAG, "Adding new unknown call with handle " + handle);
+        PhoneAccountHandle phoneAccount = new PhoneAccountHandle(
+                new ComponentName(context, TestConnectionService.class),
+                CallServiceNotifier.SIM_SUBSCRIPTION_ID);
+
+        if (extras == null) {
+            extras = new Bundle();
+        }
+
+        if (handle != null) {
+            extras.putParcelable(TelecomManager.EXTRA_UNKNOWN_CALL_HANDLE, handle);
+            extras.putParcelable(TestConnectionService.EXTRA_HANDLE, handle);
+        }
+
+        TelecomManager.from(context).addNewUnknownCall(phoneAccount, extras);
+    }
+}
diff --git a/testapps/src/com/android/server/telecom/testapps/CallServiceNotifier.java b/testapps/src/com/android/server/telecom/testapps/CallServiceNotifier.java
new file mode 100644
index 0000000..d40f92d
--- /dev/null
+++ b/testapps/src/com/android/server/telecom/testapps/CallServiceNotifier.java
@@ -0,0 +1,298 @@
+/*
+ * 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.server.telecom.testapps;
+
+import com.android.server.telecom.testapps.R;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Color;
+import android.net.Uri;
+import android.telecom.PhoneAccount;
+import android.telecom.PhoneAccountHandle;
+import android.telecom.TelecomManager;
+import android.util.Log;
+import android.widget.Toast;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Class used to create, update and cancel the notification used to display and update call state
+ * for {@link TestConnectionService}.
+ */
+public class CallServiceNotifier {
+    private static final CallServiceNotifier INSTANCE = new CallServiceNotifier();
+
+    static final String CALL_PROVIDER_ID = "testapps_TestConnectionService_CALL_PROVIDER_ID";
+    static final String SIM_SUBSCRIPTION_ID = "testapps_TestConnectionService_SIM_SUBSCRIPTION_ID";
+    static final String CONNECTION_MANAGER_ID =
+            "testapps_TestConnectionService_CONNECTION_MANAGER_ID";
+
+    /**
+     * Static notification IDs.
+     */
+    private static final int CALL_NOTIFICATION_ID = 1;
+    private static final int PHONE_ACCOUNT_NOTIFICATION_ID = 2;
+
+    /**
+     * Whether the added call should be started as a video call. Referenced by
+     * {@link TestConnectionService} to know whether to provide a call video provider.
+     */
+    public static boolean mStartVideoCall;
+
+    /**
+     * Singleton accessor.
+     */
+    public static CallServiceNotifier getInstance() {
+        return INSTANCE;
+    }
+
+    /**
+     * Creates a CallService & initializes notification manager.
+     */
+    private CallServiceNotifier() {
+    }
+
+    /**
+     * Updates the notification in the notification pane.
+     */
+    public void updateNotification(Context context) {
+        log("adding the notification ------------");
+        getNotificationManager(context).notify(CALL_NOTIFICATION_ID, getMainNotification(context));
+        getNotificationManager(context).notify(
+                PHONE_ACCOUNT_NOTIFICATION_ID, getPhoneAccountNotification(context));
+    }
+
+    /**
+     * Cancels the notification.
+     */
+    public void cancelNotifications(Context context) {
+        log("canceling notification");
+        getNotificationManager(context).cancel(CALL_NOTIFICATION_ID);
+        getNotificationManager(context).cancel(PHONE_ACCOUNT_NOTIFICATION_ID);
+    }
+
+    /**
+     * Registers a phone account with telecom.
+     */
+    public void registerPhoneAccount(Context context) {
+        TelecomManager telecomManager =
+                (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE);
+
+        telecomManager.clearAccounts();
+
+        telecomManager.registerPhoneAccount(PhoneAccount.builder(
+                new PhoneAccountHandle(
+                        new ComponentName(context, TestConnectionService.class),
+                        CALL_PROVIDER_ID),
+                "TelecomTestApp Call Provider")
+                .setAddress(Uri.parse("tel:555-TEST"))
+                .setSubscriptionAddress(Uri.parse("tel:555-TEST"))
+                .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER |
+                        PhoneAccount.CAPABILITY_VIDEO_CALLING)
+                .setIcon(context, R.drawable.stat_sys_phone_call, Color.RED)
+                .setHighlightColor(Color.RED)
+                .setShortDescription("a short description for the call provider")
+                .setSupportedUriSchemes(Arrays.asList("tel"))
+                .build());
+
+        telecomManager.registerPhoneAccount(PhoneAccount.builder(
+                new PhoneAccountHandle(
+                        new ComponentName(context, TestConnectionService.class),
+                        SIM_SUBSCRIPTION_ID),
+                "TelecomTestApp SIM Subscription")
+                .setAddress(Uri.parse("tel:555-TSIM"))
+                .setSubscriptionAddress(Uri.parse("tel:555-TSIM"))
+                .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER |
+                        PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION |
+                        PhoneAccount.CAPABILITY_VIDEO_CALLING)
+                .setIcon(context, R.drawable.stat_sys_phone_call, Color.GREEN)
+                .setHighlightColor(Color.GREEN)
+                .setShortDescription("a short description for the sim subscription")
+                .build());
+
+        telecomManager.registerPhoneAccount(PhoneAccount.builder(
+                        new PhoneAccountHandle(
+                                new ComponentName(context, TestConnectionManager.class),
+                                CONNECTION_MANAGER_ID),
+                        "TelecomTestApp CONNECTION MANAGER")
+                .setAddress(Uri.parse("tel:555-CMGR"))
+                .setSubscriptionAddress(Uri.parse("tel:555-CMGR"))
+                .setCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER)
+                .setIcon(context, R.drawable.stat_sys_phone_call, Color.BLUE)
+                .setShortDescription("a short description for the connection manager")
+                .build());
+    }
+
+    /**
+     * Displays all phone accounts registered with telecom.
+     */
+    public void showAllPhoneAccounts(Context context) {
+        TelecomManager telecomManager =
+                (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE);
+        List<PhoneAccountHandle> accounts = telecomManager.getCallCapablePhoneAccounts();
+
+        Toast.makeText(context, accounts.toString(), Toast.LENGTH_LONG).show();
+    }
+
+    /**
+     * Returns the system's notification manager needed to add/remove notifications.
+     */
+    private NotificationManager getNotificationManager(Context context) {
+        return (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
+    }
+
+    /**
+     * Creates a notification object for using the telecom APIs.
+     */
+    private Notification getPhoneAccountNotification(Context context) {
+        final Notification.Builder builder = new Notification.Builder(context);
+        // 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.
+        builder.setOngoing(false);
+        builder.setPriority(Notification.PRIORITY_HIGH);
+
+        final PendingIntent intent = createShowAllPhoneAccountsIntent(context);
+        builder.setContentIntent(intent);
+
+        builder.setSmallIcon(android.R.drawable.stat_sys_phone_call);
+        // TODO: Consider moving this into a strings.xml
+        builder.setContentText("Test phone accounts via telecom APIs.");
+        builder.setContentTitle("Test Phone Accounts");
+
+        addRegisterPhoneAccountAction(builder, context);
+        addShowAllPhoneAccountsAction(builder, context);
+
+        return builder.build();
+    }
+
+    /**
+     * Creates a notification object out of the current calls state.
+     */
+    private Notification getMainNotification(Context context) {
+        final Notification.Builder builder = new Notification.Builder(context);
+        builder.setOngoing(true);
+        builder.setPriority(Notification.PRIORITY_HIGH);
+        builder.setSmallIcon(android.R.drawable.stat_sys_phone_call);
+        builder.setContentText("Test calls via CallService API");
+        builder.setContentTitle("Test Connection Service");
+
+        addAddVideoCallAction(builder, context);
+        addAddCallAction(builder, context);
+        addExitAction(builder, context);
+
+        return builder.build();
+    }
+
+    /**
+     * Creates the intent to remove the notification.
+     */
+    private PendingIntent createExitIntent(Context context) {
+        final Intent intent = new Intent(CallNotificationReceiver.ACTION_CALL_SERVICE_EXIT, null,
+                context, CallNotificationReceiver.class);
+
+        return PendingIntent.getBroadcast(context, 0, intent, 0);
+    }
+
+    /**
+     * Creates the intent to register a phone account.
+     */
+    private PendingIntent createRegisterPhoneAccountIntent(Context context) {
+        final Intent intent = new Intent(CallNotificationReceiver.ACTION_REGISTER_PHONE_ACCOUNT,
+                null, context, CallNotificationReceiver.class);
+        return PendingIntent.getBroadcast(context, 0, intent, 0);
+    }
+
+    /**
+     * Creates the intent to show all phone accounts.
+     */
+    private PendingIntent createShowAllPhoneAccountsIntent(Context context) {
+        final Intent intent = new Intent(CallNotificationReceiver.ACTION_SHOW_ALL_PHONE_ACCOUNTS,
+                null, context, CallNotificationReceiver.class);
+        return PendingIntent.getBroadcast(context, 0, intent, 0);
+    }
+
+    /**
+     * Creates the intent to start an incoming video call
+     */
+    private PendingIntent createIncomingVideoCall(Context context) {
+        final Intent intent = new Intent(CallNotificationReceiver.ACTION_VIDEO_CALL,
+                null, context, CallNotificationReceiver.class);
+        return PendingIntent.getBroadcast(context, 0, intent, 0);
+    }
+
+    /**
+     * Creates the intent to start an incoming audio call
+     */
+    private PendingIntent createIncomingAudioCall(Context context) {
+        final Intent intent = new Intent(CallNotificationReceiver.ACTION_AUDIO_CALL,
+                null, context, CallNotificationReceiver.class);
+        return PendingIntent.getBroadcast(context, 0, intent, 0);
+    }
+
+    /**
+     * Adds an action to the Notification Builder for adding an incoming call through Telecom.
+     * @param builder The Notification Builder.
+     */
+    private void addAddCallAction(Notification.Builder builder, Context context) {
+        builder.addAction(0, "Add Call", createIncomingAudioCall(context));
+    }
+
+    /**
+     * Adds an action to the Notification Builder to add an incoming video call through Telecom.
+     */
+    private void addAddVideoCallAction(Notification.Builder builder, Context context) {
+        builder.addAction(0, "Add Video", createIncomingVideoCall(context));
+    }
+
+    /**
+     * Adds an action to remove the notification.
+     */
+    private void addExitAction(Notification.Builder builder, Context context) {
+        builder.addAction(0, "Exit", createExitIntent(context));
+    }
+
+    /**
+     * Adds an action to show all registered phone accounts on a device.
+     */
+    private void addShowAllPhoneAccountsAction(Notification.Builder builder, Context context) {
+        builder.addAction(0, "Show Accts", createShowAllPhoneAccountsIntent(context));
+    }
+
+    /**
+     * Adds an action to register a new phone account.
+     */
+    private void addRegisterPhoneAccountAction(Notification.Builder builder, Context context) {
+        builder.addAction(0, "Reg.Acct.", createRegisterPhoneAccountIntent(context));
+    }
+
+    public boolean shouldStartVideoCall() {
+        return mStartVideoCall;
+    }
+
+    private static void log(String msg) {
+        Log.w("testcallservice", "[CallServiceNotifier] " + msg);
+    }
+}
diff --git a/testapps/src/com/android/server/telecom/testapps/CameraThread.java b/testapps/src/com/android/server/telecom/testapps/CameraThread.java
new file mode 100644
index 0000000..fbcd6b2
--- /dev/null
+++ b/testapps/src/com/android/server/telecom/testapps/CameraThread.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2014 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.testapps;
+
+import android.os.ConditionVariable;
+import android.os.Handler;
+import android.os.Looper;
+import android.util.Log;
+
+import java.lang.AutoCloseable;
+import java.lang.Exception;
+import java.lang.Override;
+import java.lang.String;
+import java.lang.Thread;
+import java.lang.Throwable;
+import java.util.concurrent.TimeoutException;
+
+/**
+ * Camera thread class used for handling camera callbacks.
+ */
+public class CameraThread implements AutoCloseable {
+    private static final String TAG = "CameraThread";
+    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
+
+    // Timeout for initializing looper and opening camera in Milliseconds.
+    private static final long WAIT_FOR_COMMAND_TO_COMPLETE = 5000;
+    private Looper mLooper = null;
+    private Handler mHandler = null;
+
+    /**
+     * Create and start a looper thread, return the Handler
+     */
+    public synchronized Handler start() throws Exception {
+        final ConditionVariable startDone = new ConditionVariable();
+        if (mHandler != null) {
+            Log.w(TAG, "Looper thread already started");
+            return mHandler;
+        }
+
+        new Thread() {
+            @Override
+            public void run() {
+                if (VERBOSE) Log.v(TAG, "start loopRun");
+                Looper.prepare();
+                // Save the looper so that we can terminate this thread
+                // after we are done with it.
+                mLooper = Looper.myLooper();
+                mHandler = new Handler();
+                startDone.open();
+                Looper.loop();
+                if (VERBOSE) Log.v(TAG, "createLooperThread: finished");
+            }
+        }.start();
+
+        if (VERBOSE) Log.v(TAG, "start waiting for looper");
+        if (!startDone.block(WAIT_FOR_COMMAND_TO_COMPLETE)) {
+            throw new TimeoutException("createLooperThread: start timeout");
+        }
+        return mHandler;
+    }
+
+    /**
+     * Terminate the looper thread
+     */
+    public synchronized void close() throws Exception {
+        if (mLooper == null || mHandler == null) {
+            Log.w(TAG, "Looper thread doesn't start yet");
+            return;
+        }
+
+        if (VERBOSE) Log.v(TAG, "Terminate looper thread");
+        mLooper.quit();
+        mLooper.getThread().join();
+        mLooper = null;
+        mHandler = null;
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            close();
+        } finally {
+            super.finalize();
+        }
+    }
+}
diff --git a/testapps/src/com/android/server/telecom/testapps/TestCallActivity.java b/testapps/src/com/android/server/telecom/testapps/TestCallActivity.java
new file mode 100644
index 0000000..6f4ae20
--- /dev/null
+++ b/testapps/src/com/android/server/telecom/testapps/TestCallActivity.java
@@ -0,0 +1,60 @@
+/*
+ * 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.server.telecom.testapps;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+
+/**
+ * This activity exists in order to add an icon to the launcher. This activity has no UI of its own
+ * and instead starts the notification for {@link TestConnectionService} via
+ * {@link CallServiceNotifier}. After triggering a notification update, this activity immediately
+ * finishes.
+ *
+ * To directly trigger a new incoming call, use the following adb command:
+ *
+ * adb shell am start -a android.telecom.testapps.ACTION_START_INCOMING_CALL -d "tel:123456789"
+ */
+public class TestCallActivity extends Activity {
+
+    public static final String ACTION_NEW_INCOMING_CALL =
+            "android.telecom.testapps.ACTION_START_INCOMING_CALL";
+
+    /*
+     * Action to exercise TelecomManager.addNewUnknownCall().
+     */
+    public static final String ACTION_NEW_UNKNOWN_CALL =
+            "android.telecom.testapps.ACTION_NEW_UNKNOWN_CALL";
+
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        final Intent intent = getIntent();
+        final String action = intent != null ? intent.getAction() : null;
+        final Uri data = intent != null ? intent.getData() : null;
+        if (ACTION_NEW_INCOMING_CALL.equals(action) && data != null) {
+            CallNotificationReceiver.sendIncomingCallIntent(this, data, false);
+        } else if (ACTION_NEW_UNKNOWN_CALL.equals(action) && data != null) {
+            CallNotificationReceiver.addNewUnknownCall(this, data, intent.getExtras());
+        } else {
+            CallServiceNotifier.getInstance().updateNotification(this);
+        }
+        finish();
+    }
+}
diff --git a/testapps/src/com/android/server/telecom/testapps/TestConnectionManager.java b/testapps/src/com/android/server/telecom/testapps/TestConnectionManager.java
new file mode 100644
index 0000000..a27be39
--- /dev/null
+++ b/testapps/src/com/android/server/telecom/testapps/TestConnectionManager.java
@@ -0,0 +1,336 @@
+/*
+ * 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.server.telecom.testapps;
+
+import android.net.Uri;
+import android.telecom.AudioState;
+import android.telecom.Conference;
+import android.telecom.Connection;
+import android.telecom.ConnectionRequest;
+import android.telecom.ConnectionService;
+import android.telecom.DisconnectCause;
+import android.telecom.PhoneAccountHandle;
+import android.telecom.RemoteConference;
+import android.telecom.RemoteConnection;
+import android.telecom.StatusHints;
+import android.telecom.VideoProfile;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 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 {
+    public final class TestManagedConnection extends Connection {
+        private final RemoteConnection.Callback mRemoteCallback = new RemoteConnection.Callback() {
+            @Override
+            public void onStateChanged(RemoteConnection connection, int state) {
+                setState(state);
+            }
+
+            @Override
+            public void onDisconnected(
+                    RemoteConnection connection, DisconnectCause disconnectCause) {
+                setDisconnected(disconnectCause);
+                destroy();
+            }
+
+            @Override
+            public void onRingbackRequested(RemoteConnection connection, boolean ringback) {
+                setRingbackRequested(ringback);
+            }
+
+            @Override
+            public void onConnectionCapabilitiesChanged(RemoteConnection connection,
+                    int connectionCapabilities) {
+                setConnectionCapabilities(connectionCapabilities);
+            }
+
+            @Override
+            public void onPostDialWait(RemoteConnection connection, String remainingDigits) {
+                setPostDialWait(remainingDigits);
+            }
+
+            @Override
+            public void onVoipAudioChanged(RemoteConnection connection, boolean isVoip) {
+                setAudioModeIsVoip(isVoip);
+            }
+
+            @Override
+            public void onStatusHintsChanged(RemoteConnection connection, StatusHints statusHints) {
+                setStatusHints(statusHints);
+            }
+
+            @Override
+            public void onVideoStateChanged(RemoteConnection connection, int videoState) {
+                if (videoState == VideoProfile.VideoState.BIDIRECTIONAL) {
+                    setVideoProvider(new TestManagedVideoProvider(connection.getVideoProvider()));
+                }
+                setVideoState(videoState);
+            }
+
+            @Override
+            public void onAddressChanged(
+                    RemoteConnection connection, Uri address, int presentation) {
+                setAddress(address, presentation);
+            }
+
+            @Override
+            public void onCallerDisplayNameChanged(
+                    RemoteConnection connection, String callerDisplayName, int presentation) {
+                setCallerDisplayName(callerDisplayName, presentation);
+            }
+
+            @Override
+            public void onDestroyed(RemoteConnection connection) {
+                destroy();
+                mManagedConnectionByRemote.remove(mRemote);
+            }
+
+            @Override
+            public void onConferenceableConnectionsChanged(
+                    RemoteConnection connect,
+                    List<RemoteConnection> conferenceable) {
+                List<Connection> c = new ArrayList<>();
+                for (RemoteConnection remote : conferenceable) {
+                    if (mManagedConnectionByRemote.containsKey(remote)) {
+                        c.add(mManagedConnectionByRemote.get(remote));
+                    }
+                }
+                setConferenceableConnections(c);
+            }
+        };
+
+        private final RemoteConnection mRemote;
+        private final boolean mIsIncoming;
+
+        TestManagedConnection(RemoteConnection remote, boolean isIncoming) {
+            mRemote = remote;
+            mIsIncoming = isIncoming;
+            mRemote.registerCallback(mRemoteCallback);
+            setState(mRemote.getState());
+            setVideoState(mRemote.getVideoState());
+        }
+
+        @Override
+        public void onAbort() {
+            mRemote.abort();
+        }
+
+        /** ${inheritDoc} */
+        @Override
+        public void onAnswer(int videoState) {
+            mRemote.answer(videoState);
+        }
+
+        /** ${inheritDoc} */
+        @Override
+        public void onDisconnect() {
+            mRemote.disconnect();
+        }
+
+        @Override
+        public void onPlayDtmfTone(char c) {
+            mRemote.playDtmfTone(c);
+        }
+
+        /** ${inheritDoc} */
+        @Override
+        public void onHold() {
+            mRemote.hold();
+        }
+
+        /** ${inheritDoc} */
+        @Override
+        public void onReject() {
+            mRemote.reject();
+        }
+
+        /** ${inheritDoc} */
+        @Override
+        public void onUnhold() {
+            mRemote.unhold();
+        }
+
+        @Override
+        public void onAudioStateChanged(AudioState state) {
+            mRemote.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;
+            }
+        }
+    }
+
+    public final class TestManagedConference extends Conference {
+        private final RemoteConference.Callback mRemoteCallback = new RemoteConference.Callback() {
+            @Override
+            public void onStateChanged(RemoteConference conference, int oldState, int newState) {
+                switch (newState) {
+                    case Connection.STATE_DISCONNECTED:
+                        // See onDisconnected below
+                        break;
+                    case Connection.STATE_HOLDING:
+                        setOnHold();
+                        break;
+                    case Connection.STATE_ACTIVE:
+                        setActive();
+                        break;
+                    default:
+                        log("unrecognized state for Conference: " + newState);
+                        break;
+                }
+            }
+
+            @Override
+            public void onDisconnected(RemoteConference conference,
+                    DisconnectCause disconnectCause) {
+                setDisconnected(disconnectCause);
+            }
+
+            @Override
+            public void onConnectionAdded(
+                    RemoteConference conference,
+                    RemoteConnection connection) {
+                TestManagedConnection c = mManagedConnectionByRemote.get(connection);
+                if (c == null) {
+                    log("onConnectionAdded cannot find remote connection: " + connection);
+                } else {
+                    addConnection(c);
+                }
+            }
+
+            @Override
+            public void onConnectionRemoved(
+                    RemoteConference conference,
+                    RemoteConnection connection) {
+                TestManagedConnection c = mManagedConnectionByRemote.get(connection);
+                if (c == null) {
+                    log("onConnectionRemoved cannot find remote connection: " + connection);
+                } else {
+                    removeConnection(c);
+                }
+            }
+
+            @Override
+            public void onConnectionCapabilitiesChanged(RemoteConference conference,
+                    int connectionCapabilities) {
+                setConnectionCapabilities(connectionCapabilities);
+            }
+
+            @Override
+            public void onDestroyed(RemoteConference conference) {
+                destroy();
+                mRemote.unregisterCallback(mRemoteCallback);
+                mManagedConferenceByRemote.remove(mRemote);
+            }
+
+        };
+
+        @Override
+        public void onPlayDtmfTone(char c) {
+            mRemote.playDtmfTone(c);
+        };
+
+        @Override
+        public void onStopDtmfTone() {
+            mRemote.stopDtmfTone();
+        };
+
+        private final RemoteConference mRemote;
+
+        public TestManagedConference(RemoteConference remote) {
+            super(null);
+            mRemote = remote;
+            remote.registerCallback(mRemoteCallback);
+            setActive();
+            for (RemoteConnection r : remote.getConnections()) {
+                TestManagedConnection c = mManagedConnectionByRemote.get(r);
+                if (c != null) {
+                    addConnection(c);
+                }
+            }
+        }
+    }
+
+    static void log(String msg) {
+        Log.w("telecomtestcs", "[TestConnectionManager] " + msg);
+    }
+
+    private final Map<RemoteConference, TestManagedConference> mManagedConferenceByRemote
+            = new HashMap<>();
+    private final Map<RemoteConnection, TestManagedConnection> mManagedConnectionByRemote
+            = new HashMap<>();
+
+    @Override
+    public Connection onCreateOutgoingConnection(
+            PhoneAccountHandle connectionManagerAccount,
+            final ConnectionRequest request) {
+        return makeConnection(request, false);
+    }
+
+    @Override
+    public Connection onCreateIncomingConnection(
+            PhoneAccountHandle connectionManagerAccount,
+            final ConnectionRequest request) {
+        return makeConnection(request, true);
+    }
+
+    @Override
+    public void onConference(Connection a, Connection b) {
+        conferenceRemoteConnections(
+                ((TestManagedConnection) a).mRemote,
+                ((TestManagedConnection) b).mRemote);
+    }
+
+    @Override
+    public void onRemoteConferenceAdded(RemoteConference remoteConference) {
+        addConference(new TestManagedConference(remoteConference));
+    }
+
+    Map<RemoteConnection, TestManagedConnection> getManagedConnectionByRemote() {
+        return mManagedConnectionByRemote;
+    }
+
+    private Connection makeConnection(ConnectionRequest request, boolean incoming) {
+        RemoteConnection remote = incoming
+                ? createRemoteIncomingConnection(request.getAccountHandle(), request)
+                : createRemoteOutgoingConnection(request.getAccountHandle(), request);
+        TestManagedConnection local = new TestManagedConnection(remote, false);
+        mManagedConnectionByRemote.put(remote, local);
+        return local;
+    }
+}
diff --git a/testapps/src/com/android/server/telecom/testapps/TestConnectionService.java b/testapps/src/com/android/server/telecom/testapps/TestConnectionService.java
new file mode 100644
index 0000000..d71ef9d
--- /dev/null
+++ b/testapps/src/com/android/server/telecom/testapps/TestConnectionService.java
@@ -0,0 +1,440 @@
+/*
+ * 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.server.telecom.testapps;
+
+import android.content.ComponentName;
+import android.content.Intent;
+import android.media.MediaPlayer;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.telecom.AudioState;
+import android.telecom.Conference;
+import android.telecom.Connection;
+import android.telecom.DisconnectCause;
+import android.telecom.PhoneAccount;
+import android.telecom.ConnectionRequest;
+import android.telecom.ConnectionService;
+import android.telecom.PhoneAccountHandle;
+import android.telecom.TelecomManager;
+import android.telecom.VideoProfile;
+import android.util.Log;
+
+import com.android.server.telecom.testapps.R;
+
+import java.lang.String;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+/**
+ * Service which provides fake calls to test the ConnectionService interface.
+ * TODO: Rename all classes in the directory to Dummy* (e.g., DummyConnectionService).
+ */
+public class TestConnectionService extends ConnectionService {
+    /**
+     * Intent extra used to pass along whether a call is video or audio based on the user's choice
+     * in the notification.
+     */
+    public static final String EXTRA_IS_VIDEO_CALL = "extra_is_video_call";
+
+    public static final String EXTRA_HANDLE = "extra_handle";
+
+    /**
+     * Random number generator used to generate phone numbers.
+     */
+    private Random mRandom = new Random();
+
+    private final class TestConference extends Conference {
+
+        private final Connection.Listener mConnectionListener = new Connection.Listener() {
+            @Override
+            public void onDestroyed(Connection c) {
+                removeConnection(c);
+                if (getConnections().size() == 0) {
+                    setDisconnected(new DisconnectCause(DisconnectCause.REMOTE));
+                    destroy();
+                }
+            }
+        };
+
+        public TestConference(Connection a, Connection b) {
+            super(null);
+            setConnectionCapabilities(
+                    Connection.CAPABILITY_SUPPORT_HOLD |
+                    Connection.CAPABILITY_HOLD |
+                    Connection.CAPABILITY_MUTE |
+                    Connection.CAPABILITY_MANAGE_CONFERENCE);
+            addConnection(a);
+            addConnection(b);
+
+            a.addConnectionListener(mConnectionListener);
+            b.addConnectionListener(mConnectionListener);
+
+            a.setConference(this);
+            b.setConference(this);
+
+            setActive();
+        }
+
+        @Override
+        public void onDisconnect() {
+            for (Connection c : getConnections()) {
+                c.setDisconnected(new DisconnectCause(DisconnectCause.REMOTE));
+                c.destroy();
+            }
+        }
+
+        @Override
+        public void onSeparate(Connection connection) {
+            if (getConnections().contains(connection)) {
+                connection.setConference(null);
+                removeConnection(connection);
+                connection.removeConnectionListener(mConnectionListener);
+            }
+        }
+
+        @Override
+        public void onHold() {
+            for (Connection c : getConnections()) {
+                c.setOnHold();
+            }
+            setOnHold();
+        }
+
+        @Override
+        public void onUnhold() {
+            for (Connection c : getConnections()) {
+                c.setActive();
+            }
+            setActive();
+        }
+    }
+
+    private final class TestConnection extends Connection {
+        private final boolean mIsIncoming;
+
+        /** Used to cleanup camera and media when done with connection. */
+        private TestVideoProvider mTestVideoCallProvider;
+
+        TestConnection(boolean isIncoming) {
+            mIsIncoming = isIncoming;
+            // Assume all calls are video capable.
+            int capabilities = getConnectionCapabilities();
+            capabilities |= CAPABILITY_SUPPORTS_VT_LOCAL;
+            capabilities |= CAPABILITY_MUTE;
+            capabilities |= CAPABILITY_SUPPORT_HOLD;
+            capabilities |= CAPABILITY_HOLD;
+            setConnectionCapabilities(capabilities);
+        }
+
+        void startOutgoing() {
+            setDialing();
+            mHandler.postDelayed(new Runnable() {
+                @Override
+                public void run() {
+                    setActive();
+                    activateCall(TestConnection.this);
+                }
+            }, 4000);
+        }
+
+        /** ${inheritDoc} */
+        @Override
+        public void onAbort() {
+            destroyCall(this);
+            destroy();
+        }
+
+        /** ${inheritDoc} */
+        @Override
+        public void onAnswer(int videoState) {
+            setVideoState(videoState);
+            activateCall(this);
+            setActive();
+            updateConferenceable();
+        }
+
+        /** ${inheritDoc} */
+        @Override
+        public void onPlayDtmfTone(char c) {
+            if (c == '1') {
+                setDialing();
+            }
+        }
+
+        /** ${inheritDoc} */
+        @Override
+        public void onStopDtmfTone() { }
+
+        /** ${inheritDoc} */
+        @Override
+        public void onDisconnect() {
+            setDisconnected(new DisconnectCause(DisconnectCause.REMOTE));
+            destroyCall(this);
+            destroy();
+        }
+
+        /** ${inheritDoc} */
+        @Override
+        public void onHold() {
+            setOnHold();
+        }
+
+        /** ${inheritDoc} */
+        @Override
+        public void onReject() {
+            setDisconnected(new DisconnectCause(DisconnectCause.REJECTED));
+            destroyCall(this);
+            destroy();
+        }
+
+        /** ${inheritDoc} */
+        @Override
+        public void onUnhold() {
+            setActive();
+        }
+
+        @Override
+        public void onAudioStateChanged(AudioState state) { }
+
+        public void setTestVideoCallProvider(TestVideoProvider testVideoCallProvider) {
+            mTestVideoCallProvider = testVideoCallProvider;
+        }
+
+        /**
+         * Stops playback of test videos.
+         */
+        private void stopAndCleanupMedia() {
+            if (mTestVideoCallProvider != null) {
+                mTestVideoCallProvider.stopAndCleanupMedia();
+                mTestVideoCallProvider.stopCamera();
+            }
+        }
+    }
+
+    private final List<TestConnection> mCalls = new ArrayList<>();
+    private final Handler mHandler = new Handler();
+
+    /** Used to play an audio tone during a call. */
+    private MediaPlayer mMediaPlayer;
+
+    @Override
+    public boolean onUnbind(Intent intent) {
+        log("onUnbind");
+        mMediaPlayer = null;
+        return super.onUnbind(intent);
+    }
+
+    @Override
+    public void onConference(Connection a, Connection b) {
+        addConference(new TestConference(a, b));
+    }
+
+    @Override
+    public Connection onCreateOutgoingConnection(
+            PhoneAccountHandle connectionManagerAccount,
+            final ConnectionRequest originalRequest) {
+
+        final Uri handle = originalRequest.getAddress();
+        String number = originalRequest.getAddress().getSchemeSpecificPart();
+        log("call, number: " + number);
+
+        // Crash on 555-DEAD to test call service crashing.
+        if ("5550340".equals(number)) {
+            throw new RuntimeException("Goodbye, cruel world.");
+        }
+
+        Bundle extras = originalRequest.getExtras();
+        String gatewayPackage = extras.getString(TelecomManager.GATEWAY_PROVIDER_PACKAGE);
+        Uri originalHandle = extras.getParcelable(TelecomManager.GATEWAY_ORIGINAL_ADDRESS);
+
+        log("gateway package [" + gatewayPackage + "], original handle [" +
+                originalHandle + "]");
+
+        final TestConnection connection = new TestConnection(false /* isIncoming */);
+        connection.setAddress(handle, TelecomManager.PRESENTATION_ALLOWED);
+
+        // If the number starts with 555, then we handle it ourselves. If not, then we
+        // use a remote connection service.
+        // TODO: Have a special phone number to test the account-picker dialog flow.
+        if (number != null && number.startsWith("555")) {
+            // Normally we would use the original request as is, but for testing purposes, we are
+            // adding ".." to the end of the number to follow its path more easily through the logs.
+            final ConnectionRequest request = new ConnectionRequest(
+                    originalRequest.getAccountHandle(),
+                    Uri.fromParts(handle.getScheme(),
+                    handle.getSchemeSpecificPart() + "..", ""),
+                    originalRequest.getExtras(),
+                    originalRequest.getVideoState());
+
+            addCall(connection);
+            connection.startOutgoing();
+
+            for (Connection c : getAllConnections()) {
+                c.setOnHold();
+            }
+        } else {
+            log("Not a test number");
+        }
+        return connection;
+    }
+
+    @Override
+    public Connection onCreateIncomingConnection(
+            PhoneAccountHandle connectionManagerAccount,
+            final ConnectionRequest request) {
+        PhoneAccountHandle accountHandle = request.getAccountHandle();
+        ComponentName componentName = new ComponentName(this, TestConnectionService.class);
+
+        if (accountHandle != null && componentName.equals(accountHandle.getComponentName())) {
+            final TestConnection connection = new TestConnection(true);
+            // Get the stashed intent extra that determines if this is a video call or audio call.
+            Bundle extras = request.getExtras();
+            boolean isVideoCall = extras.getBoolean(EXTRA_IS_VIDEO_CALL);
+            Uri providedHandle = extras.getParcelable(EXTRA_HANDLE);
+
+            // Use dummy number for testing incoming calls.
+            Uri address = providedHandle == null ?
+                    Uri.fromParts(PhoneAccount.SCHEME_TEL, getDummyNumber(isVideoCall), null)
+                    : providedHandle;
+            if (isVideoCall) {
+                TestVideoProvider testVideoCallProvider =
+                        new TestVideoProvider(getApplicationContext());
+                connection.setVideoProvider(testVideoCallProvider);
+
+                // Keep reference to original so we can clean up the media players later.
+                connection.setTestVideoCallProvider(testVideoCallProvider);
+            }
+
+            int videoState = isVideoCall ?
+                    VideoProfile.VideoState.BIDIRECTIONAL :
+                    VideoProfile.VideoState.AUDIO_ONLY;
+            connection.setVideoState(videoState);
+            connection.setAddress(address, TelecomManager.PRESENTATION_ALLOWED);
+
+            addCall(connection);
+
+            ConnectionRequest newRequest = new ConnectionRequest(
+                    request.getAccountHandle(),
+                    address,
+                    request.getExtras(),
+                    videoState);
+            connection.setVideoState(videoState);
+            return connection;
+        } else {
+            return Connection.createFailedConnection(new DisconnectCause(DisconnectCause.ERROR,
+                    "Invalid inputs: " + accountHandle + " " + componentName));
+        }
+    }
+
+    @Override
+    public Connection onCreateUnknownConnection(PhoneAccountHandle connectionManagerPhoneAccount,
+            final ConnectionRequest request) {
+        PhoneAccountHandle accountHandle = request.getAccountHandle();
+        ComponentName componentName = new ComponentName(this, TestConnectionService.class);
+        if (accountHandle != null && componentName.equals(accountHandle.getComponentName())) {
+            final TestConnection connection = new TestConnection(false);
+            final Bundle extras = request.getExtras();
+            final Uri providedHandle = extras.getParcelable(EXTRA_HANDLE);
+
+            Uri handle = providedHandle == null ?
+                    Uri.fromParts(PhoneAccount.SCHEME_TEL, getDummyNumber(false), null)
+                    : providedHandle;
+
+            connection.setAddress(handle,  TelecomManager.PRESENTATION_ALLOWED);
+            connection.setDialing();
+
+            addCall(connection);
+            return connection;
+        } else {
+            return Connection.createFailedConnection(new DisconnectCause(DisconnectCause.ERROR,
+                    "Invalid inputs: " + accountHandle + " " + componentName));
+        }
+    }
+
+    private void activateCall(TestConnection connection) {
+        if (mMediaPlayer == null) {
+            mMediaPlayer = createMediaPlayer();
+        }
+        if (!mMediaPlayer.isPlaying()) {
+            mMediaPlayer.start();
+        }
+    }
+
+    private void destroyCall(TestConnection connection) {
+        mCalls.remove(connection);
+
+        // Ensure any playing media and camera resources are released.
+        connection.stopAndCleanupMedia();
+
+        // Stops audio if there are no more calls.
+        if (mCalls.isEmpty() && mMediaPlayer != null && mMediaPlayer.isPlaying()) {
+            mMediaPlayer.stop();
+            mMediaPlayer.release();
+            mMediaPlayer = createMediaPlayer();
+        }
+
+        updateConferenceable();
+    }
+
+    private void addCall(TestConnection connection) {
+        mCalls.add(connection);
+        updateConferenceable();
+    }
+
+    private void updateConferenceable() {
+        List<Connection> freeConnections = new ArrayList<>();
+        freeConnections.addAll(mCalls);
+        for (int i = 0; i < freeConnections.size(); i++) {
+            if (freeConnections.get(i).getConference() != null) {
+                freeConnections.remove(i);
+            }
+        }
+        for (int i = 0; i < freeConnections.size(); i++) {
+            Connection c = freeConnections.remove(i);
+            c.setConferenceableConnections(freeConnections);
+            freeConnections.add(i, c);
+        }
+    }
+
+    private MediaPlayer createMediaPlayer() {
+        // Prepare the media player to play a tone when there is a call.
+        MediaPlayer mediaPlayer = MediaPlayer.create(getApplicationContext(), R.raw.beep_boop);
+        mediaPlayer.setLooping(true);
+        return mediaPlayer;
+    }
+
+    private static void log(String msg) {
+        Log.w("telecomtestcs", "[TestConnectionService] " + msg);
+    }
+
+    /**
+     * Generates a random phone number of format 555YXXX.  Where Y will be {@code 1} if the
+     * phone number is for a video call and {@code 0} for an audio call.  XXX is a randomly
+     * generated phone number.
+     *
+     * @param isVideo {@code True} if the call is a video call.
+     * @return The phone number.
+     */
+    private String getDummyNumber(boolean isVideo) {
+        int videoDigit = isVideo ? 1 : 0;
+        int number = mRandom.nextInt(999);
+        return String.format("555%s%03d", videoDigit, number);
+    }
+}
+
diff --git a/testapps/src/com/android/server/telecom/testapps/TestDialerActivity.java b/testapps/src/com/android/server/telecom/testapps/TestDialerActivity.java
new file mode 100644
index 0000000..71c375a
--- /dev/null
+++ b/testapps/src/com/android/server/telecom/testapps/TestDialerActivity.java
@@ -0,0 +1,56 @@
+package com.android.server.telecom.testapps;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.EditText;
+
+import com.android.server.telecom.testapps.R;
+
+public class TestDialerActivity extends Activity {
+    private EditText mNumberView;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.testdialer_main);
+        findViewById(R.id.set_default_button).setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                setDefault();
+            }
+        });
+        findViewById(R.id.place_call_button).setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                placeCall();
+            }
+        });
+
+        mNumberView = (EditText) findViewById(R.id.number);
+        updateEditTextWithNumber();
+    }
+
+    @Override
+    protected void onNewIntent(Intent intent) {
+        super.onNewIntent(intent);
+        updateEditTextWithNumber();
+    }
+
+    private void updateEditTextWithNumber() {
+        Intent intent = getIntent();
+        if (intent != null) {
+            mNumberView.setText(intent.getDataString());
+        }
+    }
+
+    private void setDefault() {
+        // TODO: Send a request to become the default dialer application
+    }
+
+    private void placeCall() {
+        // TODO: Place a call with the number entered in the number field
+    }
+}
diff --git a/testapps/src/com/android/server/telecom/testapps/TestInCallServiceImpl.java b/testapps/src/com/android/server/telecom/testapps/TestInCallServiceImpl.java
new file mode 100644
index 0000000..1d7e805
--- /dev/null
+++ b/testapps/src/com/android/server/telecom/testapps/TestInCallServiceImpl.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2014 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.testapps;
+
+import android.telecom.InCallService;
+import android.telecom.Phone;
+import android.util.Log;
+
+import java.lang.Override;
+import java.lang.String;
+
+/**
+ * Test In-Call service implementation.  Logs incoming events.  Mainly used to test binding to
+ * multiple {@link InCallService} implementations.
+ */
+public class TestInCallServiceImpl extends InCallService {
+    private static final String TAG = "TestInCallServiceImpl";
+
+    private Phone mPhone;
+
+    private Phone.Listener mPhoneListener = new Phone.Listener() {
+        @Override
+        public void onCallAdded(Phone phone, android.telecom.Call call) {
+            Log.i(TAG, "onCallAdded: "+call.toString());
+        }
+        @Override
+        public void onCallRemoved(Phone phone, android.telecom.Call call) {
+            Log.i(TAG, "onCallRemoved: "+call.toString());
+        }
+    };
+
+    @Override
+    public void onPhoneCreated(Phone phone) {
+        Log.i(TAG, "onPhoneCreated");
+        mPhone = phone;
+        mPhone.addListener(mPhoneListener);
+
+    }
+
+    @Override
+    public void onPhoneDestroyed(Phone phone) {
+        Log.i(TAG, "onPhoneDestroyed");
+        mPhone.removeListener(mPhoneListener);
+        mPhone = null;
+    }
+}
diff --git a/testapps/src/com/android/server/telecom/testapps/TestManagedVideoProvider.java b/testapps/src/com/android/server/telecom/testapps/TestManagedVideoProvider.java
new file mode 100644
index 0000000..649d0c0
--- /dev/null
+++ b/testapps/src/com/android/server/telecom/testapps/TestManagedVideoProvider.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2014 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.testapps;
+
+import android.telecom.CameraCapabilities;
+import android.telecom.Connection;
+import android.telecom.RemoteConnection;
+import android.telecom.VideoProfile;
+import android.view.Surface;
+
+public class TestManagedVideoProvider extends Connection.VideoProvider {
+
+    private final RemoteConnection.VideoProvider.Listener mRemoteListener =
+            new RemoteConnection.VideoProvider.Listener() {
+        @Override
+        public void onReceiveSessionModifyRequest(RemoteConnection.VideoProvider rvp,
+                VideoProfile videoProfile) {
+            super.onReceiveSessionModifyRequest(rvp, videoProfile);
+        }
+
+        @Override
+        public void onReceiveSessionModifyResponse(RemoteConnection.VideoProvider rvp,
+        int status,
+        VideoProfile requestedProfile, VideoProfile responseProfile) {
+            super.onReceiveSessionModifyResponse(rvp, status, requestedProfile,
+                    responseProfile);
+        }
+
+        @Override
+        public void onHandleCallSessionEvent(RemoteConnection.VideoProvider rvp, int event) {
+            super.onHandleCallSessionEvent(rvp, event);
+        }
+
+        @Override
+        public void onPeerDimensionsChanged(RemoteConnection.VideoProvider rvp, int width,
+        int height) {
+            super.onPeerDimensionsChanged(rvp, width, height);
+        }
+
+        @Override
+        public void onCallDataUsageChanged(RemoteConnection.VideoProvider rvp, int dataUsage) {
+            super.onCallDataUsageChanged(rvp, dataUsage);
+        }
+
+        @Override
+        public void onCameraCapabilitiesChanged(RemoteConnection.VideoProvider rvp,
+                CameraCapabilities cameraCapabilities) {
+            super.onCameraCapabilitiesChanged(rvp, cameraCapabilities);
+        }
+    };
+
+    private final RemoteConnection.VideoProvider mRemoteVideoProvider;
+
+    public TestManagedVideoProvider(RemoteConnection.VideoProvider remoteVideoProvider) {
+        mRemoteVideoProvider = remoteVideoProvider;
+        mRemoteVideoProvider.addListener(mRemoteListener);
+    }
+
+    @Override
+    public void onSetCamera(String cameraId) {
+        mRemoteVideoProvider.setCamera(cameraId);
+    }
+
+    @Override
+    public void onSetPreviewSurface(Surface surface) {
+        mRemoteVideoProvider.setPreviewSurface(surface);
+    }
+
+    @Override
+    public void onSetDisplaySurface(Surface surface) {
+        mRemoteVideoProvider.setDisplaySurface(surface);
+    }
+
+    @Override
+    public void onSetDeviceOrientation(int rotation) {
+        mRemoteVideoProvider.setDeviceOrientation(rotation);
+    }
+
+    @Override
+    public void onSetZoom(float value) {
+        mRemoteVideoProvider.setZoom(value);
+    }
+
+    @Override
+    public void onSendSessionModifyRequest(VideoProfile requestProfile) {
+        mRemoteVideoProvider.sendSessionModifyRequest(requestProfile);
+    }
+
+    @Override
+    public void onSendSessionModifyResponse(VideoProfile responseProfile) {
+        mRemoteVideoProvider.sendSessionModifyResponse(responseProfile);
+    }
+
+    @Override
+    public void onRequestCameraCapabilities() {
+        mRemoteVideoProvider.requestCameraCapabilities();
+    }
+
+    @Override
+    public void onRequestConnectionDataUsage() {
+        mRemoteVideoProvider.requestCallDataUsage();
+    }
+
+    @Override
+    public void onSetPauseImage(String uri) {
+        mRemoteVideoProvider.setPauseImage(uri);
+    }
+}
diff --git a/testapps/src/com/android/server/telecom/testapps/TestVideoProvider.java b/testapps/src/com/android/server/telecom/testapps/TestVideoProvider.java
new file mode 100644
index 0000000..d372e46
--- /dev/null
+++ b/testapps/src/com/android/server/telecom/testapps/TestVideoProvider.java
@@ -0,0 +1,334 @@
+/*
+ * Copyright (C) 2014 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.testapps;
+
+import com.android.ex.camera2.blocking.BlockingCameraManager;
+import com.android.ex.camera2.blocking.BlockingCameraManager.BlockingOpenException;
+import com.android.ex.camera2.blocking.BlockingSessionCallback;
+import com.android.server.telecom.testapps.R;
+
+import android.content.Context;
+import android.graphics.SurfaceTexture;
+import android.hardware.camera2.CameraAccessException;
+import android.hardware.camera2.CameraCaptureSession;
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraDevice;
+import android.hardware.camera2.CameraManager;
+import android.hardware.camera2.CaptureFailure;
+import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.TotalCaptureResult;
+import android.hardware.camera2.params.StreamConfigurationMap;
+import android.media.MediaPlayer;
+import android.os.Handler;
+import android.telecom.CameraCapabilities;
+import android.telecom.Connection;
+import android.telecom.VideoProfile;
+import android.text.TextUtils;
+import android.util.Log;
+import android.util.Size;
+import android.view.Surface;
+
+import java.lang.IllegalArgumentException;
+import java.lang.String;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+/**
+ * Implements the VideoCallProvider.
+ */
+public class TestVideoProvider extends Connection.VideoProvider {
+    private CameraCapabilities mCameraCapabilities;
+    private Random random;
+    private Surface mDisplaySurface;
+    private Surface mPreviewSurface;
+    private Context mContext;
+    /** Used to play incoming video during a call. */
+    private MediaPlayer mIncomingMediaPlayer;
+
+    private CameraManager mCameraManager;
+    private CameraDevice mCameraDevice;
+    private CameraCaptureSession mCameraSession;
+    private CameraThread mLooperThread;
+
+    private String mCameraId;
+
+    private static final long SESSION_TIMEOUT_MS = 2000;
+
+    public TestVideoProvider(Context context) {
+        mContext = context;
+        random = new Random();
+        mCameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
+    }
+
+    @Override
+    public void onSetCamera(String cameraId) {
+        log("Set camera to " + cameraId);
+        mCameraId = cameraId;
+
+        stopCamera();
+        // Get the capabilities of the camera
+        setCameraCapabilities(mCameraId);
+    }
+
+    @Override
+    public void onSetPreviewSurface(Surface surface) {
+        log("Set preview surface " + (surface == null ? "unset" : "set"));
+        if (mPreviewSurface != null) {
+            stopCamera();
+        }
+
+        mPreviewSurface = surface;
+
+        if (!TextUtils.isEmpty(mCameraId) && mPreviewSurface != null) {
+            startCamera(mCameraId);
+        }
+    }
+
+    @Override
+    public void onSetDisplaySurface(Surface surface) {
+        log("Set display surface " + (surface == null ? "unset" : "set"));
+        mDisplaySurface = surface;
+
+        if (mDisplaySurface != null) {
+            if (mIncomingMediaPlayer == null) {
+                // For a Rick-Rolling good time use R.raw.test_video
+                mIncomingMediaPlayer = createMediaPlayer(mDisplaySurface, R.raw.test_pattern);
+            }
+            mIncomingMediaPlayer.setSurface(mDisplaySurface);
+            if (!mIncomingMediaPlayer.isPlaying()) {
+                mIncomingMediaPlayer.start();
+            }
+        } else {
+            if (mIncomingMediaPlayer != null) {
+                mIncomingMediaPlayer.stop();
+                mIncomingMediaPlayer.setSurface(null);
+            }
+        }
+    }
+
+    @Override
+    public void onSetDeviceOrientation(int rotation) {
+        log("Set device orientation " + rotation);
+    }
+
+    /**
+     * Sets the zoom value, creating a new CallCameraCapabalities object. If the zoom value is
+     * non-positive, assume that zoom is not supported.
+     */
+    @Override
+    public void onSetZoom(float value) {
+        log("Set zoom to " + value);
+    }
+
+    /**
+     * "Sends" a request with a video call profile. Assumes that this response succeeds and sends
+     * the response back via the CallVideoClient.
+     */
+    @Override
+    public void onSendSessionModifyRequest(VideoProfile requestProfile) {
+        log("Sent session modify request");
+
+        VideoProfile responseProfile = new VideoProfile(
+                requestProfile.getVideoState(), requestProfile.getQuality());
+        receiveSessionModifyResponse(
+                SESSION_MODIFY_REQUEST_SUCCESS,
+                requestProfile,
+                responseProfile);
+    }
+
+    @Override
+    public void onSendSessionModifyResponse(VideoProfile responseProfile) {
+
+    }
+
+    /**
+     * Returns a CallCameraCapabilities object without supporting zoom.
+     */
+    @Override
+    public void onRequestCameraCapabilities() {
+        log("Requested camera capabilities");
+        changeCameraCapabilities(mCameraCapabilities);
+    }
+
+    /**
+     * Randomly reports data usage of value ranging from 10MB to 60MB.
+     */
+    @Override
+    public void onRequestConnectionDataUsage() {
+        log("Requested connection data usage");
+        int dataUsageKb = (10 *1024) + random.nextInt(50 * 1024);
+        changeCallDataUsage(dataUsageKb);
+    }
+
+    /**
+     * We do not have a need to set a paused image.
+     */
+    @Override
+    public void onSetPauseImage(String uri) {
+        // Not implemented.
+    }
+
+    /**
+     * Stop and cleanup the media players used for test video playback.
+     */
+    public void stopAndCleanupMedia() {
+        if (mIncomingMediaPlayer != null) {
+            mIncomingMediaPlayer.setSurface(null);
+            mIncomingMediaPlayer.stop();
+            mIncomingMediaPlayer.release();
+            mIncomingMediaPlayer = null;
+        }
+    }
+
+    private static void log(String msg) {
+        Log.w("TestCallVideoProvider", "[TestCallServiceProvider] " + msg);
+    }
+
+    /**
+     * Creates a media player to play a video resource on a surface.
+     * @param surface The surface.
+     * @param videoResource The video resource.
+     * @return The {@code MediaPlayer}.
+     */
+    private MediaPlayer createMediaPlayer(Surface surface, int videoResource) {
+        MediaPlayer mediaPlayer = MediaPlayer.create(mContext.getApplicationContext(),
+                videoResource);
+        mediaPlayer.setSurface(surface);
+        mediaPlayer.setLooping(true);
+        return mediaPlayer;
+    }
+
+    /**
+     * Starts displaying the camera image on the preview surface.
+     *
+     * @param cameraId
+     */
+    private void startCamera(String cameraId) {
+        stopCamera();
+
+        if (mPreviewSurface == null) {
+            return;
+        }
+
+        // Configure a looper thread.
+        mLooperThread = new CameraThread();
+        Handler mHandler;
+        try {
+            mHandler = mLooperThread.start();
+        } catch (Exception e) {
+            log("Exception: " + e);
+            return;
+        }
+
+        // Get the camera device.
+        try {
+            BlockingCameraManager blockingCameraManager = new BlockingCameraManager(mCameraManager);
+            mCameraDevice = blockingCameraManager.openCamera(cameraId, null /* listener */,
+                    mHandler);
+        } catch (CameraAccessException e) {
+            log("CameraAccessException: " + e);
+            return;
+        } catch (BlockingOpenException be) {
+            log("BlockingOpenException: " + be);
+            return;
+        }
+
+        // Create a capture session to get the preview and display it on the surface.
+        List<Surface> surfaces = new ArrayList<Surface>();
+        surfaces.add(mPreviewSurface);
+        CaptureRequest.Builder mCaptureRequest = null;
+        try {
+            BlockingSessionCallback blkSession = new BlockingSessionCallback();
+            mCameraDevice.createCaptureSession(surfaces, blkSession, mHandler);
+            mCaptureRequest = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+            mCaptureRequest.addTarget(mPreviewSurface);
+            mCameraSession = blkSession.waitAndGetSession(SESSION_TIMEOUT_MS);
+        } catch (CameraAccessException e) {
+            log("CameraAccessException: " + e);
+            return;
+        }
+
+        // Keep repeating
+        try {
+            mCameraSession.setRepeatingRequest(mCaptureRequest.build(), new CameraCaptureCallback(),
+                    mHandler);
+        } catch (CameraAccessException e) {
+            log("CameraAccessException: " + e);
+            return;
+        }
+    }
+
+    /**
+     * Stops the camera and looper thread.
+     */
+    public void stopCamera() {
+        try {
+            if (mCameraDevice != null) {
+                mCameraDevice.close();
+                mCameraDevice = null;
+            }
+            if (mLooperThread != null) {
+                mLooperThread.close();
+                mLooperThread = null;
+            }
+        } catch (Exception e) {
+           log("stopCamera Exception: "+e.toString());
+        }
+    }
+
+    /**
+     * Required listener for camera capture events.
+     */
+    private class CameraCaptureCallback extends CameraCaptureSession.CaptureCallback {
+        @Override
+        public void onCaptureCompleted(CameraCaptureSession camera, CaptureRequest request,
+                TotalCaptureResult result) {
+        }
+
+        @Override
+        public void onCaptureFailed(CameraCaptureSession camera, CaptureRequest request,
+                CaptureFailure failure) {
+        }
+    }
+
+    /**
+     * Uses the camera manager to retrieve the camera capabilities for the chosen camera.
+     *
+     * @param cameraId The camera ID to get the capabilities for.
+     */
+    private void setCameraCapabilities(String cameraId) {
+        CameraManager cameraManager = (CameraManager) mContext.getSystemService(
+                Context.CAMERA_SERVICE);
+
+        CameraCharacteristics c = null;
+        try {
+            c = cameraManager.getCameraCharacteristics(cameraId);
+        } catch (IllegalArgumentException | CameraAccessException e) {
+            // Ignoring camera problems.
+        }
+        if (c != null) {
+            // Get the video size for the camera
+            StreamConfigurationMap map = c.get(
+                    CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
+            Size previewSize = map.getOutputSizes(SurfaceTexture.class)[0];
+
+            mCameraCapabilities = new CameraCapabilities(true, 1.0f, previewSize.getWidth(),
+                    previewSize.getHeight());
+        }
+    }
+}
