Conversations
Conversations copied to clipboard
conversations does not handle media call (video and audio contents) properly during jingle stanza exchanges
The problem happen in the following two java classes when testing with aTalk:
- RtpContentMap#getCredentials() where allCredentials.size() is 2 for media call (video and audio contents), hence
if (allCredentials.size() == 1 && credentials != null)
should be
if (allCredentials.size() > 0 && credentials != null)
public IceUdpTransportInfo.Credentials getCredentials() {
final Set<IceUdpTransportInfo.Credentials> allCredentials = ImmutableSet.copyOf(Collections2.transform(
contents.values(),
dt -> dt.transport.getCredentials()
));
final IceUdpTransportInfo.Credentials credentials = Iterables.getFirst(allCredentials, null);
if (allCredentials.size() == 1 && credentials != null) {
return credentials;
}
throw new IllegalStateException("Content map does not have distinct credentials");
}
- It is also necessary that getCredentials() needs a pass-in parameter mediaType to return the correct IceUdpTransportInfo.Credentials; otherwise
JingleRtpConection#onIceCandidate(final IceCandidate)
will always failed when the iceCandidate is meant for the second content i.e.
if (candidate == null) {
Log.d(Config.LOGTAG, "ignoring (not sending) candidate: " + iceCandidate.toString());
return;
}
Below are the implementations that works with aTalk;
Add a new method in RtpContentMap.java
public Set<IceUdpTransportInfo.Credentials> getAllCredentials() {
final Set<IceUdpTransportInfo.Credentials> allCredentials = ImmutableSet.copyOf(Collections2.transform(
contents.values(),
dt -> dt.transport.getCredentials()
));
if (allCredentials.size() > 0) {
return allCredentials;
}
throw new IllegalStateException("Content map does not have distinct credentials");
}
and in JingleRtpConnection.java
@Override
public void onIceCandidate(final IceCandidate iceCandidate) {
final RtpContentMap rtpContentMap = isInitiator() ? this.initiatorRtpContentMap : this.responderRtpContentMap;
IceUdpTransportInfo.Candidate candidate = null;
for (IceUdpTransportInfo.Credentials credential : rtpContentMap.getAllCredentials()) {
candidate = IceUdpTransportInfo.Candidate.fromSdpAttribute(iceCandidate.sdp, credential.ufrag);
if (candidate != null)
break;
}
if (candidate == null) {
Log.d(Config.LOGTAG, "ignoring (not sending) candidate: " + iceCandidate);
return;
}
Log.d(Config.LOGTAG, "sending candidate: " + iceCandidate);
sendTransportInfo(iceCandidate.sdpMid, candidate);
}