Fix making outgoing calls

This CL fixes the following issues with outgoing calls:
  - Switchboard.placeOutgoingCall doesn't keep track of calls
  - ServiceBinder.bind calls setServiceInterface() multiple times if service is already bound
  - OutgoingCallProcessor.mCallServicesByInfo uses a custom object as a key which makes it impossible to look up call services
  - OutgoingCallProcessor.attemptNextCallService invokes CallServiceWrapper.call without binding first

Change-Id: Ia7983f52c8c03ed9aa44e2c52c20ce9c1c9c75de
diff --git a/src/com/android/telecomm/OutgoingCallProcessor.java b/src/com/android/telecomm/OutgoingCallProcessor.java
index 0a2df04..34649f0 100644
--- a/src/com/android/telecomm/OutgoingCallProcessor.java
+++ b/src/com/android/telecomm/OutgoingCallProcessor.java
@@ -23,12 +23,12 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.RemoteException;
-import android.telecomm.CallInfo;
 import android.telecomm.CallState;
 import android.telecomm.CallServiceInfo;
 import android.telecomm.ICallServiceSelectionResponse;
 import android.telecomm.ICallServiceSelector;
-import android.util.Log;
+
+import com.android.telecomm.ServiceBinder.BindCallback;
 
 import java.util.Iterator;
 import java.util.List;
@@ -62,9 +62,9 @@
     private final List<CallServiceInfo> mCallServiceInfos = Lists.newArrayList();
 
     /**
-     * The map of currently-available call-service implementations keyed by call-service infos.
+     * The map of currently-available call-service implementations keyed by call-service ID.
      */
-    private final Map<CallServiceInfo, CallServiceWrapper> mCallServicesByInfo = Maps.newHashMap();
+    private final Map<String, CallServiceWrapper> mCallServicesById = Maps.newHashMap();
 
     /**
      * The set of currently-available call-service selector implementations.
@@ -129,7 +129,7 @@
         for (CallServiceWrapper callService : callServices) {
             CallServiceInfo info = callService.getInfo();
             mCallServiceInfos.add(info);
-            mCallServicesByInfo.put(info, callService);
+            mCallServicesById.put(info.getCallServiceId(), callService);
         }
     }
 
@@ -253,11 +253,19 @@
 
         if (mCallServiceInfoIterator.hasNext()) {
             CallServiceInfo info = mCallServiceInfoIterator.next();
-            mCallService = mCallServicesByInfo.get(info);
+            mCallService = mCallServicesById.get(info.getCallServiceId());
             if (mCallService == null) {
                 attemptNextCallService();
             } else {
-                mCallService.call(mCall.toCallInfo());
+                BindCallback callback = new BindCallback() {
+                    @Override public void onSuccess() {
+                        mCallService.call(mCall.toCallInfo());
+                    }
+                    @Override public void onFailure() {
+                        attemptNextSelector();
+                    }
+                };
+                mCallService.bind(callback);
             }
         } else {
             mCallServiceInfoIterator = null;
diff --git a/src/com/android/telecomm/ServiceBinder.java b/src/com/android/telecomm/ServiceBinder.java
index c58791c..101b940 100644
--- a/src/com/android/telecomm/ServiceBinder.java
+++ b/src/com/android/telecomm/ServiceBinder.java
@@ -59,7 +59,8 @@
 
             mServiceConnection = this;
             mBinder = binder;
-            handleSuccessfulConnection(binder);
+            setServiceInterface(binder);
+            handleSuccessfulConnection();
         }
 
         @Override
@@ -140,7 +141,7 @@
             }
         } else {
             Preconditions.checkNotNull(mBinder);
-            handleSuccessfulConnection(mBinder);
+            handleSuccessfulConnection();
         }
 
         return true;
@@ -169,12 +170,8 @@
     /**
      * Notifies all the outstanding callbacks that the service is successfully bound. The list of
      * outstanding callbacks is cleared afterwards.
-     *
-     * @param binder The actual bound service implementation.
      */
-    private void handleSuccessfulConnection(IBinder binder) {
-        setServiceInterface(binder);
-
+    private void handleSuccessfulConnection() {
         for (BindCallback callback : mCallbacks) {
             callback.onSuccess();
         }
diff --git a/src/com/android/telecomm/Switchboard.java b/src/com/android/telecomm/Switchboard.java
index 32ef914..017a8d5 100644
--- a/src/com/android/telecomm/Switchboard.java
+++ b/src/com/android/telecomm/Switchboard.java
@@ -114,10 +114,11 @@
     void placeOutgoingCall(Call call) {
         ThreadUtil.checkOnMainThread();
 
-        mLookupId++;
+        mNewOutgoingCalls.add(call);
 
         // We initialize a lookup every time because between calls the set of available call
         // services can change between calls.
+        mLookupId++;
         mCallServiceRepository.initiateLookup(mLookupId);
         mSelectorRepository.initiateLookup(mLookupId);
     }