Refuse multiple sessions and implement alternative-session; make jingle GUI a bit more reliable.
This commit is contained in:
		
							parent
							
								
									b3b8e2f46b
								
							
						
					
					
						commit
						ab0f7899ad
					
				
					 5 changed files with 42 additions and 19 deletions
				
			
		| 
						 | 
				
			
			@ -1620,11 +1620,14 @@ class ChatControl(ChatControlBase):
 | 
			
		|||
                'stop': self.JINGLE_STATE_AVAILABLE,
 | 
			
		||||
                'error': self.JINGLE_STATE_ERROR}
 | 
			
		||||
 | 
			
		||||
        if state in states:
 | 
			
		||||
            jingle_state = states[state]
 | 
			
		||||
            if getattr(self, jingle_type + '_state') == jingle_state:
 | 
			
		||||
                return
 | 
			
		||||
            setattr(self, jingle_type + '_state', jingle_state)
 | 
			
		||||
        jingle_state = states[state]
 | 
			
		||||
        if getattr(self, jingle_type + '_state') == jingle_state:
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
        if state == 'stop' and getattr(self, jingle_type + '_sid') not in (None, sid):
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
        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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -121,6 +121,20 @@ class ConnectionJingle(object):
 | 
			
		|||
            jingle.start_session()
 | 
			
		||||
        return jingle.sid
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def iter_jingle_sessions(self, jid, sid=None, media=None):
 | 
			
		||||
        if sid:
 | 
			
		||||
            return (session for session in self.__sessions.values() if session.sid == sid)
 | 
			
		||||
        sessions = (session for session in self.__sessions.values() if session.peerjid == jid)
 | 
			
		||||
        if media:
 | 
			
		||||
            if media not in ('audio', 'video'):
 | 
			
		||||
                return tuple()
 | 
			
		||||
            else:
 | 
			
		||||
                return (session for session in sessions if session.get_content(media))
 | 
			
		||||
        else:
 | 
			
		||||
            return sessions
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def get_jingle_session(self, jid, sid=None, media=None):
 | 
			
		||||
        if sid:
 | 
			
		||||
            if sid in self.__sessions:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -426,6 +426,16 @@ class JingleSession(object):
 | 
			
		|||
        # Jingle with unknown entities, it SHOULD return a <service-unavailable/>
 | 
			
		||||
        # error.
 | 
			
		||||
 | 
			
		||||
        # Check if there's already a session with this user:
 | 
			
		||||
        for session in self.connection.iter_jingle_sessions(self.peerjid):
 | 
			
		||||
            if not session is self:
 | 
			
		||||
                reason = xmpp.Node('reason')
 | 
			
		||||
                alternative_session = reason.setTag('alternative-session')
 | 
			
		||||
                alternative_session.setTagData('sid', session.sid)
 | 
			
		||||
                self.__ack(stanza, jingle, error, action)
 | 
			
		||||
                self._session_terminate(reason)
 | 
			
		||||
                raise xmpp.NodeProcessed
 | 
			
		||||
 | 
			
		||||
        # Lets check what kind of jingle session does the peer want
 | 
			
		||||
        contents, contents_rejected, reason_txt = self.__parse_contents(jingle)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -520,6 +530,7 @@ class JingleSession(object):
 | 
			
		|||
        self.connection.dispatch('JINGLE_ERROR', (self.peerjid, self.sid, text))
 | 
			
		||||
 | 
			
		||||
    def __reason_from_stanza(self, stanza):
 | 
			
		||||
        # TODO: Move to GUI?
 | 
			
		||||
        reason = 'success'
 | 
			
		||||
        reasons = ['success', 'busy', 'cancel', 'connectivity-error',
 | 
			
		||||
                'decline', 'expired', 'failed-application', 'failed-transport',
 | 
			
		||||
| 
						 | 
				
			
			@ -602,6 +613,7 @@ class JingleSession(object):
 | 
			
		|||
            jingle.addChild(node=reason)
 | 
			
		||||
        self.__broadcast_all(stanza, jingle, None, 'session-terminate-sent')
 | 
			
		||||
        self.connection.connection.send(stanza)
 | 
			
		||||
        # TODO: Move to GUI?
 | 
			
		||||
        reason, text = self.__reason_from_stanza(jingle)
 | 
			
		||||
        if reason not in ('success', 'cancel', 'decline'):
 | 
			
		||||
            self.__dispatch_error(reason, reason, text)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4925,17 +4925,10 @@ class VoIPCallReceivedDialog(object):
 | 
			
		|||
            #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)
 | 
			
		||||
            if not ctrl:
 | 
			
		||||
                ctrl = gajim.interface.msg_win_mgr.get_control(jid, self.account)
 | 
			
		||||
            if not ctrl:
 | 
			
		||||
                # open chat control
 | 
			
		||||
                contact = gajim.contacts.get_contact(self.account, jid, resource)
 | 
			
		||||
                if not contact:
 | 
			
		||||
                    contact = gajim.contacts.get_contact(self.account, jid)
 | 
			
		||||
                if not contact:
 | 
			
		||||
                    return
 | 
			
		||||
                ctrl = gajim.interface.new_chat(contact, self.account, resource)
 | 
			
		||||
            ctrl = (gajim.interface.msg_win_mgr.get_control(self.fjid, self.account)
 | 
			
		||||
                    or gajim.interface.msg_win_mgr.get_control(jid, self.account)
 | 
			
		||||
                    or gajim.interface.new_chat_from_jid(self.account, jid))
 | 
			
		||||
 | 
			
		||||
            # Chat control opened, update content's status
 | 
			
		||||
            audio = session.get_content('audio')
 | 
			
		||||
            video = session.get_content('video')
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1775,9 +1775,8 @@ class Interface:
 | 
			
		|||
 | 
			
		||||
        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 'audio' in content_types:
 | 
			
		||||
                ctrl.set_audio_state('connection_received', sid)
 | 
			
		||||
| 
						 | 
				
			
			@ -2811,6 +2810,8 @@ class Interface:
 | 
			
		|||
            ctrl.user_nick = gajim.nicks[account]
 | 
			
		||||
        gobject.idle_add(mw.window.grab_focus)
 | 
			
		||||
 | 
			
		||||
        return ctrl
 | 
			
		||||
 | 
			
		||||
    def on_open_chat_window(self, widget, contact, account, resource=None,
 | 
			
		||||
    session=None):
 | 
			
		||||
        # Get the window containing the chat
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue