Merge "Add support for DTMF and RTP header extension communications." am: 49612b38d8
Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1487449 Change-Id: I881bdd65e5ca5b9f2da8915523d9b47f420d3799
This commit is contained in:
@@ -11786,6 +11786,7 @@ package android.telephony.ims {
|
||||
ctor public ImsCallProfile(int, int);
|
||||
ctor public ImsCallProfile(int, int, android.os.Bundle, android.telephony.ims.ImsStreamMediaProfile);
|
||||
method public int describeContents();
|
||||
method @NonNull public java.util.Set<android.telephony.ims.RtpHeaderExtensionType> getAcceptedRtpHeaderExtensionTypes();
|
||||
method public String getCallExtra(String);
|
||||
method public String getCallExtra(String, String);
|
||||
method public boolean getCallExtraBoolean(String);
|
||||
@@ -11800,6 +11801,7 @@ package android.telephony.ims {
|
||||
method public int getEmergencyServiceCategories();
|
||||
method @NonNull public java.util.List<java.lang.String> getEmergencyUrns();
|
||||
method public android.telephony.ims.ImsStreamMediaProfile getMediaProfile();
|
||||
method @NonNull public java.util.Set<android.telephony.ims.RtpHeaderExtensionType> getOfferedRtpHeaderExtensionTypes();
|
||||
method @NonNull public android.os.Bundle getProprietaryCallExtras();
|
||||
method public int getRestrictCause();
|
||||
method public int getServiceType();
|
||||
@@ -11810,6 +11812,7 @@ package android.telephony.ims {
|
||||
method public boolean isVideoCall();
|
||||
method public boolean isVideoPaused();
|
||||
method public static int presentationToOir(int);
|
||||
method public void setAcceptedRtpHeaderExtensionTypes(@NonNull java.util.Set<android.telephony.ims.RtpHeaderExtensionType>);
|
||||
method public void setCallExtra(String, String);
|
||||
method public void setCallExtraBoolean(String, boolean);
|
||||
method public void setCallExtraInt(String, int);
|
||||
@@ -11820,6 +11823,7 @@ package android.telephony.ims {
|
||||
method public void setEmergencyServiceCategories(int);
|
||||
method public void setEmergencyUrns(@NonNull java.util.List<java.lang.String>);
|
||||
method public void setHasKnownUserIntentEmergency(boolean);
|
||||
method public void setOfferedRtpHeaderExtensionTypes(@NonNull java.util.Set<android.telephony.ims.RtpHeaderExtensionType>);
|
||||
method public void updateCallExtras(android.telephony.ims.ImsCallProfile);
|
||||
method public void updateCallType(android.telephony.ims.ImsCallProfile);
|
||||
method public void updateMediaProfile(android.telephony.ims.ImsCallProfile);
|
||||
@@ -11879,6 +11883,7 @@ package android.telephony.ims {
|
||||
method public void callSessionConferenceExtendReceived(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile);
|
||||
method public void callSessionConferenceExtended(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile);
|
||||
method public void callSessionConferenceStateUpdated(android.telephony.ims.ImsConferenceState);
|
||||
method public void callSessionDtmfReceived(char);
|
||||
method @Deprecated public void callSessionHandover(int, int, android.telephony.ims.ImsReasonInfo);
|
||||
method @Deprecated public void callSessionHandoverFailed(int, int, android.telephony.ims.ImsReasonInfo);
|
||||
method public void callSessionHeld(android.telephony.ims.ImsCallProfile);
|
||||
@@ -11899,6 +11904,7 @@ package android.telephony.ims {
|
||||
method public void callSessionResumeFailed(android.telephony.ims.ImsReasonInfo);
|
||||
method public void callSessionResumeReceived(android.telephony.ims.ImsCallProfile);
|
||||
method public void callSessionResumed(android.telephony.ims.ImsCallProfile);
|
||||
method public void callSessionRtpHeaderExtensionsReceived(@NonNull java.util.Set<android.telephony.ims.RtpHeaderExtension>);
|
||||
method public void callSessionRttAudioIndicatorChanged(@NonNull android.telephony.ims.ImsStreamMediaProfile);
|
||||
method public void callSessionRttMessageReceived(String);
|
||||
method public void callSessionRttModifyRequestReceived(android.telephony.ims.ImsCallProfile);
|
||||
@@ -12255,6 +12261,24 @@ package android.telephony.ims {
|
||||
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setUceSettingEnabled(boolean) throws android.telephony.ims.ImsException;
|
||||
}
|
||||
|
||||
public final class RtpHeaderExtension implements android.os.Parcelable {
|
||||
ctor public RtpHeaderExtension(@IntRange(from=1, to=14) int, @NonNull byte[]);
|
||||
method public int describeContents();
|
||||
method @NonNull public byte[] getExtensionData();
|
||||
method @IntRange(from=1, to=14) public int getLocalIdentifier();
|
||||
method public void writeToParcel(@NonNull android.os.Parcel, int);
|
||||
field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.RtpHeaderExtension> CREATOR;
|
||||
}
|
||||
|
||||
public final class RtpHeaderExtensionType implements android.os.Parcelable {
|
||||
ctor public RtpHeaderExtensionType(@IntRange(from=1, to=14) int, @NonNull android.net.Uri);
|
||||
method public int describeContents();
|
||||
method @IntRange(from=1, to=14) public int getLocalIdentifier();
|
||||
method @NonNull public android.net.Uri getUri();
|
||||
method public void writeToParcel(@NonNull android.os.Parcel, int);
|
||||
field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.RtpHeaderExtensionType> CREATOR;
|
||||
}
|
||||
|
||||
public class SipDelegateManager {
|
||||
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isSupported() throws android.telephony.ims.ImsException;
|
||||
}
|
||||
@@ -12371,6 +12395,7 @@ package android.telephony.ims.stub {
|
||||
method public void removeParticipants(String[]);
|
||||
method public void resume(android.telephony.ims.ImsStreamMediaProfile);
|
||||
method public void sendDtmf(char, android.os.Message);
|
||||
method public void sendRtpHeaderExtensions(@NonNull java.util.Set<android.telephony.ims.RtpHeaderExtension>);
|
||||
method public void sendRttMessage(String);
|
||||
method public void sendRttModifyRequest(android.telephony.ims.ImsCallProfile);
|
||||
method public void sendRttModifyResponse(boolean);
|
||||
|
||||
@@ -10668,6 +10668,7 @@ package android.telephony.ims {
|
||||
ctor public ImsCallProfile(int, int);
|
||||
ctor public ImsCallProfile(int, int, android.os.Bundle, android.telephony.ims.ImsStreamMediaProfile);
|
||||
method public int describeContents();
|
||||
method @NonNull public java.util.Set<android.telephony.ims.RtpHeaderExtensionType> getAcceptedRtpHeaderExtensionTypes();
|
||||
method public String getCallExtra(String);
|
||||
method public String getCallExtra(String, String);
|
||||
method public boolean getCallExtraBoolean(String);
|
||||
@@ -10682,6 +10683,7 @@ package android.telephony.ims {
|
||||
method public int getEmergencyServiceCategories();
|
||||
method @NonNull public java.util.List<java.lang.String> getEmergencyUrns();
|
||||
method public android.telephony.ims.ImsStreamMediaProfile getMediaProfile();
|
||||
method @NonNull public java.util.Set<android.telephony.ims.RtpHeaderExtensionType> getOfferedRtpHeaderExtensionTypes();
|
||||
method @NonNull public android.os.Bundle getProprietaryCallExtras();
|
||||
method public int getRestrictCause();
|
||||
method public int getServiceType();
|
||||
@@ -10692,6 +10694,7 @@ package android.telephony.ims {
|
||||
method public boolean isVideoCall();
|
||||
method public boolean isVideoPaused();
|
||||
method public static int presentationToOir(int);
|
||||
method public void setAcceptedRtpHeaderExtensionTypes(@NonNull java.util.Set<android.telephony.ims.RtpHeaderExtensionType>);
|
||||
method public void setCallExtra(String, String);
|
||||
method public void setCallExtraBoolean(String, boolean);
|
||||
method public void setCallExtraInt(String, int);
|
||||
@@ -10702,6 +10705,7 @@ package android.telephony.ims {
|
||||
method public void setEmergencyServiceCategories(int);
|
||||
method public void setEmergencyUrns(@NonNull java.util.List<java.lang.String>);
|
||||
method public void setHasKnownUserIntentEmergency(boolean);
|
||||
method public void setOfferedRtpHeaderExtensionTypes(@NonNull java.util.Set<android.telephony.ims.RtpHeaderExtensionType>);
|
||||
method public void updateCallExtras(android.telephony.ims.ImsCallProfile);
|
||||
method public void updateCallType(android.telephony.ims.ImsCallProfile);
|
||||
method public void updateMediaProfile(android.telephony.ims.ImsCallProfile);
|
||||
@@ -10761,6 +10765,7 @@ package android.telephony.ims {
|
||||
method public void callSessionConferenceExtendReceived(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile);
|
||||
method public void callSessionConferenceExtended(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile);
|
||||
method public void callSessionConferenceStateUpdated(android.telephony.ims.ImsConferenceState);
|
||||
method public void callSessionDtmfReceived(char);
|
||||
method @Deprecated public void callSessionHandover(int, int, android.telephony.ims.ImsReasonInfo);
|
||||
method @Deprecated public void callSessionHandoverFailed(int, int, android.telephony.ims.ImsReasonInfo);
|
||||
method public void callSessionHeld(android.telephony.ims.ImsCallProfile);
|
||||
@@ -10781,6 +10786,7 @@ package android.telephony.ims {
|
||||
method public void callSessionResumeFailed(android.telephony.ims.ImsReasonInfo);
|
||||
method public void callSessionResumeReceived(android.telephony.ims.ImsCallProfile);
|
||||
method public void callSessionResumed(android.telephony.ims.ImsCallProfile);
|
||||
method public void callSessionRtpHeaderExtensionsReceived(@NonNull java.util.Set<android.telephony.ims.RtpHeaderExtension>);
|
||||
method public void callSessionRttAudioIndicatorChanged(@NonNull android.telephony.ims.ImsStreamMediaProfile);
|
||||
method public void callSessionRttMessageReceived(String);
|
||||
method public void callSessionRttModifyRequestReceived(android.telephony.ims.ImsCallProfile);
|
||||
@@ -11137,6 +11143,24 @@ package android.telephony.ims {
|
||||
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setUceSettingEnabled(boolean) throws android.telephony.ims.ImsException;
|
||||
}
|
||||
|
||||
public final class RtpHeaderExtension implements android.os.Parcelable {
|
||||
ctor public RtpHeaderExtension(@IntRange(from=1, to=14) int, @NonNull byte[]);
|
||||
method public int describeContents();
|
||||
method @NonNull public byte[] getExtensionData();
|
||||
method @IntRange(from=1, to=14) public int getLocalIdentifier();
|
||||
method public void writeToParcel(@NonNull android.os.Parcel, int);
|
||||
field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.RtpHeaderExtension> CREATOR;
|
||||
}
|
||||
|
||||
public final class RtpHeaderExtensionType implements android.os.Parcelable {
|
||||
ctor public RtpHeaderExtensionType(@IntRange(from=1, to=14) int, @NonNull android.net.Uri);
|
||||
method public int describeContents();
|
||||
method @IntRange(from=1, to=14) public int getLocalIdentifier();
|
||||
method @NonNull public android.net.Uri getUri();
|
||||
method public void writeToParcel(@NonNull android.os.Parcel, int);
|
||||
field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.RtpHeaderExtensionType> CREATOR;
|
||||
}
|
||||
|
||||
public class SipDelegateManager {
|
||||
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isSupported() throws android.telephony.ims.ImsException;
|
||||
}
|
||||
@@ -11253,6 +11277,7 @@ package android.telephony.ims.stub {
|
||||
method public void removeParticipants(String[]);
|
||||
method public void resume(android.telephony.ims.ImsStreamMediaProfile);
|
||||
method public void sendDtmf(char, android.os.Message);
|
||||
method public void sendRtpHeaderExtensions(@NonNull java.util.Set<android.telephony.ims.RtpHeaderExtension>);
|
||||
method public void sendRttMessage(String);
|
||||
method public void sendRttModifyRequest(android.telephony.ims.ImsCallProfile);
|
||||
method public void sendRttModifyResponse(boolean);
|
||||
|
||||
@@ -28,6 +28,8 @@ import android.telecom.VideoProfile;
|
||||
import android.telephony.emergency.EmergencyNumber;
|
||||
import android.telephony.emergency.EmergencyNumber.EmergencyCallRouting;
|
||||
import android.telephony.emergency.EmergencyNumber.EmergencyServiceCategories;
|
||||
import android.telephony.ims.feature.MmTelFeature;
|
||||
import android.util.ArraySet;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
@@ -37,7 +39,10 @@ import com.android.internal.telephony.util.TelephonyUtils;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* A Parcelable object to handle the IMS call profile, which provides the service, call type, and
|
||||
@@ -444,6 +449,10 @@ public final class ImsCallProfile implements Parcelable {
|
||||
/** Indicates if we have known the intent of the user for the call is emergency */
|
||||
private boolean mHasKnownUserIntentEmergency = false;
|
||||
|
||||
private Set<RtpHeaderExtensionType> mOfferedRtpHeaderExtensionTypes = new ArraySet<>();
|
||||
|
||||
private Set<RtpHeaderExtensionType> mAcceptedRtpHeaderExtensionTypes = new ArraySet<>();
|
||||
|
||||
/**
|
||||
* Extras associated with this {@link ImsCallProfile}.
|
||||
* <p>
|
||||
@@ -682,6 +691,8 @@ public final class ImsCallProfile implements Parcelable {
|
||||
out.writeBoolean(mHasKnownUserIntentEmergency);
|
||||
out.writeInt(mRestrictCause);
|
||||
out.writeInt(mCallerNumberVerificationStatus);
|
||||
out.writeArray(mOfferedRtpHeaderExtensionTypes.toArray());
|
||||
out.writeArray(mAcceptedRtpHeaderExtensionTypes.toArray());
|
||||
}
|
||||
|
||||
private void readFromParcel(Parcel in) {
|
||||
@@ -696,9 +707,16 @@ public final class ImsCallProfile implements Parcelable {
|
||||
mHasKnownUserIntentEmergency = in.readBoolean();
|
||||
mRestrictCause = in.readInt();
|
||||
mCallerNumberVerificationStatus = in.readInt();
|
||||
Object[] offered = in.readArray(RtpHeaderExtensionType.class.getClassLoader());
|
||||
mOfferedRtpHeaderExtensionTypes = Arrays.stream(offered)
|
||||
.map(o -> (RtpHeaderExtensionType) o).collect(Collectors.toSet());
|
||||
Object[] accepted = in.readArray(RtpHeaderExtensionType.class.getClassLoader());
|
||||
mAcceptedRtpHeaderExtensionTypes = Arrays.stream(accepted)
|
||||
.map(o -> (RtpHeaderExtensionType) o).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
public static final @android.annotation.NonNull Creator<ImsCallProfile> CREATOR = new Creator<ImsCallProfile>() {
|
||||
public static final @android.annotation.NonNull Creator<ImsCallProfile> CREATOR =
|
||||
new Creator<ImsCallProfile>() {
|
||||
@Override
|
||||
public ImsCallProfile createFromParcel(Parcel in) {
|
||||
return new ImsCallProfile(in);
|
||||
@@ -1085,4 +1103,66 @@ public final class ImsCallProfile implements Parcelable {
|
||||
public boolean hasKnownUserIntentEmergency() {
|
||||
return mHasKnownUserIntentEmergency;
|
||||
}
|
||||
|
||||
/**
|
||||
* For an incoming or outgoing call, indicates the {@link RtpHeaderExtensionType}s which the
|
||||
* caller is offering to make available.
|
||||
* <p>
|
||||
* For outgoing calls, an {@link ImsService} will reserve
|
||||
* {@link RtpHeaderExtensionType#getLocalIdentifier()} identifiers the telephony stack has
|
||||
* proposed to use and not use these same local identifiers. The offered header extension
|
||||
* types for an outgoing call can be found in the
|
||||
* {@link ImsCallProfile#getOfferedRtpHeaderExtensionTypes()} and will be available to the
|
||||
* {@link ImsService} in {@link MmTelFeature#createCallSession(ImsCallProfile)}.
|
||||
* The {@link ImsService} sets the accepted {@link #setAcceptedRtpHeaderExtensionTypes(Set)}
|
||||
* when the SDP offer/accept process has completed.
|
||||
* <p>
|
||||
* According to RFC8285, RTP header extensions available to a call are determined using the
|
||||
* offer/accept phase of the SDP protocol (see RFC4566).
|
||||
*
|
||||
* @return the {@link RtpHeaderExtensionType}s which were offered by other end of the call.
|
||||
*/
|
||||
public @NonNull Set<RtpHeaderExtensionType> getOfferedRtpHeaderExtensionTypes() {
|
||||
return mOfferedRtpHeaderExtensionTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the offered {@link RtpHeaderExtensionType}s for this call.
|
||||
* <p>
|
||||
* According to RFC8285, RTP header extensions available to a call are determined using the
|
||||
* offer/accept phase of the SDP protocol (see RFC4566).
|
||||
*
|
||||
* @param rtpHeaderExtensions the {@link RtpHeaderExtensionType}s which are offered.
|
||||
*/
|
||||
public void setOfferedRtpHeaderExtensionTypes(@NonNull Set<RtpHeaderExtensionType>
|
||||
rtpHeaderExtensions) {
|
||||
mOfferedRtpHeaderExtensionTypes.clear();
|
||||
mOfferedRtpHeaderExtensionTypes.addAll(rtpHeaderExtensions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link RtpHeaderExtensionType}s which have been accepted by both ends of the call.
|
||||
* <p>
|
||||
* According to RFC8285, RTP header extensions available to a call are determined using the
|
||||
* offer/accept phase of the SDP protocol (see RFC4566).
|
||||
*
|
||||
* @return the {@link RtpHeaderExtensionType}s which were accepted by the other end of the call.
|
||||
*/
|
||||
public @NonNull Set<RtpHeaderExtensionType> getAcceptedRtpHeaderExtensionTypes() {
|
||||
return mAcceptedRtpHeaderExtensionTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the accepted {@link RtpHeaderExtensionType}s for this call.
|
||||
* <p>
|
||||
* According to RFC8285, RTP header extensions available to a call are determined using the
|
||||
* offer/accept phase of the SDP protocol (see RFC4566).
|
||||
*
|
||||
* @param rtpHeaderExtensions
|
||||
*/
|
||||
public void setAcceptedRtpHeaderExtensionTypes(@NonNull Set<RtpHeaderExtensionType>
|
||||
rtpHeaderExtensions) {
|
||||
mAcceptedRtpHeaderExtensionTypes.clear();
|
||||
mAcceptedRtpHeaderExtensionTypes.addAll(rtpHeaderExtensions);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,11 +22,16 @@ import android.os.Message;
|
||||
import android.os.RemoteException;
|
||||
import android.telephony.CallQuality;
|
||||
import android.telephony.ims.aidl.IImsCallSessionListener;
|
||||
import android.util.ArraySet;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.ims.internal.IImsCallSession;
|
||||
import com.android.ims.internal.IImsVideoCallProvider;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Provides the call initiation/termination, and media exchange between two IMS endpoints.
|
||||
* It directly communicates with IMS service which implements the IMS protocol behavior.
|
||||
@@ -467,12 +472,32 @@ public class ImsCallSession {
|
||||
// no-op
|
||||
}
|
||||
|
||||
/**
|
||||
* Informs the framework of a DTMF digit which was received from the network.
|
||||
* <p>
|
||||
* According to <a href="http://tools.ietf.org/html/rfc2833">RFC 2833 sec 3.10</a>,
|
||||
* event 0 ~ 9 maps to decimal value 0 ~ 9, '*' to 10, '#' to 11, event 'A' ~ 'D' to
|
||||
* 12 ~ 15.
|
||||
* @param digit the DTMF digit
|
||||
*/
|
||||
public void callSessionDtmfReceived(char digit) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the IMS service reports a change to the call quality.
|
||||
*/
|
||||
public void callQualityChanged(CallQuality callQuality) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the IMS service reports incoming RTP header extension data.
|
||||
*/
|
||||
public void callSessionRtpHeaderExtensionsReceived(
|
||||
@NonNull Set<RtpHeaderExtension> extensions) {
|
||||
// no-op
|
||||
}
|
||||
}
|
||||
|
||||
private final IImsCallSession miSession;
|
||||
@@ -1118,6 +1143,31 @@ public class ImsCallSession {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests that {@code rtpHeaderExtensions} are sent as a header extension with the next
|
||||
* RTP packet sent by the IMS stack.
|
||||
* <p>
|
||||
* The {@link RtpHeaderExtensionType}s negotiated during SDP (Session Description Protocol)
|
||||
* signalling determine the {@link RtpHeaderExtension}s which can be sent using this method.
|
||||
* See RFC8285 for more information.
|
||||
* <p>
|
||||
* By specification, the RTP header extension is an unacknowledged transmission and there is no
|
||||
* guarantee that the header extension will be delivered by the network to the other end of the
|
||||
* call.
|
||||
* @param rtpHeaderExtensions The header extensions to be included in the next RTP header.
|
||||
*/
|
||||
public void sendRtpHeaderExtensions(@NonNull Set<RtpHeaderExtension> rtpHeaderExtensions) {
|
||||
if (mClosed) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
miSession.sendRtpHeaderExtensions(
|
||||
new ArrayList<RtpHeaderExtension>(rtpHeaderExtensions));
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A listener type for receiving notification on IMS call session events.
|
||||
* When an event is generated for an {@link IImsCallSession},
|
||||
@@ -1476,6 +1526,17 @@ public class ImsCallSession {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DTMF digit received.
|
||||
* @param dtmf The DTMF digit.
|
||||
*/
|
||||
@Override
|
||||
public void callSessionDtmfReceived(char dtmf) {
|
||||
if (mListener != null) {
|
||||
mListener.callSessionDtmfReceived(dtmf);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Call quality updated
|
||||
*/
|
||||
@@ -1485,6 +1546,19 @@ public class ImsCallSession {
|
||||
mListener.callQualityChanged(callQuality);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* RTP header extension data received.
|
||||
* @param extensions The header extension data.
|
||||
*/
|
||||
@Override
|
||||
public void callSessionRtpHeaderExtensionsReceived(
|
||||
@NonNull List<RtpHeaderExtension> extensions) {
|
||||
if (mListener != null) {
|
||||
mListener.callSessionRtpHeaderExtensionsReceived(
|
||||
new ArraySet<RtpHeaderExtension>(extensions));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -28,6 +28,10 @@ import android.telephony.ims.stub.ImsCallSessionImplBase;
|
||||
|
||||
import com.android.ims.internal.IImsCallSession;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Listener interface for notifying the Framework's {@link ImsCallSession} for updates to an ongoing
|
||||
* IMS call.
|
||||
@@ -682,6 +686,59 @@ public class ImsCallSessionListener {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The {@link ImsService} calls this method to inform the framework of a DTMF digit which was
|
||||
* received from the network.
|
||||
* <p>
|
||||
* According to <a href="http://tools.ietf.org/html/rfc2833">RFC 2833 sec 3.10</a>,
|
||||
* event 0 ~ 9 maps to decimal value 0 ~ 9, '*' to 10, '#' to 11, event 'A' ~ 'D' to 12 ~ 15.
|
||||
* <p>
|
||||
* <em>Note:</em> Alpha DTMF digits are converted from lower-case to upper-case.
|
||||
*
|
||||
* @param dtmf The DTMF digit received, '0'-'9', *, #, A, B, C, or D.
|
||||
* @throws IllegalArgumentException If an invalid DTMF character is provided.
|
||||
*/
|
||||
public void callSessionDtmfReceived(char dtmf) {
|
||||
if (!(dtmf >= '0' && dtmf <= '9'
|
||||
|| dtmf >= 'A' && dtmf <= 'D'
|
||||
|| dtmf >= 'a' && dtmf <= 'd'
|
||||
|| dtmf == '*'
|
||||
|| dtmf == '#')) {
|
||||
throw new IllegalArgumentException("DTMF digit must be 0-9, *, #, A, B, C, D");
|
||||
}
|
||||
try {
|
||||
mListener.callSessionDtmfReceived(Character.toUpperCase(dtmf));
|
||||
} catch (RemoteException e) {
|
||||
e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The {@link ImsService} calls this method to inform the framework of RTP header extension data
|
||||
* which was received from the network.
|
||||
* <p>
|
||||
* The set of {@link RtpHeaderExtension} data are identified by local identifiers which were
|
||||
* negotiated during SDP signalling. See RFC8285,
|
||||
* {@link ImsCallProfile#getAcceptedRtpHeaderExtensionTypes()} and
|
||||
* {@link RtpHeaderExtensionType} for more information.
|
||||
* <p>
|
||||
* By specification, the RTP header extension is an unacknowledged transmission and there is no
|
||||
* guarantee that the header extension will be delivered by the network to the other end of the
|
||||
* call.
|
||||
*
|
||||
* @param extensions The RTP header extension data received.
|
||||
*/
|
||||
public void callSessionRtpHeaderExtensionsReceived(
|
||||
@NonNull Set<RtpHeaderExtension> extensions) {
|
||||
Objects.requireNonNull(extensions, "extensions are required.");
|
||||
try {
|
||||
mListener.callSessionRtpHeaderExtensionsReceived(
|
||||
new ArrayList<RtpHeaderExtension>(extensions));
|
||||
} catch (RemoteException e) {
|
||||
e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies the result of transfer request.
|
||||
* @hide
|
||||
|
||||
19
telephony/java/android/telephony/ims/RtpHeaderExtension.aidl
Normal file
19
telephony/java/android/telephony/ims/RtpHeaderExtension.aidl
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (c) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.telephony.ims;
|
||||
|
||||
parcelable RtpHeaderExtension;
|
||||
137
telephony/java/android/telephony/ims/RtpHeaderExtension.java
Normal file
137
telephony/java/android/telephony/ims/RtpHeaderExtension.java
Normal file
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.telephony.ims;
|
||||
|
||||
import android.annotation.IntRange;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.SystemApi;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* A representation of an RTP header extension.
|
||||
* <p>
|
||||
* Per RFC8285, an RTP header extension consists of both a local identifier in the range 1-14, an
|
||||
* 8-bit length indicator and a number of extension data bytes equivalent to the stated length.
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
public final class RtpHeaderExtension implements Parcelable {
|
||||
private int mLocalIdentifier;
|
||||
private byte[] mExtensionData;
|
||||
|
||||
/**
|
||||
* Creates a new {@link RtpHeaderExtension}.
|
||||
* @param localIdentifier The local identifier for this RTP header extension.
|
||||
* @param extensionData The data for this RTP header extension.
|
||||
* @throws IllegalArgumentException if {@code extensionId} is not in the range 1-14.
|
||||
* @throws NullPointerException if {@code extensionData} is null.
|
||||
*/
|
||||
public RtpHeaderExtension(@IntRange(from = 1, to = 14) int localIdentifier,
|
||||
@NonNull byte[] extensionData) {
|
||||
if (localIdentifier < 1 || localIdentifier > 13) {
|
||||
throw new IllegalArgumentException("localIdentifier must be in range 1-14");
|
||||
}
|
||||
if (extensionData == null) {
|
||||
throw new NullPointerException("extensionDa is required.");
|
||||
}
|
||||
mLocalIdentifier = localIdentifier;
|
||||
mExtensionData = extensionData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance of {@link RtpHeaderExtension} from a parcel.
|
||||
* @param in The parceled data to read.
|
||||
*/
|
||||
private RtpHeaderExtension(@NonNull Parcel in) {
|
||||
mLocalIdentifier = in.readInt();
|
||||
mExtensionData = in.createByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* The local identifier for the RTP header extension.
|
||||
* <p>
|
||||
* Per RFC8285, the extension ID is a value in the range 1-14 (0 is reserved for padding and
|
||||
* 15 is reserved for the one-byte header form.
|
||||
* <p>
|
||||
* Within the current call, this extension ID will match one of the
|
||||
* {@link RtpHeaderExtensionType#getLocalIdentifier()}s.
|
||||
*
|
||||
* @return The local identifier for this RTP header extension.
|
||||
*/
|
||||
@IntRange(from = 1, to = 14)
|
||||
public int getLocalIdentifier() {
|
||||
return mLocalIdentifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* The data payload for the RTP header extension.
|
||||
* <p>
|
||||
* Per RFC8285 Sec 4.3, an RTP header extension includes an 8-bit length field which indicate
|
||||
* how many bytes of data are present in the RTP header extension. The extension includes this
|
||||
* many bytes of actual data.
|
||||
* <p>
|
||||
* We represent this as a byte array who's length is equivalent to the 8-bit length field.
|
||||
* @return RTP header extension data payload. The payload may be up to 255 bytes in length.
|
||||
*/
|
||||
public @NonNull byte[] getExtensionData() {
|
||||
return mExtensionData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
dest.writeInt(mLocalIdentifier);
|
||||
dest.writeByteArray(mExtensionData);
|
||||
}
|
||||
|
||||
public static final @NonNull Creator<RtpHeaderExtension> CREATOR =
|
||||
new Creator<RtpHeaderExtension>() {
|
||||
@Override
|
||||
public RtpHeaderExtension createFromParcel(@NonNull Parcel in) {
|
||||
return new RtpHeaderExtension(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RtpHeaderExtension[] newArray(int size) {
|
||||
return new RtpHeaderExtension[size];
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
RtpHeaderExtension that = (RtpHeaderExtension) o;
|
||||
return mLocalIdentifier == that.mLocalIdentifier
|
||||
&& Arrays.equals(mExtensionData, that.mExtensionData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = Objects.hash(mLocalIdentifier);
|
||||
result = 31 * result + Arrays.hashCode(mExtensionData);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (c) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.telephony.ims;
|
||||
|
||||
parcelable RtpHeaderExtensionType;
|
||||
136
telephony/java/android/telephony/ims/RtpHeaderExtensionType.java
Normal file
136
telephony/java/android/telephony/ims/RtpHeaderExtensionType.java
Normal file
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.telephony.ims;
|
||||
|
||||
import android.annotation.IntRange;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.SystemApi;
|
||||
import android.net.Uri;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Defines a mapping between a local identifier and a {@link Uri} which identifies an RTP header
|
||||
* extension.
|
||||
* <p>
|
||||
* According to RFC8285, SDP (Session Description Protocol) signalling for a call provides a means
|
||||
* for the supported RTP header extensions for a call to be negotiated at call initiation time.
|
||||
* The types of RTP header extensions potentially usable in a session are identified by a local
|
||||
* identifier ({@link #getLocalIdentifier()}) when RTP header extensions are present on RTP packets.
|
||||
* A {@link Uri} ({@link #getUri()}) provides a unique identifier for the RTP header extension
|
||||
* format which parties in a call can use to identify supported RTP header extensions.
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
public final class RtpHeaderExtensionType implements Parcelable {
|
||||
private int mLocalIdentifier;
|
||||
private Uri mUri;
|
||||
|
||||
/**
|
||||
* Create a new RTP header extension type.
|
||||
* @param localIdentifier the local identifier.
|
||||
* @param uri the {@link Uri} identifying the RTP header extension type.
|
||||
* @throws IllegalArgumentException if {@code localIdentifier} is out of the expected range.
|
||||
* @throws NullPointerException if {@code uri} is null.
|
||||
*/
|
||||
public RtpHeaderExtensionType(@IntRange(from = 1, to = 14) int localIdentifier,
|
||||
@NonNull Uri uri) {
|
||||
if (localIdentifier < 1 || localIdentifier > 13) {
|
||||
throw new IllegalArgumentException("localIdentifier must be in range 1-14");
|
||||
}
|
||||
if (uri == null) {
|
||||
throw new NullPointerException("uri is required.");
|
||||
}
|
||||
mLocalIdentifier = localIdentifier;
|
||||
mUri = uri;
|
||||
}
|
||||
|
||||
private RtpHeaderExtensionType(Parcel in) {
|
||||
mLocalIdentifier = in.readInt();
|
||||
mUri = in.readParcelable(Uri.class.getClassLoader());
|
||||
}
|
||||
|
||||
public static final @NonNull Creator<RtpHeaderExtensionType> CREATOR =
|
||||
new Creator<RtpHeaderExtensionType>() {
|
||||
@Override
|
||||
public RtpHeaderExtensionType createFromParcel(@NonNull Parcel in) {
|
||||
return new RtpHeaderExtensionType(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull RtpHeaderExtensionType[] newArray(int size) {
|
||||
return new RtpHeaderExtensionType[size];
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
dest.writeInt(mLocalIdentifier);
|
||||
dest.writeParcelable(mUri, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* The local identifier for this RTP header extension type.
|
||||
* <p>
|
||||
* {@link RtpHeaderExtension}s which indicate a {@link RtpHeaderExtension#getLocalIdentifier()}
|
||||
* matching this local identifier will have the format specified by {@link #getUri()}.
|
||||
* <p>
|
||||
* Per RFC8285, the extension ID is a value in the range 1-14 (0 is reserved for padding and
|
||||
* 15 is reserved for the one-byte header form.
|
||||
*
|
||||
* @return The local identifier associated with this {@link #getUri()}.
|
||||
*/
|
||||
public @IntRange(from = 1, to = 14) int getLocalIdentifier() {
|
||||
return mLocalIdentifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* A {@link Uri} which identifies the format of the RTP extension header.
|
||||
* <p>
|
||||
* According to RFC8285 section 5, URIs MUST be absolute and SHOULD contain a month/date pair
|
||||
* in the form mmyyyy to indicate versioning of the extension. Extension headers defined in an
|
||||
* RFC are typically defined using URNs starting with {@code urn:ietf:params:rtp-hdrext:}.
|
||||
* For example, RFC6464 defines {@code urn:ietf:params:rtp-hdrext:ssrc-audio-level} which is an
|
||||
* RTP header extension for communicating client to mixer audio level indications.
|
||||
*
|
||||
* @return A unique {@link Uri} identifying the format of the RTP extension header.
|
||||
*/
|
||||
public @NonNull Uri getUri() {
|
||||
return mUri;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
RtpHeaderExtensionType that = (RtpHeaderExtensionType) o;
|
||||
return mLocalIdentifier == that.mLocalIdentifier
|
||||
&& mUri.equals(that.mUri);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(mLocalIdentifier, mUri);
|
||||
}
|
||||
}
|
||||
@@ -21,9 +21,12 @@ import android.telephony.ims.ImsStreamMediaProfile;
|
||||
import android.telephony.ims.ImsCallProfile;
|
||||
import android.telephony.ims.ImsReasonInfo;
|
||||
import android.telephony.ims.ImsConferenceState;
|
||||
import android.telephony.ims.RtpHeaderExtension;
|
||||
import com.android.ims.internal.IImsCallSession;
|
||||
import android.telephony.ims.ImsSuppServiceNotification;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A listener type for receiving notification on IMS call session events.
|
||||
* When an event is generated for an {@link IImsCallSession}, the application is notified
|
||||
@@ -153,9 +156,17 @@ oneway interface IImsCallSessionListener {
|
||||
void callSessionTransferred();
|
||||
void callSessionTransferFailed(in ImsReasonInfo reasonInfo);
|
||||
|
||||
void callSessionDtmfReceived(char dtmf);
|
||||
|
||||
/**
|
||||
* Notifies of a change to the call quality.
|
||||
* @param callQuality then updated call quality
|
||||
*/
|
||||
void callQualityChanged(in CallQuality callQuality);
|
||||
|
||||
/**
|
||||
* Notifies of incoming RTP header extensions from the network.
|
||||
* @param extensions the RTP header extensions received.
|
||||
*/
|
||||
void callSessionRtpHeaderExtensionsReceived(in List<RtpHeaderExtension> extensions);
|
||||
}
|
||||
|
||||
@@ -29,11 +29,14 @@ import android.telephony.ims.ImsConferenceState;
|
||||
import android.telephony.ims.ImsReasonInfo;
|
||||
import android.telephony.ims.ImsStreamMediaProfile;
|
||||
import android.telephony.ims.ImsSuppServiceNotification;
|
||||
import android.telephony.ims.RtpHeaderExtension;
|
||||
import android.telephony.ims.aidl.IImsCallSessionListener;
|
||||
|
||||
import com.android.ims.internal.IImsCallSession;
|
||||
import com.android.ims.internal.IImsVideoCallProvider;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Compat implementation of ImsCallSessionImplBase for older implementations.
|
||||
*
|
||||
@@ -403,6 +406,15 @@ public class ImsCallSessionImplBase extends IImsCallSession.Stub {
|
||||
public void sendRttMessage(String rttMessage) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Device sends RTP header extensions.
|
||||
* @param headerExtensions The header extensions to send.
|
||||
*/
|
||||
@Override
|
||||
public void sendRtpHeaderExtensions(@NonNull List<RtpHeaderExtension> headerExtensions) {
|
||||
// no-op; not supported in compat layer.
|
||||
}
|
||||
|
||||
/**
|
||||
* There are two different ImsCallSessionListeners that need to reconciled here, we need to
|
||||
* convert the "old" version of the com.android.ims.internal.IImsCallSessionListener to the
|
||||
|
||||
@@ -26,10 +26,17 @@ import android.telephony.ims.ImsCallSessionListener;
|
||||
import android.telephony.ims.ImsReasonInfo;
|
||||
import android.telephony.ims.ImsStreamMediaProfile;
|
||||
import android.telephony.ims.ImsVideoCallProvider;
|
||||
import android.telephony.ims.RtpHeaderExtension;
|
||||
import android.telephony.ims.RtpHeaderExtensionType;
|
||||
import android.telephony.ims.aidl.IImsCallSessionListener;
|
||||
import android.util.ArraySet;
|
||||
|
||||
import com.android.ims.internal.IImsCallSession;
|
||||
import com.android.ims.internal.IImsVideoCallProvider;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Base implementation of IImsCallSession, which implements stub versions of the methods available.
|
||||
*
|
||||
@@ -277,6 +284,12 @@ public class ImsCallSessionImplBase implements AutoCloseable {
|
||||
public void sendRttMessage(String rttMessage) {
|
||||
ImsCallSessionImplBase.this.sendRttMessage(rttMessage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendRtpHeaderExtensions(@NonNull List<RtpHeaderExtension> extensions) {
|
||||
ImsCallSessionImplBase.this.sendRtpHeaderExtensions(
|
||||
new ArraySet<RtpHeaderExtension>(extensions));
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -636,6 +649,22 @@ public class ImsCallSessionImplBase implements AutoCloseable {
|
||||
public void sendRttMessage(String rttMessage) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Device requests that {@code rtpHeaderExtensions} are sent as a header extension with the next
|
||||
* RTP packet sent by the IMS stack.
|
||||
* <p>
|
||||
* The {@link RtpHeaderExtensionType}s negotiated during SDP (Session Description Protocol)
|
||||
* signalling determine the {@link RtpHeaderExtension}s which can be sent using this method.
|
||||
* See RFC8285 for more information.
|
||||
* <p>
|
||||
* By specification, the RTP header extension is an unacknowledged transmission and there is no
|
||||
* guarantee that the header extension will be delivered by the network to the other end of the
|
||||
* call.
|
||||
* @param rtpHeaderExtensions The RTP header extensions to be included in the next RTP header.
|
||||
*/
|
||||
public void sendRtpHeaderExtensions(@NonNull Set<RtpHeaderExtension> rtpHeaderExtensions) {
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public IImsCallSession getServiceImpl() {
|
||||
return mServiceImpl;
|
||||
|
||||
@@ -20,6 +20,8 @@ import android.os.Message;
|
||||
import android.telephony.ims.aidl.IImsCallSessionListener;
|
||||
import android.telephony.ims.ImsCallProfile;
|
||||
import android.telephony.ims.ImsStreamMediaProfile;
|
||||
import android.telephony.ims.RtpHeaderExtension;
|
||||
|
||||
import com.android.ims.internal.IImsVideoCallProvider;
|
||||
|
||||
/**
|
||||
@@ -297,4 +299,10 @@ interface IImsCallSession {
|
||||
* @param rttMessage RTT message to be sent
|
||||
*/
|
||||
void sendRttMessage(in String rttMessage);
|
||||
|
||||
/*
|
||||
* Device sends RTP header extension(s).
|
||||
* @param extensions the header extensions to be sent
|
||||
*/
|
||||
void sendRtpHeaderExtensions(in List<RtpHeaderExtension> extensions);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user