summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Tyler Gunn <tgunn@google.com> 2019-06-25 13:45:32 -0700
committer Tyler Gunn <tgunn@google.com> 2019-06-25 13:48:29 -0700
commit6986a63325261b063316797c0a51f9989fbba622 (patch)
treef2f3f8ea70e99f06f7a9fdfc592e88c574152c33
parentc760a652ab4bf5cd909abf1b647fe1a84b3a7870 (diff)
Support indicating call direction on existing connections.
This is important for ensuring the original call direction for existing connections added from Conference Event Packages matches the call direction of the original calls merged into the conference. Also moved a utility function into ConferenceParticipant from ConferenceParticipantConnection to make it generically usable inside Telephony. Test: Run all unit tests. Test: Manual testing using VoLTE conference calls with mix of MO and MT calls; verify call logging is appropriate. Bug: 134471046 Change-Id: Iab09397b811782ab0f876aac02070e3447d81f09
-rw-r--r--telecomm/java/android/telecom/ConferenceParticipant.java103
-rw-r--r--telecomm/java/android/telecom/Connection.java22
-rw-r--r--telecomm/java/android/telecom/ConnectionService.java3
-rw-r--r--telecomm/java/android/telecom/ParcelableConnection.java17
4 files changed, 139 insertions, 6 deletions
diff --git a/telecomm/java/android/telecom/ConferenceParticipant.java b/telecomm/java/android/telecom/ConferenceParticipant.java
index 2f1505cd9e4e..5e4818a67b31 100644
--- a/telecomm/java/android/telecom/ConferenceParticipant.java
+++ b/telecomm/java/android/telecom/ConferenceParticipant.java
@@ -19,6 +19,7 @@ package android.telecom;
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
+import android.telephony.PhoneNumberUtils;
import android.text.TextUtils;
import com.android.internal.annotations.VisibleForTesting;
@@ -69,18 +70,28 @@ public class ConferenceParticipant implements Parcelable {
private long mConnectElapsedTime;
/**
+ * The direction of the call;
+ * {@link Call.Details#DIRECTION_INCOMING} for incoming calls, or
+ * {@link Call.Details#DIRECTION_OUTGOING} for outgoing calls.
+ */
+ private int mCallDirection;
+
+ /**
* Creates an instance of {@code ConferenceParticipant}.
*
* @param handle The conference participant's handle (e.g., phone number).
* @param displayName The display name for the participant.
* @param endpoint The enpoint Uri which uniquely identifies this conference participant.
* @param state The state of the participant in the conference.
+ * @param callDirection The direction of the call (incoming/outgoing).
*/
- public ConferenceParticipant(Uri handle, String displayName, Uri endpoint, int state) {
+ public ConferenceParticipant(Uri handle, String displayName, Uri endpoint, int state,
+ int callDirection) {
mHandle = handle;
mDisplayName = displayName;
mEndpoint = endpoint;
mState = state;
+ mCallDirection = callDirection;
}
/**
@@ -96,7 +107,16 @@ public class ConferenceParticipant implements Parcelable {
String displayName = source.readString();
Uri endpoint = source.readParcelable(classLoader);
int state = source.readInt();
- return new ConferenceParticipant(handle, displayName, endpoint, state);
+ long connectTime = source.readLong();
+ long elapsedRealTime = source.readLong();
+ int callDirection = source.readInt();
+ ConferenceParticipant participant =
+ new ConferenceParticipant(handle, displayName, endpoint, state,
+ callDirection);
+ participant.setConnectTime(connectTime);
+ participant.setConnectElapsedTime(elapsedRealTime);
+ participant.setCallDirection(callDirection);
+ return participant;
}
@Override
@@ -170,6 +190,9 @@ public class ConferenceParticipant implements Parcelable {
dest.writeString(mDisplayName);
dest.writeParcelable(mEndpoint, 0);
dest.writeInt(mState);
+ dest.writeLong(mConnectTime);
+ dest.writeLong(mConnectElapsedTime);
+ dest.writeInt(mCallDirection);
}
/**
@@ -192,6 +215,8 @@ public class ConferenceParticipant implements Parcelable {
sb.append(getConnectTime());
sb.append(" ConnectElapsedTime: ");
sb.append(getConnectElapsedTime());
+ sb.append(" Direction: ");
+ sb.append(getCallDirection() == Call.Details.DIRECTION_INCOMING ? "Incoming" : "Outgoing");
sb.append("]");
return sb.toString();
}
@@ -239,7 +264,7 @@ public class ConferenceParticipant implements Parcelable {
}
/**
- * The connect elpased time of the participant to the conference.
+ * The connect elapsed time of the participant to the conference.
*/
public long getConnectElapsedTime() {
return mConnectElapsedTime;
@@ -248,4 +273,76 @@ public class ConferenceParticipant implements Parcelable {
public void setConnectElapsedTime(long connectElapsedTime) {
mConnectElapsedTime = connectElapsedTime;
}
+
+ /**
+ * @return The direction of the call (incoming/outgoing).
+ */
+ public @Call.Details.CallDirection int getCallDirection() {
+ return mCallDirection;
+ }
+
+ /**
+ * Sets the direction of the call.
+ * @param callDirection Whether the call is incoming or outgoing.
+ */
+ public void setCallDirection(@Call.Details.CallDirection int callDirection) {
+ mCallDirection = callDirection;
+ }
+
+ /**
+ * Attempts to build a tel: style URI from a conference participant.
+ * Conference event package data contains SIP URIs, so we try to extract the phone number and
+ * format into a typical tel: style URI.
+ *
+ * @param address The conference participant's address.
+ * @param countryIso The country ISO of the current subscription; used when formatting the
+ * participant phone number to E.164 format.
+ * @return The participant's address URI.
+ * @hide
+ */
+ @VisibleForTesting
+ public static Uri getParticipantAddress(Uri address, String countryIso) {
+ if (address == null) {
+ return address;
+ }
+ // Even if address is already in tel: format, still parse it and rebuild.
+ // This is to recognize tel URIs such as:
+ // tel:6505551212;phone-context=ims.mnc012.mcc034.3gppnetwork.org
+
+ // Conference event package participants are identified using SIP URIs (see RFC3261).
+ // A valid SIP uri has the format: sip:user:password@host:port;uri-parameters?headers
+ // Per RFC3261, the "user" can be a telephone number.
+ // For example: sip:1650555121;phone-context=blah.com@host.com
+ // In this case, the phone number is in the user field of the URI, and the parameters can be
+ // ignored.
+ //
+ // A SIP URI can also specify a phone number in a format similar to:
+ // sip:+1-212-555-1212@something.com;user=phone
+ // In this case, the phone number is again in user field and the parameters can be ignored.
+ // We can get the user field in these instances by splitting the string on the @, ;, or :
+ // and looking at the first found item.
+ String number = address.getSchemeSpecificPart();
+ if (TextUtils.isEmpty(number)) {
+ return address;
+ }
+
+ String numberParts[] = number.split("[@;:]");
+ if (numberParts.length == 0) {
+ return address;
+ }
+ number = numberParts[0];
+
+ // Attempt to format the number in E.164 format and use that as part of the TEL URI.
+ // RFC2806 recommends to format telephone numbers using E.164 since it is independent of
+ // how the dialing of said numbers takes place.
+ // If conversion to E.164 fails, the returned value is null. In that case, fallback to the
+ // number which was in the CEP data.
+ String formattedNumber = null;
+ if (!TextUtils.isEmpty(countryIso)) {
+ formattedNumber = PhoneNumberUtils.formatNumberToE164(number, countryIso);
+ }
+
+ return Uri.fromParts(PhoneAccount.SCHEME_TEL,
+ formattedNumber != null ? formattedNumber : number, null);
+ }
}
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index 47587c5787f4..0983eea8e819 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -1793,6 +1793,11 @@ public abstract class Connection extends Conferenceable {
private ConnectionService mConnectionService;
private Bundle mExtras;
private final Object mExtrasLock = new Object();
+ /**
+ * The direction of the connection; used where an existing connection is created and we need to
+ * communicate to Telecom whether its incoming or outgoing.
+ */
+ private @Call.Details.CallDirection int mCallDirection = Call.Details.DIRECTION_UNKNOWN;
/**
* Tracks the key set for the extras bundle provided on the last invocation of
@@ -3357,4 +3362,21 @@ public abstract class Connection extends Conferenceable {
l.onConnectionEvent(this, event, extras);
}
}
+
+ /**
+ * @return The direction of the call.
+ * @hide
+ */
+ public final @Call.Details.CallDirection int getCallDirection() {
+ return mCallDirection;
+ }
+
+ /**
+ * Sets the direction of this connection.
+ * @param callDirection The direction of this connection.
+ * @hide
+ */
+ public void setCallDirection(@Call.Details.CallDirection int callDirection) {
+ mCallDirection = callDirection;
+ }
}
diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java
index 626fcc4ddc1e..35488100fb58 100644
--- a/telecomm/java/android/telecom/ConnectionService.java
+++ b/telecomm/java/android/telecom/ConnectionService.java
@@ -2144,7 +2144,8 @@ public abstract class ConnectionService extends Service {
connection.getDisconnectCause(),
emptyList,
connection.getExtras(),
- conferenceId);
+ conferenceId,
+ connection.getCallDirection());
mAdapter.addExistingConnection(id, parcelableConnection);
}
}
diff --git a/telecomm/java/android/telecom/ParcelableConnection.java b/telecomm/java/android/telecom/ParcelableConnection.java
index dab1c6e7ae77..4734af6371d4 100644
--- a/telecomm/java/android/telecom/ParcelableConnection.java
+++ b/telecomm/java/android/telecom/ParcelableConnection.java
@@ -53,6 +53,7 @@ public final class ParcelableConnection implements Parcelable {
private final List<String> mConferenceableConnectionIds;
private final Bundle mExtras;
private String mParentCallId;
+ private @Call.Details.CallDirection int mCallDirection;
/** @hide */
public ParcelableConnection(
@@ -75,13 +76,15 @@ public final class ParcelableConnection implements Parcelable {
DisconnectCause disconnectCause,
List<String> conferenceableConnectionIds,
Bundle extras,
- String parentCallId) {
+ String parentCallId,
+ @Call.Details.CallDirection int callDirection) {
this(phoneAccount, state, capabilities, properties, supportedAudioRoutes, address,
addressPresentation, callerDisplayName, callerDisplayNamePresentation,
videoProvider, videoState, ringbackRequested, isVoipAudioMode, connectTimeMillis,
connectElapsedTimeMillis, statusHints, disconnectCause, conferenceableConnectionIds,
extras);
mParentCallId = parentCallId;
+ mCallDirection = callDirection;
}
/** @hide */
@@ -125,6 +128,7 @@ public final class ParcelableConnection implements Parcelable {
mConferenceableConnectionIds = conferenceableConnectionIds;
mExtras = extras;
mParentCallId = null;
+ mCallDirection = Call.Details.DIRECTION_UNKNOWN;
}
public PhoneAccountHandle getPhoneAccount() {
@@ -219,6 +223,10 @@ public final class ParcelableConnection implements Parcelable {
return mParentCallId;
}
+ public @Call.Details.CallDirection int getCallDirection() {
+ return mCallDirection;
+ }
+
@Override
public String toString() {
return new StringBuilder()
@@ -234,6 +242,8 @@ public final class ParcelableConnection implements Parcelable {
.append(mExtras)
.append(", parent:")
.append(mParentCallId)
+ .append(", callDirection:")
+ .append(mCallDirection)
.toString();
}
@@ -265,6 +275,7 @@ public final class ParcelableConnection implements Parcelable {
int supportedAudioRoutes = source.readInt();
String parentCallId = source.readString();
long connectElapsedTimeMillis = source.readLong();
+ int callDirection = source.readInt();
return new ParcelableConnection(
phoneAccount,
@@ -286,7 +297,8 @@ public final class ParcelableConnection implements Parcelable {
disconnectCause,
conferenceableConnectionIds,
extras,
- parentCallId);
+ parentCallId,
+ callDirection);
}
@Override
@@ -325,5 +337,6 @@ public final class ParcelableConnection implements Parcelable {
destination.writeInt(mSupportedAudioRoutes);
destination.writeString(mParentCallId);
destination.writeLong(mConnectElapsedTimeMillis);
+ destination.writeInt(mCallDirection);
}
}