diff --git a/tests/Android.mk b/tests/Android.mk
index 44575f5..ca1b835 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -38,11 +38,9 @@
     --auto-add-overlay \
     --extra-packages com.android.server.telecom
 
-LOCAL_PACKAGE_NAME := TelecomTests
+LOCAL_PACKAGE_NAME := TelecomUnitTests
 LOCAL_CERTIFICATE := platform
 
 LOCAL_MODULE_TAGS := tests
 
-LOCAL_INSTRUMENTATION_FOR := Telecom
-
 include $(BUILD_PACKAGE)
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
index 0c632ec..6a08c63 100644
--- a/tests/AndroidManifest.xml
+++ b/tests/AndroidManifest.xml
@@ -30,94 +30,6 @@
     <application android:label="@string/app_name"
                  android:debuggable="true">
         <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.tests.MockConnectionService"
-                 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>
 
     <!--
diff --git a/tests/res/layout/testdialer_main.xml b/tests/res/layout/testdialer_main.xml
deleted file mode 100644
index a5453fc..0000000
--- a/tests/res/layout/testdialer_main.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?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/tests/res/raw/beep_boop.ogg b/tests/res/raw/beep_boop.ogg
deleted file mode 100644
index 83148f0..0000000
--- a/tests/res/raw/beep_boop.ogg
+++ /dev/null
Binary files differ
diff --git a/tests/res/raw/outgoing_video.mp4 b/tests/res/raw/outgoing_video.mp4
deleted file mode 100644
index 3e4f1cb..0000000
--- a/tests/res/raw/outgoing_video.mp4
+++ /dev/null
Binary files differ
diff --git a/tests/res/raw/test_pattern.mp4 b/tests/res/raw/test_pattern.mp4
deleted file mode 100644
index 401066f..0000000
--- a/tests/res/raw/test_pattern.mp4
+++ /dev/null
Binary files differ
diff --git a/tests/res/raw/test_video.mp4 b/tests/res/raw/test_video.mp4
deleted file mode 100644
index 1a454b3..0000000
--- a/tests/res/raw/test_video.mp4
+++ /dev/null
Binary files differ
diff --git a/tests/res/values/donottranslate_strings.xml b/tests/res/values/donottranslate_strings.xml
index 91d8628..0a6f5c4 100644
--- a/tests/res/values/donottranslate_strings.xml
+++ b/tests/res/values/donottranslate_strings.xml
@@ -16,17 +16,5 @@
 
 <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>
+    <string name="app_name">Telecom Unit Tests</string>
 </resources>
diff --git a/tests/src/com/android/server/telecom/testapps/CallNotificationReceiver.java b/tests/src/com/android/server/telecom/testapps/CallNotificationReceiver.java
deleted file mode 100644
index a835bf1..0000000
--- a/tests/src/com/android/server/telecom/testapps/CallNotificationReceiver.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * 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/tests/src/com/android/server/telecom/testapps/CallServiceNotifier.java b/tests/src/com/android/server/telecom/testapps/CallServiceNotifier.java
deleted file mode 100644
index d25cc2d..0000000
--- a/tests/src/com/android/server/telecom/testapps/CallServiceNotifier.java
+++ /dev/null
@@ -1,298 +0,0 @@
-/*
- * 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.tests.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/tests/src/com/android/server/telecom/testapps/CameraThread.java b/tests/src/com/android/server/telecom/testapps/CameraThread.java
deleted file mode 100644
index fbcd6b2..0000000
--- a/tests/src/com/android/server/telecom/testapps/CameraThread.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * 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/tests/src/com/android/server/telecom/testapps/TestCallActivity.java b/tests/src/com/android/server/telecom/testapps/TestCallActivity.java
deleted file mode 100644
index 6f4ae20..0000000
--- a/tests/src/com/android/server/telecom/testapps/TestCallActivity.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * 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/tests/src/com/android/server/telecom/testapps/TestConnectionManager.java b/tests/src/com/android/server/telecom/testapps/TestConnectionManager.java
deleted file mode 100644
index a27be39..0000000
--- a/tests/src/com/android/server/telecom/testapps/TestConnectionManager.java
+++ /dev/null
@@ -1,336 +0,0 @@
-/*
- * 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/tests/src/com/android/server/telecom/testapps/TestConnectionService.java b/tests/src/com/android/server/telecom/testapps/TestConnectionService.java
deleted file mode 100644
index 2e01276..0000000
--- a/tests/src/com/android/server/telecom/testapps/TestConnectionService.java
+++ /dev/null
@@ -1,440 +0,0 @@
-/*
- * 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.tests.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/tests/src/com/android/server/telecom/testapps/TestDialerActivity.java b/tests/src/com/android/server/telecom/testapps/TestDialerActivity.java
deleted file mode 100644
index 7a9ed3f..0000000
--- a/tests/src/com/android/server/telecom/testapps/TestDialerActivity.java
+++ /dev/null
@@ -1,56 +0,0 @@
-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.tests.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/tests/src/com/android/server/telecom/testapps/TestInCallServiceImpl.java b/tests/src/com/android/server/telecom/testapps/TestInCallServiceImpl.java
deleted file mode 100644
index 1d7e805..0000000
--- a/tests/src/com/android/server/telecom/testapps/TestInCallServiceImpl.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * 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/tests/src/com/android/server/telecom/testapps/TestManagedVideoProvider.java b/tests/src/com/android/server/telecom/testapps/TestManagedVideoProvider.java
deleted file mode 100644
index 649d0c0..0000000
--- a/tests/src/com/android/server/telecom/testapps/TestManagedVideoProvider.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * 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/tests/src/com/android/server/telecom/testapps/TestVideoProvider.java b/tests/src/com/android/server/telecom/testapps/TestVideoProvider.java
deleted file mode 100644
index 494eacc..0000000
--- a/tests/src/com/android/server/telecom/testapps/TestVideoProvider.java
+++ /dev/null
@@ -1,334 +0,0 @@
-/*
- * 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.tests.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());
-        }
-    }
-}
diff --git a/tests/src/com/android/server/telecom/tests/PhoneAccountRegistrarTest.java b/tests/src/com/android/server/telecom/tests/PhoneAccountRegistrarTest.java
index a980b48..a5fc04c 100644
--- a/tests/src/com/android/server/telecom/tests/PhoneAccountRegistrarTest.java
+++ b/tests/src/com/android/server/telecom/tests/PhoneAccountRegistrarTest.java
@@ -67,11 +67,11 @@
     @Override
     public void tearDown() throws Exception {
         mRegistrar = null;
-        mComponentContextFixture = null;
         new File(
                 mComponentContextFixture.getTestDouble().getApplicationContext().getFilesDir(),
                 FILE_NAME)
                 .delete();
+        mComponentContextFixture = null;
         super.tearDown();
     }
 
