Merge "Add necessary APIs to support conference calling." into lmp-preview-dev

This commit is contained in:
Santos Cordon
2014-06-02 17:21:03 +00:00
committed by Android (Google) Code Review
8 changed files with 250 additions and 6 deletions

View File

@@ -27,6 +27,8 @@ import com.android.internal.os.SomeArgs;
import com.android.internal.telecomm.ICallService;
import com.android.internal.telecomm.ICallServiceAdapter;
import java.util.List;
/**
* Base implementation of CallService which can be used to provide calls for the system
* in-call UI. CallService is a one-way service from the framework's CallsManager to any app
@@ -59,6 +61,8 @@ public abstract class CallService extends Service {
private static final int MSG_ON_AUDIO_STATE_CHANGED = 11;
private static final int MSG_PLAY_DTMF_TONE = 12;
private static final int MSG_STOP_DTMF_TONE = 13;
private static final int MSG_ADD_TO_CONFERENCE = 14;
private static final int MSG_SPLIT_FROM_CONFERENCE = 15;
/**
* Default Handler used to consolidate binder method calls onto a single thread.
@@ -123,6 +127,29 @@ public abstract class CallService extends Service {
case MSG_STOP_DTMF_TONE:
stopDtmfTone((String) msg.obj);
break;
case MSG_ADD_TO_CONFERENCE: {
SomeArgs args = (SomeArgs) msg.obj;
try {
@SuppressWarnings("unchecked")
List<String> callIds = (List<String>) args.arg2;
String conferenceCallId = (String) args.arg1;
addToConference(conferenceCallId, callIds);
} finally {
args.recycle();
}
break;
}
case MSG_SPLIT_FROM_CONFERENCE: {
SomeArgs args = (SomeArgs) msg.obj;
try {
String conferenceCallId = (String) args.arg1;
String callId = (String) args.arg2;
splitFromConference(conferenceCallId, callId);
} finally {
args.recycle();
}
break;
}
default:
break;
}
@@ -204,6 +231,22 @@ public abstract class CallService extends Service {
args.arg2 = audioState;
mMessageHandler.obtainMessage(MSG_ON_AUDIO_STATE_CHANGED, args).sendToTarget();
}
@Override
public void addToConference(String conferenceCallId, List<String> callsToConference) {
SomeArgs args = SomeArgs.obtain();
args.arg1 = conferenceCallId;
args.arg2 = callsToConference;
mMessageHandler.obtainMessage(MSG_ADD_TO_CONFERENCE, args).sendToTarget();
}
@Override
public void splitFromConference(String conferenceCallId, String callId) {
SomeArgs args = SomeArgs.obtain();
args.arg1 = conferenceCallId;
args.arg2 = callId;
mMessageHandler.obtainMessage(MSG_SPLIT_FROM_CONFERENCE, args).sendToTarget();
}
}
/**
@@ -359,4 +402,24 @@ public abstract class CallService extends Service {
* @param audioState The new {@link CallAudioState}.
*/
public abstract void onAudioStateChanged(String activeCallId, CallAudioState audioState);
/**
* Adds the specified calls to the specified conference call.
*
* @param conferenceCallId The unique ID of the conference call onto which the specified calls
* should be added.
* @param callIds The calls to add to the conference call.
* @hide
*/
public abstract void addToConference(String conferenceCallId, List<String> callIds);
/**
* Removes the specified call from the specified conference call. This is a no-op if the call
* is not already part of the conference call.
*
* @param conferenceCallId The conference call.
* @param callId The call to remove from the conference call
* @hide
*/
public abstract void splitFromConference(String conferenceCallId, String callId);
}

View File

@@ -20,6 +20,8 @@ import android.os.RemoteException;
import com.android.internal.telecomm.ICallServiceAdapter;
import java.util.List;
/**
* Provides methods for ICallService implementations to interact with the system phone app.
* TODO(santoscordon): Need final public-facing comments in this file.
@@ -169,4 +171,46 @@ public final class CallServiceAdapter {
}
}
/**
* Indicates that the specified call can conference with any of the specified list of calls.
*
* @param callId The unique ID of the call.
* @param conferenceCapableCallIds The unique IDs of the calls which can be conferenced.
* @hide
*/
public void setCanConferenceWith(String callId, List<String> conferenceCapableCallIds) {
try {
mAdapter.setCanConferenceWith(callId, conferenceCapableCallIds);
} catch (RemoteException ignored) {
}
}
/**
* Indicates whether or not the specified call is currently conferenced into the specified
* conference call.
*
* @param conferenceCallId The unique ID of the conference call.
* @param callId The unique ID of the call being conferenced.
* @hide
*/
public void setIsConferenced(String conferenceCallId, String callId, boolean isConferenced) {
try {
mAdapter.setIsConferenced(conferenceCallId, callId, isConferenced);
} catch (RemoteException ignored) {
}
}
/**
* Indicates that the call no longer exists. Can be used with either a call or a conference
* call.
*
* @param callId The unique ID of the call.
* @hide
*/
public void removeCall(String callId) {
try {
mAdapter.removeCall(callId);
} catch (RemoteException ignored) {
}
}
}

View File

@@ -20,6 +20,8 @@ import android.net.Uri;
import android.os.Bundle;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
/**
@@ -248,6 +250,39 @@ public abstract class ConnectionService extends CallService {
findConnectionForAction(callId, "onAudioStateChanged").setAudioState(audioState);
}
/** @hide */
@Override
public final void addToConference(String conferenceCallId, List<String> callIds) {
Log.d(this, "addToConference %s, %s", conferenceCallId, callIds);
List<Connection> connections = new LinkedList<>();
for (String id : callIds) {
Connection connection = findConnectionForAction(id, "addToConference");
if (connection == NULL_CONNECTION) {
Log.w(this, "Connection missing in conference request %s.", id);
return;
}
connections.add(connection);
}
// TODO(santoscordon): Find an existing conference call or create a new one. Then call
// conferenceWith on it.
}
/** @hide */
@Override
public final void splitFromConference(String conferenceCallId, String callId) {
Log.d(this, "splitFromConference(%s, %s)", conferenceCallId, callId);
Connection connection = findConnectionForAction(callId, "splitFromConference");
if (connection == NULL_CONNECTION) {
Log.w(this, "Connection missing in conference request %s.", callId);
return;
}
// TODO(santoscordon): Find existing conference call and invoke split(connection).
}
/**
* Find a set of Subscriptions matching a given handle (e.g. phone number).
*
@@ -342,4 +377,4 @@ public abstract class ConnectionService extends CallService {
Log.w(this, "%s - Cannot find Connection %s", action, callId);
return NULL_CONNECTION;
}
}
}

View File

@@ -196,4 +196,32 @@ public final class InCallAdapter {
} catch (RemoteException e) {
}
}
/**
* Instructs Telecomm to conference the specified calls together.
*
* @param callId The unique ID of the call.
* @param callIdToConference The unique ID of the call to conference with.
* @hide
*/
void conferenceWith(String callId, String callIdToConference) {
try {
mAdapter.conferenceWith(callId, callIdToConference);
} catch (RemoteException ignored) {
}
}
/**
* Instructs Telecomm to split the specified call from any conference call with which it may be
* connected.
*
* @param callId The unique ID of the call.
* @hide
*/
void splitFromConference(String callId) {
try {
mAdapter.splitFromConference(callId);
} catch (RemoteException ignored) {
}
}
}

View File

@@ -17,13 +17,13 @@
package android.telecomm;
import android.net.Uri;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.telephony.DisconnectCause;
import java.util.Date;
import java.util.UUID;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Information about a call that is used between InCallService and Telecomm.
@@ -38,6 +38,26 @@ public final class InCallCall implements Parcelable {
private final GatewayInfo mGatewayInfo;
private final CallServiceDescriptor mCurrentCallServiceDescriptor;
private final CallServiceDescriptor mHandoffCallServiceDescriptor;
private final List<String> mConferenceCapableCallIds;
private final String mParentCallId;
private final List<String> mChildCallIds;
/** @hide */
@SuppressWarnings("unchecked")
public InCallCall(
String id,
CallState state,
int disconnectCause,
int capabilities,
long connectTimeMillis,
Uri handle,
GatewayInfo gatewayInfo,
CallServiceDescriptor descriptor,
CallServiceDescriptor handoffDescriptor) {
this(id, state, disconnectCause, capabilities, connectTimeMillis, handle, gatewayInfo,
descriptor, handoffDescriptor, Collections.EMPTY_LIST, null,
Collections.EMPTY_LIST);
}
/** @hide */
public InCallCall(
@@ -49,7 +69,10 @@ public final class InCallCall implements Parcelable {
Uri handle,
GatewayInfo gatewayInfo,
CallServiceDescriptor descriptor,
CallServiceDescriptor handoffDescriptor) {
CallServiceDescriptor handoffDescriptor,
List<String> conferenceCapableCallIds,
String parentCallId,
List<String> childCallIds) {
mId = id;
mState = state;
mDisconnectCause = disconnectCause;
@@ -59,6 +82,9 @@ public final class InCallCall implements Parcelable {
mGatewayInfo = gatewayInfo;
mCurrentCallServiceDescriptor = descriptor;
mHandoffCallServiceDescriptor = handoffDescriptor;
mConferenceCapableCallIds = conferenceCapableCallIds;
mParentCallId = parentCallId;
mChildCallIds = childCallIds;
}
/** The unique ID of the call. */
@@ -112,6 +138,31 @@ public final class InCallCall implements Parcelable {
return mHandoffCallServiceDescriptor;
}
/**
* The calls with which this call can conference.
* @hide
*/
public List<String> getConferenceCapableCallIds() {
return mConferenceCapableCallIds;
}
/**
* The conference call to which this call is conferenced. Null if not conferenced.
* @hide
*/
public String getParentCallId() {
return mParentCallId;
}
/**
* The child call-IDs if this call is a conference call. Returns an empty list if this is not
* a conference call or if the conference call contains no children.
* @hide
*/
public List<String> getChildCallIds() {
return mChildCallIds;
}
/** Responsible for creating InCallCall objects for deserialized Parcels. */
public static final Parcelable.Creator<InCallCall> CREATOR =
new Parcelable.Creator<InCallCall> () {
@@ -127,8 +178,14 @@ public final class InCallCall implements Parcelable {
GatewayInfo gatewayInfo = source.readParcelable(classLoader);
CallServiceDescriptor descriptor = source.readParcelable(classLoader);
CallServiceDescriptor handoffDescriptor = source.readParcelable(classLoader);
List<String> conferenceCapableCallIds = new ArrayList<>();
source.readList(conferenceCapableCallIds, classLoader);
String parentCallId = source.readString();
List<String> childCallIds = new ArrayList<>();
source.readList(childCallIds, classLoader);
return new InCallCall(id, state, disconnectCause, capabilities, connectTimeMillis,
handle, gatewayInfo, descriptor, handoffDescriptor);
handle, gatewayInfo, descriptor, handoffDescriptor, conferenceCapableCallIds,
parentCallId, childCallIds);
}
@Override
@@ -155,5 +212,8 @@ public final class InCallCall implements Parcelable {
destination.writeParcelable(mGatewayInfo, 0);
destination.writeParcelable(mCurrentCallServiceDescriptor, 0);
destination.writeParcelable(mHandoffCallServiceDescriptor, 0);
destination.writeList(mConferenceCapableCallIds);
destination.writeString(mParentCallId);
destination.writeList(mChildCallIds);
}
}

View File

@@ -55,4 +55,8 @@ oneway interface ICallService {
void playDtmfTone(String callId, char digit);
void stopDtmfTone(String callId);
void addToConference(String conferenceCallId, in List<String> callIds);
void splitFromConference(String conferenceCallId, String callId);
}

View File

@@ -45,4 +45,10 @@ oneway interface ICallServiceAdapter {
void setOnHold(String callId);
void setRequestingRingback(String callId, boolean ringing);
void setCanConferenceWith(String callId, in List<String> conferenceCapableCallIds);
void setIsConferenced(String conferenceCallId, String callId, boolean isConferenced);
void removeCall(String callId);
}

View File

@@ -47,4 +47,8 @@ oneway interface IInCallAdapter {
void postDialContinue(String callId);
void handoffCall(String callId);
void conferenceWith(String callId, String callIdToConference);
void splitFromConference(String callId);
}