diff options
author | Will Thompson <will.thompson@collabora.co.uk> | 2012-03-30 18:43:22 +0100 |
---|---|---|
committer | Matúš Kukan <matus.kukan@gmail.com> | 2012-07-17 16:40:06 +0200 |
commit | 86268ec22035855de9a505706c35217ba5a11565 (patch) | |
tree | 2a34667db715574846ea291e259d85abd8db32d7 /tubes | |
parent | tubes: reduce code duplication when opening connection (diff) | |
download | core-86268ec22035855de9a505706c35217ba5a11565.tar.gz core-86268ec22035855de9a505706c35217ba5a11565.zip |
tubes: move Accept() logic into conference
This makes sense, because the flow for Accept() and Offer() is basically
symmetrical, and then conference becomes solely responsible for the
handling of channels once they've been requested/given to us.
While we're at it we also fix both code paths to work correctly if the
state becomes Open before Accept/Offer returns (which is possible).
Diffstat (limited to 'tubes')
-rw-r--r-- | tubes/inc/tubes/conference.hxx | 15 | ||||
-rw-r--r-- | tubes/inc/tubes/manager.hxx | 12 | ||||
-rw-r--r-- | tubes/source/conference.cxx | 124 | ||||
-rw-r--r-- | tubes/source/manager.cxx | 66 |
4 files changed, 98 insertions, 119 deletions
diff --git a/tubes/inc/tubes/conference.hxx b/tubes/inc/tubes/conference.hxx index f4ae973a7737..4ae49c84530f 100644 --- a/tubes/inc/tubes/conference.hxx +++ b/tubes/inc/tubes/conference.hxx @@ -82,36 +82,39 @@ public: void setChannel( TpAccount* pAccount, TpChannel* pChannel ); TpChannel* getChannel() const { return mpChannel; } bool offerTube(); - bool acceptTube( const char* pAddress ); + bool acceptTube(); /// got tube accepted on other end as well? bool isTubeOpen() const { return meTubeChannelState == TP_TUBE_CHANNEL_STATE_OPEN; } // Only for callbacks. void setTubeOfferedHandlerInvoked( bool b ) { mbTubeOfferedHandlerInvoked = b; } bool isTubeOfferedHandlerInvoked() const { return mbTubeOfferedHandlerInvoked; } - void setTubeChannelStateChangedHandlerInvoked( bool b ) - { mbTubeChannelStateChangedHandlerInvoked = b; } - bool isTubeChannelStateChangedHandlerInvoked() const - { return mbTubeChannelStateChangedHandlerInvoked; } + bool isTubeChannelStateChangedToOpen() const + { return meTubeChannelState == TP_TUBE_CHANNEL_STATE_OPEN; }; void setTubeChannelState( TpTubeChannelState eState ) { meTubeChannelState = eState; } + static void TubeChannelStateChangedHandler(TpChannel*, guint, void*, GObject*); static void TubeOfferedHandler(TpChannel* pChannel, const gchar* pAddress, const GError* pError, gpointer pUserData, GObject*pWeakObject); + static void TubeAcceptedHandler(TpChannel* pChannel, const gchar* pAddress, const GError* pError, + gpointer pUserData, GObject*pWeakObject); static void FTReady( EmpathyFTHandler *handler, GError *error, gpointer user_data); private: + bool tryToOpen(); + bool spinUntilTubeEstablished(); bool setTube( const char* pTube ); rtl::OString maSessionId; TeleManager* mpManager; TpAccount* mpAccount; TpChannel* mpChannel; + gchar* mpAddress; DBusConnection* mpTube; TelePacketQueue maPacketQueue; TpTubeChannelState meTubeChannelState; bool mbTubeOfferedHandlerInvoked : 1; - bool mbTubeChannelStateChangedHandlerInvoked : 1; // hide from the public using boost::enable_shared_from_this<TeleConference>::shared_from_this; diff --git a/tubes/inc/tubes/manager.hxx b/tubes/inc/tubes/manager.hxx index 74d04246aea3..75e298c1c60e 100644 --- a/tubes/inc/tubes/manager.hxx +++ b/tubes/inc/tubes/manager.hxx @@ -131,8 +131,6 @@ public: void disconnect(); - void acceptTube( TpAccount* pAccount, TpChannel* pChannel, const char* pAddress ); - /** Send data to all registered conferences. @returns to how many conferences the packet was send @@ -217,6 +215,16 @@ public: /* Callbacks; not for use outside this class. */ static void TransferDone( EmpathyFTHandler *handler, TpFileTransferChannel *, gpointer user_data); + static void DBusChannelHandler( + TpSimpleHandler* /*handler*/, + TpAccount* pAccount, + TpConnection* /*connection*/, + GList* pChannels, + GList* /*requests_satisfied*/, + gint64 /*user_action_time*/, + TpHandleChannelsContext* pContext, + gpointer pUserData); + private: void ensureLegacyChannel( TpAccount* pAccount, TpContact* pBuddy ); diff --git a/tubes/source/conference.cxx b/tubes/source/conference.cxx index 82eb1e78af14..824b9c828056 100644 --- a/tubes/source/conference.cxx +++ b/tubes/source/conference.cxx @@ -169,34 +169,48 @@ void TeleConference::TubeOfferedHandler( if (pChannel != pConference->getChannel()) return; - pConference->setTube( pAddress ); + pConference->mpAddress = g_strdup( pAddress ); + pConference->tryToOpen(); } -static void TeleConference_TubeChannelStateChangedHandler( +bool TeleConference::tryToOpen() +{ + if (mpTube) + return true; + + if (!isTubeOpen()) + return false; + + if (!mpAddress) + return false; + + return setTube( mpAddress); +} + +void TeleConference::TubeChannelStateChangedHandler( TpChannel* pChannel, guint nState, gpointer pUserData, GObject* /*weak_object*/ ) { - INFO_LOGGER_F( "TeleConference_TubeChannelStateChangedHandler"); + INFO_LOGGER_F( "TeleConference::TubeChannelStateChangedHandler"); - SAL_INFO( "tubes", "TeleConference_TubeChannelStateChangedHandler: state: " << static_cast<sal_uInt32>(nState)); + SAL_INFO( "tubes", "TeleConference::TubeChannelStateChangedHandler: state: " << static_cast<sal_uInt32>(nState)); TeleConference* pConference = reinterpret_cast<TeleConference*>(pUserData); SAL_WARN_IF( !pConference, "tubes", "TeleConference_DBusMessageHandler: no conference"); if (!pConference) return; - pConference->setTubeChannelStateChangedHandlerInvoked( true); - SAL_WARN_IF( pChannel != pConference->getChannel(), "tubes", - "TeleConference_TubeChannelStateChangedHandler: not my channel"); + "TeleConference::TubeChannelStateChangedHandler: not my channel"); if (pChannel != pConference->getChannel()) return; pConference->setTubeChannelState( static_cast<TpTubeChannelState>(nState)); + pConference->tryToOpen(); } @@ -204,18 +218,14 @@ TeleConference::TeleConference( TeleManager* pManager, TpAccount* pAccount, TpCh : maSessionId( rSessionId ), mpManager( pManager), - mpAccount( pAccount), - mpChannel( pChannel), + mpAccount( NULL), + mpChannel( NULL), + mpAddress( NULL), mpTube( NULL), meTubeChannelState( TP_TUBE_CHANNEL_STATE_NOT_OFFERED), - mbTubeOfferedHandlerInvoked( false), - mbTubeChannelStateChangedHandlerInvoked( false) + mbTubeOfferedHandlerInvoked( false) { - if (mpAccount) - g_object_ref( mpAccount); - - if (mpChannel) - g_object_ref( mpChannel); + setChannel( pAccount, pChannel ); } @@ -234,30 +244,59 @@ void TeleConference::setChannel( TpAccount *pAccount, TpChannel* pChannel ) g_object_unref( mpAccount); mpChannel = pChannel; - if (mpChannel) + if (mpChannel) { g_object_ref( mpChannel); + /* TODO: remember the TpProxySignalConnection and disconnect in finalize */ + GError* pError = NULL; + TpProxySignalConnection* pProxySignalConnection = + tp_cli_channel_interface_tube_connect_to_tube_channel_state_changed( + mpChannel, + &TeleConference::TubeChannelStateChangedHandler, + this, + NULL, + NULL, + &pError); + + if (!pProxySignalConnection || pError) + { + SAL_WARN_IF( pError, "tubes", + "TeleConference::setChannel: channel state changed error: " << pError->message); + g_error_free( pError); + } + } + mpAccount = pAccount; if (mpAccount) g_object_ref( mpAccount); } -bool TeleConference::acceptTube( const char* pAddress ) +bool TeleConference::spinUntilTubeEstablished() { - INFO_LOGGER( "TeleConference::acceptTube"); + mpManager->iterateLoop( this, &TeleConference::isTubeOfferedHandlerInvoked); + mpManager->iterateLoop( this, &TeleConference::isTubeChannelStateChangedToOpen); - SAL_WARN_IF( !pAddress, "tubes", "TeleConference::acceptTube: no address"); - if (!pAddress) - return false; - SAL_INFO( "tubes", "TeleConference::acceptTube: address: " << pAddress); + bool bOpen = isTubeOpen(); + SAL_INFO( "tubes", "TeleConference::spinUntilTubeEstablished: tube open: " << bOpen); + return bOpen; +} + + +bool TeleConference::acceptTube() +{ + INFO_LOGGER( "TeleConference::acceptTube"); SAL_WARN_IF( !mpChannel, "tubes", "TeleConference::acceptTube: no channel setup"); SAL_WARN_IF( mpTube, "tubes", "TeleConference::acceptTube: already tubed"); if (!mpChannel || mpTube) return false; - return setTube( pAddress ); + tp_cli_channel_type_dbus_tube_call_accept( mpChannel, -1, + TP_SOCKET_ACCESS_CONTROL_CREDENTIALS, + &TeleConference::TubeOfferedHandler, + this, NULL, NULL); + return spinUntilTubeEstablished(); } @@ -269,8 +308,6 @@ bool TeleConference::offerTube() if (!mpChannel) return false; - setTubeOfferedHandlerInvoked( false); - // We must pass a hash table, it could be empty though. /* TODO: anything meaningful to go in here? */ GHashTable* pParams = tp_asv_new( @@ -287,35 +324,8 @@ bool TeleConference::offerTube() NULL, // destroy NULL); // weak_object - mpManager->iterateLoop( this, &TeleConference::isTubeOfferedHandlerInvoked); - g_hash_table_unref( pParams); - - setTubeChannelStateChangedHandlerInvoked( false); - - /* TODO: remember the TpProxySignalConnection for further use? */ - GError* pError = NULL; - TpProxySignalConnection* pProxySignalConnection = - tp_cli_channel_interface_tube_connect_to_tube_channel_state_changed( - mpChannel, - TeleConference_TubeChannelStateChangedHandler, - this, - NULL, - NULL, - &pError); - - if (!pProxySignalConnection || pError) - { - SAL_WARN_IF( pError, "tubes", "TeleConference::offerTube: channel state changed error: " << pError->message); - g_error_free( pError); - return false; - } - - mpManager->iterateLoop( this, &TeleConference::isTubeChannelStateChangedHandlerInvoked); - - bool bOpen = isTubeOpen(); - SAL_INFO( "tubes", "TeleConference::offerTube: tube open: " << bOpen); - return bOpen; + return spinUntilTubeEstablished(); } @@ -379,6 +389,12 @@ void TeleConference::finalize() mpTube = NULL; } + if (mpAddress) + { + g_free( mpAddress); + mpAddress = NULL; + } + TeleConferencePtr pThis( shared_from_this()); mpManager->unregisterConference( pThis); diff --git a/tubes/source/manager.cxx b/tubes/source/manager.cxx index b9ecfd0a00c8..32589f10a9ae 100644 --- a/tubes/source/manager.cxx +++ b/tubes/source/manager.cxx @@ -92,38 +92,7 @@ public: }; -static void TeleManager_DBusTubeAcceptHandler( - TpChannel* pChannel, - const char* pAddress, - const GError* pError, - gpointer pUserData, - GObject* pWeakObject) -{ - INFO_LOGGER_F( "TeleManager_DBusTubeAcceptHandler"); - - TpAccount* pAccount = TP_ACCOUNT(pWeakObject); - - SAL_WARN_IF( pError, "tubes", "TeleManager_DBusTubeAcceptHandler: entered with error: " << pError->message); - if (pError) - { - g_object_unref(pAccount); - return; - } - - TeleManager* pManager = reinterpret_cast<TeleManager*>(pUserData); - SAL_WARN_IF( !pManager, "tubes", "TeleManager_DBusTubeAcceptHandler: no manager"); - if (!pManager) - { - g_object_unref(pAccount); - return; - } - - pManager->acceptTube( pAccount, pChannel, pAddress); - g_object_unref (pAccount); -} - - -static void TeleManager_DBusChannelHandler( +void TeleManager::DBusChannelHandler( TpSimpleHandler* /*handler*/, TpAccount* pAccount, TpConnection* /*connection*/, @@ -134,10 +103,10 @@ static void TeleManager_DBusChannelHandler( gpointer pUserData) { bool aAccepted = false; - INFO_LOGGER_F( "TeleManager_DBusChannelHandler"); + INFO_LOGGER_F( "TeleManager::DBusChannelHandler"); TeleManager* pManager = reinterpret_cast<TeleManager*>(pUserData); - SAL_WARN_IF( !pManager, "tubes", "TeleManager_DBusChannelHandler: no manager"); + SAL_WARN_IF( !pManager, "tubes", "TeleManager::DBusChannelHandler: no manager"); if (!pManager) return; @@ -147,18 +116,17 @@ static void TeleManager_DBusChannelHandler( if (!pChannel) continue; - SAL_INFO( "tubes", "TeleManager_DBusChannelHandler: incoming dbus channel: " + SAL_INFO( "tubes", "TeleManager::DBusChannelHandler: incoming dbus channel: " << tp_channel_get_identifier( pChannel)); if (tp_channel_get_channel_type_id( pChannel) == TP_IFACE_QUARK_CHANNEL_TYPE_DBUS_TUBE) { SAL_INFO( "tubes", "accepting"); aAccepted = true; - g_object_ref( pAccount); - tp_cli_channel_type_dbus_tube_call_accept( pChannel, -1, - TP_SOCKET_ACCESS_CONTROL_CREDENTIALS, - TeleManager_DBusTubeAcceptHandler, pUserData, NULL, - G_OBJECT (pAccount)); + + TeleConferencePtr pConference( new TeleConference( pManager, pAccount, pChannel, "")); + pManager->maConferences.push_back( pConference); + pConference->acceptTube(); } else { @@ -456,7 +424,7 @@ bool TeleManager::connect() FALSE, // requests getFullClientName().getStr(), // name FALSE, // uniquify - TeleManager_DBusChannelHandler, // callback + &TeleManager::DBusChannelHandler, // callback this, // user_data NULL // destroy ); @@ -847,22 +815,6 @@ void TeleManager::disconnect() } -void TeleManager::acceptTube( TpAccount* pAccount, TpChannel* pChannel, const char* pAddress ) -{ - INFO_LOGGER( "TeleManager::acceptTube"); - - SAL_INFO( "tubes", "TeleManager::acceptTube: address " << pAddress); - - SAL_WARN_IF( !pChannel || !pAddress, "tubes", "TeleManager::acceptTube: no channel or no address"); - if (!pChannel || !pAddress) - return; - - TeleConferencePtr pConference( new TeleConference( this, pAccount, pChannel, "")); - maConferences.push_back( pConference); - pConference->acceptTube( pAddress); -} - - void TeleManager::setAccountManagerReady( bool bPrepared) { pImpl->meAccountManagerStatus = (bPrepared ? AMS_PREPARED : AMS_UNPREPARABLE); |