diff --git a/src/main/java/eu/siacs/conversations/entities/Account.java b/src/main/java/eu/siacs/conversations/entities/Account.java index 365df734e..168e7a9ce 100644 --- a/src/main/java/eu/siacs/conversations/entities/Account.java +++ b/src/main/java/eu/siacs/conversations/entities/Account.java @@ -29,6 +29,7 @@ import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.utils.UIHelper; import eu.siacs.conversations.utils.XmppUri; import eu.siacs.conversations.xmpp.XmppConnection; +import eu.siacs.conversations.xmpp.jingle.RtpCapability; import rocks.xmpp.addr.Jid; public class Account extends AbstractEntity implements AvatarService.Avatarable { @@ -426,6 +427,16 @@ public class Account extends AbstractEntity implements AvatarService.Avatarable return this.getSelfContact().getPresences().size(); } + public int activeDevicesWithRtpCapability() { + int i = 0; + for(Presence presence : getSelfContact().getPresences().getPresences().values()) { + if (RtpCapability.check(presence) != RtpCapability.Capability.NONE) { + i++; + } + } + return i; + } + public String getPgpSignature() { return getKey(KEY_PGP_SIGNATURE); } diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index e8016fc01..9bd9ba63e 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -120,7 +120,10 @@ import eu.siacs.conversations.utils.UIHelper; import eu.siacs.conversations.xmpp.XmppConnection; import eu.siacs.conversations.xmpp.chatstate.ChatState; import eu.siacs.conversations.xmpp.jingle.AbstractJingleConnection; +import eu.siacs.conversations.xmpp.jingle.JingleConnectionManager; import eu.siacs.conversations.xmpp.jingle.JingleFileTransferConnection; +import eu.siacs.conversations.xmpp.jingle.Media; +import eu.siacs.conversations.xmpp.jingle.OngoingRtpSession; import eu.siacs.conversations.xmpp.jingle.RtpCapability; import rocks.xmpp.addr.Jid; @@ -971,7 +974,7 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke menuCall.setVisible(false); menuOngoingCall.setVisible(false); } else { - final Optional ongoingRtpSession = activity.xmppConnectionService.getJingleConnectionManager().getOngoingRtpConnection(conversation.getContact()); + final Optional ongoingRtpSession = activity.xmppConnectionService.getJingleConnectionManager().getOngoingRtpConnection(conversation.getContact()); if (ongoingRtpSession.isPresent()) { menuOngoingCall.setVisible(true); menuCall.setVisible(false); @@ -1267,13 +1270,22 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke } private void returnToOngoingCall() { - final Optional ongoingRtpSession = activity.xmppConnectionService.getJingleConnectionManager().getOngoingRtpConnection(conversation.getContact()); + final Optional ongoingRtpSession = activity.xmppConnectionService.getJingleConnectionManager().getOngoingRtpConnection(conversation.getContact()); if (ongoingRtpSession.isPresent()) { - final AbstractJingleConnection.Id id = ongoingRtpSession.get(); + final OngoingRtpSession id = ongoingRtpSession.get(); final Intent intent = new Intent(getActivity(), RtpSessionActivity.class); - intent.putExtra(RtpSessionActivity.EXTRA_ACCOUNT, id.account.getJid().asBareJid().toEscapedString()); - intent.putExtra(RtpSessionActivity.EXTRA_WITH, id.with.toEscapedString()); - intent.putExtra(RtpSessionActivity.EXTRA_SESSION_ID, id.sessionId); + intent.putExtra(RtpSessionActivity.EXTRA_ACCOUNT, id.getAccount().getJid().asBareJid().toEscapedString()); + intent.putExtra(RtpSessionActivity.EXTRA_WITH, id.getWith().toEscapedString()); + if (id instanceof AbstractJingleConnection.Id) { + intent.setAction(Intent.ACTION_VIEW); + intent.putExtra(RtpSessionActivity.EXTRA_SESSION_ID, id.getSessionId()); + } else if (id instanceof JingleConnectionManager.RtpSessionProposal) { + if (((JingleConnectionManager.RtpSessionProposal) id).media.contains(Media.VIDEO)) { + intent.setAction(RtpSessionActivity.ACTION_MAKE_VIDEO_CALL); + } else { + intent.setAction(RtpSessionActivity.ACTION_MAKE_VOICE_CALL); + } + } startActivity(intent); } diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java index dacfc8df0..1618cca7f 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java @@ -26,6 +26,7 @@ import eu.siacs.conversations.utils.EmojiWrapper; import eu.siacs.conversations.utils.IrregularUnicodeDetector; import eu.siacs.conversations.utils.UIHelper; import eu.siacs.conversations.xmpp.jingle.AbstractJingleConnection; +import eu.siacs.conversations.xmpp.jingle.OngoingRtpSession; import rocks.xmpp.addr.Jid; public class ConversationAdapter extends RecyclerView.Adapter { @@ -165,7 +166,7 @@ public class ConversationAdapter extends RecyclerView.Adapter ongoingCall; + final Optional ongoingCall; if (conversation.getMode() == Conversational.MODE_MULTI) { ongoingCall = Optional.absent(); } else { diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/AbstractJingleConnection.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/AbstractJingleConnection.java index 088b4fc17..99da9fa18 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/AbstractJingleConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/AbstractJingleConnection.java @@ -1,6 +1,7 @@ package eu.siacs.conversations.xmpp.jingle; import com.google.common.base.Objects; +import com.google.common.base.Optional; import com.google.common.base.Preconditions; import eu.siacs.conversations.entities.Account; @@ -40,7 +41,7 @@ public abstract class AbstractJingleConnection { abstract void notifyRebound(); - public static class Id { + public static class Id implements OngoingRtpSession { public final Account account; public final Jid with; public final String sessionId; @@ -87,6 +88,21 @@ public abstract class AbstractJingleConnection { public int hashCode() { return Objects.hashCode(account.getJid(), with, sessionId); } + + @Override + public Account getAccount() { + return account; + } + + @Override + public Jid getWith() { + return with; + } + + @Override + public String getSessionId() { + return sessionId; + } } diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java index 0ec367880..146cf3b43 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java @@ -233,8 +233,8 @@ public class JingleConnectionManager extends AbstractConnectionManager { Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": ignoring call proposal from stranger " + id.with); return; } - final int activeDevices = account.countPresences(); - Log.d(Config.LOGTAG, "active devices: " + activeDevices); + final int activeDevices = account.activeDevicesWithRtpCapability(); + Log.d(Config.LOGTAG, "active devices with rtp capability: " + activeDevices); if (activeDevices == 0) { final MessagePacket reject = mXmppConnectionService.getMessageGenerator().sessionReject(from, sessionId); mXmppConnectionService.sendMessagePacket(account, reject); @@ -353,7 +353,7 @@ public class JingleConnectionManager extends AbstractConnectionManager { connection.init(message); } - public Optional getOngoingRtpConnection(final Contact contact) { + public Optional getOngoingRtpConnection(final Contact contact) { for (final Map.Entry entry : this.connections.entrySet()) { if (entry.getValue() instanceof JingleRtpConnection) { final AbstractJingleConnection.Id id = entry.getKey(); @@ -362,6 +362,17 @@ public class JingleConnectionManager extends AbstractConnectionManager { } } } + synchronized (this.rtpSessionProposals) { + for (Map.Entry entry : this.rtpSessionProposals.entrySet()) { + RtpSessionProposal proposal = entry.getKey(); + if (proposal.account == contact.getAccount() && contact.getJid().asBareJid().equals(proposal.with)) { + final DeviceDiscoveryState preexistingState = entry.getValue(); + if (preexistingState != null && preexistingState != DeviceDiscoveryState.FAILED) { + return Optional.of(proposal); + } + } + } + } return Optional.absent(); } @@ -625,7 +636,7 @@ public class JingleConnectionManager extends AbstractConnectionManager { } } - public static class RtpSessionProposal { + public static class RtpSessionProposal implements OngoingRtpSession { public final Jid with; public final String sessionId; public final Set media; @@ -660,5 +671,20 @@ public class JingleConnectionManager extends AbstractConnectionManager { public int hashCode() { return Objects.hashCode(account.getJid(), with, sessionId); } + + @Override + public Account getAccount() { + return account; + } + + @Override + public Jid getWith() { + return with; + } + + @Override + public String getSessionId() { + return sessionId; + } } } diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/OngoingRtpSession.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/OngoingRtpSession.java new file mode 100644 index 000000000..95328f8c6 --- /dev/null +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/OngoingRtpSession.java @@ -0,0 +1,12 @@ +package eu.siacs.conversations.xmpp.jingle; + +import com.google.common.base.Optional; + +import eu.siacs.conversations.entities.Account; +import rocks.xmpp.addr.Jid; + +public interface OngoingRtpSession { + Account getAccount(); + Jid getWith(); + String getSessionId(); +}