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:
Thibaut GIRKA 2009-10-03 22:40:12 +02:00
parent 01d7be2d61
commit b2b8ac4b76
3 changed files with 60 additions and 28 deletions

View File

@ -50,7 +50,7 @@ from common.logger import constants
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_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
@ -1256,16 +1256,6 @@ class ChatControl(ChatControlBase, ChatCommands):
self.audio_state = self.JINGLE_STATE_NOT_AVAILABLE
self.video_sid = None
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()
@ -1375,6 +1365,26 @@ class ChatControl(ChatControlBase, ChatCommands):
else:
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
if self.audio_state == self.JINGLE_STATE_NOT_AVAILABLE:
self._audio_button.set_sensitive(False)
@ -1579,22 +1589,26 @@ class ChatControl(ChatControlBase, ChatCommands):
elif state == 'connecting':
self.audio_state = self.JINGLE_STATE_CONNECTING
self.audio_sid = sid
self._audio_button.set_active(True)
elif state == 'connection_received':
self.audio_state = self.JINGLE_STATE_CONNECTION_RECEIVED
self.audio_sid = sid
self._audio_button.set_active(True)
elif state == 'connected':
self.audio_state = self.JINGLE_STATE_CONNECTED
elif state == 'stop':
self.audio_state = self.JINGLE_STATE_AVAILABLE
self.audio_sid = None
self._audio_button.set_active(False)
elif 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()
def set_video_state(self, state, sid=None, reason=None):
#TODO: Share code with set_audio_state?
if state in ('connecting', 'connected', 'stop'):
str = _('Video state : %s') % state
if reason:
@ -1608,11 +1622,9 @@ class ChatControl(ChatControlBase, ChatCommands):
self.video_sid = None
elif state == 'connecting':
self.video_state = self.JINGLE_STATE_CONNECTING
self._video_button.set_active(True)
self.video_sid = sid
elif state == 'connection_received':
self.video_state = self.JINGLE_STATE_CONNECTION_RECEIVED
self._video_button.set_active(True)
self.video_sid = sid
elif state == 'connected':
self.video_state = self.JINGLE_STATE_CONNECTED
@ -1622,6 +1634,12 @@ class ChatControl(ChatControlBase, ChatCommands):
self._video_button.set_active(False)
elif 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()
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):
if widget.get_active():
sid = gajim.connections[self.account].startVoIP(
self.contact.get_full_jid())
self.set_audio_state('connecting', sid)
if self.audio_state == self.JINGLE_STATE_AVAILABLE:
sid = gajim.connections[self.account].startVoIP(
self.contact.get_full_jid())
self.set_audio_state('connecting', sid)
else:
session = gajim.connections[self.account].get_jingle_session(
self.contact.get_full_jid(), self.audio_sid)
@ -1839,9 +1858,10 @@ class ChatControl(ChatControlBase, ChatCommands):
def on_video_button_toggled(self, widget):
if widget.get_active():
sid = gajim.connections[self.account].startVideoIP(
self.contact.get_full_jid())
self.set_video_state('connecting', sid)
if self.video_state == self.JINGLE_STATE_AVAILABLE:
sid = gajim.connections[self.account].startVideoIP(
self.contact.get_full_jid())
self.set_video_state('connecting', sid)
else:
session = gajim.connections[self.account].get_jingle_session(
self.contact.get_full_jid(), self.video_sid)

View File

@ -671,6 +671,7 @@ class JingleContent(object):
self.accepted = False
self.sent = False
self.candidates = [] # Local transport candidates
self.remote_candidates = [] # Remote transport candidates
self.senders = 'both' #FIXME
self.allow_sending = True # Used for stream direction, attribute 'senders'
@ -750,8 +751,12 @@ class JingleContent(object):
#FIXME: connectivity should not be etablished yet
# Instead, it should be etablished after session-accept!
if len(candidates) > 0:
self.p2pstream.set_remote_candidates(candidates)
print self.media, self.creator, self.name, candidates
if self.sent:
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=[]):
''' Build a XML content-wrapper for our data. '''
@ -917,6 +922,9 @@ class JingleRTPContent(JingleContent):
def __contentAcceptCB(self, stanza, content, error, action):
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'
self.p2pstream.set_property('direction', farsight.DIRECTION_BOTH)
self.session.content_negociated(self.media)

View File

@ -4518,10 +4518,7 @@ class VoIPCallReceivedDialog(object):
if not session:
return
if response == gtk.RESPONSE_YES:
if not session.accepted:
session.approve_session()
for content in self.content_types:
session.approve_content(content)
#TODO: Ensure that ctrl.contact.resource == resource
jid = gajim.get_jid_without_resource(self.fjid)
resource = gajim.get_resource_from_jid(self.fjid)
ctrl = gajim.interface.msg_win_mgr.get_control(self.fjid, self.account)
@ -4535,10 +4532,17 @@ class VoIPCallReceivedDialog(object):
if not contact:
return
ctrl = gajim.interface.new_chat(contact, self.account)
# Chat control opened, update content's status
if session.get_content('audio'):
ctrl.set_audio_state('connecting', self.sid)
if session.get_content('video'):
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
if not session.accepted:
session.decline_session()