rtp session propsoal: fix race condition with very fast 'busy' or 'error'
This commit is contained in:
parent
c527e76337
commit
cb37321ecb
|
@ -131,6 +131,7 @@ public class CallIntegrationConnectionService extends ConnectionService {
|
||||||
intent.putExtra(
|
intent.putExtra(
|
||||||
RtpSessionActivity.EXTRA_LAST_REPORTED_STATE,
|
RtpSessionActivity.EXTRA_LAST_REPORTED_STATE,
|
||||||
RtpEndUserState.FINDING_DEVICE.toString());
|
RtpEndUserState.FINDING_DEVICE.toString());
|
||||||
|
intent.putExtra(RtpSessionActivity.EXTRA_PROPOSED_SESSION_ID, proposal.sessionId);
|
||||||
callIntegration = proposal.getCallIntegration();
|
callIntegration = proposal.getCallIntegration();
|
||||||
}
|
}
|
||||||
if (Media.audioOnly(media)) {
|
if (Media.audioOnly(media)) {
|
||||||
|
|
|
@ -80,6 +80,7 @@ public class RtpSessionActivity extends XmppActivity
|
||||||
|
|
||||||
public static final String EXTRA_WITH = "with";
|
public static final String EXTRA_WITH = "with";
|
||||||
public static final String EXTRA_SESSION_ID = "session_id";
|
public static final String EXTRA_SESSION_ID = "session_id";
|
||||||
|
public static final String EXTRA_PROPOSED_SESSION_ID = "proposed_session_id";
|
||||||
public static final String EXTRA_LAST_REPORTED_STATE = "last_reported_state";
|
public static final String EXTRA_LAST_REPORTED_STATE = "last_reported_state";
|
||||||
public static final String EXTRA_LAST_ACTION = "last_action";
|
public static final String EXTRA_LAST_ACTION = "last_action";
|
||||||
public static final String ACTION_ACCEPT_CALL = "action_accept_call";
|
public static final String ACTION_ACCEPT_CALL = "action_accept_call";
|
||||||
|
@ -386,7 +387,6 @@ public class RtpSessionActivity extends XmppActivity
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void putScreenInCallMode() {
|
private void putScreenInCallMode() {
|
||||||
putScreenInCallMode(requireRtpConnection().getMedia());
|
putScreenInCallMode(requireRtpConnection().getMedia());
|
||||||
}
|
}
|
||||||
|
@ -509,6 +509,16 @@ public class RtpSessionActivity extends XmppActivity
|
||||||
proposeJingleRtpSession(account, with, actionToMedia(action));
|
proposeJingleRtpSession(account, with, actionToMedia(action));
|
||||||
setWith(account.getRoster().getContact(with), null);
|
setWith(account.getRoster().getContact(with), null);
|
||||||
} else if (Intent.ACTION_VIEW.equals(action)) {
|
} else if (Intent.ACTION_VIEW.equals(action)) {
|
||||||
|
final String proposedSessionId = intent.getStringExtra(EXTRA_PROPOSED_SESSION_ID);
|
||||||
|
final JingleConnectionManager.TerminatedRtpSession terminatedRtpSession =
|
||||||
|
xmppConnectionService
|
||||||
|
.getJingleConnectionManager()
|
||||||
|
.getTerminalSessionState(with, proposedSessionId);
|
||||||
|
if (terminatedRtpSession != null) {
|
||||||
|
// termination (due to message error or 'busy' was faster than opening the activity
|
||||||
|
initializeWithTerminatedSessionState(account, with, terminatedRtpSession);
|
||||||
|
return;
|
||||||
|
}
|
||||||
final String extraLastState = intent.getStringExtra(EXTRA_LAST_REPORTED_STATE);
|
final String extraLastState = intent.getStringExtra(EXTRA_LAST_REPORTED_STATE);
|
||||||
final String lastAction = intent.getStringExtra(EXTRA_LAST_ACTION);
|
final String lastAction = intent.getStringExtra(EXTRA_LAST_ACTION);
|
||||||
final Set<Media> media = actionToMedia(lastAction);
|
final Set<Media> media = actionToMedia(lastAction);
|
||||||
|
@ -1007,7 +1017,7 @@ public class RtpSessionActivity extends XmppActivity
|
||||||
private void updateInCallButtonConfiguration(
|
private void updateInCallButtonConfiguration(
|
||||||
final RtpEndUserState state, final Set<Media> media) {
|
final RtpEndUserState state, final Set<Media> media) {
|
||||||
if (STATES_CONSIDERED_CONNECTED.contains(state) && !isPictureInPicture()) {
|
if (STATES_CONSIDERED_CONNECTED.contains(state) && !isPictureInPicture()) {
|
||||||
Preconditions.checkArgument(media.size() > 0, "Media must not be empty");
|
Preconditions.checkArgument(!media.isEmpty(), "Media must not be empty");
|
||||||
if (media.contains(Media.VIDEO)) {
|
if (media.contains(Media.VIDEO)) {
|
||||||
final JingleRtpConnection rtpConnection = requireRtpConnection();
|
final JingleRtpConnection rtpConnection = requireRtpConnection();
|
||||||
updateInCallButtonConfigurationVideo(
|
updateInCallButtonConfigurationVideo(
|
||||||
|
@ -1028,7 +1038,13 @@ public class RtpSessionActivity extends XmppActivity
|
||||||
} else if (STATES_SHOWING_SPEAKER_CONFIGURATION.contains(state)
|
} else if (STATES_SHOWING_SPEAKER_CONFIGURATION.contains(state)
|
||||||
&& !isPictureInPicture()
|
&& !isPictureInPicture()
|
||||||
&& Media.audioOnly(media)) {
|
&& Media.audioOnly(media)) {
|
||||||
final CallIntegration callIntegration = requireCallIntegration();
|
final CallIntegration callIntegration;
|
||||||
|
try {
|
||||||
|
callIntegration = requireCallIntegration();
|
||||||
|
} catch (final IllegalStateException e) {
|
||||||
|
Log.e(Config.LOGTAG, "can not update InCallButtonConfiguration in state " + state);
|
||||||
|
return;
|
||||||
|
}
|
||||||
updateInCallButtonConfigurationSpeaker(
|
updateInCallButtonConfigurationSpeaker(
|
||||||
callIntegration.getSelectedAudioDevice(),
|
callIntegration.getSelectedAudioDevice(),
|
||||||
callIntegration.getAudioDevices().size());
|
callIntegration.getAudioDevices().size());
|
||||||
|
|
|
@ -505,6 +505,7 @@ public class JingleConnectionManager extends AbstractConnectionManager {
|
||||||
getRtpSessionProposal(account, from.asBareJid(), sessionId);
|
getRtpSessionProposal(account, from.asBareJid(), sessionId);
|
||||||
synchronized (rtpSessionProposals) {
|
synchronized (rtpSessionProposals) {
|
||||||
if (proposal != null) {
|
if (proposal != null) {
|
||||||
|
setTerminalSessionState(proposal, RtpEndUserState.DECLINED_OR_BUSY);
|
||||||
rtpSessionProposals.remove(proposal);
|
rtpSessionProposals.remove(proposal);
|
||||||
proposal.callIntegration.busy();
|
proposal.callIntegration.busy();
|
||||||
writeLogMissedOutgoing(
|
writeLogMissedOutgoing(
|
||||||
|
@ -938,7 +939,12 @@ public class JingleConnectionManager extends AbstractConnectionManager {
|
||||||
final DeviceDiscoveryState currentState =
|
final DeviceDiscoveryState currentState =
|
||||||
sessionProposal == null ? null : rtpSessionProposals.get(sessionProposal);
|
sessionProposal == null ? null : rtpSessionProposals.get(sessionProposal);
|
||||||
if (currentState == null) {
|
if (currentState == null) {
|
||||||
Log.d(Config.LOGTAG, "unable to find session proposal for session id " + sessionId);
|
Log.d(
|
||||||
|
Config.LOGTAG,
|
||||||
|
"unable to find session proposal for session id "
|
||||||
|
+ sessionId
|
||||||
|
+ " target="
|
||||||
|
+ target);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (currentState == DeviceDiscoveryState.DISCOVERED) {
|
if (currentState == DeviceDiscoveryState.DISCOVERED) {
|
||||||
|
@ -947,14 +953,7 @@ public class JingleConnectionManager extends AbstractConnectionManager {
|
||||||
"session proposal already at discovered. not going to fall back");
|
"session proposal already at discovered. not going to fall back");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.rtpSessionProposals.put(sessionProposal, target);
|
|
||||||
final RtpEndUserState endUserState = target.toEndUserState();
|
|
||||||
if (endUserState == RtpEndUserState.RINGING) {
|
|
||||||
sessionProposal.callIntegration.setDialing();
|
|
||||||
}
|
|
||||||
// toneManager.transition(endUserState, sessionProposal.media);
|
|
||||||
mXmppConnectionService.notifyJingleRtpConnectionUpdate(
|
|
||||||
account, sessionProposal.with, sessionProposal.sessionId, endUserState);
|
|
||||||
Log.d(
|
Log.d(
|
||||||
Config.LOGTAG,
|
Config.LOGTAG,
|
||||||
account.getJid().asBareJid()
|
account.getJid().asBareJid()
|
||||||
|
@ -962,6 +961,30 @@ public class JingleConnectionManager extends AbstractConnectionManager {
|
||||||
+ sessionId
|
+ sessionId
|
||||||
+ " as "
|
+ " as "
|
||||||
+ target);
|
+ target);
|
||||||
|
|
||||||
|
final RtpEndUserState endUserState = target.toEndUserState();
|
||||||
|
|
||||||
|
if (target == DeviceDiscoveryState.FAILED) {
|
||||||
|
Log.d(Config.LOGTAG, "removing session proposal after failure");
|
||||||
|
setTerminalSessionState(sessionProposal, endUserState);
|
||||||
|
this.rtpSessionProposals.remove(sessionProposal);
|
||||||
|
sessionProposal.getCallIntegration().error();
|
||||||
|
mXmppConnectionService.notifyJingleRtpConnectionUpdate(
|
||||||
|
account,
|
||||||
|
sessionProposal.with,
|
||||||
|
sessionProposal.sessionId,
|
||||||
|
endUserState);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.rtpSessionProposals.put(sessionProposal, target);
|
||||||
|
|
||||||
|
if (endUserState == RtpEndUserState.RINGING) {
|
||||||
|
sessionProposal.callIntegration.setDialing();
|
||||||
|
}
|
||||||
|
|
||||||
|
mXmppConnectionService.notifyJingleRtpConnectionUpdate(
|
||||||
|
account, sessionProposal.with, sessionProposal.sessionId, endUserState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1020,6 +1043,11 @@ public class JingleConnectionManager extends AbstractConnectionManager {
|
||||||
PersistableSessionId.of(id), new TerminatedRtpSession(state, media));
|
PersistableSessionId.of(id), new TerminatedRtpSession(state, media));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setTerminalSessionState(final RtpSessionProposal proposal, final RtpEndUserState state) {
|
||||||
|
this.terminatedSessions.put(
|
||||||
|
PersistableSessionId.of(proposal), new TerminatedRtpSession(state, proposal.media));
|
||||||
|
}
|
||||||
|
|
||||||
public TerminatedRtpSession getTerminalSessionState(final Jid with, final String sessionId) {
|
public TerminatedRtpSession getTerminalSessionState(final Jid with, final String sessionId) {
|
||||||
return this.terminatedSessions.getIfPresent(new PersistableSessionId(with, sessionId));
|
return this.terminatedSessions.getIfPresent(new PersistableSessionId(with, sessionId));
|
||||||
}
|
}
|
||||||
|
@ -1033,10 +1061,14 @@ public class JingleConnectionManager extends AbstractConnectionManager {
|
||||||
this.sessionId = sessionId;
|
this.sessionId = sessionId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PersistableSessionId of(AbstractJingleConnection.Id id) {
|
public static PersistableSessionId of(final AbstractJingleConnection.Id id) {
|
||||||
return new PersistableSessionId(id.with, id.sessionId);
|
return new PersistableSessionId(id.with, id.sessionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static PersistableSessionId of(final RtpSessionProposal proposal) {
|
||||||
|
return new PersistableSessionId(proposal.with, proposal.sessionId);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
|
|
|
@ -2708,14 +2708,14 @@ public class JingleRtpConnection extends AbstractJingleConnection
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCallIntegrationShowIncomingCallUi() {
|
public synchronized void onCallIntegrationShowIncomingCallUi() {
|
||||||
if (isTerminated()) {
|
if (isTerminated()) {
|
||||||
// there might be race conditions with the call integration service invoking this
|
// there might be race conditions with the call integration service invoking this
|
||||||
// callback when the rtp session has already ended. It should be enough to just return
|
// callback when the rtp session has already ended.
|
||||||
// instead of throwing an exception. however throwing an exception gives us a sense of
|
Log.w(
|
||||||
// if and how frequently this happens
|
Config.LOGTAG,
|
||||||
throw new IllegalStateException(
|
|
||||||
"CallIntegration requested incoming call UI but session was already terminated");
|
"CallIntegration requested incoming call UI but session was already terminated");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
// TODO apparently this can be called too early as well?
|
// TODO apparently this can be called too early as well?
|
||||||
xmppConnectionService.getNotificationService().startRinging(id, getMedia());
|
xmppConnectionService.getNotificationService().startRinging(id, getMedia());
|
||||||
|
|
Loading…
Reference in a new issue