Remove CallServiceProvider and CallServiceDescript: Impl do not merge

This CL removes usage CallServiceProvider. Instead
ConnectionServiceRepository uses package manager to look up
all ConnectionService implementations.

Everywhere we used CallServiceDescriptors has now been
replaced by ComponentNames.

Change-Id: I2e40c5c64c0d242dc41b680943d7e9209142db5b
(cherry picked from commit 10e6050b2186650fbc18b0aa62b2e7d74e0aa80a)
diff --git a/src/com/android/telecomm/BaseRepository.java b/src/com/android/telecomm/BaseRepository.java
deleted file mode 100644
index 4b913ee..0000000
--- a/src/com/android/telecomm/BaseRepository.java
+++ /dev/null
@@ -1,94 +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.telecomm;
-
-import android.content.ComponentName;
-
-import com.google.common.collect.Maps;
-
-import java.util.Collection;
-import java.util.Map;
-
-/**
- * Looks up, caches and returns binder services. Ensures that there is only one instance of a
- * service per component.
- */
-abstract class BaseRepository<ServiceClass extends ServiceBinder<?>>
-        implements ServiceBinder.Listener<ServiceClass> {
-
-    /**
-     * Callback interface for notifying when a lookup has completed.
-     */
-    interface LookupCallback<ServiceClass> {
-        void onComplete(Collection<ServiceClass> services);
-    }
-
-    /** Map of cached services. */
-    private final Map<ComponentName, ServiceClass> mServiceCache = Maps.newHashMap();
-
-    /**
-     * Removes the specified service from the cache when the service unbinds.
-     *
-     * {@inheritDoc}
-     */
-    @Override
-    public void onUnbind(ServiceClass service) {
-        mServiceCache.remove(service.getComponentName());
-    }
-
-    /**
-     * Looks up service implementations.
-     *
-     * @param callback The callback on which to return execution when complete.
-     */
-    final void lookupServices(final LookupCallback<ServiceClass> callback) {
-        onLookupServices(callback);
-    }
-
-    /**
-     * Performs the grunt work of the lookup, to be implemented by the subclass.
-     *
-     * @param callback The callback on which to return execution when complete.
-     */
-    protected abstract void onLookupServices(LookupCallback<ServiceClass> callback);
-
-    /**
-     * Creates a new service implementation for the specified component.
-     *
-     * @param componentName The component name for the service.
-     * @param param Sub-class-provided parameter, see {@link #getService}.
-     */
-    protected abstract ServiceClass onCreateNewServiceWrapper(
-            ComponentName componentName, Object param);
-
-    /**
-     * Returns a cached implementation of the service. If no cached version exists, makes a
-     * request to the subclass for a new implementation which will then be cached and returned.
-     *
-     * @param componentName The component name for the service.
-     * @param param Sub-class-provided parameter.
-     */
-    protected final ServiceClass getService(ComponentName componentName, Object param) {
-        ServiceClass service = mServiceCache.get(componentName);
-        if (service == null) {
-            service = onCreateNewServiceWrapper(componentName, param);
-            service.addListener(this);
-            mServiceCache.put(componentName, service);
-        }
-        return service;
-    }
-}
diff --git a/src/com/android/telecomm/Call.java b/src/com/android/telecomm/Call.java
index c1c7eb4..e6a3dbc 100644
--- a/src/com/android/telecomm/Call.java
+++ b/src/com/android/telecomm/Call.java
@@ -16,6 +16,7 @@
 
 package com.android.telecomm;
 
+import android.content.ComponentName;
 import android.content.ContentUris;
 import android.graphics.Bitmap;
 import android.graphics.drawable.Drawable;
@@ -24,7 +25,6 @@
 import android.os.Handler;
 import android.provider.ContactsContract.Contacts;
 import android.telecomm.CallPropertyPresentation;
-import android.telecomm.CallServiceDescriptor;
 import android.telecomm.CallState;
 import android.telecomm.ConnectionRequest;
 import android.telecomm.GatewayInfo;
@@ -215,9 +215,6 @@
 
     private OutgoingCallProcessor mOutgoingCallProcessor;
 
-    // TODO(santoscordon): The repositories should be changed into singleton types.
-    private CallServiceRepository mCallServiceRepository;
-
     /** Caller information retrieved from the latest contact query. */
     private CallerInfo mCallerInfo;
 
@@ -250,15 +247,6 @@
     private StatusHints mStatusHints;
 
     /**
-     * Creates an empty call object.
-     *
-     * @param isIncoming True if this is an incoming call.
-     */
-    Call(boolean isIncoming, boolean isConference) {
-        this(null, null, null, isIncoming, isConference);
-    }
-
-    /**
      * Persists the specified parameters and initializes the new instance.
      *
      * @param handle The handle to dial.
@@ -388,7 +376,7 @@
     /**
      * @param disconnectCause The reason for the disconnection, any of
      *         {@link android.telephony.DisconnectCause}.
-     * @param disconnectMessage Optional call-service-provided message about the disconnect.
+     * @param disconnectMessage Optional message about the disconnect.
      */
     void setDisconnectCause(int disconnectCause, String disconnectMessage) {
         // TODO: Consider combining this method with a setDisconnected() method that is totally
@@ -514,13 +502,9 @@
     /**
      * Starts the incoming call flow through the switchboard. When switchboard completes, it will
      * invoke handle[Un]SuccessfulIncomingCall.
-     *
-     * @param descriptor The relevant call-service descriptor.
-     * @param extras The optional extras passed via
-     *         {@link TelecommConstants#EXTRA_INCOMING_CALL_EXTRAS}.
      */
-    void startIncoming(CallServiceDescriptor descriptor, Bundle extras) {
-        Switchboard.getInstance().retrieveIncomingCall(this, descriptor, extras);
+    void startIncoming() {
+        Switchboard.getInstance().retrieveIncomingCall(this);
     }
 
     /**
@@ -594,7 +578,7 @@
         Preconditions.checkState(mOutgoingCallProcessor == null);
 
         mOutgoingCallProcessor = new OutgoingCallProcessor(
-                this, Switchboard.getInstance().getCallServiceRepository(), this);
+                this, Switchboard.getInstance().getConnectionServiceRepository(), this);
         mOutgoingCallProcessor.process();
     }
 
diff --git a/src/com/android/telecomm/CallActivity.java b/src/com/android/telecomm/CallActivity.java
index 4766310..0086c99 100644
--- a/src/com/android/telecomm/CallActivity.java
+++ b/src/com/android/telecomm/CallActivity.java
@@ -20,7 +20,7 @@
 import android.content.Intent;
 import android.content.res.Configuration;
 import android.os.Bundle;
-import android.telecomm.CallServiceDescriptor;
+import android.telecomm.PhoneAccount;
 import android.telecomm.TelecommConstants;
 
 /**
@@ -102,10 +102,14 @@
      * @param intent The incoming call intent.
      */
     private void processIncomingCallIntent(Intent intent) {
-        CallServiceDescriptor descriptor =
-                intent.getParcelableExtra(TelecommConstants.EXTRA_CALL_SERVICE_DESCRIPTOR);
-        if (descriptor == null) {
-            Log.w(this, "Rejecting incoming call due to null descriptor");
+        PhoneAccount phoneAccount = intent.getParcelableExtra(
+                TelecommConstants.EXTRA_PHONE_ACCOUNT);
+        if (phoneAccount == null) {
+            Log.w(this, "Rejecting incoming call due to null phone account");
+            return;
+        }
+        if (phoneAccount.getComponentName() == null) {
+            Log.w(this, "Rejecting incoming call due to null component name");
             return;
         }
 
@@ -114,7 +118,8 @@
             clientExtras = intent.getBundleExtra(TelecommConstants.EXTRA_INCOMING_CALL_EXTRAS);
         }
 
-        Log.d(this, "Processing incoming call from connection service [%s]", descriptor);
-        mCallsManager.processIncomingCallIntent(descriptor, clientExtras);
+        Log.d(this, "Processing incoming call from connection service [%s]",
+                phoneAccount.getComponentName());
+        mCallsManager.processIncomingCallIntent(phoneAccount, clientExtras);
     }
 }
diff --git a/src/com/android/telecomm/CallServiceProviderWrapper.java b/src/com/android/telecomm/CallServiceProviderWrapper.java
deleted file mode 100644
index 22b8187..0000000
--- a/src/com/android/telecomm/CallServiceProviderWrapper.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright 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.telecomm;
-
-import android.content.ComponentName;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.telecomm.CallServiceDescriptor;
-import android.telecomm.TelecommConstants;
-
-import com.android.internal.telecomm.ICallServiceLookupResponse;
-import com.android.internal.telecomm.ICallServiceProvider;
-
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-/**
- * Wrapper for {@link ICallServiceProvider}s, handles binding to {@link ICallServiceProvider} and
- * keeps track of when the object can safely be unbound. Other classes should not use
- * {@link ICallServiceProvider} directly and instead should use this class to invoke methods of
- * {@link ICallServiceProvider}.
- */
-final class CallServiceProviderWrapper extends ServiceBinder<ICallServiceProvider> {
-    interface LookupResponse {
-        void setCallServiceDescriptors(List<CallServiceDescriptor> descriptors);
-    }
-
-    private class LookupResponseWrapper extends ICallServiceLookupResponse.Stub {
-        private final LookupResponse mResponse;
-
-        LookupResponseWrapper(LookupResponse response) {
-            mResponse = response;
-        }
-
-        @Override
-        public void setCallServiceDescriptors(final List<CallServiceDescriptor> descriptors) {
-            mHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    if (mLookupResponses.remove(mResponse)) {
-                        mResponse.setCallServiceDescriptors(descriptors);
-                    }
-                }
-            });
-        }
-    };
-
-    /** The actual service implementation. */
-    private ICallServiceProvider mServiceInterface;
-    private final Binder mBinder = new Binder();
-    private Set<LookupResponse> mLookupResponses = new HashSet<LookupResponse>();
-    private final Handler mHandler = new Handler();
-
-    /**
-     * Creates a call-service provider for the specified component.
-     *
-     * @param componentName The component name of the service to bind to.
-     */
-    CallServiceProviderWrapper(ComponentName componentName) {
-        super(TelecommConstants.ACTION_CALL_SERVICE_PROVIDER, componentName);
-    }
-
-    /**
-     * Initiates a call-service lookup cycle, see {@link ICallServiceProvider#lookupCallServices}.
-     * Can be invoked even when the call service is unbound.
-     *
-     * @param response The response object via which to return the relevant call-service
-     *     implementations, if any.
-     */
-    void lookupCallServices(final LookupResponse response) {
-        mLookupResponses.add(response);
-        BindCallback callback = new BindCallback() {
-            @Override
-            public void onSuccess() {
-                if (isServiceValid("lookupCallServices")) {
-                    try {
-                        mServiceInterface.lookupCallServices(new LookupResponseWrapper(response));
-                    } catch (RemoteException e) {
-                    }
-                }
-            }
-
-            @Override
-            public void onFailure() {
-                if (mLookupResponses.remove(response)) {
-                    response.setCallServiceDescriptors(null);
-                }
-            }
-        };
-
-        mBinder.bind(callback);
-    }
-
-    /** {@inheritDoc} */
-    @Override protected void setServiceInterface(IBinder binder) {
-        if (binder == null) {
-            mServiceInterface = null;
-
-            Set<LookupResponse> responses = mLookupResponses;
-            mLookupResponses = new HashSet<LookupResponse>();
-            for (LookupResponse response : responses) {
-                response.setCallServiceDescriptors(null);
-            }
-        } else {
-            mServiceInterface = ICallServiceProvider.Stub.asInterface(binder);
-        }
-    }
-}
diff --git a/src/com/android/telecomm/CallServiceRepository.java b/src/com/android/telecomm/CallServiceRepository.java
deleted file mode 100644
index cdef130..0000000
--- a/src/com/android/telecomm/CallServiceRepository.java
+++ /dev/null
@@ -1,174 +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.telecomm;
-
-import android.content.ComponentName;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.content.pm.ServiceInfo;
-import android.telecomm.CallServiceDescriptor;
-import android.telecomm.TelecommConstants;
-
-import com.android.internal.telecomm.ICallServiceLookupResponse;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-
-import java.util.List;
-import java.util.Set;
-
-/**
- * Searches for and returns connection services.
- */
-class CallServiceRepository extends BaseRepository<ConnectionServiceWrapper> {
-    /**
-     * The representation of a single lookup. Maintains lookup state and invokes the "complete"
-     * callback when finished.
-     */
-    private final class CallServiceLookup {
-        final Set<ComponentName> mOutstandingProviders = Sets.newHashSet();
-        final Set<ConnectionServiceWrapper> mServices = Sets.newHashSet();
-        final LookupCallback<ConnectionServiceWrapper> mCallback;
-
-        CallServiceLookup(LookupCallback<ConnectionServiceWrapper> callback) {
-            mCallback = callback;
-        }
-
-        /** Starts the lookup. */
-        void start() {
-            List<ComponentName> providerNames = getProviderNames();
-            if (providerNames.isEmpty()) {
-                finishLookup();
-                return;
-            }
-
-            for (ComponentName name : providerNames) {
-                mOutstandingProviders.add(name);
-                queryProviderForCallServices(name);
-            }
-
-            Log.i(this, "Found %d implementations of ICallServiceProvider.",
-                    mOutstandingProviders.size());
-        }
-
-        /**
-         * Returns the all-inclusive list of call-service-provider names.
-         *
-         * @return The list containing the (component) names of all known ICallServiceProvider
-         *         implementations or the empty list upon no available providers.
-         */
-        private List<ComponentName> getProviderNames() {
-            // The list of provider names to return to the caller, may be populated below.
-            List<ComponentName> providerNames = Lists.newArrayList();
-
-            PackageManager packageManager = TelecommApp.getInstance().getPackageManager();
-            Intent intent = new Intent(TelecommConstants.ACTION_CALL_SERVICE_PROVIDER);
-            for (ResolveInfo entry : packageManager.queryIntentServices(intent, 0)) {
-                ServiceInfo serviceInfo = entry.serviceInfo;
-                if (serviceInfo != null) {
-                    // The entry resolves to a proper service, add it to the list of provider names.
-                    providerNames.add(
-                            new ComponentName(serviceInfo.packageName, serviceInfo.name));
-                }
-            }
-
-            return providerNames;
-        }
-
-        /**
-         * Attempts to obtain call-service descriptors from the specified provider (asynchronously)
-         * and passes the list through to {@link #processCallServices}, which then relinquishes
-         * control back to the switchboard.
-         *
-         * @param providerName The component name of the relevant provider.
-         */
-        private void queryProviderForCallServices(final ComponentName providerName) {
-            final CallServiceProviderWrapper provider = new CallServiceProviderWrapper(
-                    providerName);
-            provider.lookupCallServices(new CallServiceProviderWrapper.LookupResponse() {
-                @Override
-                public void setCallServiceDescriptors(List<CallServiceDescriptor> descriptors) {
-                    processCallServices(provider, descriptors);
-                }
-            });
-        }
-
-        /**
-         * Processes the call-service descriptors provided by the specified provider.
-         *
-         * @param provider The call-service provider.
-         * @param callServiceDescriptors The set of descriptors to process.
-         */
-        private void processCallServices(
-                CallServiceProviderWrapper provider,
-                List<CallServiceDescriptor> descriptors) {
-
-            // Descriptor lookup finished, we no longer need the provider.
-            provider.unbind();
-
-            ComponentName providerName = provider.getComponentName();
-            if (mOutstandingProviders.remove(providerName)) {
-                if (descriptors != null) {
-                    // Add all the connection services from this provider to the connection-service
-                    // cache.
-                    for (CallServiceDescriptor descriptor : descriptors) {
-                        mServices.add(getService(descriptor.getServiceComponent(), descriptor));
-                    }
-                }
-
-                if (mOutstandingProviders.isEmpty()) {
-                    finishLookup();
-                }
-            } else {
-                Log.i(this, "Unexpected connection services from %s in lookup.", providerName);
-            }
-        }
-
-        void finishLookup() {
-            mCallback.onComplete(mServices);
-        }
-    }
-
-    private final IncomingCallsManager mIncomingCallsManager;
-
-    /** Persists specified parameters. */
-    CallServiceRepository(IncomingCallsManager incomingCallsManager) {
-        mIncomingCallsManager = incomingCallsManager;
-    }
-
-    /**
-     * Returns the connection service implementation specified by the descriptor.
-     *
-     * @param descriptor The call-service descriptor.
-     */
-    ConnectionServiceWrapper getService(CallServiceDescriptor descriptor) {
-        return getService(descriptor.getServiceComponent(), descriptor);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected void onLookupServices(LookupCallback<ConnectionServiceWrapper> callback) {
-        new CallServiceLookup(callback).start();
-    }
-
-    @Override
-    protected ConnectionServiceWrapper onCreateNewServiceWrapper(ComponentName componentName,
-            Object param) {
-        return new ConnectionServiceWrapper(
-                (CallServiceDescriptor) param, mIncomingCallsManager, this);
-    }
-}
diff --git a/src/com/android/telecomm/CallsManager.java b/src/com/android/telecomm/CallsManager.java
index e7a8c70..2d5d5c0 100644
--- a/src/com/android/telecomm/CallsManager.java
+++ b/src/com/android/telecomm/CallsManager.java
@@ -19,7 +19,6 @@
 import android.net.Uri;
 import android.os.Bundle;
 import android.telecomm.CallAudioState;
-import android.telecomm.CallServiceDescriptor;
 import android.telecomm.CallState;
 import android.telecomm.GatewayInfo;
 import android.telecomm.PhoneAccount;
@@ -30,7 +29,6 @@
 import com.google.common.collect.ImmutableList;
 
 import java.util.HashSet;
-import java.util.LinkedHashSet;
 import java.util.Set;
 import java.util.concurrent.CopyOnWriteArraySet;
 
@@ -233,22 +231,25 @@
 
     /**
      * Starts the incoming call sequence by having switchboard gather more information about the
-     * specified call; using the specified call service descriptor. Upon success, execution returns
-     * to {@link #onSuccessfulIncomingCall} to start the in-call UI.
+     * specified call; using the specified connection service component name. Upon success,
+     * execution returns to {@link #onSuccessfulIncomingCall} to start the in-call UI.
      *
-     * @param descriptor The descriptor of the connection service to use for this incoming call.
+     * @param phoneAccount The phone account which contains the component name of the connection
+     *                     serivce to use for this call.
      * @param extras The optional extras Bundle passed with the intent used for the incoming call.
      */
-    void processIncomingCallIntent(CallServiceDescriptor descriptor, Bundle extras) {
+    void processIncomingCallIntent(PhoneAccount phoneAccount, Bundle extras) {
         Log.d(this, "processIncomingCallIntent");
         // Create a call with no handle. Eventually, switchboard will update the call with
         // additional information from the connection service, but for now we just need one to pass
         // around.
-        Call call = new Call(true /* isIncoming */, false /* isConference */);
+        Call call = new Call(
+                null, null, phoneAccount, true /* isIncoming */, false /* isConference */);
+        call.setExtras(extras);
         // TODO(santoscordon): Move this to be a part of addCall()
         call.addListener(this);
 
-        call.startIncoming(descriptor, extras);
+        call.startIncoming();
     }
 
     /**
@@ -274,8 +275,7 @@
         }
 
         Call call = new Call(
-                uriHandle, gatewayInfo, account,
-                false /* isIncoming */, false /* isConference */);
+                uriHandle, gatewayInfo, account, false /* isIncoming */, false /* isConference */);
         call.setStartWithSpeakerphoneOn(speakerphoneOn);
         call.setVideoState(videoState);
 
@@ -292,7 +292,8 @@
      * @param call The call to conference with.
      */
     void conference(Call call) {
-        Call conferenceCall = new Call(false, true);
+        Call conferenceCall = new Call(
+                null, null, null, false /* isIncoming */, true /* isConference */);
         conferenceCall.addListener(this);
         call.conferenceInto(conferenceCall);
     }
@@ -482,7 +483,7 @@
      * live call, then also disconnect from the in-call controller.
      *
      * @param disconnectCause The disconnect reason, see {@link android.telephony.DisconnectCause}.
-     * @param disconnectMessage Optional call-service-provided message about the disconnect.
+     * @param disconnectMessage Optional message about the disconnect.
      */
     void markCallAsDisconnected(Call call, int disconnectCause, String disconnectMessage) {
         call.setDisconnectCause(disconnectCause, disconnectMessage);
@@ -492,7 +493,7 @@
 
     /**
      * Cleans up any calls currently associated with the specified connection service when the
-     * call-service binder disconnects unexpectedly.
+     * service binder disconnects unexpectedly.
      *
      * @param service The connection service that disconnected.
      */
diff --git a/src/com/android/telecomm/CallsManagerListenerBase.java b/src/com/android/telecomm/CallsManagerListenerBase.java
index 70dac25..86c723d 100644
--- a/src/com/android/telecomm/CallsManagerListenerBase.java
+++ b/src/com/android/telecomm/CallsManagerListenerBase.java
@@ -18,7 +18,6 @@
 
 import android.net.Uri;
 import android.telecomm.CallAudioState;
-import android.telecomm.CallServiceDescriptor;
 import android.telecomm.CallState;
 
 /**
diff --git a/src/com/android/telecomm/ConnectionServiceRepository.java b/src/com/android/telecomm/ConnectionServiceRepository.java
new file mode 100644
index 0000000..7672e30
--- /dev/null
+++ b/src/com/android/telecomm/ConnectionServiceRepository.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.telecomm;
+
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+import android.telecomm.TelecommConstants;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+
+/**
+ * Searches for and returns connection services.
+ */
+final class ConnectionServiceRepository
+        implements ServiceBinder.Listener<ConnectionServiceWrapper> {
+    private final IncomingCallsManager mIncomingCallsManager;
+    private final HashMap<ComponentName, ConnectionServiceWrapper> mServiceCache =
+            new HashMap<ComponentName, ConnectionServiceWrapper>();
+
+    ConnectionServiceRepository(IncomingCallsManager incomingCallsManager) {
+        mIncomingCallsManager = incomingCallsManager;
+    }
+
+    Collection<ConnectionServiceWrapper> lookupServices() {
+        PackageManager packageManager = TelecommApp.getInstance().getPackageManager();
+        Intent intent = new Intent(TelecommConstants.ACTION_CONNECTION_SERVICE);
+        ArrayList<ConnectionServiceWrapper> services = new ArrayList<>();
+
+        for (ResolveInfo entry : packageManager.queryIntentServices(intent, 0)) {
+            ServiceInfo serviceInfo = entry.serviceInfo;
+            if (serviceInfo != null) {
+                services.add(getService(new ComponentName(
+                        serviceInfo.packageName, serviceInfo.name)));
+            }
+        }
+        return services;
+    }
+
+    ConnectionServiceWrapper getService(ComponentName componentName) {
+        ConnectionServiceWrapper service = mServiceCache.get(componentName);
+        if (service == null) {
+            service = new ConnectionServiceWrapper(componentName, mIncomingCallsManager, this);
+            service.addListener(this);
+            mServiceCache.put(componentName, service);
+        }
+        return service;
+    }
+
+    /**
+     * Removes the specified service from the cache when the service unbinds.
+     *
+     * {@inheritDoc}
+     */
+    @Override
+    public void onUnbind(ConnectionServiceWrapper service) {
+        mServiceCache.remove(service.getComponentName());
+    }
+}
diff --git a/src/com/android/telecomm/ConnectionServiceWrapper.java b/src/com/android/telecomm/ConnectionServiceWrapper.java
index e131e07..1b0dcdf 100644
--- a/src/com/android/telecomm/ConnectionServiceWrapper.java
+++ b/src/com/android/telecomm/ConnectionServiceWrapper.java
@@ -25,7 +25,6 @@
 import android.os.RemoteException;
 import android.telecomm.CallAudioState;
 import android.telecomm.ConnectionService;
-import android.telecomm.CallServiceDescriptor;
 import android.telecomm.ConnectionRequest;
 import android.telecomm.GatewayInfo;
 import android.telecomm.StatusHints;
@@ -35,10 +34,8 @@
 import com.android.internal.os.SomeArgs;
 import com.android.internal.telecomm.IConnectionService;
 import com.android.internal.telecomm.IConnectionServiceAdapter;
-import com.android.internal.telecomm.ICallServiceProvider;
 import com.android.internal.telecomm.ICallVideoProvider;
 import com.android.internal.telecomm.RemoteServiceCallback;
-import com.android.telecomm.BaseRepository.LookupCallback;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
 
@@ -522,35 +519,28 @@
     private final CallsManager mCallsManager = CallsManager.getInstance();
     private final Set<Call> mPendingIncomingCalls = new HashSet<>();
     private final Set<Call> mPendingConferenceCalls = new HashSet<>();
-    private final CallServiceDescriptor mDescriptor;
     private final CallIdMapper mCallIdMapper = new CallIdMapper("ConnectionService");
     private final IncomingCallsManager mIncomingCallsManager;
     private final Map<String, OutgoingCallResponse> mPendingOutgoingCalls = new HashMap<>();
 
     private Binder mBinder = new Binder();
     private IConnectionService mServiceInterface;
-    private final CallServiceRepository mCallServiceRepository;
+    private final ConnectionServiceRepository mConnectionServiceRepository;
 
     /**
-     * Creates a call-service for the specified descriptor.
+     * Creates a connection service.
      *
-     * @param descriptor The call-service descriptor from
-     *            {@link ICallServiceProvider#lookupCallServices}.
+     * @param componentName The component name of the service with which to bind.
      * @param incomingCallsManager Manages the incoming call initialization flow.
-     * @param callServiceRepository Connection service repository.
+     * @param connectionServiceRepository Connection service repository.
      */
     ConnectionServiceWrapper(
-            CallServiceDescriptor descriptor,
+            ComponentName componentName,
             IncomingCallsManager incomingCallsManager,
-            CallServiceRepository callServiceRepository) {
-        super(TelecommConstants.ACTION_CONNECTION_SERVICE, descriptor.getServiceComponent());
-        mDescriptor = descriptor;
+            ConnectionServiceRepository connectionServiceRepository) {
+        super(TelecommConstants.ACTION_CONNECTION_SERVICE, componentName);
         mIncomingCallsManager = incomingCallsManager;
-        mCallServiceRepository = callServiceRepository;
-    }
-
-    CallServiceDescriptor getDescriptor() {
-        return mDescriptor;
+        mConnectionServiceRepository = connectionServiceRepository;
     }
 
     /** See {@link IConnectionService#addConnectionServiceAdapter}. */
@@ -599,7 +589,7 @@
                 try {
                     mServiceInterface.call(request);
                 } catch (RemoteException e) {
-                    Log.e(this, e, "Failure to call -- %s", getDescriptor());
+                    Log.e(this, e, "Failure to call -- %s", getComponentName());
                     mPendingOutgoingCalls.remove(callId).onOutgoingCallFailure(
                             DisconnectCause.ERROR_UNSPECIFIED, e.toString());
                 }
@@ -607,7 +597,7 @@
 
             @Override
             public void onFailure() {
-                Log.e(this, new Exception(), "Failure to call %s", getDescriptor());
+                Log.e(this, new Exception(), "Failure to call %s", getComponentName());
                 callResponse.onOutgoingCallFailure(DisconnectCause.ERROR_UNSPECIFIED, null);
             }
         };
@@ -668,16 +658,15 @@
     }
 
     /**
-     * Starts retrieval of details for an incoming call. Details are returned through the
-     * call-service adapter using the specified call ID. Upon failure, the specified error callback
-     * is invoked. Can be invoked even when the connection service is unbound. See
+     * Starts retrieval of details for an incoming call. Details are returned through the connection
+     * service adapter using the specified call ID. Upon failure, the specified error callback is
+     * invoked. Can be invoked even when the connection service is unbound. See
      * {@link IConnectionService#createIncomingCall}.
      *
      * @param call The call used for the incoming call.
-     * @param extras The {@link ConnectionService}-provided extras which need to be sent back.
      * @param errorCallback The callback to invoke upon failure.
      */
-    void createIncomingCall(final Call call, final Bundle extras, final Runnable errorCallback) {
+    void createIncomingCall(final Call call, final Runnable errorCallback) {
         Log.d(this, "createIncomingCall(%s) via %s.", call, getComponentName());
         BindCallback callback = new BindCallback() {
             @Override
@@ -685,13 +674,13 @@
                 if (isServiceValid("createIncomingCall")) {
                     mPendingIncomingCalls.add(call);
                     String callId = mCallIdMapper.getCallId(call);
-                    logOutgoing("createIncomingCall %s %s", callId, extras);
+                    logOutgoing("createIncomingCall %s", callId);
                     ConnectionRequest request = new ConnectionRequest(
                             call.getPhoneAccount(),
                             callId,
                             call.getHandle(),
                             call.getHandlePresentation(),
-                            extras,
+                            call.getExtras(),
                             call.getVideoState());
                     try {
                         mServiceInterface.createIncomingCall(request);
@@ -911,47 +900,41 @@
     private void queryRemoteConnectionServices(final RemoteServiceCallback callback) {
         final List<IBinder> connectionServices = new ArrayList<>();
         final List<ComponentName> components = new ArrayList<>();
+        final Collection<ConnectionServiceWrapper> services =
+                mConnectionServiceRepository.lookupServices();
 
-        mCallServiceRepository.lookupServices(new LookupCallback<ConnectionServiceWrapper>() {
-            private int mRemainingResponses;
+        for (ConnectionServiceWrapper cs : services) {
+            if (cs != this) {
+                final ConnectionServiceWrapper currentConnectionService = cs;
+                cs.mBinder.bind(new BindCallback() {
+                    private int mRemainingResponses = services.size() - 1;
 
-            /** ${inheritDoc} */
-            @Override
-            public void onComplete(Collection<ConnectionServiceWrapper> services) {
-                mRemainingResponses = services.size() - 1;
-                for (ConnectionServiceWrapper cs : services) {
-                    if (cs != ConnectionServiceWrapper.this) {
-                        final ConnectionServiceWrapper currentConnectionService = cs;
-                        cs.mBinder.bind(new BindCallback() {
-                            @Override
-                            public void onSuccess() {
-                                Log.d(this, "Adding ***** %s",
-                                        currentConnectionService.getDescriptor());
-                                connectionServices.add(
-                                        currentConnectionService.mServiceInterface.asBinder());
-                                components.add(currentConnectionService.getComponentName());
-                                maybeComplete();
-                            }
-
-                            @Override
-                            public void onFailure() {
-                                // add null so that we always add up to totalExpected even if
-                                // some of the connection services fail to bind.
-                                maybeComplete();
-                            }
-
-                            private void maybeComplete() {
-                                if (--mRemainingResponses == 0) {
-                                    try {
-                                        callback.onResult(components, connectionServices);
-                                    } catch (RemoteException ignored) {
-                                    }
-                                }
-                            }
-                        });
+                    @Override
+                    public void onSuccess() {
+                        Log.d(this, "Adding ***** %s", currentConnectionService.getComponentName());
+                        connectionServices.add(
+                                currentConnectionService.mServiceInterface.asBinder());
+                        components.add(currentConnectionService.getComponentName());
+                        maybeComplete();
                     }
-                }
+
+                    @Override
+                    public void onFailure() {
+                        // add null so that we always add up to totalExpected even if
+                        // some of the connection services fail to bind.
+                        maybeComplete();
+                    }
+
+                    private void maybeComplete() {
+                        if (--mRemainingResponses == 0) {
+                            try {
+                                callback.onResult(components, connectionServices);
+                            } catch (RemoteException ignored) {
+                            }
+                        }
+                    }
+                });
             }
-        });
+        }
     }
 }
diff --git a/src/com/android/telecomm/InCallController.java b/src/com/android/telecomm/InCallController.java
index d8e4030..3824c6f 100644
--- a/src/com/android/telecomm/InCallController.java
+++ b/src/com/android/telecomm/InCallController.java
@@ -29,7 +29,6 @@
 import android.telecomm.CallAudioState;
 import android.telecomm.CallCapabilities;
 import android.telecomm.CallPropertyPresentation;
-import android.telecomm.CallServiceDescriptor;
 import android.telecomm.CallState;
 import android.telecomm.InCallCall;
 
@@ -275,8 +274,6 @@
 
     private InCallCall toInCallCall(Call call) {
         String callId = mCallIdMapper.getCallId(call);
-        CallServiceDescriptor descriptor = call.getConnectionService() != null ?
-                call.getConnectionService().getDescriptor() : null;
 
         int capabilities = call.getCallCapabilities();
         if (!CallsManager.getInstance().isAddCallCapable(call)) {
@@ -321,7 +318,7 @@
                 call.getCannedSmsResponses(), capabilities, connectTimeMillis, handle,
                 call.getHandlePresentation(), callerDisplayName,
                 call.getCallerDisplayNamePresentation(), call.getGatewayInfo(),
-                call.getPhoneAccount(), descriptor, call.getCallVideoProvider(), parentCallId,
-                childCallIds, call.getStatusHints());
+                call.getPhoneAccount(), call.getCallVideoProvider(), parentCallId, childCallIds,
+                call.getStatusHints());
     }
 }
diff --git a/src/com/android/telecomm/IncomingCallsManager.java b/src/com/android/telecomm/IncomingCallsManager.java
index 197f699..5fa80f5 100644
--- a/src/com/android/telecomm/IncomingCallsManager.java
+++ b/src/com/android/telecomm/IncomingCallsManager.java
@@ -37,11 +37,8 @@
      * Retrieves details of an incoming call through its associated connection service.
      *
      * @param call The call object.
-     * @param extras The optional extras passed with the incoming call intent (to be returned to
-     *     the connection service via
-     *     {@link ConnectionService#createIncomingCall(ConnectionRequest)}.
      */
-    void retrieveIncomingCall(final Call call, Bundle extras) {
+    void retrieveIncomingCall(final Call call) {
         ThreadUtil.checkOnMainThread();
         Log.d(this, "retrieveIncomingCall");
 
@@ -56,7 +53,7 @@
             }
         };
 
-        call.getConnectionService().createIncomingCall(call, extras, errorCallback);
+        call.getConnectionService().createIncomingCall(call, errorCallback);
     }
 
     /**
diff --git a/src/com/android/telecomm/NewOutgoingCallIntentBroadcaster.java b/src/com/android/telecomm/NewOutgoingCallIntentBroadcaster.java
index cdc5dea..a83afaf 100644
--- a/src/com/android/telecomm/NewOutgoingCallIntentBroadcaster.java
+++ b/src/com/android/telecomm/NewOutgoingCallIntentBroadcaster.java
@@ -26,7 +26,6 @@
 import android.telecomm.GatewayInfo;
 import android.telecomm.PhoneAccount;
 import android.telecomm.TelecommConstants;
-import android.telecomm.TelecommManager;
 import android.telecomm.VideoCallProfile;
 import android.telephony.PhoneNumberUtils;
 import android.text.TextUtils;
@@ -188,11 +187,13 @@
             Log.i(this, "Placing call immediately instead of waiting for "
                     + " OutgoingCallBroadcastReceiver: %s", intent);
             String scheme = isUriNumber ? SCHEME_SIP : SCHEME_TEL;
+            boolean speakerphoneOn = mIntent.getBooleanExtra(
+                    TelecommConstants.EXTRA_START_CALL_WITH_SPEAKERPHONE, false);
+            int videoState = mIntent.getIntExtra(
+                    TelecommConstants.EXTRA_START_CALL_WITH_VIDEO_STATE,
+                    VideoCallProfile.VIDEO_STATE_AUDIO_ONLY);
             mCallsManager.placeOutgoingCall(
-                    Uri.fromParts(scheme, handle, null), null, null, mIntent.getBooleanExtra(TelecommConstants.EXTRA_START_CALL_WITH_SPEAKERPHONE,
-                            false),
-                    mIntent.getIntExtra(TelecommConstants.EXTRA_START_CALL_WITH_VIDEO_STATE,
-                            VideoCallProfile.VIDEO_STATE_AUDIO_ONLY));
+                    Uri.fromParts(scheme, handle, null), null, null, speakerphoneOn, videoState);
 
             // Don't return but instead continue and send the ACTION_NEW_OUTGOING_CALL broadcast
             // so that third parties can still inspect (but not intercept) the outgoing call. When
@@ -260,10 +261,9 @@
             Log.d(this, "Found and copied gateway provider extras to broadcast intent.");
             return;
         }
-        PhoneAccount extraAccount = src.getParcelableExtra(
-                TelecommManager.EXTRA_PHONE_ACCOUNT);
+        PhoneAccount extraAccount = src.getParcelableExtra(TelecommConstants.EXTRA_PHONE_ACCOUNT);
         if (extraAccount != null) {
-            dst.putExtra(TelecommManager.EXTRA_PHONE_ACCOUNT, extraAccount);
+            dst.putExtra(TelecommConstants.EXTRA_PHONE_ACCOUNT, extraAccount);
             Log.d(this, "Found and copied account extra to broadcast intent.");
         }
 
@@ -321,7 +321,7 @@
             return null;
         }
 
-        return intent.getParcelableExtra(TelecommManager.EXTRA_PHONE_ACCOUNT);
+        return intent.getParcelableExtra(TelecommConstants.EXTRA_PHONE_ACCOUNT);
     }
 
     private void launchSystemDialer(Context context, Uri handle) {
diff --git a/src/com/android/telecomm/OutgoingCallProcessor.java b/src/com/android/telecomm/OutgoingCallProcessor.java
index 1f6e4f3..c24a83b 100644
--- a/src/com/android/telecomm/OutgoingCallProcessor.java
+++ b/src/com/android/telecomm/OutgoingCallProcessor.java
@@ -20,11 +20,9 @@
 import android.net.Uri;
 import android.os.Handler;
 import android.os.Message;
-import android.telecomm.CallServiceDescriptor;
 import android.telephony.DisconnectCause;
 import android.telephony.PhoneNumberUtils;
 
-import com.android.telecomm.BaseRepository.LookupCallback;
 import com.google.android.collect.Sets;
 import com.google.common.collect.Maps;
 
@@ -36,9 +34,9 @@
 import java.util.Set;
 
 /**
- * Utility class to place a call using the specified set of call-services. Each of the connection
- * services is then attempted until either the outgoing call is placed, the attempted call is
- * aborted, or the list is exhausted -- whichever occurs first.
+ * Utility class to place a call using the specified set of connection services. Each of the
+ * connection services is then attempted until either the outgoing call is placed, the attempted
+ * call is aborted, or the list is exhausted -- whichever occurs first.
  *
  * Except for the abort case, all other scenarios should terminate with the call notified
  * of the result.
@@ -51,27 +49,22 @@
     private final Call mCall;
 
     /**
-     * The map of currently-available call-service implementations keyed by call-service ID.
-     */
-    private final Map<String, ConnectionServiceWrapper> mConnectionServicesById = Maps.newHashMap();
-
-    /**
      * The set of attempted connection services, used to ensure services are attempted at most once
      * per outgoing-call attempt.
      */
-    private final Set<ConnectionServiceWrapper> mAttemptedConnectionServices = Sets.newHashSet();
+    private final Set<ConnectionServiceWrapper> mAttemptedServices = Sets.newHashSet();
 
-    private final CallServiceRepository mCallServiceRepository;
+    private final ConnectionServiceRepository mConnectionServiceRepository;
 
     /**
-     * The duplicate-free list of currently-available call-service descriptors.
+     * The duplicate-free list of currently-available connection service component names.
      */
-    private List<CallServiceDescriptor> mCallServiceDescriptors;
+    private List<ComponentName> mServiceComponentNames;
 
     /**
-     * The iterator over the currently-selected ordered list of call-service descriptors.
+     * The iterator over the currently-selected ordered list of connection service component names.
      */
-    private Iterator<CallServiceDescriptor> mCallServiceDescriptorIterator;
+    private Iterator<ComponentName> mServiceComponentNameIterator;
 
     private OutgoingCallResponse mResultCallback;
 
@@ -87,19 +80,18 @@
      * connection service will eventually be killed by the cleanup/monitor switchboard handler.
      *
      * @param call The call to place.
-     * @param callServiceRepository
      * @param resultCallback The callback on which to return the result.
      */
     OutgoingCallProcessor(
             Call call,
-            CallServiceRepository callServiceRepository,
+            ConnectionServiceRepository connectionServiceRepository,
             OutgoingCallResponse resultCallback) {
 
         ThreadUtil.checkOnMainThread();
 
         mCall = call;
         mResultCallback = resultCallback;
-        mCallServiceRepository = callServiceRepository;
+        mConnectionServiceRepository = connectionServiceRepository;
     }
 
     /**
@@ -108,13 +100,7 @@
     void process() {
         Log.v(this, "process, mIsAborted: %b", mIsAborted);
         if (!mIsAborted) {
-            // Lookup connection services
-            mCallServiceRepository.lookupServices(new LookupCallback<ConnectionServiceWrapper>() {
-                @Override
-                public void onComplete(Collection<ConnectionServiceWrapper> services) {
-                    setConnectionServices(services);
-                }
-            });
+            setConnectionServices(mConnectionServiceRepository.lookupServices());
         }
     }
 
@@ -191,35 +177,36 @@
      * @param services The connection services.
      */
     private void setConnectionServices(Collection<ConnectionServiceWrapper> services) {
-        mCallServiceDescriptors = new ArrayList<>();
+        mServiceComponentNames = new ArrayList<>();
 
-        // Populate the list and map of call-service descriptors.
+        // TODO(sail): Remove once there's a way to pick the service.
+        ArrayList<ComponentName> priorityComponents = new ArrayList<>();
+        priorityComponents.add(new ComponentName("com.android.phone",
+                "com.android.services.telephony.sip.SipConnectionService"));
+        priorityComponents.add(new ComponentName("com.google.android.talk",
+                "com.google.android.apps.babel.telephony.TeleConnectionService"));
+        priorityComponents.add(new ComponentName("com.android.telecomm.tests",
+                "com.android.telecomm.testapps.TestConnectionService"));
+
         for (ConnectionServiceWrapper service : services) {
-            CallServiceDescriptor descriptor = service.getDescriptor();
-            // TODO(sail): Remove once there's a way to pick the service.
-            ComponentName sipName = new ComponentName("com.android.phone",
-                    "com.android.services.telephony.sip.SipConnectionService");
-            ComponentName hangoutsName = new ComponentName("com.google.android.talk",
-                    "com.google.android.apps.babel.telephony.TeleConnectionService");
-            ComponentName serviceName = descriptor.getServiceComponent();
-            if (serviceName.equals(sipName) || serviceName.equals(hangoutsName)) {
-                Log.i(this, "Moving connection service %s to top of list", descriptor);
-                mCallServiceDescriptors.add(0, descriptor);
+            ComponentName serviceName = service.getComponentName();
+            if (priorityComponents.contains(serviceName)) {
+                Log.i(this, "Moving connection service %s to top of list", serviceName);
+                mServiceComponentNames .add(0, serviceName);
             } else {
-                mCallServiceDescriptors.add(descriptor);
+                mServiceComponentNames.add(serviceName);
             }
-            mConnectionServicesById.put(descriptor.getConnectionServiceId(), service);
         }
 
-        adjustCallServiceDescriptorsForEmergency();
+        adjustComponentNamesForEmergency();
 
-        mCallServiceDescriptorIterator = mCallServiceDescriptors.iterator();
+        mServiceComponentNameIterator = mServiceComponentNames.iterator();
         attemptNextConnectionService();
     }
 
     /**
-     * Attempts to place the call using the connection service specified by the next call-service
-     * descriptor of mCallServiceDescriptorIterator.
+     * Attempts to place the call using the connection service specified by the next connection
+     * service component name of mServiceComponentNameIterator.
      */
     private void attemptNextConnectionService() {
         Log.v(this, "attemptNextConnectionService, mIsAborted: %b", mIsAborted);
@@ -227,24 +214,24 @@
             return;
         }
 
-        if (mCallServiceDescriptorIterator != null && mCallServiceDescriptorIterator.hasNext()) {
-            CallServiceDescriptor descriptor = mCallServiceDescriptorIterator.next();
+        if (mServiceComponentNameIterator != null && mServiceComponentNameIterator.hasNext()) {
+            ComponentName component = mServiceComponentNameIterator.next();
             final ConnectionServiceWrapper service =
-                    mConnectionServicesById.get(descriptor.getConnectionServiceId());
+                    mConnectionServiceRepository.getService(component);
 
-            if (service == null || mAttemptedConnectionServices.contains(service)) {
+            if (service == null || mAttemptedServices.contains(service)) {
                 // The next connection service is either null or has already been attempted, fast
                 // forward to the next.
                 attemptNextConnectionService();
             } else {
-                mAttemptedConnectionServices.add(service);
+                mAttemptedServices.add(service);
                 mCall.setConnectionService(service);
 
                 // Increment the associated call count until we get a result. This prevents the call
                 // service from unbinding while we are using it.
                 service.incrementAssociatedCallCount();
 
-                Log.i(this, "Attempting to call from %s", service.getDescriptor());
+                Log.i(this, "Attempting to call from %s", service.getComponentName());
                 service.call(mCall, new OutgoingCallResponse() {
                     @Override
                     public void onOutgoingCallSuccess() {
@@ -266,8 +253,8 @@
                 });
             }
         } else {
-            Log.v(this, "attemptNextConnectionService, no more service descriptors, failing");
-            mCallServiceDescriptorIterator = null;
+            Log.v(this, "attemptNextConnectionService, no more services, failing");
+            mServiceComponentNameIterator = null;
             mCall.clearConnectionService();
             sendResult(false, mLastErrorCode, mLastErrorMsg);
         }
@@ -290,18 +277,13 @@
 
     // If we are possibly attempting to call a local emergency number, ensure that the
     // plain PSTN connection service, if it exists, is attempted first.
-    private void adjustCallServiceDescriptorsForEmergency()  {
-        for (int i = 0; i < mCallServiceDescriptors.size(); i++) {
+    private void adjustComponentNamesForEmergency()  {
+        for (int i = 0; i < mServiceComponentNames.size(); i++) {
             if (shouldProcessAsEmergency(mCall.getHandle())) {
-                if (TelephonyUtil.isPstnConnectionService(mCallServiceDescriptors.get(i))) {
-                    mCallServiceDescriptors.add(0, mCallServiceDescriptors.remove(i));
+                if (TelephonyUtil.isPstnComponentName(mServiceComponentNames.get(i))) {
+                    mServiceComponentNames.add(0, mServiceComponentNames.remove(i));
                     return;
                 }
-            } else {
-                if (mCallServiceDescriptors.get(i).getServiceComponent().getPackageName().equals(
-                        "com.android.telecomm.tests")) {
-                    mCallServiceDescriptors.add(0, mCallServiceDescriptors.remove(i));
-                }
             }
         }
     }
diff --git a/src/com/android/telecomm/RespondViaSmsManager.java b/src/com/android/telecomm/RespondViaSmsManager.java
index bf1a2a5..8618af0 100644
--- a/src/com/android/telecomm/RespondViaSmsManager.java
+++ b/src/com/android/telecomm/RespondViaSmsManager.java
@@ -108,7 +108,7 @@
                         SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
                 final Resources res = TelecommApp.getInstance().getInstance().getResources();
 
-                final ArrayList<String> textMessages = new ArrayList<String>(NUM_CANNED_RESPONSES);
+                final ArrayList<String> textMessages = new ArrayList<>(NUM_CANNED_RESPONSES);
 
                 // Note the default values here must agree with the corresponding
                 // android:defaultValue attributes in respond_via_sms_settings.xml.
diff --git a/src/com/android/telecomm/Switchboard.java b/src/com/android/telecomm/Switchboard.java
index b7a7e9e..2dfcfea 100644
--- a/src/com/android/telecomm/Switchboard.java
+++ b/src/com/android/telecomm/Switchboard.java
@@ -20,10 +20,8 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
-import android.telecomm.CallServiceDescriptor;
 import android.telecomm.TelecommConstants;
 
-import com.android.telecomm.BaseRepository.LookupCallback;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableCollection;
 import com.google.common.collect.ImmutableList;
@@ -42,7 +40,7 @@
     /** Used to retrieve incoming call details. */
     private final IncomingCallsManager mIncomingCallsManager;
 
-    private final CallServiceRepository mCallServiceRepository;
+    private final ConnectionServiceRepository mConnectionServiceRepository;
 
     /** Singleton accessor. */
     static Switchboard getInstance() {
@@ -56,26 +54,24 @@
         ThreadUtil.checkOnMainThread();
 
         mIncomingCallsManager = new IncomingCallsManager();
-        mCallServiceRepository =
-                new CallServiceRepository(mIncomingCallsManager);
+        mConnectionServiceRepository =
+                new ConnectionServiceRepository(mIncomingCallsManager);
     }
 
-    CallServiceRepository getCallServiceRepository() {
-        return mCallServiceRepository;
+    ConnectionServiceRepository getConnectionServiceRepository() {
+        return mConnectionServiceRepository;
     }
 
     /**
      * Retrieves details about the incoming call through the incoming call manager.
      *
      * @param call The call object.
-     * @param descriptor The relevant call-service descriptor.
-     * @param extras The optional extras passed via
-     *         {@link TelecommConstants#EXTRA_INCOMING_CALL_EXTRAS}
      */
-    void retrieveIncomingCall(Call call, CallServiceDescriptor descriptor, Bundle extras) {
+    void retrieveIncomingCall(Call call) {
         Log.d(this, "retrieveIncomingCall");
-        ConnectionServiceWrapper service = mCallServiceRepository.getService(descriptor);
+        ConnectionServiceWrapper service = mConnectionServiceRepository.getService(
+                call.getPhoneAccount().getComponentName());
         call.setConnectionService(service);
-        mIncomingCallsManager.retrieveIncomingCall(call, extras);
+        mIncomingCallsManager.retrieveIncomingCall(call);
     }
 }
diff --git a/src/com/android/telecomm/TelephonyUtil.java b/src/com/android/telecomm/TelephonyUtil.java
index 783b427..ac19525 100644
--- a/src/com/android/telecomm/TelephonyUtil.java
+++ b/src/com/android/telecomm/TelephonyUtil.java
@@ -19,7 +19,7 @@
 import android.content.ComponentName;
 import android.content.pm.PackageManager;
 import android.content.pm.ServiceInfo;
-import android.telecomm.CallServiceDescriptor;
+import android.telecomm.PhoneAccount;
 
 /**
  * Utilities to deal with the system telephony services. The system telephony services are treated
@@ -35,26 +35,10 @@
 
     private TelephonyUtil() {}
 
-    static boolean isPstnConnectionService(CallServiceDescriptor descriptor) {
+    static boolean isPstnComponentName(ComponentName componentName) {
         final ComponentName pstnComponentName = new ComponentName(
                 TELEPHONY_PACKAGE_NAME, PSTN_CALL_SERVICE_CLASS_NAME);
-        return pstnComponentName.equals(descriptor.getServiceComponent());
-    }
-
-    /**
-     * Returns whether or not the call is currently connected as a cellular call (through the
-     * device's cellular radio).
-     */
-    static boolean isCurrentlyPSTNCall(Call call) {
-        if (Log.DEBUG) {
-            verifyConnectionServiceExists(PSTN_CALL_SERVICE_CLASS_NAME);
-        }
-
-        ConnectionServiceWrapper service = call.getConnectionService();
-        if (service == null) {
-            return false;
-        }
-        return isPstnConnectionService(service.getDescriptor());
+        return pstnComponentName.equals(componentName);
     }
 
     private static void verifyConnectionServiceExists(String serviceName) {
diff --git a/src/com/android/telecomm/Timeouts.java b/src/com/android/telecomm/Timeouts.java
index 9fa44d3..3ae3f1d 100644
--- a/src/com/android/telecomm/Timeouts.java
+++ b/src/com/android/telecomm/Timeouts.java
@@ -17,7 +17,6 @@
 package com.android.telecomm;
 
 import android.provider.Settings;
-import android.telecomm.CallServiceProvider;
 
 /**
  * A helper class which serves only to make it easier to lookup timeout values. This class should
@@ -45,14 +44,6 @@
     }
 
     /**
-     * @return The longest period in milliseconds each {@link CallServiceProvider} lookup cycle is
-     *     allowed to span over.
-     */
-    public static long getProviderLookupMillis() {
-        return get("provider_lookup_ms", 1000);
-    }
-
-    /**
      * Returns the longest period, in milliseconds, to wait for the query for direct-to-voicemail
      * to complete. If the query goes beyond this timeout, the incoming call screen is shown to the
      * user.
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
index 2bcb756..a7b34f2 100644
--- a/tests/AndroidManifest.xml
+++ b/tests/AndroidManifest.xml
@@ -22,16 +22,9 @@
 
         <!-- Miscellaneous telecomm app-related test activities. -->
 
-        <!-- TODO(santoscordon): STOPSHIP Services in this manifest need permission protection. -->
-        <service android:name="com.android.telecomm.testapps.TestCallServiceProvider">
-            <intent-filter>
-                <action android:name="android.telecomm.CallServiceProvider" />
-            </intent-filter>
-        </service>
-
         <service android:name="com.android.telecomm.testapps.TestConnectionService">
             <intent-filter>
-                <action android:name="android.telecomm.CallService" />
+                <action android:name="android.telecomm.ConnectionService" />
             </intent-filter>
         </service>
 
diff --git a/tests/src/com/android/telecomm/testapps/CallNotificationReceiver.java b/tests/src/com/android/telecomm/testapps/CallNotificationReceiver.java
index 4ab908f..ac39171 100644
--- a/tests/src/com/android/telecomm/testapps/CallNotificationReceiver.java
+++ b/tests/src/com/android/telecomm/testapps/CallNotificationReceiver.java
@@ -22,12 +22,12 @@
 
 /**
  * This class receives the notification callback intents used to update call states for
- * {@link TestCallService}.
+ * {@link TestConnectionService}.
  */
 public class CallNotificationReceiver extends BroadcastReceiver {
     /**
-     * Exit intent action is sent when the user clicks the "exit" action of the TestCallService
-     * notification. Used to cancel (remove) the notification.
+     * 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.telecomm.testcallservice.ACTION_CALL_SERVICE_EXIT";
diff --git a/tests/src/com/android/telecomm/testapps/CallServiceNotifier.java b/tests/src/com/android/telecomm/testapps/CallServiceNotifier.java
index 60f4250..7f5fe96 100644
--- a/tests/src/com/android/telecomm/testapps/CallServiceNotifier.java
+++ b/tests/src/com/android/telecomm/testapps/CallServiceNotifier.java
@@ -19,9 +19,10 @@
 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.telecomm.CallServiceDescriptor;
+import android.telecomm.PhoneAccount;
 import android.telecomm.TelecommConstants;
 import android.telecomm.VideoCallProfile;
 import android.util.Log;
@@ -117,17 +118,19 @@
      */
     private PendingIntent createIncomingCallIntent(Context context, boolean isVideoCall) {
         log("Creating incoming call pending intent.");
-        // Build descriptor for TestConnectionService.
-        CallServiceDescriptor.Builder descriptorBuilder = CallServiceDescriptor.newBuilder(context);
-        descriptorBuilder.setConnectionService(TestConnectionService.class);
-        descriptorBuilder.setNetworkType(CallServiceDescriptor.FLAG_WIFI);
 
         // Create intent for adding an incoming call.
         Intent intent = new Intent(TelecommConstants.ACTION_INCOMING_CALL);
         // TODO(santoscordon): Use a private @hide permission to make sure this only goes to
         // Telecomm instead of setting the package explicitly.
         intent.setPackage("com.android.telecomm");
-        intent.putExtra(TelecommConstants.EXTRA_CALL_SERVICE_DESCRIPTOR, descriptorBuilder.build());
+
+        PhoneAccount phoneAccount = new PhoneAccount(
+                new ComponentName(context, TestConnectionService.class),
+                null /* id */,
+                null /* handle */,
+                PhoneAccount.CAPABILITY_CALL_PROVIDER);
+        intent.putExtra(TelecommConstants.EXTRA_PHONE_ACCOUNT, phoneAccount);
 
         mStartVideoCall = isVideoCall;
 
diff --git a/tests/src/com/android/telecomm/testapps/TestCallActivity.java b/tests/src/com/android/telecomm/testapps/TestCallActivity.java
index 9752252..b85888d 100644
--- a/tests/src/com/android/telecomm/testapps/TestCallActivity.java
+++ b/tests/src/com/android/telecomm/testapps/TestCallActivity.java
@@ -21,8 +21,9 @@
 
 /**
  * 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 TestCallService} via {@link CallServiceNotifier}.
- * After triggering a notification update, this activity immediately finishes.
+ * and instead starts the notification for {@link TestConnectionService} via
+ * {@link CallServiceNotifier}. After triggering a notification update, this activity immediately
+ * finishes.
  */
 public class TestCallActivity extends Activity {
 
diff --git a/tests/src/com/android/telecomm/testapps/TestCallServiceProvider.java b/tests/src/com/android/telecomm/testapps/TestCallServiceProvider.java
deleted file mode 100644
index 41a893e..0000000
--- a/tests/src/com/android/telecomm/testapps/TestCallServiceProvider.java
+++ /dev/null
@@ -1,46 +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.telecomm.testapps;
-
-import android.telecomm.CallServiceDescriptor;
-import android.telecomm.CallServiceLookupResponse;
-import android.telecomm.CallServiceProvider;
-import android.util.Log;
-
-import com.google.common.collect.Lists;
-
-/**
- * Service which provides fake calls to test the IConnectionService interface.
- * TODO(santoscordon): Build more dummy providers for more CallServiceDescriptor.FLAG_* types.
- */
-public class TestCallServiceProvider extends CallServiceProvider {
-    /** {@inheritDoc} */
-    @Override
-    public void lookupCallServices(CallServiceLookupResponse response) {
-        log("lookupCallServices");
-
-        CallServiceDescriptor.Builder builder = CallServiceDescriptor.newBuilder(this);
-        builder.setConnectionService(TestConnectionService.class);
-        builder.setNetworkType(CallServiceDescriptor.FLAG_WIFI);
-
-        response.setCallServiceDescriptors(Lists.newArrayList(builder.build()));
-    }
-
-    private static void log(String msg) {
-        Log.w("testcallservice", "[TestCallServiceProvider] " + msg);
-    }
-}
diff --git a/tests/src/com/android/telecomm/testapps/TestCallVideoProvider.java b/tests/src/com/android/telecomm/testapps/TestCallVideoProvider.java
index 5b673ad..484871e 100644
--- a/tests/src/com/android/telecomm/testapps/TestCallVideoProvider.java
+++ b/tests/src/com/android/telecomm/testapps/TestCallVideoProvider.java
@@ -149,6 +149,6 @@
     }
 
     private static void log(String msg) {
-        Log.w("TestCallServiceProvider", "[TestCallServiceProvider] " + msg);
+        Log.w("TestCallVideoProvider", "[TestCallServiceProvider] " + msg);
     }
-}
\ No newline at end of file
+}