OutgoingCalls(1/6) - Filling in lifecycle of outgoing call.

This CL adds the following:
1. CallServiceAdapter implementation
2. Setting call-service adapters when the finder receives call services.
3. CallServiceAdapter notifies OutgoingCallManager/OCP about a successful
    outgoing call
4. Switchboard notifies CallsManager of the successful outgoing call
5. CallsManager adds the call to it's call repository.

What remains after this CL:
CallsManager sending the call to the InCall app and listening to
commands from in-call.

depends on: I086443e3f17ae0233b7b0fd5629119e989d06a40

Change-Id: I86f3e7ab02a47485eb2a5fb3557819418f3c4adf
diff --git a/src/com/android/telecomm/OutgoingCallsManager.java b/src/com/android/telecomm/OutgoingCallsManager.java
new file mode 100644
index 0000000..27472f1
--- /dev/null
+++ b/src/com/android/telecomm/OutgoingCallsManager.java
@@ -0,0 +1,131 @@
+/*
+ * 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.os.RemoteException;
+import android.telecomm.ICallService;
+import android.telecomm.ICallServiceSelector;
+import android.util.Log;
+
+import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
+import com.google.common.collect.Maps;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Responsible for placing all outgoing calls. For each outgoing call, this class creates an
+ * instance of {@link OutgoingCallProcessor} which handles the details of connecting to the
+ * appropriate call service and placing the call. This class maintains a mapping from call ID
+ * to {@link OutgoingCallProcessor} so that other classes (Switchboard, CallServiceAdapter, etc),
+ * can simply call into this class instead of individual OutgoingCallProcessors.
+ */
+final class OutgoingCallsManager {
+    private static final String TAG = OutgoingCallsManager.class.getSimpleName();
+
+    private final Switchboard mSwitchboard;
+
+    /**
+     * Maps call IDs to {@link OutgoingCallProcessor}s.
+     */
+    private Map<String, OutgoingCallProcessor> mOutgoingCallProcessors = Maps.newHashMap();
+
+    /** Persists specified parameters. */
+    OutgoingCallsManager(Switchboard switchboard) {
+        mSwitchboard = switchboard;
+    }
+
+    /**
+     * Starts the process of placing a call by constructing an outgoing call processor and asking
+     * it to place the call. Upon success, execution will continue (via {@link CallServiceAdapter})
+     * to {@link #handleSuccessfulCall}. Upon failure, execution will return to
+     * {@link #handleFailedCall}.
+     *
+     * @param call The call to place.
+     * @param callServices The set of call services which can potentially place the call.
+     * @param selectors The ordered list of selectors used in placing the call.
+     */
+    void placeCall(
+            Call call, Set<ICallService> callServices, List<ICallServiceSelector> selectors) {
+
+        Log.i(TAG, "Placing an outgoing call (" + call.getId() + ")");
+
+        // Create the processor for this (outgoing) call and store it in a map such that call
+        // attempts can be aborted etc.
+        // TODO(gilad): Consider passing mSelector as an immutable set.
+        OutgoingCallProcessor processor =
+                new OutgoingCallProcessor(call, callServices, selectors, this, mSwitchboard);
+
+        mOutgoingCallProcessors.put(call.getId(), processor);
+        processor.process();
+    }
+
+    /**
+     * Removes the outgoing call processor mapping for the successful call and returns execution to
+     * the switchboard. This method is invoked from {@link CallServiceAdapter} after a call service
+     * has notified Telecomm that it successfully placed the call.
+     *
+     * @param callId The ID of the call.
+     */
+    void handleSuccessfulCallAttempt(String callId) {
+        OutgoingCallProcessor processor = mOutgoingCallProcessors.remove(callId);
+
+        if (processor == null) {
+            // Shouldn't happen, so log a wtf if it does.
+            Log.wtf(TAG, "Received an unexpected placed-call notification.");
+        } else {
+            processor.handleSuccessfulCallAttempt();
+        }
+    }
+
+    /**
+     * Notifies the appropriate outgoing call processor that a call attempt to place the call has
+     * failed and the processor should continue attempting to place the call with the next call
+     * service. This method is called from {@link CallServiceAdapter} after a call service has
+     * notified Telecomm that it could not place the call.
+     *
+     * @param callId The ID of the failed outgoing call.
+     * @param reason The call-service supplied reason for the failed call attempt.
+     */
+    void handleFailedCallAttempt(String callId, String reason) {
+        OutgoingCallProcessor processor = mOutgoingCallProcessors.get(callId);
+
+        // TODO(santoscordon): Consider combining the check here and in handleSuccessfulCallAttempt.
+        if (processor == null) {
+            // Shouldn't happen, so log a wtf if it does.
+            Log.wtf(TAG, "Received an unexpected failed-call notification.");
+        } else {
+            processor.handleFailedCallAttempt(reason);
+        }
+    }
+
+    /**
+     * Removes the outgoing call processor mapping for the failed call and returns execution to the
+     * switchboard. In contrast to handleFailedCallAttempt which comes from the call-service and
+     * goes to the outgoing-call processor indicating a single failed call attempt, this method is
+     * invoked by the outgoing-call processor to indicate that the entire process has failed and we
+     * should cleanup and notify Switchboard.
+     *
+     * @param call The failed outgoing call.
+     */
+    void handleFailedOutgoingCall(Call call) {
+        mOutgoingCallProcessors.remove(call.getId());
+        mSwitchboard.handleFailedOutgoingCall(call);
+    }
+}