Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f5d04f86 authored by Tyler Gunn's avatar Tyler Gunn Committed by android-build-merger
Browse files

Merge "Support indicating call direction on existing connections." into qt-dev

am: 91130d9c

Change-Id: I7c0754771947fe4bdd7dfa0e25eb4af4cb646db5
parents ccedca8d 91130d9c
Loading
Loading
Loading
Loading
+100 −3
Original line number Diff line number Diff line
@@ -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;
@@ -68,6 +69,13 @@ 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}.
     *
@@ -75,12 +83,15 @@ public class ConferenceParticipant implements Parcelable {
     * @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);
    }
}
+22 −0
Original line number Diff line number Diff line
@@ -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;
    }
}
+2 −1
Original line number Diff line number Diff line
@@ -2144,7 +2144,8 @@ public abstract class ConnectionService extends Service {
                    connection.getDisconnectCause(),
                    emptyList,
                    connection.getExtras(),
                    conferenceId);
                    conferenceId,
                    connection.getCallDirection());
            mAdapter.addExistingConnection(id, parcelableConnection);
        }
    }
+15 −2
Original line number Diff line number Diff line
@@ -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);
    }
}