diff --git a/testapps/Android.mk b/testapps/Android.mk
new file mode 100644
index 0000000..74928d0
--- /dev/null
+++ b/testapps/Android.mk
@@ -0,0 +1,32 @@
+#
+# 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-support-v4 \
+        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..0589a8e
--- /dev/null
+++ b/testapps/src/com/android/server/telecom/testapps/CallNotificationReceiver.java
@@ -0,0 +1,115 @@
+/*
+ * 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.support.v4.content.LocalBroadcastManager;
+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);
+    }
+
+    public static void hangupCalls(Context context) {
+        Log.i(TAG, "Hanging up all calls");
+        LocalBroadcastManager.getInstance(context).sendBroadcast(
+                new Intent(TestCallActivity.ACTION_HANGUP_CALLS));
+    }
+}
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..38d2565
--- /dev/null
+++ b/testapps/src/com/android/server/telecom/testapps/TestCallActivity.java
@@ -0,0 +1,68 @@
+/*
+ * 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";
+
+    /*
+     * Hang up any test incoming calls, to simulate the user missing a call.
+     */
+    public static final String ACTION_HANGUP_CALLS =
+            "android.telecom.testapps.ACTION_HANGUP_CALLS";
+
+    @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 if (ACTION_HANGUP_CALLS.equals(action)) {
+            CallNotificationReceiver.hangupCalls(this);
+        } 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..b99ee13
--- /dev/null
+++ b/testapps/src/com/android/server/telecom/testapps/TestConnectionManager.java
@@ -0,0 +1,341 @@
+/*
+ * 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);
+            }
+
+            @Override
+            public void onCallSubstateChanged(RemoteConnection connection, int callSubstate) {
+                setCallSubstate(callSubstate);
+            }
+        };
+
+        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..9f5d579
--- /dev/null
+++ b/testapps/src/com/android/server/telecom/testapps/TestConnectionService.java
@@ -0,0 +1,468 @@
+/*
+ * 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.content.IntentFilter;
+import android.media.MediaPlayer;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.support.v4.content.LocalBroadcastManager;
+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;
+
+        private BroadcastReceiver mHangupReceiver = new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                setDisconnected(new DisconnectCause(DisconnectCause.MISSED));
+                destroyCall(TestConnection.this);
+                destroy();
+            }
+        };
+
+        TestConnection(boolean isIncoming) {
+            mIsIncoming = isIncoming;
+            // Assume all calls are video capable.
+            int capabilities = getConnectionCapabilities();
+            capabilities |= CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL;
+            capabilities |= CAPABILITY_MUTE;
+            capabilities |= CAPABILITY_SUPPORT_HOLD;
+            capabilities |= CAPABILITY_HOLD;
+            setConnectionCapabilities(capabilities);
+
+            LocalBroadcastManager.getInstance(getApplicationContext()).registerReceiver(
+                    mHangupReceiver, new IntentFilter(TestCallActivity.ACTION_HANGUP_CALLS));
+        }
+
+        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;
+        }
+
+        public void cleanup() {
+            LocalBroadcastManager.getInstance(getApplicationContext()).unregisterReceiver(
+                    mHangupReceiver);
+        }
+
+        /**
+         * 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());
+            connection.setVideoState(originalRequest.getVideoState());
+            maybeAddVideoProvider(connection);
+            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;
+
+            int videoState = isVideoCall ?
+                    VideoProfile.VideoState.BIDIRECTIONAL :
+                    VideoProfile.VideoState.AUDIO_ONLY;
+            connection.setVideoState(videoState);
+            connection.setAddress(address, TelecomManager.PRESENTATION_ALLOWED);
+
+            maybeAddVideoProvider(connection);
+
+            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 maybeAddVideoProvider(TestConnection connection) {
+        if (connection.getVideoState() == VideoProfile.VideoState.BIDIRECTIONAL) {
+            TestVideoProvider testVideoCallProvider =
+                    new TestVideoProvider(getApplicationContext());
+            connection.setVideoProvider(testVideoCallProvider);
+
+            // Keep reference to original so we can clean up the media players later.
+            connection.setTestVideoCallProvider(testVideoCallProvider);
+        }
+    }
+
+    private void activateCall(TestConnection connection) {
+        if (mMediaPlayer == null) {
+            mMediaPlayer = createMediaPlayer();
+        }
+        if (!mMediaPlayer.isPlaying()) {
+            mMediaPlayer.start();
+        }
+    }
+
+    private void destroyCall(TestConnection connection) {
+        connection.cleanup();
+        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 = null;
+        }
+
+        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..68206e4
--- /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, long 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..2dad471
--- /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");
+        long 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(previewSize.getWidth(),
+                    previewSize.getHeight());
+        }
+    }
+}
