Connect only if user accepts, move jingle detection to 'update_toolbar'
This allows jingle availability to be updated if contact sign in/out. This patch will also wait for user acceptance before connecting. This will, among other things, ensure that audio/video state won't be set to JINGLE_STATE_CONNECTING while the connection is already up.
This commit is contained in:
parent
01d7be2d61
commit
b2b8ac4b76
3 changed files with 60 additions and 28 deletions
|
@ -50,7 +50,7 @@ from common.logger import constants
|
||||||
from common.pep import MOODS, ACTIVITIES
|
from common.pep import MOODS, ACTIVITIES
|
||||||
from common.xmpp.protocol import NS_XHTML, NS_XHTML_IM, NS_FILE, NS_MUC
|
from common.xmpp.protocol import NS_XHTML, NS_XHTML_IM, NS_FILE, NS_MUC
|
||||||
from common.xmpp.protocol import NS_RECEIPTS, NS_ESESSION
|
from common.xmpp.protocol import NS_RECEIPTS, NS_ESESSION
|
||||||
from common.xmpp.protocol import NS_JINGLE_RTP_AUDIO, NS_JINGLE_RTP_VIDEO
|
from common.xmpp.protocol import NS_JINGLE_RTP_AUDIO, NS_JINGLE_RTP_VIDEO, NS_JINGLE_ICE_UDP
|
||||||
|
|
||||||
from commands.implementation import CommonCommands, ChatCommands
|
from commands.implementation import CommonCommands, ChatCommands
|
||||||
|
|
||||||
|
@ -1256,16 +1256,6 @@ class ChatControl(ChatControlBase, ChatCommands):
|
||||||
self.audio_state = self.JINGLE_STATE_NOT_AVAILABLE
|
self.audio_state = self.JINGLE_STATE_NOT_AVAILABLE
|
||||||
self.video_sid = None
|
self.video_sid = None
|
||||||
self.video_state = self.JINGLE_STATE_NOT_AVAILABLE
|
self.video_state = self.JINGLE_STATE_NOT_AVAILABLE
|
||||||
if gajim.capscache.is_supported(contact, NS_JINGLE_RTP_AUDIO) and \
|
|
||||||
gajim.HAVE_FARSIGHT:
|
|
||||||
self.set_audio_state('available')
|
|
||||||
else:
|
|
||||||
self.set_audio_state('not_available')
|
|
||||||
if gajim.capscache.is_supported(contact, NS_JINGLE_RTP_VIDEO) and \
|
|
||||||
gajim.HAVE_FARSIGHT:
|
|
||||||
self.set_video_state('available')
|
|
||||||
else:
|
|
||||||
self.set_video_state('not_available')
|
|
||||||
|
|
||||||
self.update_toolbar()
|
self.update_toolbar()
|
||||||
|
|
||||||
|
@ -1375,6 +1365,26 @@ class ChatControl(ChatControlBase, ChatCommands):
|
||||||
else:
|
else:
|
||||||
self._add_to_roster_button.hide()
|
self._add_to_roster_button.hide()
|
||||||
|
|
||||||
|
# Jingle detection
|
||||||
|
if gajim.capscache.is_supported(self.contact, NS_JINGLE_ICE_UDP) and \
|
||||||
|
gajim.HAVE_FARSIGHT and self.contact.resource:
|
||||||
|
if gajim.capscache.is_supported(self.contact, 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 gajim.capscache.is_supported(self.contact, 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')
|
||||||
|
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')
|
||||||
|
|
||||||
# Audio buttons
|
# Audio buttons
|
||||||
if self.audio_state == self.JINGLE_STATE_NOT_AVAILABLE:
|
if self.audio_state == self.JINGLE_STATE_NOT_AVAILABLE:
|
||||||
self._audio_button.set_sensitive(False)
|
self._audio_button.set_sensitive(False)
|
||||||
|
@ -1579,22 +1589,26 @@ class ChatControl(ChatControlBase, ChatCommands):
|
||||||
elif state == 'connecting':
|
elif state == 'connecting':
|
||||||
self.audio_state = self.JINGLE_STATE_CONNECTING
|
self.audio_state = self.JINGLE_STATE_CONNECTING
|
||||||
self.audio_sid = sid
|
self.audio_sid = sid
|
||||||
self._audio_button.set_active(True)
|
|
||||||
elif state == 'connection_received':
|
elif state == 'connection_received':
|
||||||
self.audio_state = self.JINGLE_STATE_CONNECTION_RECEIVED
|
self.audio_state = self.JINGLE_STATE_CONNECTION_RECEIVED
|
||||||
self.audio_sid = sid
|
self.audio_sid = sid
|
||||||
self._audio_button.set_active(True)
|
|
||||||
elif state == 'connected':
|
elif state == 'connected':
|
||||||
self.audio_state = self.JINGLE_STATE_CONNECTED
|
self.audio_state = self.JINGLE_STATE_CONNECTED
|
||||||
elif state == 'stop':
|
elif state == 'stop':
|
||||||
self.audio_state = self.JINGLE_STATE_AVAILABLE
|
self.audio_state = self.JINGLE_STATE_AVAILABLE
|
||||||
self.audio_sid = None
|
self.audio_sid = None
|
||||||
self._audio_button.set_active(False)
|
|
||||||
elif state == 'error':
|
elif state == 'error':
|
||||||
self.audio_state = self.JINGLE_STATE_ERROR
|
self.audio_state = self.JINGLE_STATE_ERROR
|
||||||
|
|
||||||
|
if state in ('connecting', 'connected', 'connection_received'):
|
||||||
|
self._audio_button.set_active(True)
|
||||||
|
elif state in ('not_available', 'stop'):
|
||||||
|
#TODO: Destroy existing session(s) with this user?
|
||||||
|
self._audio_button.set_active(False)
|
||||||
self.update_audio()
|
self.update_audio()
|
||||||
|
|
||||||
def set_video_state(self, state, sid=None, reason=None):
|
def set_video_state(self, state, sid=None, reason=None):
|
||||||
|
#TODO: Share code with set_audio_state?
|
||||||
if state in ('connecting', 'connected', 'stop'):
|
if state in ('connecting', 'connected', 'stop'):
|
||||||
str = _('Video state : %s') % state
|
str = _('Video state : %s') % state
|
||||||
if reason:
|
if reason:
|
||||||
|
@ -1608,11 +1622,9 @@ class ChatControl(ChatControlBase, ChatCommands):
|
||||||
self.video_sid = None
|
self.video_sid = None
|
||||||
elif state == 'connecting':
|
elif state == 'connecting':
|
||||||
self.video_state = self.JINGLE_STATE_CONNECTING
|
self.video_state = self.JINGLE_STATE_CONNECTING
|
||||||
self._video_button.set_active(True)
|
|
||||||
self.video_sid = sid
|
self.video_sid = sid
|
||||||
elif state == 'connection_received':
|
elif state == 'connection_received':
|
||||||
self.video_state = self.JINGLE_STATE_CONNECTION_RECEIVED
|
self.video_state = self.JINGLE_STATE_CONNECTION_RECEIVED
|
||||||
self._video_button.set_active(True)
|
|
||||||
self.video_sid = sid
|
self.video_sid = sid
|
||||||
elif state == 'connected':
|
elif state == 'connected':
|
||||||
self.video_state = self.JINGLE_STATE_CONNECTED
|
self.video_state = self.JINGLE_STATE_CONNECTED
|
||||||
|
@ -1622,6 +1634,12 @@ class ChatControl(ChatControlBase, ChatCommands):
|
||||||
self._video_button.set_active(False)
|
self._video_button.set_active(False)
|
||||||
elif state == 'error':
|
elif state == 'error':
|
||||||
self.video_state = self.JINGLE_STATE_ERROR
|
self.video_state = self.JINGLE_STATE_ERROR
|
||||||
|
|
||||||
|
if state in ('connecting', 'connected', 'connection_received'):
|
||||||
|
self._video_button.set_active(True)
|
||||||
|
elif state in ('not_available', 'stop'):
|
||||||
|
#TODO: Destroy existing session(s) with this user?
|
||||||
|
self._video_button.set_active(False)
|
||||||
self.update_video()
|
self.update_video()
|
||||||
|
|
||||||
def on_avatar_eventbox_enter_notify_event(self, widget, event):
|
def on_avatar_eventbox_enter_notify_event(self, widget, event):
|
||||||
|
@ -1826,9 +1844,10 @@ class ChatControl(ChatControlBase, ChatCommands):
|
||||||
|
|
||||||
def on_audio_button_toggled(self, widget):
|
def on_audio_button_toggled(self, widget):
|
||||||
if widget.get_active():
|
if widget.get_active():
|
||||||
sid = gajim.connections[self.account].startVoIP(
|
if self.audio_state == self.JINGLE_STATE_AVAILABLE:
|
||||||
self.contact.get_full_jid())
|
sid = gajim.connections[self.account].startVoIP(
|
||||||
self.set_audio_state('connecting', sid)
|
self.contact.get_full_jid())
|
||||||
|
self.set_audio_state('connecting', sid)
|
||||||
else:
|
else:
|
||||||
session = gajim.connections[self.account].get_jingle_session(
|
session = gajim.connections[self.account].get_jingle_session(
|
||||||
self.contact.get_full_jid(), self.audio_sid)
|
self.contact.get_full_jid(), self.audio_sid)
|
||||||
|
@ -1839,9 +1858,10 @@ class ChatControl(ChatControlBase, ChatCommands):
|
||||||
|
|
||||||
def on_video_button_toggled(self, widget):
|
def on_video_button_toggled(self, widget):
|
||||||
if widget.get_active():
|
if widget.get_active():
|
||||||
sid = gajim.connections[self.account].startVideoIP(
|
if self.video_state == self.JINGLE_STATE_AVAILABLE:
|
||||||
self.contact.get_full_jid())
|
sid = gajim.connections[self.account].startVideoIP(
|
||||||
self.set_video_state('connecting', sid)
|
self.contact.get_full_jid())
|
||||||
|
self.set_video_state('connecting', sid)
|
||||||
else:
|
else:
|
||||||
session = gajim.connections[self.account].get_jingle_session(
|
session = gajim.connections[self.account].get_jingle_session(
|
||||||
self.contact.get_full_jid(), self.video_sid)
|
self.contact.get_full_jid(), self.video_sid)
|
||||||
|
|
|
@ -671,6 +671,7 @@ class JingleContent(object):
|
||||||
self.accepted = False
|
self.accepted = False
|
||||||
self.sent = False
|
self.sent = False
|
||||||
self.candidates = [] # Local transport candidates
|
self.candidates = [] # Local transport candidates
|
||||||
|
self.remote_candidates = [] # Remote transport candidates
|
||||||
|
|
||||||
self.senders = 'both' #FIXME
|
self.senders = 'both' #FIXME
|
||||||
self.allow_sending = True # Used for stream direction, attribute 'senders'
|
self.allow_sending = True # Used for stream direction, attribute 'senders'
|
||||||
|
@ -750,8 +751,12 @@ class JingleContent(object):
|
||||||
#FIXME: connectivity should not be etablished yet
|
#FIXME: connectivity should not be etablished yet
|
||||||
# Instead, it should be etablished after session-accept!
|
# Instead, it should be etablished after session-accept!
|
||||||
if len(candidates) > 0:
|
if len(candidates) > 0:
|
||||||
self.p2pstream.set_remote_candidates(candidates)
|
if self.sent:
|
||||||
print self.media, self.creator, self.name, candidates
|
self.p2pstream.set_remote_candidates(candidates)
|
||||||
|
else:
|
||||||
|
self.remote_candidates.extend(candidates)
|
||||||
|
#self.p2pstream.set_remote_candidates(candidates)
|
||||||
|
#print self.media, self.creator, self.name, candidates
|
||||||
|
|
||||||
def __content(self, payload=[]):
|
def __content(self, payload=[]):
|
||||||
''' Build a XML content-wrapper for our data. '''
|
''' Build a XML content-wrapper for our data. '''
|
||||||
|
@ -917,6 +922,9 @@ class JingleRTPContent(JingleContent):
|
||||||
|
|
||||||
def __contentAcceptCB(self, stanza, content, error, action):
|
def __contentAcceptCB(self, stanza, content, error, action):
|
||||||
if self.accepted:
|
if self.accepted:
|
||||||
|
if len(self.remote_candidates) > 0:
|
||||||
|
self.p2pstream.set_remote_candidates(self.remote_candidates)
|
||||||
|
self.remote_candidates = []
|
||||||
#TODO: farsight.DIRECTION_BOTH only if senders='both'
|
#TODO: farsight.DIRECTION_BOTH only if senders='both'
|
||||||
self.p2pstream.set_property('direction', farsight.DIRECTION_BOTH)
|
self.p2pstream.set_property('direction', farsight.DIRECTION_BOTH)
|
||||||
self.session.content_negociated(self.media)
|
self.session.content_negociated(self.media)
|
||||||
|
|
|
@ -4518,10 +4518,7 @@ class VoIPCallReceivedDialog(object):
|
||||||
if not session:
|
if not session:
|
||||||
return
|
return
|
||||||
if response == gtk.RESPONSE_YES:
|
if response == gtk.RESPONSE_YES:
|
||||||
if not session.accepted:
|
#TODO: Ensure that ctrl.contact.resource == resource
|
||||||
session.approve_session()
|
|
||||||
for content in self.content_types:
|
|
||||||
session.approve_content(content)
|
|
||||||
jid = gajim.get_jid_without_resource(self.fjid)
|
jid = gajim.get_jid_without_resource(self.fjid)
|
||||||
resource = gajim.get_resource_from_jid(self.fjid)
|
resource = gajim.get_resource_from_jid(self.fjid)
|
||||||
ctrl = gajim.interface.msg_win_mgr.get_control(self.fjid, self.account)
|
ctrl = gajim.interface.msg_win_mgr.get_control(self.fjid, self.account)
|
||||||
|
@ -4535,10 +4532,17 @@ class VoIPCallReceivedDialog(object):
|
||||||
if not contact:
|
if not contact:
|
||||||
return
|
return
|
||||||
ctrl = gajim.interface.new_chat(contact, self.account)
|
ctrl = gajim.interface.new_chat(contact, self.account)
|
||||||
|
# Chat control opened, update content's status
|
||||||
if session.get_content('audio'):
|
if session.get_content('audio'):
|
||||||
ctrl.set_audio_state('connecting', self.sid)
|
ctrl.set_audio_state('connecting', self.sid)
|
||||||
if session.get_content('video'):
|
if session.get_content('video'):
|
||||||
ctrl.set_video_state('connecting', self.sid)
|
ctrl.set_video_state('connecting', self.sid)
|
||||||
|
# Now, accept the content/sessions.
|
||||||
|
# This should be done after the chat control is running
|
||||||
|
if not session.accepted:
|
||||||
|
session.approve_session()
|
||||||
|
for content in self.content_types:
|
||||||
|
session.approve_content(content)
|
||||||
else: # response==gtk.RESPONSE_NO
|
else: # response==gtk.RESPONSE_NO
|
||||||
if not session.accepted:
|
if not session.accepted:
|
||||||
session.decline_session()
|
session.decline_session()
|
||||||
|
|
Loading…
Add table
Reference in a new issue