From 3088879a7b35fede494ca3a8b961a0142f36593a Mon Sep 17 00:00:00 2001 From: fiaxh Date: Mon, 7 Feb 2022 22:09:51 +0100 Subject: Various call fixes - Use groupchat message type for invites in MUCs - Use call id (from propose) instead of message id for Call Invite Messages - Fix call window controlls appearing when hovering controls --- libdino/src/service/call_peer_state.vala | 2 +- libdino/src/service/call_state.vala | 14 +++++----- libdino/src/service/calls.vala | 46 ++++++++++++-------------------- libdino/src/service/muc_manager.vala | 6 +++++ 4 files changed, 32 insertions(+), 36 deletions(-) (limited to 'libdino') diff --git a/libdino/src/service/call_peer_state.vala b/libdino/src/service/call_peer_state.vala index 52b3e6ef..de5c69cb 100644 --- a/libdino/src/service/call_peer_state.vala +++ b/libdino/src/service/call_peer_state.vala @@ -90,7 +90,7 @@ public class Dino.PeerState : Object { } stream.get_module(Xmpp.Xep.JingleMessageInitiation.Module.IDENTITY).send_session_propose_to_peer(stream, jid, sid, descriptions); -// call_state.cim_invite_id = stream.get_module(Xmpp.Xep.CallInvites.Module.IDENTITY).send_jingle_propose(stream, jid, sid, we_should_send_video); +// call_state.cim_call_id = stream.get_module(Xmpp.Xep.CallInvites.Module.IDENTITY).send_jingle_propose(stream, jid, sid, we_should_send_video); } else if (jid_for_direct != null) { yield call_resource(jid_for_direct); } diff --git a/libdino/src/service/call_state.vala b/libdino/src/service/call_state.vala index 14821ab1..ecb69773 100644 --- a/libdino/src/service/call_state.vala +++ b/libdino/src/service/call_state.vala @@ -16,7 +16,7 @@ public class Dino.CallState : Object { public bool accepted { get; private set; default=false; } public bool use_cim = false; - public string? cim_invite_id = null; + public string? cim_call_id = null; public Jid? cim_counterpart = null; public string cim_message_type { get; set; default=Xmpp.MessageStanza.TYPE_CHAT; } @@ -46,6 +46,7 @@ public class Dino.CallState : Object { internal async void initiate_groupchat_call(Jid muc) { parent_muc = muc; + cim_message_type = MessageStanza.TYPE_GROUPCHAT; if (this.group_call == null) yield convert_into_group_call(); if (this.group_call == null) return; @@ -63,7 +64,7 @@ public class Dino.CallState : Object { yield stream.get_module(Xep.Muc.Module.IDENTITY).change_affiliation(stream, group_call.muc_jid, real_jid.bare_jid, null, "owner"); } - stream.get_module(Xep.CallInvites.Module.IDENTITY).send_muji_propose(stream, muc, group_call.muc_jid, we_should_send_video, cim_message_type); + stream.get_module(Xep.CallInvites.Module.IDENTITY).send_muji_propose(stream, cim_call_id, muc, group_call.muc_jid, we_should_send_video, cim_message_type); } internal PeerState set_first_peer(Jid peer) { @@ -86,7 +87,7 @@ public class Dino.CallState : Object { if (use_cim) { XmppStream stream = stream_interactor.get_stream(call.account); if (stream == null) return; - stream.get_module(Xep.CallInvites.Module.IDENTITY).send_accept(stream, cim_counterpart, cim_invite_id, cim_message_type); + stream.get_module(Xep.CallInvites.Module.IDENTITY).send_accept(stream, cim_counterpart, cim_call_id, cim_message_type); } else { foreach (PeerState peer in peers.values) { peer.accept(); @@ -104,7 +105,7 @@ public class Dino.CallState : Object { if (use_cim) { XmppStream stream = stream_interactor.get_stream(call.account); if (stream == null) return; - stream.get_module(Xep.CallInvites.Module.IDENTITY).send_reject(stream, cim_counterpart, cim_invite_id, cim_message_type); + stream.get_module(Xep.CallInvites.Module.IDENTITY).send_reject(stream, cim_counterpart, cim_call_id, cim_message_type); } var peers_cpy = new ArrayList(); peers_cpy.add_all(peers.values); @@ -137,7 +138,7 @@ public class Dino.CallState : Object { if (call.direction == Call.DIRECTION_OUTGOING && use_cim) { XmppStream stream = stream_interactor.get_stream(call.account); if (stream == null) return; - stream.get_module(Xep.CallInvites.Module.IDENTITY).send_retract(stream, cim_counterpart, cim_invite_id, cim_message_type); + stream.get_module(Xep.CallInvites.Module.IDENTITY).send_retract(stream, cim_counterpart, cim_call_id, cim_message_type); } call.state = Call.State.MISSED; } else { @@ -176,7 +177,7 @@ public class Dino.CallState : Object { debug("[%s] Inviting to muji call %s", call.account.bare_jid.to_string(), invitee.to_string()); yield stream.get_module(Xep.Muc.Module.IDENTITY).change_affiliation(stream, group_call.muc_jid, invitee, null, "owner"); - stream.get_module(Xep.CallInvites.Module.IDENTITY).send_muji_propose(stream, invitee, group_call.muc_jid, we_should_send_video, "chat"); + stream.get_module(Xep.CallInvites.Module.IDENTITY).send_muji_propose(stream, cim_call_id, invitee, group_call.muc_jid, we_should_send_video, "chat"); // If the peer hasn't accepted within a minute, retract the invite // TODO this should be unset when we retract the invite. otherwise a second invite attempt might break due to this @@ -288,6 +289,7 @@ public class Dino.CallState : Object { return; } + if (cim_call_id == null) cim_call_id = Xmpp.random_uuid(); muc_jid = new Jid("%08x@".printf(Random.next_int()) + muc_jid.to_string()); // TODO longer? debug("[%s] Converting call to groupcall %s", call.account.bare_jid.to_string(), muc_jid.to_string()); diff --git a/libdino/src/service/calls.vala b/libdino/src/service/calls.vala index c97b296c..7900824e 100644 --- a/libdino/src/service/calls.vala +++ b/libdino/src/service/calls.vala @@ -244,13 +244,13 @@ namespace Dino { return peer_state; } - private CallState? get_call_state_by_invite_id(Account account, string invite_id, Jid jid1, Jid jid2) { + private CallState? get_call_state_by_call_id(Account account, string call_id, Jid jid1, Jid jid2) { Jid relevant_jid = jid1.equals_bare(account.bare_jid) ? jid2 : jid1; foreach (CallState call_state in call_states.values) { if (!call_state.call.account.equals(account)) continue; - if (call_state.cim_invite_id == invite_id) { + if (call_state.cim_call_id == call_id) { foreach (Jid jid in call_state.peers.keys) { if (jid.equals_bare(relevant_jid)) { return call_state; @@ -278,7 +278,7 @@ namespace Dino { return null; } - private CallState? create_recv_muji_call(Account account, Jid inviter_jid, Jid muc_jid, string invite_id, string message_type) { + private CallState? create_recv_muji_call(Account account, Jid inviter_jid, Jid muc_jid, string message_type) { debug("[%s] Muji call received from %s for MUC %s, type %s", account.bare_jid.to_string(), inviter_jid.to_string(), muc_jid.to_string(), message_type); foreach (Call call in call_states.keys) { @@ -286,12 +286,6 @@ namespace Dino { CallState call_state = call_states[call]; - // If this is a MUC reflection of our own invite, store the sid assigned by the MUC - if (call_state.parent_muc != null && call_state.parent_muc.equals_bare(inviter_jid)) { - call_state.cim_invite_id = invite_id; - return null; - } - if (call.counterparts.contains(inviter_jid) && call_state.accepted) { // A call is converted into a group call. call_state.join_group_call.begin(muc_jid); @@ -416,35 +410,29 @@ namespace Dino { }); Xep.CallInvites.Module call_invites_module = stream_interactor.module_manager.get_module(account, Xep.CallInvites.Module.IDENTITY); - call_invites_module.call_proposed.connect((from_jid, to_jid, video_requested, join_methods, message_stanza) => { + call_invites_module.call_proposed.connect((from_jid, to_jid, call_id, video_requested, join_methods, message_stanza) => { if (from_jid.equals_bare(account.bare_jid)) return; - - string? invite_id = null; - if (message_stanza.type_ == Xmpp.MessageStanza.TYPE_GROUPCHAT) { - invite_id = Xep.UniqueStableStanzaIDs.get_stanza_id(message_stanza, from_jid.bare_jid); - } else { - invite_id = message_stanza.id; - } - if (invite_id == null) { - warning("Got call invite without ID"); - return; - } + if (stream_interactor.get_module(MucManager.IDENTITY).is_own_muc_jid(from_jid, account)) return; CallState? call_state = null; foreach (StanzaNode join_method_node in join_methods) { if (join_method_node.name == "muji" && join_method_node.ns_uri == Xep.Muji.NS_URI) { - // This is a MUJI invite + + // Disregard calls from muc history + DateTime? delay = Xep.DelayedDelivery.get_time_for_message(message_stanza, from_jid.bare_jid); + if (delay != null) return; + string? room_jid_str = join_method_node.get_attribute("room"); if (room_jid_str == null) return; Jid room_jid = new Jid(room_jid_str); - call_state = create_recv_muji_call(account, from_jid, room_jid, invite_id, message_stanza.type_); + call_state = create_recv_muji_call(account, from_jid, room_jid, message_stanza.type_); break; } else if (join_method_node.name == "jingle" && join_method_node.ns_uri == Xep.CallInvites.NS_URI) { - // This is an invite for a direct Jingle session + if (message_stanza.type_ != Xmpp.MessageStanza.TYPE_CHAT) return; string? sid = join_method_node.get_attribute("sid"); @@ -467,7 +455,7 @@ namespace Dino { call_state.we_should_send_video = video_requested; call_state.use_cim = true; - call_state.cim_invite_id = invite_id; + call_state.cim_call_id = call_id; call_state.cim_counterpart = message_stanza.type_ == MessageStanza.TYPE_GROUPCHAT ? from_jid.bare_jid : from_jid; call_state.cim_message_type = message_stanza.type_; @@ -477,8 +465,8 @@ namespace Dino { call_incoming(call_state.call, call_state, conversation, video_requested); }); - call_invites_module.call_accepted.connect((from_jid, to_jid, invite_id, message_type) => { - CallState? call_state = get_call_state_by_invite_id(account, invite_id, from_jid, to_jid); + call_invites_module.call_accepted.connect((from_jid, to_jid, call_id, message_type) => { + CallState? call_state = get_call_state_by_call_id(account, call_id, from_jid, to_jid); if (call_state == null) return; Call call = call_state.call; @@ -497,11 +485,11 @@ namespace Dino { jmi_request_peer[call].call_resource.begin(from_jid); } }); - call_invites_module.call_retracted.connect((from_jid, to_jid, invite_id, message_type) => { + call_invites_module.call_retracted.connect((from_jid, to_jid, call_id, message_type) => { if (from_jid.equals_bare(account.bare_jid)) return; // The call was retracted by the counterpart - CallState? call_state = get_call_state_by_invite_id(account, invite_id, from_jid, to_jid); + CallState? call_state = get_call_state_by_call_id(account, call_id, from_jid, to_jid); if (call_state == null) return; if (call_state.call.state != Call.State.RINGING) { diff --git a/libdino/src/service/muc_manager.vala b/libdino/src/service/muc_manager.vala index 5d0b05b9..5cfe5528 100644 --- a/libdino/src/service/muc_manager.vala +++ b/libdino/src/service/muc_manager.vala @@ -347,6 +347,12 @@ public class MucManager : StreamInteractionModule, Object { return null; } + public bool is_own_muc_jid(Jid full_jid, Account account) { + if (!is_groupchat(full_jid.bare_jid, account)) return false; + Jid? own_jid = get_own_jid(full_jid, account); + return own_jid != null && own_jid.equals(full_jid); + } + private Xep.Muc.Flag? get_muc_flag(Account account) { XmppStream? stream = stream_interactor.get_stream(account); if (stream != null) { -- cgit v1.2.3-54-g00ecf