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/CallsManager.java b/src/com/android/telecomm/CallsManager.java
index 0712f03..332eb0a 100644
--- a/src/com/android/telecomm/CallsManager.java
+++ b/src/com/android/telecomm/CallsManager.java
@@ -17,11 +17,18 @@
package com.android.telecomm;
import android.content.Context;
+import android.telecomm.CallState;
+import android.text.TextUtils;
+import android.util.Log;
import com.android.telecomm.exceptions.RestrictedCallException;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
import java.util.List;
+import java.util.Map;
/**
* Singleton.
@@ -31,6 +38,7 @@
* beyond the com.android.telecomm package boundary.
*/
public final class CallsManager {
+ private static final String TAG = CallsManager.class.getSimpleName();
private static final CallsManager INSTANCE = new CallsManager();
@@ -40,6 +48,14 @@
private final InCallController mInCallController;
/**
+ * The main call repository. Keeps an instance of all live calls keyed by call ID. New incoming
+ * and outgoing calls are added to the map and removed when the calls move to the disconnected
+ * state.
+ * TODO(santoscordon): Add new CallId class and use it in place of String.
+ */
+ private final Map<String, Call> mCalls = Maps.newHashMap();
+
+ /**
* May be unnecessary per off-line discussions (between santoscordon and gilad) since the set
* of CallsManager APIs that need to be exposed to the dialer (or any application firing call
* intents) may be empty.
@@ -65,7 +81,7 @@
*/
private CallsManager() {
mSwitchboard = new Switchboard();
- mInCallController = new InCallController(this);
+ mInCallController = new InCallController();
}
/**
@@ -90,6 +106,21 @@
}
/**
+ * Adds a new outgoing call to the list of live calls and notifies the in-call app.
+ *
+ * @param call The new outgoing call.
+ */
+ void handleSuccessfulOutgoingCall(Call call) {
+ // OutgoingCallProcessor sets the call state to DIALING when it receives confirmation of the
+ // placed call from the call service so there is no need to set it here. Instead, check that
+ // the state is appropriate.
+ Preconditions.checkState(call.getState() == CallState.DIALING);
+
+ addCall(call);
+ // TODO(santoscordon): Notify in-call UI.
+ }
+
+ /**
* Instructs Telecomm to answer the specified call. Intended to be invoked by the in-call
* app through {@link InCallAdapter} after Telecomm notifies it of an incoming call followed by
* the user opting to answer said call.
@@ -121,4 +152,57 @@
void disconnectCall(String callId) {
// TODO(santoscordon): fill in and check that the call is in the active state.
}
+
+ void markCallAsRinging(String callId) {
+ setCallState(callId, CallState.RINGING);
+ }
+
+ void markCallAsDialing(String callId) {
+ setCallState(callId, CallState.DIALING);
+ }
+
+ void markCallAsActive(String callId) {
+ setCallState(callId, CallState.ACTIVE);
+ }
+
+ void markCallAsDisconnected(String callId) {
+ setCallState(callId, CallState.DISCONNECTED);
+ mCalls.remove(callId);
+ }
+
+ /**
+ * Sets the specified state on the specified call.
+ *
+ * @param callId The ID of the call to update.
+ * @param state The new state of the call.
+ */
+ private void setCallState(String callId, CallState state) {
+ Preconditions.checkState(!Strings.isNullOrEmpty(callId));
+ Preconditions.checkNotNull(state);
+
+ Call call = mCalls.get(callId);
+ if (call == null) {
+ Log.e(TAG, "Call " + callId + " was not found while attempting to upda the state to " +
+ state + ".");
+ } else {
+ // Unfortunately, in the telephony world, the radio is king. So if the call notifies us
+ // that the call is in a particular state, we allow it even if it doesn't make sense
+ // (e.g., ACTIVE -> RINGING).
+ // TODO(santoscordon): Consider putting a stop to the above and turning CallState into
+ // a well-defined state machine.
+ // TODO(santoscordon): Define expected state transitions here, and log when an
+ // unexpected transition occurs.
+ call.setState(state);
+ // TODO(santoscordon): Notify the in-call app whenever a call changes state.
+ }
+ }
+
+ /**
+ * Adds the specified call to the main list of live calls.
+ *
+ * @param call The call to add.
+ */
+ private void addCall(Call call) {
+ mCalls.put(call.getId(), call);
+ }
}