Improve call details dialog + small multi-party call fixes
This commit is contained in:
parent
ec65415186
commit
2b3d150949
|
@ -11,7 +11,7 @@ namespace Dino.Entities {
|
|||
RINGING,
|
||||
ESTABLISHING,
|
||||
IN_PROGRESS,
|
||||
OTHER_DEVICE_ACCEPTED,
|
||||
OTHER_DEVICE,
|
||||
ENDED,
|
||||
DECLINED,
|
||||
MISSED,
|
||||
|
|
|
@ -251,53 +251,43 @@ public class Dino.PeerState : Object {
|
|||
|
||||
public PeerInfo get_info() {
|
||||
var ret = new PeerInfo();
|
||||
if (audio_content != null || audio_content_parameter != null) {
|
||||
ret.audio = get_content_info(audio_content, audio_content_parameter);
|
||||
}
|
||||
if (video_content != null || video_content_parameter != null) {
|
||||
ret.video = get_content_info(video_content, video_content_parameter);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (audio_content_parameter != null) {
|
||||
ret.audio_rtcp_ready = audio_content_parameter.rtcp_ready;
|
||||
ret.audio_rtp_ready = audio_content_parameter.rtp_ready;
|
||||
private PeerContentInfo get_content_info(Xep.Jingle.Content? content, Xep.JingleRtp.Parameters? parameter) {
|
||||
PeerContentInfo ret = new PeerContentInfo();
|
||||
if (parameter != null) {
|
||||
ret.rtcp_ready = parameter.rtcp_ready;
|
||||
ret.rtp_ready = parameter.rtp_ready;
|
||||
|
||||
if (audio_content_parameter.agreed_payload_type != null) {
|
||||
ret.audio_codec = audio_content_parameter.agreed_payload_type.name;
|
||||
ret.audio_clockrate = audio_content_parameter.agreed_payload_type.clockrate;
|
||||
if (parameter.agreed_payload_type != null) {
|
||||
ret.codec = parameter.agreed_payload_type.name;
|
||||
ret.clockrate = parameter.agreed_payload_type.clockrate;
|
||||
}
|
||||
if (audio_content_parameter.stream != null && audio_content_parameter.stream.remb_enabled) {
|
||||
ret.audio_target_receive_bitrate = audio_content_parameter.stream.target_receive_bitrate;
|
||||
ret.audio_target_send_bitrate = audio_content_parameter.stream.target_send_bitrate;
|
||||
if (parameter.stream != null && parameter.stream.remb_enabled) {
|
||||
ret.target_receive_bytes = parameter.stream.target_receive_bitrate;
|
||||
ret.target_send_bytes = parameter.stream.target_send_bitrate;
|
||||
}
|
||||
}
|
||||
|
||||
if (audio_content != null) {
|
||||
Xmpp.Xep.Jingle.ComponentConnection? component0 = audio_content.get_transport_connection(1);
|
||||
if (content != null) {
|
||||
Xmpp.Xep.Jingle.ComponentConnection? component0 = content.get_transport_connection(1);
|
||||
if (component0 != null) {
|
||||
ret.audio_bytes_received = component0.bytes_received;
|
||||
ret.audio_bytes_sent = component0.bytes_sent;
|
||||
}
|
||||
}
|
||||
|
||||
if (video_content_parameter != null) {
|
||||
ret.video_content_exists = true;
|
||||
ret.video_rtcp_ready = video_content_parameter.rtcp_ready;
|
||||
ret.video_rtp_ready = video_content_parameter.rtp_ready;
|
||||
|
||||
if (video_content_parameter.agreed_payload_type != null) {
|
||||
ret.video_codec = video_content_parameter.agreed_payload_type.name;
|
||||
}
|
||||
if (video_content_parameter.stream != null && video_content_parameter.stream.remb_enabled) {
|
||||
ret.video_target_receive_bitrate = video_content_parameter.stream.target_receive_bitrate;
|
||||
ret.video_target_send_bitrate = video_content_parameter.stream.target_send_bitrate;
|
||||
}
|
||||
}
|
||||
|
||||
if (video_content != null) {
|
||||
Xmpp.Xep.Jingle.ComponentConnection? component0 = video_content.get_transport_connection(1);
|
||||
if (component0 != null) {
|
||||
ret.video_bytes_received = component0.bytes_received;
|
||||
ret.video_bytes_sent = component0.bytes_sent;
|
||||
ret.bytes_received = component0.bytes_received;
|
||||
ret.bytes_sent = component0.bytes_sent;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void connect_content_signals(Xep.Jingle.Content content, Xep.JingleRtp.Parameters rtp_content_parameter) {
|
||||
if (rtp_content_parameter.media == "audio") {
|
||||
audio_content = content;
|
||||
|
@ -444,22 +434,18 @@ public class Dino.PeerState : Object {
|
|||
}
|
||||
}
|
||||
|
||||
public class Dino.PeerInfo {
|
||||
public bool audio_rtp_ready { get; set; }
|
||||
public bool audio_rtcp_ready { get; set; }
|
||||
public ulong? audio_bytes_sent { get; set; default=0; }
|
||||
public ulong? audio_bytes_received { get; set; default=0; }
|
||||
public string? audio_codec { get; set; }
|
||||
public uint32 audio_clockrate { get; set; }
|
||||
public uint audio_target_receive_bitrate { get; set; default=0; }
|
||||
public uint audio_target_send_bitrate { get; set; default=0; }
|
||||
|
||||
public bool video_content_exists { get; set; }
|
||||
public bool video_rtp_ready { get; set; }
|
||||
public bool video_rtcp_ready { get; set; }
|
||||
public ulong? video_bytes_sent { get; set; default=0; }
|
||||
public ulong? video_bytes_received { get; set; default=0; }
|
||||
public string? video_codec { get; set; }
|
||||
public uint video_target_receive_bitrate { get; set; default=0; }
|
||||
public uint video_target_send_bitrate { get; set; default=0; }
|
||||
public class Dino.PeerContentInfo {
|
||||
public bool rtp_ready { get; set; }
|
||||
public bool rtcp_ready { get; set; }
|
||||
public ulong? bytes_sent { get; set; default=0; }
|
||||
public ulong? bytes_received { get; set; default=0; }
|
||||
public string? codec { get; set; }
|
||||
public uint32 clockrate { get; set; }
|
||||
public uint target_receive_bytes { get; set; default=-1; }
|
||||
public uint target_send_bytes { get; set; default=-1; }
|
||||
}
|
||||
|
||||
public class Dino.PeerInfo {
|
||||
public PeerContentInfo? audio = null;
|
||||
public PeerContentInfo? video = null;
|
||||
}
|
|
@ -202,16 +202,17 @@ namespace Dino {
|
|||
// Call requested by another of our devices
|
||||
call.direction = Call.DIRECTION_OUTGOING;
|
||||
call.ourpart = from;
|
||||
call.state = Call.State.OTHER_DEVICE;
|
||||
counterpart = to;
|
||||
} else {
|
||||
call.direction = Call.DIRECTION_INCOMING;
|
||||
call.ourpart = account.full_jid;
|
||||
call.state = Call.State.RINGING;
|
||||
counterpart = from;
|
||||
}
|
||||
call.add_peer(counterpart);
|
||||
call.account = account;
|
||||
call.time = call.local_time = call.end_time = new DateTime.now_utc();
|
||||
call.state = Call.State.RINGING;
|
||||
|
||||
Conversation conversation = stream_interactor.get_module(ConversationManager.IDENTITY).create_conversation(counterpart.bare_jid, account, Conversation.Type.CHAT);
|
||||
|
||||
|
@ -329,7 +330,7 @@ namespace Dino {
|
|||
current_jmi_request_peer[account] = peer_state;
|
||||
current_jmi_request_call[account] = call_states[peer_state.call];
|
||||
});
|
||||
mi_module.session_accepted.connect((from, sid) => {
|
||||
mi_module.session_accepted.connect((from, to, sid) => {
|
||||
if (!current_jmi_request_peer.has_key(account) || current_jmi_request_peer[account].sid != sid) return;
|
||||
|
||||
if (from.equals_bare(account.bare_jid)) { // Carboned message from our account
|
||||
|
@ -337,9 +338,9 @@ namespace Dino {
|
|||
if (from.equals(account.full_jid)) return;
|
||||
|
||||
Call call = current_jmi_request_peer[account].call;
|
||||
call.state = Call.State.OTHER_DEVICE_ACCEPTED;
|
||||
call.state = Call.State.OTHER_DEVICE;
|
||||
remove_call_from_datastructures(call);
|
||||
} else if (from.equals_bare(current_jmi_request_peer[account].jid)) { // Message from our peer
|
||||
} else if (from.equals_bare(current_jmi_request_peer[account].jid) && to.equals(account.full_jid)) { // Message from our peer
|
||||
// We proposed the call
|
||||
// We know the full jid of our peer now
|
||||
current_jmi_request_call[account].rename_peer(current_jmi_request_peer[account].jid, from);
|
||||
|
@ -383,7 +384,7 @@ namespace Dino {
|
|||
CallState? call_state = get_call_state_for_groupcall(account, muc_jid);
|
||||
if (call_state == null) return;
|
||||
|
||||
call_state.call.state = Call.State.OTHER_DEVICE_ACCEPTED;
|
||||
call_state.call.state = Call.State.OTHER_DEVICE;
|
||||
remove_call_from_datastructures(call_state.call);
|
||||
});
|
||||
muji_meta_module.call_retracted.connect((from_jid, muc_jid) => {
|
||||
|
|
|
@ -4,100 +4,107 @@ namespace Dino.Ui {
|
|||
|
||||
public class CallConnectionDetailsWindow : Gtk.Window {
|
||||
|
||||
public Grid grid = new Grid() { column_spacing=5, margin=10, halign=Align.CENTER, valign=Align.CENTER, visible=true };
|
||||
public Box box = new Box(Orientation.VERTICAL, 15) { margin=10, halign=Align.CENTER, valign=Align.CENTER, visible=true };
|
||||
|
||||
public Label audio_rtp_ready = new Label("?") { xalign=0, visible=true };
|
||||
public Label audio_rtcp_ready = new Label("?") { xalign=0, visible=true };
|
||||
public Label audio_sent_bps = new Label("?") { use_markup=true, xalign=0, visible=true };
|
||||
public Label audio_recv_bps = new Label("?") { use_markup=true, xalign=0, visible=true };
|
||||
public Label audio_codec = new Label("?") { xalign=0, visible=true };
|
||||
public Label audio_target_receive_bitrate = new Label("n/a") { xalign=0, visible=true };
|
||||
public Label audio_target_send_bitrate = new Label("n/a") { xalign=0, visible=true };
|
||||
|
||||
public Label video_rtp_ready = new Label("") { xalign=0, visible=true };
|
||||
public Label video_rtcp_ready = new Label("") { xalign=0, visible=true };
|
||||
public Label video_sent_bps = new Label("") { use_markup=true, xalign=0, visible=true };
|
||||
public Label video_recv_bps = new Label("") { use_markup=true, xalign=0, visible=true };
|
||||
public Label video_codec = new Label("") { xalign=0, visible=true };
|
||||
public Label video_target_receive_bitrate = new Label("n/a") { xalign=0, visible=true };
|
||||
public Label video_target_send_bitrate = new Label("n/a") { xalign=0, visible=true };
|
||||
|
||||
private int row_at = 0;
|
||||
private bool video_added = false;
|
||||
private PeerInfo? prev_peer_info = null;
|
||||
private CallContentDetails audio_details = new CallContentDetails("Audio") { visible=true };
|
||||
private CallContentDetails video_details = new CallContentDetails("Video");
|
||||
|
||||
public CallConnectionDetailsWindow() {
|
||||
grid.attach(new Label("<b>Audio</b>") { use_markup=true, xalign=0, visible=true }, 0, row_at++, 1, 1);
|
||||
put_row("RTP");
|
||||
grid.attach(audio_rtp_ready, 1, row_at++, 1, 1);
|
||||
put_row("RTCP");
|
||||
grid.attach(audio_rtcp_ready, 1, row_at++, 1, 1);
|
||||
put_row("Sent bp/s");
|
||||
grid.attach(audio_sent_bps, 1, row_at++, 1, 1);
|
||||
put_row("Received bp/s");
|
||||
grid.attach(audio_recv_bps, 1, row_at++, 1, 1);
|
||||
put_row("Codec");
|
||||
grid.attach(audio_codec, 1, row_at++, 1, 1);
|
||||
put_row("Target receive bitrate");
|
||||
grid.attach(audio_target_receive_bitrate, 1, row_at++, 1, 1);
|
||||
put_row("Target send bitrate");
|
||||
grid.attach(audio_target_send_bitrate, 1, row_at++, 1, 1);
|
||||
|
||||
this.child = grid;
|
||||
}
|
||||
|
||||
private void put_row(string label) {
|
||||
grid.attach(new Label(label) { xalign=0, visible=true }, 0, row_at, 1, 1);
|
||||
box.add(audio_details);
|
||||
box.add(video_details);
|
||||
add(box);
|
||||
}
|
||||
|
||||
public void update_content(PeerInfo peer_info) {
|
||||
audio_rtp_ready.label = peer_info.audio_rtp_ready.to_string();
|
||||
audio_rtcp_ready.label = peer_info.audio_rtcp_ready.to_string();
|
||||
audio_codec.label = peer_info.audio_codec + " " + peer_info.audio_clockrate.to_string();
|
||||
audio_target_receive_bitrate.label = peer_info.audio_target_receive_bitrate.to_string();
|
||||
audio_target_send_bitrate.label = peer_info.audio_target_send_bitrate.to_string();
|
||||
|
||||
video_rtp_ready.label = peer_info.video_rtp_ready.to_string();
|
||||
video_rtcp_ready.label = peer_info.video_rtcp_ready.to_string();
|
||||
video_codec.label = peer_info.video_codec;
|
||||
video_target_receive_bitrate.label = peer_info.video_target_receive_bitrate.to_string();
|
||||
video_target_send_bitrate.label = peer_info.video_target_send_bitrate.to_string();
|
||||
|
||||
if (peer_info.video_content_exists) add_video_widgets();
|
||||
|
||||
if (prev_peer_info != null) {
|
||||
ulong audio_sent_kbps = (peer_info.audio_bytes_sent - prev_peer_info.audio_bytes_sent) * 8 / 1000;
|
||||
audio_sent_bps.label = "<span font_family='monospace'>%lu</span> kbps".printf(audio_sent_kbps);
|
||||
ulong audio_recv_kbps = (peer_info.audio_bytes_received - prev_peer_info.audio_bytes_received) * 8 / 1000;
|
||||
audio_recv_bps.label = "<span font_family='monospace'>%lu</span> kbps".printf(audio_recv_kbps);
|
||||
ulong video_sent_kbps = (peer_info.video_bytes_sent - prev_peer_info.video_bytes_sent) * 8 / 1000;
|
||||
video_sent_bps.label = "<span font_family='monospace'>%lu</span> kbps".printf(video_sent_kbps);
|
||||
ulong video_recv_kbps = (peer_info.video_bytes_received - prev_peer_info.video_bytes_received) * 8 / 1000;
|
||||
video_recv_bps.label = "<span font_family='monospace'>%lu</span> kbps".printf(video_recv_kbps);
|
||||
}
|
||||
prev_peer_info = peer_info;
|
||||
if (peer_info.audio != null) {
|
||||
audio_details.update_content(peer_info.audio);
|
||||
}
|
||||
if (peer_info.video != null) {
|
||||
add_video_widgets();
|
||||
video_details.update_content(peer_info.video);
|
||||
}
|
||||
}
|
||||
|
||||
private void add_video_widgets() {
|
||||
if (video_added) return;
|
||||
if (video_added) return;
|
||||
|
||||
grid.attach(new Label("<b>Video</b>") { use_markup=true, xalign=0, visible=true }, 0, row_at++, 1, 1);
|
||||
put_row("RTP");
|
||||
grid.attach(video_rtp_ready, 1, row_at++, 1, 1);
|
||||
put_row("RTCP");
|
||||
grid.attach(video_rtcp_ready, 1, row_at++, 1, 1);
|
||||
put_row("Sent bp/s");
|
||||
grid.attach(video_sent_bps, 1, row_at++, 1, 1);
|
||||
put_row("Received bp/s");
|
||||
grid.attach(video_recv_bps, 1, row_at++, 1, 1);
|
||||
put_row("Codec");
|
||||
grid.attach(video_codec, 1, row_at++, 1, 1);
|
||||
put_row("Target receive bitrate");
|
||||
grid.attach(video_target_receive_bitrate, 1, row_at++, 1, 1);
|
||||
put_row("Target send bitrate");
|
||||
grid.attach(video_target_send_bitrate, 1, row_at++, 1, 1);
|
||||
video_details.visible = true;
|
||||
video_added = true;
|
||||
}
|
||||
}
|
||||
|
||||
video_added = true;
|
||||
public class CallContentDetails : Gtk.Grid {
|
||||
|
||||
public Label rtp_title = new Label("RTP") { xalign=0, visible=true };
|
||||
public Label rtcp_title = new Label("RTCP") { xalign=0, visible=true };
|
||||
public Label target_recv_title = new Label("Target receive bitrate") { xalign=0, visible=true };
|
||||
public Label target_send_title = new Label("Target send bitrate") { xalign=0, visible=true };
|
||||
|
||||
public Label rtp_ready = new Label("?") { xalign=0, visible=true };
|
||||
public Label rtcp_ready = new Label("?") { xalign=0, visible=true };
|
||||
public Label sent_bps = new Label("?") { use_markup=true, xalign=0, visible=true };
|
||||
public Label recv_bps = new Label("?") { use_markup=true, xalign=0, visible=true };
|
||||
public Label codec = new Label("?") { xalign=0, visible=true };
|
||||
public Label target_receive_bitrate = new Label("n/a") { use_markup=true, xalign=0, visible=true };
|
||||
public Label target_send_bitrate = new Label("n/a") { use_markup=true, xalign=0, visible=true };
|
||||
|
||||
private PeerContentInfo? prev_info = null;
|
||||
private int row_at = 0;
|
||||
|
||||
public CallContentDetails(string headline) {
|
||||
attach(new Label("<b>%s</b>".printf(headline)) { use_markup=true, xalign=0, visible=true }, 0, row_at++, 1, 1);
|
||||
attach(rtp_title, 0, row_at, 1, 1);
|
||||
attach(rtp_ready, 1, row_at++, 1, 1);
|
||||
attach(rtcp_title, 0, row_at, 1, 1);
|
||||
attach(rtcp_ready, 1, row_at++, 1, 1);
|
||||
put_row("Sent");
|
||||
attach(sent_bps, 1, row_at++, 1, 1);
|
||||
put_row("Received");
|
||||
attach(recv_bps, 1, row_at++, 1, 1);
|
||||
put_row("Codec");
|
||||
attach(codec, 1, row_at++, 1, 1);
|
||||
attach(target_recv_title, 0, row_at, 1, 1);
|
||||
attach(target_receive_bitrate, 1, row_at++, 1, 1);
|
||||
attach(target_send_title, 0, row_at, 1, 1);
|
||||
attach(target_send_bitrate, 1, row_at++, 1, 1);
|
||||
|
||||
this.column_spacing = 5;
|
||||
}
|
||||
|
||||
public void update_content(PeerContentInfo info) {
|
||||
if (!info.rtp_ready) {
|
||||
rtp_ready.visible = rtcp_ready.visible = true;
|
||||
rtp_title.visible = rtcp_title.visible = true;
|
||||
rtp_ready.label = info.rtp_ready.to_string();
|
||||
rtcp_ready.label = info.rtcp_ready.to_string();
|
||||
} else {
|
||||
rtp_ready.visible = rtcp_ready.visible = false;
|
||||
rtp_title.visible = rtcp_title.visible = false;
|
||||
}
|
||||
if (info.target_send_bytes != -1) {
|
||||
target_receive_bitrate.visible = target_send_bitrate.visible = true;
|
||||
target_recv_title.visible = target_send_title.visible = true;
|
||||
target_receive_bitrate.label = "<span font_family='monospace'>%u</span> kbps".printf(info.target_receive_bytes);
|
||||
target_send_bitrate.label = "<span font_family='monospace'>%u</span> kbps".printf(info.target_send_bytes);
|
||||
} else {
|
||||
target_receive_bitrate.visible = target_send_bitrate.visible = false;
|
||||
target_recv_title.visible = target_send_title.visible = false;
|
||||
}
|
||||
|
||||
codec.label = info.codec + " " + info.clockrate.to_string();
|
||||
|
||||
if (prev_info != null) {
|
||||
ulong audio_sent_kbps = (info.bytes_sent - prev_info.bytes_sent) * 8 / 1000;
|
||||
sent_bps.label = "<span font_family='monospace'>%lu</span> kbps".printf(audio_sent_kbps);
|
||||
ulong audio_recv_kbps = (info.bytes_received - prev_info.bytes_received) * 8 / 1000;
|
||||
recv_bps.label = "<span font_family='monospace'>%lu</span> kbps".printf(audio_recv_kbps);
|
||||
}
|
||||
prev_info = info;
|
||||
}
|
||||
|
||||
private void put_row(string label) {
|
||||
attach(new Label(label) { xalign=0, visible=true }, 0, row_at, 1, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -144,7 +144,7 @@ namespace Dino.Ui {
|
|||
});
|
||||
|
||||
break;
|
||||
case Call.State.OTHER_DEVICE_ACCEPTED:
|
||||
case Call.State.OTHER_DEVICE:
|
||||
image.set_from_icon_name("dino-phone-hangup-symbolic", IconSize.LARGE_TOOLBAR);
|
||||
title_label.label = call.direction == Call.DIRECTION_INCOMING ? _("Incoming call") : _("Outgoing call");
|
||||
subtitle_label.label = _("You handled this call on another device");
|
||||
|
|
|
@ -99,7 +99,7 @@ public class Dino.Plugins.Rtp.Stream : Xmpp.Xep.JingleRtp.Stream {
|
|||
debug("%s.%s probed upstream query %s", pad.get_parent_element().name, pad.name, info.get_query().type.get_name());
|
||||
}
|
||||
if ((info.type & Gst.PadProbeType.BUFFER) > 0) {
|
||||
uint id = pad.get_data("no_buffer_probe_timeout");
|
||||
uint id = pad.steal_data("no_buffer_probe_timeout");
|
||||
if (id != 0) {
|
||||
Source.remove(id);
|
||||
}
|
||||
|
|
|
@ -151,6 +151,7 @@ public class Xmpp.Xep.JingleRtp.Parameters : Jingle.ContentParameters, Object {
|
|||
}
|
||||
|
||||
this.stream = parent.create_stream(content);
|
||||
this.stream.weak_ref(() => this.stream = null);
|
||||
rtp_datagram.datagram_received.connect(this.stream.on_recv_rtp_data);
|
||||
rtcp_datagram.datagram_received.connect(this.stream.on_recv_rtcp_data);
|
||||
this.stream.on_send_rtp_data.connect(rtp_datagram.send_datagram);
|
||||
|
|
|
@ -8,7 +8,7 @@ namespace Xmpp.Xep.JingleMessageInitiation {
|
|||
|
||||
public signal void session_proposed(Jid from, Jid to, string sid, Gee.List<StanzaNode> descriptions);
|
||||
public signal void session_retracted(Jid from, Jid to, string sid);
|
||||
public signal void session_accepted(Jid from, string sid);
|
||||
public signal void session_accepted(Jid from, Jid to, string sid);
|
||||
public signal void session_rejected(Jid from, Jid to, string sid);
|
||||
|
||||
public void send_session_propose_to_peer(XmppStream stream, Jid to, string sid, Gee.List<StanzaNode> descriptions) {
|
||||
|
@ -65,7 +65,7 @@ namespace Xmpp.Xep.JingleMessageInitiation {
|
|||
switch (mi_node.name) {
|
||||
case "accept":
|
||||
case "proceed":
|
||||
session_accepted(message.from, mi_node.get_attribute("id"));
|
||||
session_accepted(message.from, message.to, mi_node.get_attribute("id"));
|
||||
break;
|
||||
case "propose":
|
||||
ArrayList<StanzaNode> descriptions = new ArrayList<StanzaNode>();
|
||||
|
|
Loading…
Reference in a new issue