From f0500bd63571c667df7865d7484c89f671382711 Mon Sep 17 00:00:00 2001 From: Tyler Gunn Date: Tue, 1 Sep 2015 10:59:48 -0700 Subject: [PATCH] Support for Telecom Call IDs. Add support for caching telecom call ID in connection and conference classes. Enhance connection service call ID generation: For "existing calls", the connection service will try to use a call ID of the format ClassName@ID Where ClassName is the ComponentName of the connection service, and ID is a unique incrementing ID for the connection service. Bug: 23357902 Change-Id: I2284b018465e2b330fc8a3b556758e9f34a2daba --- telecomm/java/android/telecom/Conference.java | 21 ++++++++++ telecomm/java/android/telecom/Connection.java | 24 +++++++++++ .../android/telecom/ConnectionRequest.java | 33 ++++++++++++++- .../android/telecom/ConnectionService.java | 42 ++++++++++++++++--- 4 files changed, 113 insertions(+), 7 deletions(-) diff --git a/telecomm/java/android/telecom/Conference.java b/telecomm/java/android/telecom/Conference.java index 77fdb65f638f2..094b3a94bd7b6 100644 --- a/telecomm/java/android/telecom/Conference.java +++ b/telecomm/java/android/telecom/Conference.java @@ -65,6 +65,7 @@ public abstract class Conference extends Conferenceable { private final List mUnmodifiableConferenceableConnections = Collections.unmodifiableList(mConferenceableConnections); + private String mTelecomCallId; private PhoneAccountHandle mPhoneAccount; private CallAudioState mCallAudioState; private int mState = Connection.STATE_NEW; @@ -93,6 +94,26 @@ public abstract class Conference extends Conferenceable { mPhoneAccount = phoneAccount; } + /** + * Returns the telecom internal call ID associated with this conference. + * + * @return The telecom call ID. + * @hide + */ + public final String getTelecomCallId() { + return mTelecomCallId; + } + + /** + * Sets the telecom internal call ID associated with this conference. + * + * @param telecomCallId The telecom call ID. + * @hide + */ + public final void setTelecomCallId(String telecomCallId) { + mTelecomCallId = telecomCallId; + } + /** * Returns the {@link PhoneAccountHandle} the conference call is being placed through. * diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java index 7b277c5dcc94c..594e45ac5da25 100644 --- a/telecomm/java/android/telecom/Connection.java +++ b/telecomm/java/android/telecom/Connection.java @@ -1063,6 +1063,8 @@ public abstract class Connection extends Conferenceable { private final List mUnmodifiableConferenceables = Collections.unmodifiableList(mConferenceables); + // The internal telecom call ID associated with this connection. + private String mTelecomCallId; private int mState = STATE_NEW; private CallAudioState mCallAudioState; private Uri mAddress; @@ -1086,6 +1088,17 @@ public abstract class Connection extends Conferenceable { */ public Connection() {} + /** + * Returns the Telecom internal call ID associated with this connection. Should only be used + * for debugging and tracing purposes. + * + * @return The Telecom call ID. + * @hide + */ + public final String getTelecomCallId() { + return mTelecomCallId; + } + /** * @return The address (e.g., phone number) to which this Connection is currently communicating. */ @@ -1247,6 +1260,17 @@ public abstract class Connection extends Conferenceable { return mDisconnectCause; } + /** + * Sets the telecom call ID associated with this Connection. The Telecom Call ID should be used + * ONLY for debugging purposes. + * + * @param callId The telecom call ID. + * @hide + */ + public void setTelecomCallId(String callId) { + mTelecomCallId = callId; + } + /** * Inform this Connection that the state of its audio output has been changed externally. * diff --git a/telecomm/java/android/telecom/ConnectionRequest.java b/telecomm/java/android/telecom/ConnectionRequest.java index 686321476bd18..aba38fe8a376e 100644 --- a/telecomm/java/android/telecom/ConnectionRequest.java +++ b/telecomm/java/android/telecom/ConnectionRequest.java @@ -32,6 +32,7 @@ public final class ConnectionRequest implements Parcelable { private final Uri mAddress; private final Bundle mExtras; private final int mVideoState; + private final String mTelecomCallId; /** * @param accountHandle The accountHandle which should be used to place the call. @@ -42,7 +43,7 @@ public final class ConnectionRequest implements Parcelable { PhoneAccountHandle accountHandle, Uri handle, Bundle extras) { - this(accountHandle, handle, extras, VideoProfile.STATE_AUDIO_ONLY); + this(accountHandle, handle, extras, VideoProfile.STATE_AUDIO_ONLY, null); } /** @@ -56,10 +57,28 @@ public final class ConnectionRequest implements Parcelable { Uri handle, Bundle extras, int videoState) { + this(accountHandle, handle, extras, videoState, null); + } + + /** + * @param accountHandle The accountHandle which should be used to place the call. + * @param handle The handle (e.g., phone number) to which the {@link Connection} is to connect. + * @param extras Application-specific extra data. + * @param videoState Determines the video state for the connection. + * @param telecomCallId The telecom call ID. + * @hide + */ + public ConnectionRequest( + PhoneAccountHandle accountHandle, + Uri handle, + Bundle extras, + int videoState, + String telecomCallId) { mAccountHandle = accountHandle; mAddress = handle; mExtras = extras; mVideoState = videoState; + mTelecomCallId = telecomCallId; } private ConnectionRequest(Parcel in) { @@ -67,6 +86,7 @@ public final class ConnectionRequest implements Parcelable { mAddress = in.readParcelable(getClass().getClassLoader()); mExtras = in.readParcelable(getClass().getClassLoader()); mVideoState = in.readInt(); + mTelecomCallId = in.readString(); } /** @@ -99,6 +119,16 @@ public final class ConnectionRequest implements Parcelable { return mVideoState; } + /** + * Returns the internal Telecom ID associated with the connection request. + * + * @return The Telecom ID. + * @hide + */ + public String getTelecomCallId() { + return mTelecomCallId; + } + @Override public String toString() { return String.format("ConnectionRequest %s %s", @@ -134,5 +164,6 @@ public final class ConnectionRequest implements Parcelable { destination.writeParcelable(mAddress, 0); destination.writeParcelable(mExtras, 0); destination.writeInt(mVideoState); + destination.writeString(mTelecomCallId); } } diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java index 383e45b75fb04..f6ba53b0cf86c 100644 --- a/telecomm/java/android/telecom/ConnectionService.java +++ b/telecomm/java/android/telecom/ConnectionService.java @@ -115,6 +115,8 @@ public abstract class ConnectionService extends Service { private boolean mAreAccountsInitialized = false; private Conference sNullConference; + private Object mIdSyncRoot = new Object(); + private int mId = 0; private final IBinder mBinder = new IConnectionService.Stub() { @Override @@ -611,7 +613,8 @@ public abstract class ConnectionService extends Service { boolean isIncoming, boolean isUnknown) { Log.d(this, "createConnection, callManagerAccount: %s, callId: %s, request: %s, " + - "isIncoming: %b, isUnknown: %b", callManagerAccount, callId, request, isIncoming, + "isIncoming: %b, isUnknown: %b", callManagerAccount, callId, request, + isIncoming, isUnknown); Connection connection = isUnknown ? onCreateUnknownConnection(callManagerAccount, request) @@ -623,6 +626,7 @@ public abstract class ConnectionService extends Service { new DisconnectCause(DisconnectCause.ERROR)); } + connection.setTelecomCallId(callId); if (connection.getState() != Connection.STATE_DISCONNECTED) { addConnection(callId, connection); } @@ -930,6 +934,7 @@ public abstract class ConnectionService extends Service { connectionIds.add(mIdByConnection.get(connection)); } } + conference.setTelecomCallId(id); ParcelableConference parcelableConference = new ParcelableConference( conference.getPhoneAccountHandle(), conference.getState(), @@ -966,7 +971,7 @@ public abstract class ConnectionService extends Service { public final void addExistingConnection(PhoneAccountHandle phoneAccountHandle, Connection connection) { - String id = addExistingConnectionInternal(connection); + String id = addExistingConnectionInternal(phoneAccountHandle, connection); if (id != null) { List emptyList = new ArrayList<>(0); @@ -1128,18 +1133,29 @@ public abstract class ConnectionService extends Service { } /** - * Adds an existing connection to the list of connections, identified by a new UUID. + * Adds an existing connection to the list of connections, identified by a new call ID unique + * to this connection service. * * @param connection The connection. - * @return The UUID of the connection (e.g. the call-id). + * @return The ID of the connection (e.g. the call-id). */ - private String addExistingConnectionInternal(Connection connection) { - String id = UUID.randomUUID().toString(); + private String addExistingConnectionInternal(PhoneAccountHandle handle, Connection connection) { + String id; + if (handle == null) { + // If no phone account handle was provided, we cannot be sure the call ID is unique, + // so just use a random UUID. + id = UUID.randomUUID().toString(); + } else { + // Phone account handle was provided, so use the ConnectionService class name as a + // prefix for a unique incremental call ID. + id = handle.getComponentName().getClassName() + "@" + getNextCallId(); + } addConnection(id, connection); return id; } private void addConnection(String callId, Connection connection) { + connection.setTelecomCallId(callId); mConnectionById.put(callId, connection); mIdByConnection.put(connection, callId); connection.addConnectionListener(mConnectionListener); @@ -1160,6 +1176,9 @@ public abstract class ConnectionService extends Service { if (mIdByConference.containsKey(conference)) { Log.w(this, "Re-adding an existing conference: %s.", conference); } else if (conference != null) { + // Conferences do not (yet) have a PhoneAccountHandle associated with them, so we + // cannot determine a ConnectionService class name to associate with the ID, so use + // a unique UUID (for now). String id = UUID.randomUUID().toString(); mConferenceById.put(id, conference); mIdByConference.put(conference, id); @@ -1261,4 +1280,15 @@ public abstract class ConnectionService extends Service { conference.onDisconnect(); } } + + /** + * Retrieves the next call ID as maintainted by the connection service. + * + * @return The call ID. + */ + private int getNextCallId() { + synchronized(mIdSyncRoot) { + return ++mId; + } + } }