Delete invalid jingle sessions. Kick audio/video availability from jingle states.
Fixes #5668, #5651
This commit is contained in:
parent
8b497d64ec
commit
fbf9a769d8
|
@ -1259,13 +1259,12 @@ class ChatControl(ChatControlBase):
|
|||
A control for standard 1-1 chat
|
||||
"""
|
||||
(
|
||||
JINGLE_STATE_NOT_AVAILABLE,
|
||||
JINGLE_STATE_AVAILABLE,
|
||||
JINGLE_STATE_NULL,
|
||||
JINGLE_STATE_CONNECTING,
|
||||
JINGLE_STATE_CONNECTION_RECEIVED,
|
||||
JINGLE_STATE_CONNECTED,
|
||||
JINGLE_STATE_ERROR
|
||||
) = range(6)
|
||||
) = range(5)
|
||||
|
||||
TYPE_ID = message_control.TYPE_CHAT
|
||||
old_msg_kind = None # last kind of the printed message
|
||||
|
@ -1352,9 +1351,11 @@ class ChatControl(ChatControlBase):
|
|||
self._audio_banner_image = self.xml.get_object('audio_banner_image')
|
||||
self._video_banner_image = self.xml.get_object('video_banner_image')
|
||||
self.audio_sid = None
|
||||
self.audio_state = self.JINGLE_STATE_NOT_AVAILABLE
|
||||
self.audio_state = self.JINGLE_STATE_NULL
|
||||
self.audio_available = False
|
||||
self.video_sid = None
|
||||
self.video_state = self.JINGLE_STATE_NOT_AVAILABLE
|
||||
self.video_state = self.JINGLE_STATE_NULL
|
||||
self.video_available = False
|
||||
|
||||
self.update_toolbar()
|
||||
|
||||
|
@ -1480,34 +1481,19 @@ class ChatControl(ChatControlBase):
|
|||
# Jingle detection
|
||||
if self.contact.supports(NS_JINGLE_ICE_UDP) and \
|
||||
gajim.HAVE_FARSIGHT and self.contact.resource:
|
||||
if self.contact.supports(NS_JINGLE_RTP_AUDIO):
|
||||
if self.audio_state == self.JINGLE_STATE_NOT_AVAILABLE:
|
||||
self.set_audio_state('available')
|
||||
else:
|
||||
self.set_audio_state('not_available')
|
||||
|
||||
if self.contact.supports(NS_JINGLE_RTP_VIDEO):
|
||||
if self.video_state == self.JINGLE_STATE_NOT_AVAILABLE:
|
||||
self.set_video_state('available')
|
||||
else:
|
||||
self.set_video_state('not_available')
|
||||
self.audio_available = self.contact.supports(NS_JINGLE_RTP_AUDIO)
|
||||
self.video_available = self.contact.supports(NS_JINGLE_RTP_VIDEO)
|
||||
else:
|
||||
if self.audio_state != self.JINGLE_STATE_NOT_AVAILABLE:
|
||||
self.set_audio_state('not_available')
|
||||
if self.video_state != self.JINGLE_STATE_NOT_AVAILABLE:
|
||||
self.set_video_state('not_available')
|
||||
if self.video_available or self.audio_available:
|
||||
self.stop_jingle()
|
||||
self.video_available = False
|
||||
self.audio_available = False
|
||||
|
||||
# Audio buttons
|
||||
if self.audio_state == self.JINGLE_STATE_NOT_AVAILABLE:
|
||||
self._audio_button.set_sensitive(False)
|
||||
else:
|
||||
self._audio_button.set_sensitive(True)
|
||||
self._audio_button.set_sensitive(self.audio_available)
|
||||
|
||||
# Video buttons
|
||||
if self.video_state == self.JINGLE_STATE_NOT_AVAILABLE:
|
||||
self._video_button.set_sensitive(False)
|
||||
else:
|
||||
self._video_button.set_sensitive(True)
|
||||
self._video_button.set_sensitive(self.video_available)
|
||||
|
||||
# Send file
|
||||
if self.contact.supports(NS_FILE) and self.contact.resource:
|
||||
|
@ -1551,8 +1537,7 @@ class ChatControl(ChatControlBase):
|
|||
return
|
||||
banner_image = getattr(self, '_' + jingle_type + '_banner_image')
|
||||
state = getattr(self, jingle_type + '_state')
|
||||
if state in (self.JINGLE_STATE_NOT_AVAILABLE,
|
||||
self.JINGLE_STATE_AVAILABLE):
|
||||
if state == self.JINGLE_STATE_NULL:
|
||||
banner_image.hide()
|
||||
else:
|
||||
banner_image.show()
|
||||
|
@ -1604,24 +1589,29 @@ class ChatControl(ChatControlBase):
|
|||
# update MessageWindow._controls
|
||||
self.parent_win.change_jid(self.account, old_full_jid, new_full_jid)
|
||||
|
||||
def stop_jingle(self, sid=None, reason=None):
|
||||
if self.audio_sid and sid in (self.audio_sid, None):
|
||||
self.close_jingle_content('audio')
|
||||
if self.video_sid and sid in (self.video_sid, None):
|
||||
self.close_jingle_content('video')
|
||||
|
||||
|
||||
def _set_jingle_state(self, jingle_type, state, sid=None, reason=None):
|
||||
if jingle_type not in ('audio', 'video'):
|
||||
return
|
||||
if state in ('connecting', 'connected', 'stop') and reason:
|
||||
if state in ('connecting', 'connected', 'stop', 'error') and reason:
|
||||
str = _('%(type)s state : %(state)s, reason: %(reason)s') % {
|
||||
'type': jingle_type.capitalize(), 'state': state, 'reason': reason}
|
||||
self.print_conversation(str, 'info')
|
||||
|
||||
states = {'not_available': self.JINGLE_STATE_NOT_AVAILABLE,
|
||||
'available': self.JINGLE_STATE_AVAILABLE,
|
||||
'connecting': self.JINGLE_STATE_CONNECTING,
|
||||
states = {'connecting': self.JINGLE_STATE_CONNECTING,
|
||||
'connection_received': self.JINGLE_STATE_CONNECTION_RECEIVED,
|
||||
'connected': self.JINGLE_STATE_CONNECTED,
|
||||
'stop': self.JINGLE_STATE_AVAILABLE,
|
||||
'stop': self.JINGLE_STATE_NULL,
|
||||
'error': self.JINGLE_STATE_ERROR}
|
||||
|
||||
jingle_state = states[state]
|
||||
if getattr(self, jingle_type + '_state') == jingle_state:
|
||||
if getattr(self, jingle_type + '_state') == jingle_state or state == 'error':
|
||||
return
|
||||
|
||||
if state == 'stop' and getattr(self, jingle_type + '_sid') not in (None, sid):
|
||||
|
@ -1629,21 +1619,12 @@ class ChatControl(ChatControlBase):
|
|||
|
||||
setattr(self, jingle_type + '_state', jingle_state)
|
||||
|
||||
# Destroy existing session with the user when he signs off
|
||||
# We need to do that before modifying the sid
|
||||
if state == 'not_available':
|
||||
gajim.connections[self.account].delete_jingle_session(
|
||||
getattr(self, jingle_type + '_sid'))
|
||||
|
||||
if state in ('not_available', 'available', 'stop'):
|
||||
if jingle_state == self.JINGLE_STATE_NULL:
|
||||
setattr(self, jingle_type + '_sid', None)
|
||||
if state in ('connection_received', 'connecting'):
|
||||
setattr(self, jingle_type + '_sid', sid)
|
||||
|
||||
if state in ('connecting', 'connected', 'connection_received'):
|
||||
getattr(self, '_' + jingle_type + '_button').set_active(True)
|
||||
elif state in ('not_available', 'stop'):
|
||||
getattr(self, '_' + jingle_type + '_button').set_active(False)
|
||||
getattr(self, '_' + jingle_type + '_button').set_active(jingle_state != self.JINGLE_STATE_NULL)
|
||||
|
||||
getattr(self, 'update_' + jingle_type)()
|
||||
|
||||
|
@ -1892,12 +1873,16 @@ class ChatControl(ChatControlBase):
|
|||
sid = getattr(self, jingle_type + '_sid')
|
||||
if not sid:
|
||||
return
|
||||
setattr(self, jingle_type + '_sid', None)
|
||||
setattr(self, jingle_type + '_state', self.JINGLE_STATE_NULL)
|
||||
session = gajim.connections[self.account].get_jingle_session(
|
||||
self.contact.get_full_jid(), sid)
|
||||
if session:
|
||||
content = session.get_content(jingle_type)
|
||||
if content:
|
||||
session.remove_content(content.creator, content.name)
|
||||
getattr(self, '_' + jingle_type + '_button').set_active(False)
|
||||
getattr(self, 'update_' + jingle_type)()
|
||||
|
||||
def on_jingle_button_toggled(self, widget, jingle_type):
|
||||
img_name = 'gajim-%s_%s' % ({'audio': 'mic', 'video': 'cam'}[jingle_type],
|
||||
|
@ -1906,7 +1891,7 @@ class ChatControl(ChatControlBase):
|
|||
|
||||
if widget.get_active():
|
||||
if getattr(self, jingle_type + '_state') == \
|
||||
self.JINGLE_STATE_AVAILABLE:
|
||||
self.JINGLE_STATE_NULL:
|
||||
sid = getattr(gajim.connections[self.account],
|
||||
'start_' + jingle_type)(self.contact.get_full_jid())
|
||||
getattr(self, 'set_' + jingle_type + '_state')('connecting', sid)
|
||||
|
|
|
@ -195,8 +195,8 @@ class StandardCommonChatCommands(CommandContainer):
|
|||
@command
|
||||
@doc(_("Toggle audio session"))
|
||||
def audio(self):
|
||||
if self.audio_state == self.JINGLE_STATE_NOT_AVAILABLE:
|
||||
raise CommandError(_("Video sessions are not available"))
|
||||
if not self.audio_available:
|
||||
raise CommandError(_("Audio sessions are not available"))
|
||||
else:
|
||||
# A state of an audio session is toggled by inverting a state of the
|
||||
# appropriate button.
|
||||
|
@ -206,7 +206,7 @@ class StandardCommonChatCommands(CommandContainer):
|
|||
@command
|
||||
@doc(_("Toggle video session"))
|
||||
def video(self):
|
||||
if self.video_state == self.JINGLE_STATE_NOT_AVAILABLE:
|
||||
if not self.video_available:
|
||||
raise CommandError(_("Video sessions are not available"))
|
||||
else:
|
||||
# A state of a video session is toggled by inverting a state of the
|
||||
|
|
|
@ -33,7 +33,7 @@ Handles the jingle signalling protocol
|
|||
import xmpp
|
||||
import helpers
|
||||
|
||||
from jingle_session import JingleSession
|
||||
from jingle_session import JingleSession, JingleStates
|
||||
from jingle_rtp import JingleAudio, JingleVideo
|
||||
|
||||
|
||||
|
@ -92,6 +92,9 @@ class ConnectionJingle(object):
|
|||
|
||||
# we already have such session in dispatcher...
|
||||
self.__sessions[sid].on_stanza(stanza)
|
||||
# Delete invalid/unneeded sessions
|
||||
if sid in self.__sessions and self.__sessions[sid].state == JingleStates.ended:
|
||||
self.delete_jingle_session(sid)
|
||||
|
||||
raise xmpp.NodeProcessed
|
||||
|
||||
|
|
|
@ -320,8 +320,6 @@ class JingleSession(object):
|
|||
xmpp_error = child.getName()
|
||||
self.__dispatch_error(xmpp_error, jingle_error, text)
|
||||
# FIXME: Not sure when we would want to do that...
|
||||
if xmpp_error == 'item-not-found':
|
||||
self.connection.delete_jingle_session(self.sid)
|
||||
|
||||
def __on_transport_replace(self, stanza, jingle, error, action):
|
||||
for content in jingle.iterTags('content'):
|
||||
|
|
|
@ -4907,6 +4907,15 @@ class VoIPCallReceivedDialog(object):
|
|||
self.content_types.add(type_)
|
||||
self.set_secondary_text()
|
||||
|
||||
def remove_contents(self, content_types):
|
||||
for type_ in content_types:
|
||||
if type_ in self.content_types:
|
||||
self.content_types.remove(type_)
|
||||
if not self.content_types:
|
||||
self.dialog.destroy()
|
||||
else:
|
||||
self.set_secondary_text()
|
||||
|
||||
def on_voip_call_received_messagedialog_destroy(self, dialog):
|
||||
if (self.fjid, self.sid) in self.instances:
|
||||
del self.instances[(self.fjid, self.sid)]
|
||||
|
|
|
@ -1810,9 +1810,8 @@ class Interface:
|
|||
if media in ('audio', 'video'):
|
||||
jid = gajim.get_jid_without_resource(peerjid)
|
||||
resource = gajim.get_resource_from_jid(peerjid)
|
||||
ctrl = self.msg_win_mgr.get_control(peerjid, account)
|
||||
if not ctrl:
|
||||
ctrl = self.msg_win_mgr.get_control(jid, account)
|
||||
ctrl = (self.msg_win_mgr.get_control(peerjid, account)
|
||||
or self.msg_win_mgr.get_control(jid, account))
|
||||
if ctrl:
|
||||
if media == 'audio':
|
||||
ctrl.set_audio_state('connected', sid)
|
||||
|
@ -1824,26 +1823,29 @@ class Interface:
|
|||
peerjid, sid, media, reason = data
|
||||
jid = gajim.get_jid_without_resource(peerjid)
|
||||
resource = gajim.get_resource_from_jid(peerjid)
|
||||
ctrl = self.msg_win_mgr.get_control(peerjid, account)
|
||||
if not ctrl:
|
||||
ctrl = self.msg_win_mgr.get_control(jid, account)
|
||||
ctrl = (self.msg_win_mgr.get_control(peerjid, account)
|
||||
or self.msg_win_mgr.get_control(jid, account))
|
||||
if ctrl:
|
||||
if media in ('audio', None):
|
||||
if media is None:
|
||||
ctrl.stop_jingle(sid=sid, reason=reason)
|
||||
elif media == 'audio':
|
||||
ctrl.set_audio_state('stop', sid=sid, reason=reason)
|
||||
if media in ('video', None):
|
||||
elif media == 'video':
|
||||
ctrl.set_video_state('stop', sid=sid, reason=reason)
|
||||
dialog = dialogs.VoIPCallReceivedDialog.get_dialog(peerjid, sid)
|
||||
if dialog:
|
||||
dialog.dialog.destroy()
|
||||
if media is None:
|
||||
dialog.dialog.destroy()
|
||||
else:
|
||||
dialog.remove_contents((media, ))
|
||||
|
||||
def handle_event_jingle_error(self, account, data):
|
||||
# ('JINGLE_ERROR', account, (peerjid, sid, reason))
|
||||
peerjid, sid, reason = data
|
||||
jid = gajim.get_jid_without_resource(peerjid)
|
||||
resource = gajim.get_resource_from_jid(peerjid)
|
||||
ctrl = self.msg_win_mgr.get_control(peerjid, account)
|
||||
if not ctrl:
|
||||
ctrl = self.msg_win_mgr.get_control(jid, account)
|
||||
ctrl = (self.msg_win_mgr.get_control(peerjid, account)
|
||||
or self.msg_win_mgr.get_control(jid, account))
|
||||
if ctrl:
|
||||
ctrl.set_audio_state('error', reason=reason)
|
||||
|
||||
|
|
Loading…
Reference in New Issue