Kaydet (Commit) 86268ec2 authored tarafından Will Thompson's avatar Will Thompson Kaydeden (comit) Matúš Kukan

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).
üst 22614912
...@@ -82,36 +82,39 @@ public: ...@@ -82,36 +82,39 @@ public:
void setChannel( TpAccount* pAccount, TpChannel* pChannel ); void setChannel( TpAccount* pAccount, TpChannel* pChannel );
TpChannel* getChannel() const { return mpChannel; } TpChannel* getChannel() const { return mpChannel; }
bool offerTube(); bool offerTube();
bool acceptTube( const char* pAddress ); bool acceptTube();
/// got tube accepted on other end as well? /// got tube accepted on other end as well?
bool isTubeOpen() const { return meTubeChannelState == TP_TUBE_CHANNEL_STATE_OPEN; } bool isTubeOpen() const { return meTubeChannelState == TP_TUBE_CHANNEL_STATE_OPEN; }
// Only for callbacks. // Only for callbacks.
void setTubeOfferedHandlerInvoked( bool b ) { mbTubeOfferedHandlerInvoked = b; } void setTubeOfferedHandlerInvoked( bool b ) { mbTubeOfferedHandlerInvoked = b; }
bool isTubeOfferedHandlerInvoked() const { return mbTubeOfferedHandlerInvoked; } bool isTubeOfferedHandlerInvoked() const { return mbTubeOfferedHandlerInvoked; }
void setTubeChannelStateChangedHandlerInvoked( bool b ) bool isTubeChannelStateChangedToOpen() const
{ mbTubeChannelStateChangedHandlerInvoked = b; } { return meTubeChannelState == TP_TUBE_CHANNEL_STATE_OPEN; };
bool isTubeChannelStateChangedHandlerInvoked() const
{ return mbTubeChannelStateChangedHandlerInvoked; }
void setTubeChannelState( TpTubeChannelState eState ) { meTubeChannelState = eState; } void setTubeChannelState( TpTubeChannelState eState ) { meTubeChannelState = eState; }
static void TubeChannelStateChangedHandler(TpChannel*, guint, void*, GObject*);
static void TubeOfferedHandler(TpChannel* pChannel, const gchar* pAddress, const GError* pError, static void TubeOfferedHandler(TpChannel* pChannel, const gchar* pAddress, const GError* pError,
gpointer pUserData, GObject*pWeakObject); 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); static void FTReady( EmpathyFTHandler *handler, GError *error, gpointer user_data);
private: private:
bool tryToOpen();
bool spinUntilTubeEstablished();
bool setTube( const char* pTube ); bool setTube( const char* pTube );
rtl::OString maSessionId; rtl::OString maSessionId;
TeleManager* mpManager; TeleManager* mpManager;
TpAccount* mpAccount; TpAccount* mpAccount;
TpChannel* mpChannel; TpChannel* mpChannel;
gchar* mpAddress;
DBusConnection* mpTube; DBusConnection* mpTube;
TelePacketQueue maPacketQueue; TelePacketQueue maPacketQueue;
TpTubeChannelState meTubeChannelState; TpTubeChannelState meTubeChannelState;
bool mbTubeOfferedHandlerInvoked : 1; bool mbTubeOfferedHandlerInvoked : 1;
bool mbTubeChannelStateChangedHandlerInvoked : 1;
// hide from the public // hide from the public
using boost::enable_shared_from_this<TeleConference>::shared_from_this; using boost::enable_shared_from_this<TeleConference>::shared_from_this;
......
...@@ -131,8 +131,6 @@ public: ...@@ -131,8 +131,6 @@ public:
void disconnect(); void disconnect();
void acceptTube( TpAccount* pAccount, TpChannel* pChannel, const char* pAddress );
/** Send data to all registered conferences. /** Send data to all registered conferences.
@returns to how many conferences the packet was send @returns to how many conferences the packet was send
...@@ -217,6 +215,16 @@ public: ...@@ -217,6 +215,16 @@ public:
/* Callbacks; not for use outside this class. */ /* Callbacks; not for use outside this class. */
static void TransferDone( EmpathyFTHandler *handler, TpFileTransferChannel *, gpointer user_data); 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: private:
void ensureLegacyChannel( TpAccount* pAccount, TpContact* pBuddy ); void ensureLegacyChannel( TpAccount* pAccount, TpContact* pBuddy );
......
...@@ -169,34 +169,48 @@ void TeleConference::TubeOfferedHandler( ...@@ -169,34 +169,48 @@ void TeleConference::TubeOfferedHandler(
if (pChannel != pConference->getChannel()) if (pChannel != pConference->getChannel())
return; 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, TpChannel* pChannel,
guint nState, guint nState,
gpointer pUserData, gpointer pUserData,
GObject* /*weak_object*/ 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); TeleConference* pConference = reinterpret_cast<TeleConference*>(pUserData);
SAL_WARN_IF( !pConference, "tubes", "TeleConference_DBusMessageHandler: no conference"); SAL_WARN_IF( !pConference, "tubes", "TeleConference_DBusMessageHandler: no conference");
if (!pConference) if (!pConference)
return; return;
pConference->setTubeChannelStateChangedHandlerInvoked( true);
SAL_WARN_IF( pChannel != pConference->getChannel(), "tubes", SAL_WARN_IF( pChannel != pConference->getChannel(), "tubes",
"TeleConference_TubeChannelStateChangedHandler: not my channel"); "TeleConference::TubeChannelStateChangedHandler: not my channel");
if (pChannel != pConference->getChannel()) if (pChannel != pConference->getChannel())
return; return;
pConference->setTubeChannelState( static_cast<TpTubeChannelState>(nState)); pConference->setTubeChannelState( static_cast<TpTubeChannelState>(nState));
pConference->tryToOpen();
} }
...@@ -204,18 +218,14 @@ TeleConference::TeleConference( TeleManager* pManager, TpAccount* pAccount, TpCh ...@@ -204,18 +218,14 @@ TeleConference::TeleConference( TeleManager* pManager, TpAccount* pAccount, TpCh
: :
maSessionId( rSessionId ), maSessionId( rSessionId ),
mpManager( pManager), mpManager( pManager),
mpAccount( pAccount), mpAccount( NULL),
mpChannel( pChannel), mpChannel( NULL),
mpAddress( NULL),
mpTube( NULL), mpTube( NULL),
meTubeChannelState( TP_TUBE_CHANNEL_STATE_NOT_OFFERED), meTubeChannelState( TP_TUBE_CHANNEL_STATE_NOT_OFFERED),
mbTubeOfferedHandlerInvoked( false), mbTubeOfferedHandlerInvoked( false)
mbTubeChannelStateChangedHandlerInvoked( false)
{ {
if (mpAccount) setChannel( pAccount, pChannel );
g_object_ref( mpAccount);
if (mpChannel)
g_object_ref( mpChannel);
} }
...@@ -234,30 +244,59 @@ void TeleConference::setChannel( TpAccount *pAccount, TpChannel* pChannel ) ...@@ -234,30 +244,59 @@ void TeleConference::setChannel( TpAccount *pAccount, TpChannel* pChannel )
g_object_unref( mpAccount); g_object_unref( mpAccount);
mpChannel = pChannel; mpChannel = pChannel;
if (mpChannel) if (mpChannel) {
g_object_ref( 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; mpAccount = pAccount;
if (mpAccount) if (mpAccount)
g_object_ref( 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"); bool bOpen = isTubeOpen();
if (!pAddress) SAL_INFO( "tubes", "TeleConference::spinUntilTubeEstablished: tube open: " << bOpen);
return false; return bOpen;
SAL_INFO( "tubes", "TeleConference::acceptTube: address: " << pAddress); }
bool TeleConference::acceptTube()
{
INFO_LOGGER( "TeleConference::acceptTube");
SAL_WARN_IF( !mpChannel, "tubes", "TeleConference::acceptTube: no channel setup"); SAL_WARN_IF( !mpChannel, "tubes", "TeleConference::acceptTube: no channel setup");
SAL_WARN_IF( mpTube, "tubes", "TeleConference::acceptTube: already tubed"); SAL_WARN_IF( mpTube, "tubes", "TeleConference::acceptTube: already tubed");
if (!mpChannel || mpTube) if (!mpChannel || mpTube)
return false; 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() ...@@ -269,8 +308,6 @@ bool TeleConference::offerTube()
if (!mpChannel) if (!mpChannel)
return false; return false;
setTubeOfferedHandlerInvoked( false);
// We must pass a hash table, it could be empty though. // We must pass a hash table, it could be empty though.
/* TODO: anything meaningful to go in here? */ /* TODO: anything meaningful to go in here? */
GHashTable* pParams = tp_asv_new( GHashTable* pParams = tp_asv_new(
...@@ -287,35 +324,8 @@ bool TeleConference::offerTube() ...@@ -287,35 +324,8 @@ bool TeleConference::offerTube()
NULL, // destroy NULL, // destroy
NULL); // weak_object NULL); // weak_object
mpManager->iterateLoop( this, &TeleConference::isTubeOfferedHandlerInvoked);
g_hash_table_unref( pParams); g_hash_table_unref( pParams);
return spinUntilTubeEstablished();
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;
} }
...@@ -379,6 +389,12 @@ void TeleConference::finalize() ...@@ -379,6 +389,12 @@ void TeleConference::finalize()
mpTube = NULL; mpTube = NULL;
} }
if (mpAddress)
{
g_free( mpAddress);
mpAddress = NULL;
}
TeleConferencePtr pThis( shared_from_this()); TeleConferencePtr pThis( shared_from_this());
mpManager->unregisterConference( pThis); mpManager->unregisterConference( pThis);
......
...@@ -92,38 +92,7 @@ public: ...@@ -92,38 +92,7 @@ public:
}; };
static void TeleManager_DBusTubeAcceptHandler( void TeleManager::DBusChannelHandler(
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(
TpSimpleHandler* /*handler*/, TpSimpleHandler* /*handler*/,
TpAccount* pAccount, TpAccount* pAccount,
TpConnection* /*connection*/, TpConnection* /*connection*/,
...@@ -134,10 +103,10 @@ static void TeleManager_DBusChannelHandler( ...@@ -134,10 +103,10 @@ static void TeleManager_DBusChannelHandler(
gpointer pUserData) gpointer pUserData)
{ {
bool aAccepted = false; bool aAccepted = false;
INFO_LOGGER_F( "TeleManager_DBusChannelHandler"); INFO_LOGGER_F( "TeleManager::DBusChannelHandler");
TeleManager* pManager = reinterpret_cast<TeleManager*>(pUserData); 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) if (!pManager)
return; return;
...@@ -147,18 +116,17 @@ static void TeleManager_DBusChannelHandler( ...@@ -147,18 +116,17 @@ static void TeleManager_DBusChannelHandler(
if (!pChannel) if (!pChannel)
continue; continue;
SAL_INFO( "tubes", "TeleManager_DBusChannelHandler: incoming dbus channel: " SAL_INFO( "tubes", "TeleManager::DBusChannelHandler: incoming dbus channel: "
<< tp_channel_get_identifier( pChannel)); << tp_channel_get_identifier( pChannel));
if (tp_channel_get_channel_type_id( pChannel) == TP_IFACE_QUARK_CHANNEL_TYPE_DBUS_TUBE) if (tp_channel_get_channel_type_id( pChannel) == TP_IFACE_QUARK_CHANNEL_TYPE_DBUS_TUBE)
{ {
SAL_INFO( "tubes", "accepting"); SAL_INFO( "tubes", "accepting");
aAccepted = true; aAccepted = true;
g_object_ref( pAccount);
tp_cli_channel_type_dbus_tube_call_accept( pChannel, -1, TeleConferencePtr pConference( new TeleConference( pManager, pAccount, pChannel, ""));
TP_SOCKET_ACCESS_CONTROL_CREDENTIALS, pManager->maConferences.push_back( pConference);
TeleManager_DBusTubeAcceptHandler, pUserData, NULL, pConference->acceptTube();
G_OBJECT (pAccount));
} }
else else
{ {
...@@ -456,7 +424,7 @@ bool TeleManager::connect() ...@@ -456,7 +424,7 @@ bool TeleManager::connect()
FALSE, // requests FALSE, // requests
getFullClientName().getStr(), // name getFullClientName().getStr(), // name
FALSE, // uniquify FALSE, // uniquify
TeleManager_DBusChannelHandler, // callback &TeleManager::DBusChannelHandler, // callback
this, // user_data this, // user_data
NULL // destroy NULL // destroy
); );
...@@ -847,22 +815,6 @@ void TeleManager::disconnect() ...@@ -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) void TeleManager::setAccountManagerReady( bool bPrepared)
{ {
pImpl->meAccountManagerStatus = (bPrepared ? AMS_PREPARED : AMS_UNPREPARABLE); pImpl->meAccountManagerStatus = (bPrepared ? AMS_PREPARED : AMS_UNPREPARABLE);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment