summaryrefslogtreecommitdiff
path: root/tubes/source/manager.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'tubes/source/manager.cxx')
-rw-r--r--tubes/source/manager.cxx905
1 files changed, 0 insertions, 905 deletions
diff --git a/tubes/source/manager.cxx b/tubes/source/manager.cxx
deleted file mode 100644
index 08dacfb3ed58..000000000000
--- a/tubes/source/manager.cxx
+++ /dev/null
@@ -1,905 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- */
-
-#include <tubes/collaboration.hxx>
-#include <tubes/manager.hxx>
-
-#include <conference.hxx>
-#include <constants.h>
-#include <file-transfer-helper.h>
-
-#include <com/sun/star/uno/Sequence.hxx>
-#include <com/sun/star/frame/Desktop.hpp>
-#include <com/sun/star/frame/XComponentLoader.hpp>
-#include <com/sun/star/lang/XMultiServiceFactory.hpp>
-#include <com/sun/star/beans/PropertyValue.hpp>
-#include <com/sun/star/util/XCloseable.hpp>
-#include <comphelper/processfactory.hxx>
-#include <osl/mutex.hxx>
-#include <rtl/strbuf.hxx>
-#include <rtl/uuid.h>
-#include <vcl/svapp.hxx>
-
-#include <telepathy-glib/telepathy-glib.h>
-#include <stdio.h>
-#include <map>
-#include <set>
-
-#if defined SAL_LOG_INFO
-namespace
-{
-struct InfoLogger
-{
- const void* mpThat;
- const char* mpMethod;
- explicit InfoLogger( const void* pThat, const char* pMethod )
- :
- mpThat( pThat),
- mpMethod( pMethod)
- {
- SAL_INFO( "tubes.method", mpThat << " entering " << mpMethod);
- }
- ~InfoLogger()
- {
- SAL_INFO( "tubes.method", mpThat << " leaving " << mpMethod);
- }
-};
-}
-#define INFO_LOGGER_F(s) InfoLogger aLogger(nullptr,(s))
-#else
-#define INFO_LOGGER_F(s)
-#endif // SAL_LOG_INFO
-
-using namespace osl;
-
-/** Refcounted singleton implementation class. */
-class TeleManagerImpl
-{
-public:
- TpSimpleClientFactory* mpFactory;
- TpBaseClient* mpClient;
- TpBaseClient* mpFileTransferClient;
- TpAccountManager* mpAccountManager;
- static bool mbAccountManagerReady;
- static bool mbAccountManagerReadyHandlerInvoked;
- static bool mbChannelReadyHandlerInvoked;
- OString msCurrentUUID;
- OString msNameSuffix;
- typedef std::map< OString, TeleConference* > MapStringConference;
- MapStringConference maAcceptedConferences;
- typedef std::set< TeleConference* > DemoConferences;
- DemoConferences maDemoConferences;
- typedef std::set< Collaboration* > Collaborations;
- Collaborations maCollaborations;
- typedef std::set< TpContact* > RegisteredContacts;
- RegisteredContacts maRegisteredContacts;
-
- TeleManagerImpl();
- ~TeleManagerImpl();
- static void AccountManagerReadyHandler( GObject* pSourceObject, GAsyncResult* pResult, gpointer pUserData );
- static void ChannelReadyHandler( GObject* pSourceObject, GAsyncResult* pResult, gpointer pUserData );
-};
-
-TeleManagerImpl* TeleManager::pImpl = new TeleManagerImpl();
-bool TeleManagerImpl::mbAccountManagerReady;
-bool TeleManagerImpl::mbAccountManagerReadyHandlerInvoked;
-bool TeleManagerImpl::mbChannelReadyHandlerInvoked;
-
-static void TeleManager_DBusChannelHandler(
- TpSimpleHandler* /*handler*/,
- TpAccount* pAccount,
- TpConnection* /*connection*/,
- GList* pChannels,
- GList* /*requests_satisfied*/,
- gint64 /*user_action_time*/,
- TpHandleChannelsContext* pContext,
- gpointer /*pUserData*/ )
-{
- bool aAccepted = false;
- INFO_LOGGER_F( "TeleManager_DBusChannelHandler");
-
- for (GList* p = pChannels; p; p = p->next)
- {
- TpChannel* pChannel = TP_CHANNEL(p->data);
- if (!pChannel)
- continue;
-
- SAL_INFO( "tubes", "TeleManager_DBusChannelHandler: incoming dbus channel: "
- << tp_channel_get_identifier( pChannel));
-
- if (TP_IS_DBUS_TUBE_CHANNEL( pChannel))
- {
- SAL_INFO( "tubes", "accepting");
- aAccepted = true;
-
- TeleConference* pConference = new TeleConference( pAccount, TP_DBUS_TUBE_CHANNEL( pChannel ) );
- pConference->acceptTube();
- TeleManager::addConference( pConference );
- }
- else
- {
- SAL_INFO( "tubes", "ignored");
- }
- }
-
- if (aAccepted)
- tp_handle_channels_context_accept( pContext);
- else
- {
- SAL_WNODEPRECATED_DECLARATIONS_PUSH
- // 'tp_errors_quark' [expanded from macro 'TP_ERRORS'] is deprecated
- GError *pError = g_error_new_literal( TP_ERRORS, TP_ERROR_CONFUSED,
- "None of these channels were LibreOffice D-Bus tubes; "
- "why did the Channel Dispatcher give them to us?");
- SAL_WNODEPRECATED_DECLARATIONS_PUSH
- tp_handle_channels_context_fail( pContext, pError);
- g_clear_error (&pError);
- }
-}
-
-
-void TeleManager::addConference( TeleConference* pConference )
-{
- MutexGuard aGuard( GetMutex());
-
- SAL_WARN_IF( pConference->getUuid().isEmpty(), "tubes",
- "Adding conference with empty UUID should not happen!" );
- pImpl->maAcceptedConferences[ pConference->getUuid() ] = pConference;
-}
-
-TeleConference* TeleManager::getConference()
-{
- MutexGuard aGuard( GetMutex());
-
- TeleManagerImpl::MapStringConference::const_iterator it =
- pImpl->maAcceptedConferences.find( pImpl->msCurrentUUID );
- TeleConference* pConference = nullptr;
- if (it != pImpl->maAcceptedConferences.end())
- pConference = it->second;
- SAL_WARN_IF( !pConference, "tubes", "TeleManager::getConference: "
- << pImpl->msCurrentUUID.getStr() << " not found!" );
- (pImpl->msCurrentUUID).clear();
- return pConference;
-}
-
-void TeleManager::registerCollaboration( Collaboration* pCollaboration )
-{
- MutexGuard aGuard( GetMutex());
-
- pImpl->maCollaborations.insert( pCollaboration );
-}
-
-void TeleManager::unregisterCollaboration( Collaboration* pCollaboration )
-{
- MutexGuard aGuard( GetMutex());
-
- pImpl->maCollaborations.erase( pCollaboration );
-}
-
-bool TeleManager::existsCollaboration( Collaboration* pCollaboration )
-{
- MutexGuard aGuard( GetMutex());
-
- return pImpl->maCollaborations.find( pCollaboration ) != pImpl->maCollaborations.end();
-}
-
-void TeleManager::displayAllContacts()
-{
- MutexGuard aGuard( GetMutex());
-
- for (TeleManagerImpl::Collaborations::iterator it = pImpl->maCollaborations.begin();
- it != pImpl->maCollaborations.end(); ++it)
- (*it)->DisplayContacts();
-}
-
-void TeleManager::registerDemoConference( TeleConference* pConference )
-{
- MutexGuard aGuard( GetMutex());
-
- pImpl->maDemoConferences.insert( pConference );
-}
-
-void TeleManager::unregisterDemoConference( TeleConference* pConference )
-{
- MutexGuard aGuard( GetMutex());
-
- pImpl->maDemoConferences.erase( pConference );
-}
-
-void TeleManager::broadcastPacket( const OString& rPacket )
-{
- MutexGuard aGuard( GetMutex());
-
- INFO_LOGGER_F( "TeleManager::broadcastPacket" );
- for (TeleManagerImpl::DemoConferences::iterator it = pImpl->maDemoConferences.begin();
- it != pImpl->maDemoConferences.end(); ++it)
- if ((*it)->getCollaboration())
- (*it)->getCollaboration()->PacketReceived( rPacket );
-}
-
-bool TeleManager::hasWaitingConference()
-{
- MutexGuard aGuard( GetMutex());
-
- return !pImpl->msCurrentUUID.isEmpty();
-}
-
-void TeleManager::setCurrentUuid( const OString& rUuid )
-{
- MutexGuard aGuard( GetMutex());
-
- pImpl->msCurrentUUID = rUuid;
-}
-
-void TeleManager_fileReceived( const OUString& rStr, const OString& rUuid )
-{
- SAL_INFO( "tubes", "TeleManager_fileReceived: incoming file: " << rStr );
-
- OString sUuid( rUuid );
- if (sUuid == "demo")
- {
- sUuid = TeleManager::createUuid();
- TeleConference* pConference = new TeleConference( nullptr, nullptr, sUuid );
- TeleManager::addConference( pConference );
- TeleManager::registerDemoConference( pConference );
- }
- TeleManager::setCurrentUuid( sUuid );
-
- try
- {
- css::uno::Reference < css::frame::XDesktop2 > xLoader = css::frame::Desktop::create(
- ::comphelper::getProcessComponentContext() );
- css::uno::Sequence < css::beans::PropertyValue > args(0);
- css::uno::Reference < css::util::XCloseable > xDoc(
- xLoader->loadComponentFromURL( rStr, "_blank", 0, args ),
- css::uno::UNO_QUERY_THROW );
- }
- catch ( const css::uno::Exception& e )
- {
- // Expected to happen for unit test
- SAL_WARN( "tubes", "TeleManager_fileReceived: exception when loading: " << e.Message );
- }
-}
-
-static void TeleManager_TransferDone( EmpathyFTHandler *handler, TpFileTransferChannel *, gpointer )
-{
- SAL_INFO( "tubes", "TeleManager_TransferDone: hooray!");
- GFile *gfile = empathy_ft_handler_get_gfile( handler);
- char *uri = g_file_get_uri( gfile);
- OUString aUri( OUString::createFromAscii( uri ) );
- g_free( uri);
-
- TeleManager_fileReceived( aUri, empathy_ft_handler_get_description( handler ) );
-
- g_object_unref( handler);
-}
-
-static void TeleManager_TransferError( EmpathyFTHandler *handler, const GError *error, void*)
-{
- SAL_INFO( "tubes", "TeleManager_TransferError: " << error->message);
-
- g_object_unref( handler);
-}
-
-static void lcl_IncomingHandlerReady (
- EmpathyFTHandler* pHandler,
- GError* pError,
- void* /*pUserData*/ )
-{
- if (pError)
- {
- SAL_INFO ("tubes", "failed to prepare incoming transfer: " << pError->message);
- g_object_unref( pHandler);
- return;
- }
-
- /* The filename suggested by the sender, which in our case is the last bit
- * of whatever URI got passed to ::sendFile()
- */
- const char* pFileName = empathy_ft_handler_get_filename( pHandler);
- char* pLocalUri = g_strdup_printf( "file:///tmp/LibreOffice-collab-%s", pFileName);
- GFile *pDestination = g_file_new_for_uri( pLocalUri);
- g_free( pLocalUri);
-
- empathy_ft_handler_incoming_set_destination( pHandler, pDestination);
- g_object_unref( pDestination);
-
- g_signal_connect( pHandler, "transfer-done", G_CALLBACK (TeleManager_TransferDone), nullptr);
- g_signal_connect( pHandler, "transfer-error", G_CALLBACK (TeleManager_TransferError), nullptr);
- SAL_INFO ("tubes", "lcl_IncomingHandlerReady: starting file transfer..");
- empathy_ft_handler_start_transfer( pHandler);
-}
-
-static void TeleManager_FileTransferHandler(
- TpSimpleHandler* /*handler*/,
- TpAccount* /*Account*/,
- TpConnection* /*connection*/,
- GList* pChannels,
- GList* /*requests_satisfied*/,
- gint64 /*user_action_time*/,
- TpHandleChannelsContext* pContext,
- gpointer /*pUserData*/ )
-{
- bool aAccepted = false;
- INFO_LOGGER_F( "TeleManager_FileTransferHandler");
-
- for (GList* p = pChannels; p; p = p->next)
- {
- TpChannel* pChannel = TP_CHANNEL(p->data);
-
- SAL_INFO( "tubes", "TeleManager_FileTransferHandler: incoming dbus channel: "
- << tp_channel_get_identifier( pChannel));
-
- if (TP_IS_FILE_TRANSFER_CHANNEL( pChannel))
- {
- SAL_INFO( "tubes", "accepting file transfer");
- empathy_ft_handler_new_incoming( TP_FILE_TRANSFER_CHANNEL( pChannel),
- lcl_IncomingHandlerReady, nullptr);
- aAccepted = true;
- }
- else
- {
- SAL_INFO( "tubes", "ignored");
- }
- }
-
- if (aAccepted)
- tp_handle_channels_context_accept( pContext);
- else
- {
- SAL_WNODEPRECATED_DECLARATIONS_PUSH
- // 'tp_errors_quark' [expanded from macro 'TP_ERRORS'] is deprecated
- GError *pError = g_error_new_literal( TP_ERRORS, TP_ERROR_CONFUSED,
- "None of these channels were file transfers; "
- "why did the Channel Dispatcher give them to us?");
- SAL_WNODEPRECATED_DECLARATIONS_POP
- tp_handle_channels_context_fail( pContext, pError);
- g_clear_error (&pError);
- }
-}
-
-
-void TeleManagerImpl::ChannelReadyHandler(
- GObject* pSourceObject,
- GAsyncResult* pResult,
- gpointer pUserData
- )
-{
- INFO_LOGGER_F( "TeleManagerImpl::ChannelReadyHandler");
-
- TeleConference* pConference = static_cast<TeleConference*>(pUserData);
- SAL_WARN_IF( !pConference, "tubes", "TeleManagerImpl::ChannelReadyHandler: no conference");
- if (!pConference)
- return;
-
- mbChannelReadyHandlerInvoked = true;
-
- TpAccountChannelRequest* pChannelRequest = TP_ACCOUNT_CHANNEL_REQUEST( pSourceObject);
- GError* pError = nullptr;
- TpChannel * pChannel = tp_account_channel_request_create_and_handle_channel_finish(
- pChannelRequest, pResult, nullptr, &pError);
- if (!pChannel)
- {
- // "account isn't Enabled" means just that..
- /* FIXME: detect and handle, domain=132, code=3 */
- SAL_WARN( "tubes", "TeleManagerImpl::ChannelReadyHandler: no channel: " << pError->message);
- g_error_free( pError);
- return;
- }
- pConference->setChannel( tp_account_channel_request_get_account( pChannelRequest),
- TP_DBUS_TUBE_CHANNEL (pChannel));
- pConference->offerTube();
-}
-
-void TeleManagerImpl::AccountManagerReadyHandler(
- GObject* pSourceObject,
- GAsyncResult* pResult,
- gpointer /*pUserData*/
- )
-{
- INFO_LOGGER_F( "TeleManagerImpl::AccountManagerReadyHandler");
-
- GError* pError = nullptr;
- gboolean bPrepared = tp_proxy_prepare_finish( pSourceObject, pResult, &pError);
- SAL_WARN_IF( !bPrepared, "tubes", "TeleManagerImpl::AccountManagerReadyHandler: not prepared");
- if (!bPrepared || pError)
- {
- SAL_WARN_IF( pError, "tubes", "TeleManagerImpl::AccountManagerReadyHandler: error: " << pError->message);
- g_error_free( pError);
- }
-
- mbAccountManagerReady = bPrepared;
- mbAccountManagerReadyHandlerInvoked = true;
-}
-
-
-bool TeleManager::init( bool bListen )
-{
- if (createAccountManager())
- {
- if (bListen && !registerClients())
- SAL_WARN( "tubes", "TeleManager::init: Could not register client handlers." );
-
- return true;
- }
- else
- SAL_WARN( "tubes", "TeleManager::init: Could not create AccountManager." );
-
- return false;
-}
-
-void TeleManager::finalize()
-{
- pImpl.reset();
-}
-
-bool TeleManager::createAccountManager()
-{
- INFO_LOGGER_F( "TeleManager::createAccountManager");
-
- MutexGuard aGuard( GetMutex());
-
- SAL_INFO_IF( pImpl->mpAccountManager, "tubes", "TeleManager::createAccountManager: already connected");
- if (pImpl->mpAccountManager)
- return true;
-
- GError* pError = nullptr;
- TpDBusDaemon *pDBus = tp_dbus_daemon_dup( &pError);
- SAL_WARN_IF( !pDBus, "tubes", "TeleManager::createAccountManager: no dbus daemon");
- if (!pDBus || pError)
- {
- SAL_WARN_IF( pError, "tubes", "TeleManager::createAccountManager: dbus daemon error: " << pError->message);
- g_error_free( pError);
- return false;
- }
-
- pImpl->mpFactory = TP_SIMPLE_CLIENT_FACTORY( tp_automatic_client_factory_new( pDBus));
- g_object_unref( pDBus);
- SAL_WARN_IF( !pImpl->mpFactory, "tubes", "TeleManager::createAccountManager: no client factory");
- if (!pImpl->mpFactory)
- return false;
-
- /* Tell the client factory (which creates and prepares proxy objects) to
- * get the features we need ready before giving us any objects.
- */
- /* We need every online account's connection object to be available... */
- tp_simple_client_factory_add_account_features_varargs (pImpl->mpFactory,
- TP_ACCOUNT_FEATURE_CONNECTION,
- 0);
- /* ...and we want those connection objects to have the contact list
- * available... */
- tp_simple_client_factory_add_connection_features_varargs (pImpl->mpFactory,
- TP_CONNECTION_FEATURE_CONTACT_LIST,
- 0);
- /* ...and those contacts should have their alias and their capabilities
- * available.
- */
- tp_simple_client_factory_add_contact_features_varargs (pImpl->mpFactory,
- TP_CONTACT_FEATURE_ALIAS,
- TP_CONTACT_FEATURE_AVATAR_DATA,
- TP_CONTACT_FEATURE_CAPABILITIES,
- TP_CONTACT_FEATURE_PRESENCE,
- TP_CONTACT_FEATURE_INVALID);
-
- pImpl->mpAccountManager = tp_account_manager_new_with_factory (pImpl->mpFactory);
- tp_account_manager_set_default (pImpl->mpAccountManager);
-
- TeleManagerImpl::mbAccountManagerReadyHandlerInvoked = false;
- tp_proxy_prepare_async( pImpl->mpAccountManager, nullptr, TeleManagerImpl::AccountManagerReadyHandler, nullptr);
- while (!TeleManagerImpl::mbAccountManagerReadyHandlerInvoked)
- {
- SolarMutexReleaser rel;
- g_main_context_iteration( nullptr, TRUE);
- }
-
- return TeleManagerImpl::mbAccountManagerReady;
-}
-
-bool TeleManager::registerClients()
-{
- INFO_LOGGER_F( "TeleManager::registerClients");
-
- MutexGuard aGuard( GetMutex());
-
- /* TODO: also check whether client could be registered and retry if not? */
- SAL_INFO_IF( pImpl->mpClient && pImpl->mpFileTransferClient, "tubes", "TeleManager::registerClients: already registered");
- if (pImpl->mpClient && pImpl->mpFileTransferClient)
- return true;
-
- pImpl->mpClient = tp_simple_handler_new_with_factory(
- pImpl->mpFactory, // factory
- FALSE, // bypass_approval
- FALSE, // requests
- getFullClientName().getStr(), // name
- FALSE, // uniquify
- TeleManager_DBusChannelHandler, // callback
- nullptr, // user_data
- nullptr // destroy
- );
- SAL_WARN_IF( !pImpl->mpClient, "tubes", "TeleManager::registerClients: no client");
- if (!pImpl->mpClient)
- return false;
-
- // Setup client handler for buddy channels with our service.
- tp_base_client_take_handler_filter( pImpl->mpClient,
- tp_asv_new(
- TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING, TP_IFACE_CHANNEL_TYPE_DBUS_TUBE,
- TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, G_TYPE_UINT, TP_HANDLE_TYPE_CONTACT,
- TP_PROP_CHANNEL_TYPE_DBUS_TUBE_SERVICE_NAME, G_TYPE_STRING, getFullServiceName().getStr(),
- nullptr));
-
- /* TODO: setup filters for LibreOfficeCalc, LibreOfficeWriter, ... */
-
- // Setup client handler for MUC channels with our service.
- tp_base_client_take_handler_filter( pImpl->mpClient,
- tp_asv_new(
- TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING, TP_IFACE_CHANNEL_TYPE_DBUS_TUBE,
- TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, G_TYPE_UINT, TP_HANDLE_TYPE_ROOM,
- TP_PROP_CHANNEL_TYPE_DBUS_TUBE_SERVICE_NAME, G_TYPE_STRING, getFullServiceName().getStr(),
- nullptr));
-
- GError* pError = nullptr;
- if (!tp_base_client_register( pImpl->mpClient, &pError))
- {
- SAL_WARN( "tubes", "TeleManager::registerClients: error registering client handler: " << pError->message);
- g_error_free( pError);
- return false;
- }
-
- SAL_INFO( "tubes", "TeleManager::registerClients: bus name: " << tp_base_client_get_bus_name( pImpl->mpClient));
- SAL_INFO( "tubes", "TeleManager::registerClients: object path: " << tp_base_client_get_object_path( pImpl->mpClient));
-
- /* Register a second "head" for incoming file transfers. This uses a more
- * specific filter than Empathy's handler by matching on the file
- * transfer's ServiceName property, and uses bypass_approval to ensure the
- * user isn't prompted before the channel gets passed to us.
- */
- pImpl->mpFileTransferClient = tp_simple_handler_new_with_factory (
- pImpl->mpFactory, // factory
- TRUE, // bypass_approval
- FALSE, // requests
- getFullClientName().getStr(), // name
- TRUE, // uniquify to get a different bus name to the main client, above
- TeleManager_FileTransferHandler, // callback
- nullptr, // user_data
- nullptr // destroy
- );
- tp_base_client_take_handler_filter( pImpl->mpFileTransferClient,
- tp_asv_new(
- TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING, TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER,
- TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, G_TYPE_UINT, TP_HANDLE_TYPE_CONTACT,
- TP_PROP_CHANNEL_INTERFACE_FILE_TRANSFER_METADATA_SERVICE_NAME, G_TYPE_STRING, getFullServiceName().getStr(),
- nullptr));
-
- if (!tp_base_client_register( pImpl->mpFileTransferClient, &pError))
- {
- /* This shouldn't fail if registering the main handler succeeded */
- SAL_WARN( "tubes", "TeleManager::registerClients: error registering file transfer handler: " << pError->message);
- g_error_free( pError);
- return false;
- }
-
- return true;
-}
-
-TeleConference* TeleManager::startDemoSession()
-{
- INFO_LOGGER_F( "TeleManager::startDemoSession");
-
- TeleConference* pConference = new TeleConference( nullptr, nullptr, "demo" );
- registerDemoConference( pConference );
-
- return pConference;
-}
-
-/* TODO: factor out common code with startBuddySession() */
-TeleConference* TeleManager::startGroupSession( TpAccount *pAccount,
- const OUString& rUConferenceRoom,
- const OUString& rUConferenceServer )
-{
- INFO_LOGGER_F( "TeleManager::startGroupSession");
-
- OString aSessionId( TeleManager::createUuid());
-
- /* FIXME: does this work at all _creating_ a MUC? */
- // Use conference and server if given, else create conference.
- OString aConferenceRoom( OUStringToOString( rUConferenceRoom, RTL_TEXTENCODING_UTF8));
- OString aConferenceServer( OUStringToOString( rUConferenceServer, RTL_TEXTENCODING_UTF8));
- OStringBuffer aBuf(64);
- if (!aConferenceRoom.isEmpty() && !aConferenceServer.isEmpty())
- aBuf.append( aConferenceRoom).append( '@').append( aConferenceServer);
- else
- {
- aBuf.append( aSessionId);
- if (!aConferenceServer.isEmpty())
- aBuf.append( '@').append( aConferenceServer);
- /* FIXME: else? bail out? we have only a session ID without server then */
- }
- OString aTarget( aBuf.makeStringAndClear());
-
- SAL_INFO( "tubes", "TeleManager::startGroupSession: creating channel request from "
- << tp_account_get_path_suffix( pAccount ) << " to " << aTarget.getStr() );
-
- // MUC request
- GHashTable* pRequest = tp_asv_new(
- TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING, TP_IFACE_CHANNEL_TYPE_DBUS_TUBE,
- TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, TP_TYPE_HANDLE, TP_HANDLE_TYPE_ROOM,
- TP_PROP_CHANNEL_TARGET_ID, G_TYPE_STRING, aTarget.getStr(),
- TP_PROP_CHANNEL_TYPE_DBUS_TUBE_SERVICE_NAME, G_TYPE_STRING, getFullServiceName().getStr(),
- nullptr);
-
- TpAccountChannelRequest * pChannelRequest = tp_account_channel_request_new(
- pAccount, pRequest, TP_USER_ACTION_TIME_NOT_USER_ACTION);
- SAL_WARN_IF( !pChannelRequest, "tubes", "TeleManager::startGroupSession: no channel");
- if (!pChannelRequest)
- {
- g_hash_table_unref( pRequest);
- return nullptr;
- }
-
- TeleManagerImpl::mbChannelReadyHandlerInvoked = false;
-
- TeleConference* pConference = new TeleConference( nullptr, nullptr, aSessionId );
-
- tp_account_channel_request_create_and_handle_channel_async(
- pChannelRequest, nullptr, TeleManagerImpl::ChannelReadyHandler, pConference);
-
- while (!TeleManagerImpl::mbChannelReadyHandlerInvoked)
- g_main_context_iteration( nullptr, TRUE );
-
- g_object_unref( pChannelRequest);
- g_hash_table_unref( pRequest);
-
- if (!pConference->isReady())
- return nullptr;
-
- return pConference;
-}
-
-static void lcl_ensureLegacyChannel( TpAccount* pAccount, TpContact* pBuddy )
-{
- /* This is a workaround for a Telepathy bug.
- * <https://bugs.libreoffice.org/show_bug.cgi?id=47760>. The first time you
- * request a tube to a contact on an account, you actually get two channels
- * back: the tube you asked for, along with a legacy Channel.Type.Tubes
- * object. This breaks create_and_handle_channel_async(), which expects to
- * only get one channel back.
- *
- * To work around this, we make sure the legacy Tubes channel already
- * exists before we request the channel we actually want. We don't actually
- * have to wait for this request to succeed - we fire it off and forget
- * about it.
- */
- GHashTable* pRequest = tp_asv_new(
- TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING, TP_IFACE_CHANNEL_TYPE_TUBES,
- TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, TP_TYPE_HANDLE, TP_HANDLE_TYPE_CONTACT,
- TP_PROP_CHANNEL_TARGET_ID, G_TYPE_STRING, tp_contact_get_identifier (pBuddy),
- nullptr);
- TpAccountChannelRequest* pChannelRequest = tp_account_channel_request_new(
- pAccount, pRequest, TP_USER_ACTION_TIME_NOT_USER_ACTION);
- tp_account_channel_request_ensure_channel_async( pChannelRequest, nullptr,
- nullptr, nullptr, nullptr );
- g_object_unref( pChannelRequest );
- g_hash_table_unref( pRequest );
-}
-
-/* TODO: factor out common code with startGroupSession() */
-TeleConference* TeleManager::startBuddySession( TpAccount *pAccount, TpContact *pBuddy )
-{
- INFO_LOGGER_F( "TeleManager::startBuddySession");
-
- lcl_ensureLegacyChannel( pAccount, pBuddy );
-
- const char *pIdentifier = tp_contact_get_identifier( pBuddy);
- SAL_INFO( "tubes", "TeleManager::startBuddySession: creating channel request from "
- << tp_account_get_path_suffix( pAccount)
- << " to " << pIdentifier);
-
- GHashTable* pRequest = tp_asv_new(
- TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING, TP_IFACE_CHANNEL_TYPE_DBUS_TUBE,
- TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, TP_TYPE_HANDLE, TP_HANDLE_TYPE_CONTACT,
- TP_PROP_CHANNEL_TARGET_ID, G_TYPE_STRING, pIdentifier,
- TP_PROP_CHANNEL_TYPE_DBUS_TUBE_SERVICE_NAME, G_TYPE_STRING, getFullServiceName().getStr(),
- nullptr);
-
- TpAccountChannelRequest * pChannelRequest = tp_account_channel_request_new(
- pAccount, pRequest, TP_USER_ACTION_TIME_NOT_USER_ACTION);
- SAL_WARN_IF( !pChannelRequest, "tubes", "TeleManager::startBuddySession: no channel");
- if (!pChannelRequest)
- {
- g_hash_table_unref( pRequest);
- return nullptr;
- }
-
- TeleManagerImpl::mbChannelReadyHandlerInvoked = false;
-
- TeleConference* pConference = new TeleConference( nullptr, nullptr, createUuid(), true );
-
- tp_account_channel_request_create_and_handle_channel_async(
- pChannelRequest, nullptr, TeleManagerImpl::ChannelReadyHandler, pConference );
-
- while (!TeleManagerImpl::mbChannelReadyHandlerInvoked)
- g_main_context_iteration( nullptr, TRUE );
-
- g_object_unref( pChannelRequest);
- g_hash_table_unref( pRequest);
-
- if (!pConference->isReady())
- return nullptr;
-
- return pConference;
-}
-
-static bool tb_presence_is_online( const TpConnectionPresenceType& presence )
-{
- switch (presence)
- {
- case TP_CONNECTION_PRESENCE_TYPE_UNSET:
- case TP_CONNECTION_PRESENCE_TYPE_OFFLINE:
- return false;
- case TP_CONNECTION_PRESENCE_TYPE_AVAILABLE:
- case TP_CONNECTION_PRESENCE_TYPE_AWAY:
- case TP_CONNECTION_PRESENCE_TYPE_EXTENDED_AWAY:
- case TP_CONNECTION_PRESENCE_TYPE_HIDDEN:
- case TP_CONNECTION_PRESENCE_TYPE_BUSY:
- return true;
- case TP_CONNECTION_PRESENCE_TYPE_UNKNOWN:
- case TP_CONNECTION_PRESENCE_TYPE_ERROR:
- default:
- return false;
- }
-}
-
-static bool tb_contact_is_online( TpContact *contact )
-{
- return tb_presence_is_online (tp_contact_get_presence_type (contact));
-}
-
-static void presence_changed_cb( TpContact* /* contact */,
- guint /* type */,
- gchar* /* status */,
- gchar* /* message */,
- gpointer /* pContactList*/ )
-{
- TeleManager::displayAllContacts();
-}
-
-AccountContactPairV TeleManager::getContacts()
-{
- AccountContactPairV pairs;
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
- for (GList *accounts = tp_account_manager_get_valid_accounts (pImpl->mpAccountManager);
- accounts != nullptr; accounts = g_list_delete_link (accounts, accounts))
- {
- TpAccount *account = static_cast<TpAccount *>(accounts->data);
- TpConnection *connection = tp_account_get_connection (account);
-
- /* Verify account is online and received its contact list. If state is not
- * SUCCESS this means we didn't received the roster from server yet and
- * we would have to wait for the "notify:contact-list-state" signal. */
- if (connection == nullptr || tp_connection_get_contact_list_state (connection) !=
- TP_CONTACT_LIST_STATE_SUCCESS)
- continue;
-
- TpContact *self = tp_connection_get_self_contact (connection);
- GPtrArray *contacts = tp_connection_dup_contact_list (connection);
- for (guint i = 0; i < contacts->len; i++)
- {
- TpContact *contact = static_cast<TpContact *>(g_ptr_array_index (contacts, i));
- if (pImpl->maRegisteredContacts.find (contact) == pImpl->maRegisteredContacts.end())
- {
- pImpl->maRegisteredContacts.insert (contact);
- g_signal_connect (contact, "presence-changed",
- G_CALLBACK (presence_changed_cb), nullptr );
- }
- if (contact != self && tb_contact_is_online (contact))
- {
- g_object_ref (account);
- g_object_ref (contact);
-
- AccountContactPair pair(account, contact);
- pairs.push_back(pair);
- }
- }
- g_ptr_array_unref (contacts);
- }
- #pragma GCC diagnostic pop
- return pairs;
-}
-
-OString TeleManager::getFullClientName()
-{
- OStringBuffer aBuf(64);
- aBuf.append( LIBO_CLIENT_SUFFIX ).append( pImpl->msNameSuffix);
- return aBuf.makeStringAndClear();
-}
-
-OString TeleManager::getFullServiceName()
-{
- OStringBuffer aBuf(64);
- aBuf.append( LIBO_DTUBE_SERVICE ).append( pImpl->msNameSuffix);
- return aBuf.makeStringAndClear();
-}
-
-OString TeleManager::getFullObjectPath()
-{
- OStringBuffer aBuf(64);
- aBuf.append( '/').append( LIBO_DTUBE_SERVICE ).append( pImpl->msNameSuffix);
- OString aStr( aBuf.makeStringAndClear().replace( '.', '/'));
- return aStr;
-}
-
-OString TeleManager::createUuid()
-{
- sal_uInt8 nId[16];
- rtl_createUuid( nId, nullptr, true);
- char aBuf[33];
- for (size_t i=0; i<16; ++i)
- {
- snprintf( aBuf+2*i, 3, "%02x", (unsigned char)nId[i]);
- }
- aBuf[32] = 0;
- return OString( aBuf);
-}
-
-Mutex& TeleManager::GetMutex()
-{
- static Mutex* pMutex = nullptr;
- if (!pMutex)
- {
- MutexGuard aGuard( Mutex::getGlobalMutex());
- if (!pMutex)
- pMutex = new Mutex;
- }
- return *pMutex;
-}
-
-void TeleManager::addSuffixToNames( const char* pName )
-{
- pImpl->msNameSuffix = pName;
-}
-
-
-TeleManagerImpl::TeleManagerImpl()
- :
- mpFactory( nullptr),
- mpClient( nullptr),
- mpFileTransferClient( nullptr),
- mpAccountManager( nullptr)
-{
-#if !GLIB_CHECK_VERSION(2,36,0)
- g_type_init();
-#endif
-}
-
-TeleManagerImpl::~TeleManagerImpl()
-{
- // There may be unused conferences left opened, so close them.
- // It should not make a problem to close already closed conference.
- for (MapStringConference::iterator it = maAcceptedConferences.begin();
- it != maAcceptedConferences.end(); ++it)
- it->second->close();
- if (mpClient)
- {
- tp_base_client_unregister( mpClient);
- g_object_unref( mpClient);
- }
- if (mpFileTransferClient)
- {
- tp_base_client_unregister( mpFileTransferClient);
- g_object_unref( mpFileTransferClient);
- }
- if (mpFactory)
- g_object_unref( mpFactory);
- if (mpAccountManager)
- g_object_unref( mpAccountManager);
-}
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */