Various call fixes
- If peer invited us claiming audio-only and then wants to have a video content, do a content-modify and accept audio-only
- Check contents for video (and modify) and whether call is truly accepted in PeerState.accept() directly
- If a message contains both JMI and CIM, only use JMI
- Fix outgoing CIM (disabled)
- Use opacity instead of visiblity for file_menu, small fixes
- Add back owner/admin/member queries when joining MUC (regression from 33104a7
)
This commit is contained in:
parent
6532c2b160
commit
be751a5dda
|
@ -90,7 +90,10 @@ public class Dino.PeerState : Object {
|
||||||
}
|
}
|
||||||
|
|
||||||
stream.get_module(Xmpp.Xep.JingleMessageInitiation.Module.IDENTITY).send_session_propose_to_peer(stream, jid, sid, descriptions);
|
stream.get_module(Xmpp.Xep.JingleMessageInitiation.Module.IDENTITY).send_session_propose_to_peer(stream, jid, sid, descriptions);
|
||||||
// call_state.cim_call_id = stream.get_module(Xmpp.Xep.CallInvites.Module.IDENTITY).send_jingle_propose(stream, jid, sid, we_should_send_video);
|
|
||||||
|
// Uncomment this use CIM instead of JMI
|
||||||
|
// call_state.cim_call_id = sid;
|
||||||
|
// stream.get_module(Xmpp.Xep.CallInvites.Module.IDENTITY).send_jingle_propose(stream, call_state.cim_call_id, jid, sid, we_should_send_video);
|
||||||
} else if (jid_for_direct != null) {
|
} else if (jid_for_direct != null) {
|
||||||
yield call_resource(jid_for_direct);
|
yield call_resource(jid_for_direct);
|
||||||
}
|
}
|
||||||
|
@ -111,8 +114,27 @@ public class Dino.PeerState : Object {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void accept() {
|
public void accept() {
|
||||||
|
if (!call_state.accepted) {
|
||||||
|
critical("Tried to accept peer in unaccepted call?! Something's fishy. Abort.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (session != null) {
|
if (session != null) {
|
||||||
foreach (Xep.Jingle.Content content in session.contents) {
|
foreach (Xep.Jingle.Content content in session.contents) {
|
||||||
|
Xep.JingleRtp.Parameters? rtp_content_parameter = content.content_params as Xep.JingleRtp.Parameters;
|
||||||
|
if (rtp_content_parameter != null && rtp_content_parameter.media == "video") {
|
||||||
|
// We didn't accept video but our peer wants to negotiate that content
|
||||||
|
if (!we_should_send_video && session.senders_include_us(content.senders)) {
|
||||||
|
if (session.senders_include_counterpart(content.senders)) {
|
||||||
|
// If our peer wants to send, let them
|
||||||
|
content.modify(session.we_initiated ? Xep.Jingle.Senders.RESPONDER : Xep.Jingle.Senders.INITIATOR);
|
||||||
|
} else {
|
||||||
|
// If only we're supposed to send, reject
|
||||||
|
content.reject();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
content.accept();
|
content.accept();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -373,7 +373,7 @@ public class Dino.CallState : Object {
|
||||||
handle_peer_left(peer_state, false, Xep.Jingle.ReasonElement.CANCEL, "Peer left the MUJI MUC");
|
handle_peer_left(peer_state, false, Xep.Jingle.ReasonElement.CANCEL, "Peer left the MUJI MUC");
|
||||||
});
|
});
|
||||||
|
|
||||||
if (group_call.peers_to_connect_to.size > 3) {
|
if (group_call.peers_to_connect_to.size > 4) {
|
||||||
end("Call too full - P2p calls don't work well with many participants");
|
end("Call too full - P2p calls don't work well with many participants");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -159,7 +159,7 @@ namespace Dino {
|
||||||
debug("[%s] Incoming call from %s from MUJI muc %s", account.bare_jid.to_string(), session.peer_full_jid.to_string(), muji_muc.to_string());
|
debug("[%s] Incoming call from %s from MUJI muc %s", account.bare_jid.to_string(), session.peer_full_jid.to_string(), muji_muc.to_string());
|
||||||
|
|
||||||
foreach (CallState call_state in call_states.values) {
|
foreach (CallState call_state in call_states.values) {
|
||||||
if (call_state.group_call != null && call_state.group_call.muc_jid.equals(muji_muc)) {
|
if (call_state.call.account.equals(account) && call_state.group_call != null && call_state.group_call.muc_jid.equals(muji_muc)) {
|
||||||
if (call_state.peers.keys.contains(session.peer_full_jid)) {
|
if (call_state.peers.keys.contains(session.peer_full_jid)) {
|
||||||
PeerState peer_state = call_state.peers[session.peer_full_jid];
|
PeerState peer_state = call_state.peers[session.peer_full_jid];
|
||||||
debug("[%s] Incoming call, we know the peer. Expected %s", account.bare_jid.to_string(), peer_state.waiting_for_inbound_muji_connection.to_string());
|
debug("[%s] Incoming call, we know the peer. Expected %s", account.bare_jid.to_string(), peer_state.waiting_for_inbound_muji_connection.to_string());
|
||||||
|
@ -182,28 +182,19 @@ namespace Dino {
|
||||||
|
|
||||||
debug(@"[%s] Incoming call from %s", account.bare_jid.to_string(), session.peer_full_jid.to_string());
|
debug(@"[%s] Incoming call from %s", account.bare_jid.to_string(), session.peer_full_jid.to_string());
|
||||||
|
|
||||||
// Check if we already accepted this call via Jingle Message Initiation => accept
|
// Check if we already got this call via Jingle Message Initiation => accept
|
||||||
Call? call = null;
|
// PeerState.accept() checks if the call was accepted and ensures that we don't accidentally send video
|
||||||
foreach (PeerState peer_state in jmi_request_peer.values) {
|
PeerState? peer_state = get_peer_by_sid(account, session.sid, session.peer_full_jid);
|
||||||
CallState call_state = call_states[peer_state.call];
|
if (peer_state != null) {
|
||||||
if (peer_state.sid == session.sid &&
|
jmi_request_peer[peer_state.call].set_session(session);
|
||||||
call_state.call.account.equals(account) &&
|
jmi_request_peer[peer_state.call].accept();
|
||||||
peer_state.jid.equals_bare(session.peer_full_jid) &&
|
jmi_request_peer.unset(peer_state.call);
|
||||||
call_state.we_should_send_video == counterpart_wants_video &&
|
|
||||||
call_state.accepted) {
|
|
||||||
call = peer_state.call;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (call != null) {
|
|
||||||
jmi_request_peer[call].set_session(session);
|
|
||||||
jmi_request_peer[call].accept();
|
|
||||||
jmi_request_peer.unset(call);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is a direct call without prior JMI. Ask user.
|
// This is a direct call without prior JMI. Ask user.
|
||||||
PeerState peer_state = create_received_call(account, session.peer_full_jid, account.full_jid, counterpart_wants_video);
|
if (stream_interactor.get_module(MucManager.IDENTITY).might_be_groupchat(session.peer_full_jid.bare_jid, account)) return;
|
||||||
|
peer_state = create_received_call(account, session.peer_full_jid, account.full_jid, counterpart_wants_video);
|
||||||
peer_state.set_session(session);
|
peer_state.set_session(session);
|
||||||
Conversation conversation = stream_interactor.get_module(ConversationManager.IDENTITY).get_conversation(peer_state.call.counterpart.bare_jid, account, Conversation.Type.CHAT);
|
Conversation conversation = stream_interactor.get_module(ConversationManager.IDENTITY).get_conversation(peer_state.call.counterpart.bare_jid, account, Conversation.Type.CHAT);
|
||||||
call_incoming(peer_state.call, peer_state.call_state, conversation, counterpart_wants_video, false);
|
call_incoming(peer_state.call, peer_state.call_state, conversation, counterpart_wants_video, false);
|
||||||
|
@ -260,8 +251,8 @@ namespace Dino {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private PeerState? get_peer_by_sid(Account account, string sid, Jid jid1, Jid jid2) {
|
private PeerState? get_peer_by_sid(Account account, string sid, Jid jid1, Jid? jid2 = null) {
|
||||||
Jid relevant_jid = jid1.equals_bare(account.bare_jid) ? jid2 : jid1;
|
Jid relevant_jid = jid1.equals_bare(account.bare_jid) && jid2 != null ? jid2 : jid1;
|
||||||
|
|
||||||
foreach (CallState call_state in call_states.values) {
|
foreach (CallState call_state in call_states.values) {
|
||||||
if (!call_state.call.account.equals(account)) continue;
|
if (!call_state.call.account.equals(account)) continue;
|
||||||
|
@ -284,7 +275,7 @@ namespace Dino {
|
||||||
|
|
||||||
CallState call_state = call_states[call];
|
CallState call_state = call_states[call];
|
||||||
|
|
||||||
if (call.counterparts.contains(inviter_jid) && call_state.accepted) {
|
if (call.counterparts.size == 1 && call.counterparts.contains(inviter_jid) && call_state.accepted) {
|
||||||
// A call is converted into a group call.
|
// A call is converted into a group call.
|
||||||
call_state.join_group_call.begin(muc_jid);
|
call_state.join_group_call.begin(muc_jid);
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -90,7 +90,8 @@
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkMenuButton" id="file_menu">
|
<object class="GtkMenuButton" id="file_menu">
|
||||||
<property name="visible">False</property>
|
<property name="visible">True</property>
|
||||||
|
<property name="opacity">0</property>
|
||||||
<property name="relief">none</property>
|
<property name="relief">none</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImage">
|
<object class="GtkImage">
|
||||||
|
|
|
@ -85,7 +85,7 @@ public class FileDefaultWidget : EventBox {
|
||||||
image_stack.set_visible_child_name("download_image");
|
image_stack.set_visible_child_name("download_image");
|
||||||
}
|
}
|
||||||
if (state == FileTransfer.State.COMPLETE) {
|
if (state == FileTransfer.State.COMPLETE) {
|
||||||
file_menu.visible = true;
|
file_menu.opacity = 1;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -104,7 +104,7 @@ public class FileDefaultWidget : EventBox {
|
||||||
if (state == FileTransfer.State.NOT_STARTED) {
|
if (state == FileTransfer.State.NOT_STARTED) {
|
||||||
image_stack.set_visible_child_name("content_type_image");
|
image_stack.set_visible_child_name("content_type_image");
|
||||||
}
|
}
|
||||||
file_menu.visible = false;
|
file_menu.opacity = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string get_file_icon_name(string? mime_type) {
|
private static string get_file_icon_name(string? mime_type) {
|
||||||
|
|
|
@ -345,6 +345,12 @@ public class Module : XmppStreamModule {
|
||||||
if (status_codes.contains(StatusCode.SELF_PRESENCE)) {
|
if (status_codes.contains(StatusCode.SELF_PRESENCE)) {
|
||||||
Jid bare_jid = presence.from.bare_jid;
|
Jid bare_jid = presence.from.bare_jid;
|
||||||
if (flag.get_enter_id(bare_jid) != null) {
|
if (flag.get_enter_id(bare_jid) != null) {
|
||||||
|
|
||||||
|
// TODO only query that if we actually have the rights to
|
||||||
|
query_affiliation.begin(stream, bare_jid, "member");
|
||||||
|
query_affiliation.begin(stream, bare_jid, "admin");
|
||||||
|
query_affiliation.begin(stream, bare_jid, "owner");
|
||||||
|
|
||||||
flag.finish_muc_enter(bare_jid);
|
flag.finish_muc_enter(bare_jid);
|
||||||
var join_result = new JoinResult() { nick=presence.from.resourcepart, newly_created=status_codes.contains(StatusCode.NEW_ROOM_CREATED) };
|
var join_result = new JoinResult() { nick=presence.from.resourcepart, newly_created=status_codes.contains(StatusCode.NEW_ROOM_CREATED) };
|
||||||
flag.enter_futures[bare_jid].set_value(join_result);
|
flag.enter_futures[bare_jid].set_value(join_result);
|
||||||
|
|
|
@ -12,10 +12,10 @@ namespace Xmpp.Xep.CallInvites {
|
||||||
public signal void call_rejected(Jid from, Jid to, string call_id, string message_type);
|
public signal void call_rejected(Jid from, Jid to, string call_id, string message_type);
|
||||||
public signal void call_left(Jid from, Jid to, string call_id, string message_type);
|
public signal void call_left(Jid from, Jid to, string call_id, string message_type);
|
||||||
|
|
||||||
public string send_jingle_propose(XmppStream stream, Jid invitee, string sid, bool video) {
|
public void send_jingle_propose(XmppStream stream, string call_id, Jid invitee, string sid, bool video) {
|
||||||
StanzaNode jingle_node = new StanzaNode.build("jingle", CallInvites.NS_URI)
|
StanzaNode jingle_node = new StanzaNode.build("jingle", CallInvites.NS_URI)
|
||||||
.put_attribute("sid", sid);
|
.put_attribute("sid", sid);
|
||||||
return send_propose(stream, sid, invitee, jingle_node, video, false, MessageStanza.TYPE_CHAT);
|
send_propose(stream, call_id, invitee, jingle_node, video, false, MessageStanza.TYPE_CHAT);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void send_muji_propose(XmppStream stream, string call_id, Jid invitee, Jid muc_jid, bool video, string message_type) {
|
public void send_muji_propose(XmppStream stream, string call_id, Jid invitee, Jid muc_jid, bool video, string message_type) {
|
||||||
|
@ -24,7 +24,7 @@ namespace Xmpp.Xep.CallInvites {
|
||||||
send_propose(stream, call_id, invitee, muji_node, video, true, message_type);
|
send_propose(stream, call_id, invitee, muji_node, video, true, message_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string send_propose(XmppStream stream, string call_id, Jid invitee, StanzaNode inner_node, bool video, bool multiparty, string message_type) {
|
private void send_propose(XmppStream stream, string call_id, Jid invitee, StanzaNode inner_node, bool video, bool multiparty, string message_type) {
|
||||||
StanzaNode invite_node = new StanzaNode.build("propose", NS_URI).add_self_xmlns()
|
StanzaNode invite_node = new StanzaNode.build("propose", NS_URI).add_self_xmlns()
|
||||||
.put_attribute("id", call_id)
|
.put_attribute("id", call_id)
|
||||||
.put_attribute("video", video.to_string())
|
.put_attribute("video", video.to_string())
|
||||||
|
@ -34,7 +34,6 @@ namespace Xmpp.Xep.CallInvites {
|
||||||
MessageProcessingHints.set_message_hint(invite_message, MessageProcessingHints.HINT_STORE);
|
MessageProcessingHints.set_message_hint(invite_message, MessageProcessingHints.HINT_STORE);
|
||||||
invite_message.stanza.put_node(invite_node);
|
invite_message.stanza.put_node(invite_node);
|
||||||
stream.get_module(MessageModule.IDENTITY).send_message.begin(stream, invite_message);
|
stream.get_module(MessageModule.IDENTITY).send_message.begin(stream, invite_message);
|
||||||
return invite_message.id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void send_retract(XmppStream stream, Jid to, string call_id, string message_type) {
|
public void send_retract(XmppStream stream, Jid to, string call_id, string message_type) {
|
||||||
|
@ -81,6 +80,12 @@ namespace Xmpp.Xep.CallInvites {
|
||||||
|
|
||||||
if (relevant_node.name == "propose") {
|
if (relevant_node.name == "propose") {
|
||||||
if (relevant_node.sub_nodes.is_empty) return;
|
if (relevant_node.sub_nodes.is_empty) return;
|
||||||
|
|
||||||
|
// If there's also a JMI node, just use that one instead.
|
||||||
|
foreach (StanzaNode node in message.stanza.sub_nodes) {
|
||||||
|
if (node.ns_uri == JingleMessageInitiation.NS_URI) return;
|
||||||
|
}
|
||||||
|
|
||||||
bool video = relevant_node.get_attribute_bool("video", false);
|
bool video = relevant_node.get_attribute_bool("video", false);
|
||||||
call_proposed(message.from, message.to, call_id, video, relevant_node.sub_nodes, message);
|
call_proposed(message.from, message.to, call_id, video, relevant_node.sub_nodes, message);
|
||||||
return;
|
return;
|
||||||
|
|
Loading…
Reference in a new issue