summaryrefslogtreecommitdiff
path: root/tubes
diff options
context:
space:
mode:
authorMarkus Mohrhard <markus.mohrhard@googlemail.com>2017-04-14 02:44:20 +0200
committerMarkus Mohrhard <markus.mohrhard@googlemail.com>2017-04-14 03:32:37 +0200
commitb7b159d79c2b4ec53915e0b9c3e28912c289a5ba (patch)
tree2510d25832202cfbc79378473b497540dd5a5500 /tubes
parent6f12914ddfb4d69c0267b206be654c875da17426 (diff)
remove the old collaboration feature based on telepathy
Change-Id: I1f08d6ef43b76e7bae41ac33bb954f506ae7c485 Reviewed-on: https://gerrit.libreoffice.org/36542 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Markus Mohrhard <markus.mohrhard@googlemail.com>
Diffstat (limited to 'tubes')
-rw-r--r--tubes/CppunitTest_tubes_test.mk29
-rw-r--r--tubes/Executable_liboapprover.mk21
-rw-r--r--tubes/Library_tubes.mk47
-rw-r--r--tubes/LibreOffice.client11
-rw-r--r--tubes/LibreOfficeApprover.client8
-rw-r--r--tubes/Makefile7
-rw-r--r--tubes/Module_tubes.mk30
-rw-r--r--tubes/README82
-rw-r--r--tubes/UIConfig_tubes.mk16
-rw-r--r--tubes/org.freedesktop.Telepathy.Client.LibreOffice.service3
-rw-r--r--tubes/org.freedesktop.Telepathy.Client.LibreOfficeApprover.service3
-rw-r--r--tubes/qa/test-config.ini.example5
-rw-r--r--tubes/qa/test_manager.cxx192
-rw-r--r--tubes/source/approver.c235
-rw-r--r--tubes/source/collaboration.cxx68
-rw-r--r--tubes/source/conference.cxx574
-rw-r--r--tubes/source/conference.hxx81
-rw-r--r--tubes/source/constants.h35
-rw-r--r--tubes/source/contacts.cxx191
-rw-r--r--tubes/source/contacts.hxx64
-rw-r--r--tubes/source/file-transfer-helper.c1853
-rw-r--r--tubes/source/file-transfer-helper.h121
-rw-r--r--tubes/source/manager.cxx905
-rw-r--r--tubes/uiconfig/ui/contacts.ui143
24 files changed, 0 insertions, 4724 deletions
diff --git a/tubes/CppunitTest_tubes_test.mk b/tubes/CppunitTest_tubes_test.mk
deleted file mode 100644
index eada4f0de92e..000000000000
--- a/tubes/CppunitTest_tubes_test.mk
+++ /dev/null
@@ -1,29 +0,0 @@
-# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
-#
-# 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/.
-#
-
-$(eval $(call gb_CppunitTest_CppunitTest,tubes_test))
-
-$(eval $(call gb_CppunitTest_add_exception_objects,tubes_test, \
- tubes/qa/test_manager \
-))
-
-$(eval $(call gb_CppunitTest_use_libraries,tubes_test, \
- sal \
- tubes \
- utl \
- $(gb_UWINAPI) \
-))
-
-$(eval $(call gb_CppunitTest_use_externals,tubes_test,\
- telepathy \
-))
-
-$(eval $(call gb_CppunitTest_use_udk_api,tubes_test))
-
-# vim: set noet sw=4 ts=4:
diff --git a/tubes/Executable_liboapprover.mk b/tubes/Executable_liboapprover.mk
deleted file mode 100644
index 57d785099180..000000000000
--- a/tubes/Executable_liboapprover.mk
+++ /dev/null
@@ -1,21 +0,0 @@
-# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
-#
-# 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/.
-#
-
-$(eval $(call gb_Executable_Executable,liboapprover))
-
-$(eval $(call gb_Executable_use_externals,liboapprover,\
- gtk \
- telepathy \
-))
-
-$(eval $(call gb_Executable_add_cobjects,liboapprover,\
- tubes/source/approver \
-))
-
-# vim: set ts=4 sw=4 et:
diff --git a/tubes/Library_tubes.mk b/tubes/Library_tubes.mk
deleted file mode 100644
index 96e93563d1f3..000000000000
--- a/tubes/Library_tubes.mk
+++ /dev/null
@@ -1,47 +0,0 @@
-# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
-#
-#
-# 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/.
-#
-
-$(eval $(call gb_Library_Library,tubes))
-
-$(eval $(call gb_Library_use_sdk_api,tubes))
-
-$(eval $(call gb_Library_add_defs,tubes,\
- -DTUBES_DLLIMPLEMENTATION \
-))
-
-$(eval $(call gb_Library_use_libraries,tubes,\
- comphelper \
- cppu \
- sal \
- svt \
- svxcore \
- tl \
- vcl \
- $(gb_UWINAPI) \
-))
-
-$(eval $(call gb_Library_use_externals,tubes,\
- boost_headers \
- gtk \
- telepathy \
-))
-
-$(eval $(call gb_Library_add_exception_objects,tubes,\
- tubes/source/collaboration \
- tubes/source/conference \
- tubes/source/contacts \
- tubes/source/manager \
-))
-
-$(eval $(call gb_Library_add_cobjects,tubes,\
- tubes/source/file-transfer-helper \
-))
-
-# vim:set shiftwidth=4 tabstop=4 noexpandtab: */
diff --git a/tubes/LibreOffice.client b/tubes/LibreOffice.client
deleted file mode 100644
index 8c3356fd30d2..000000000000
--- a/tubes/LibreOffice.client
+++ /dev/null
@@ -1,11 +0,0 @@
-[org.freedesktop.Telepathy.Client]
-Interfaces = org.freedesktop.Telepathy.Client.Handler;
-
-[org.freedesktop.Telepathy.Client.Handler]
-BypassApproval = false
-
-[org.freedesktop.Telepathy.Client.Handler.HandlerChannelFilter 0]
-org.freedesktop.Telepathy.Channel.TargetHandleType u = 1
-org.freedesktop.Telepathy.Channel.ChannelType s = org.freedesktop.Telepathy.Channel.Type.DBusTube
-org.freedesktop.Telepathy.Channel.Type.DBusTube.ServiceName s = org.libreoffice.calc
-
diff --git a/tubes/LibreOfficeApprover.client b/tubes/LibreOfficeApprover.client
deleted file mode 100644
index 035e02255d84..000000000000
--- a/tubes/LibreOfficeApprover.client
+++ /dev/null
@@ -1,8 +0,0 @@
-[org.freedesktop.Telepathy.Client]
-Interfaces = org.freedesktop.Telepathy.Client.Approver;
-
-[org.freedesktop.Telepathy.Client.Approver.ApproverChannelFilter 0]
-org.freedesktop.Telepathy.Channel.TargetHandleType u = 1
-org.freedesktop.Telepathy.Channel.ChannelType s = org.freedesktop.Telepathy.Channel.Type.DBusTube
-org.freedesktop.Telepathy.Channel.Type.DBusTube.ServiceName s = org.libreoffice.calc
-
diff --git a/tubes/Makefile b/tubes/Makefile
deleted file mode 100644
index ccb1c85a04da..000000000000
--- a/tubes/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
-
-module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
-
-include $(module_directory)/../solenv/gbuild/partial_build.mk
-
-# vim: set noet sw=4 ts=4:
diff --git a/tubes/Module_tubes.mk b/tubes/Module_tubes.mk
deleted file mode 100644
index abccf51b2cbc..000000000000
--- a/tubes/Module_tubes.mk
+++ /dev/null
@@ -1,30 +0,0 @@
-# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
-#
-#
-# 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/.
-#
-
-$(eval $(call gb_Module_Module,tubes))
-
-ifeq ($(ENABLE_TELEPATHY),TRUE)
-
-$(eval $(call gb_Module_add_targets,tubes,\
- Executable_liboapprover \
- Library_tubes \
-))
-
-$(eval $(call gb_Module_add_l10n_targets,tubes,\
- UIConfig_tubes \
-))
-
-$(eval $(call gb_Module_add_subsequentcheck_targets,tubes,\
- CppunitTest_tubes_test \
-))
-
-endif
-
-# vim:set shiftwidth=4 tabstop=4 noexpandtab: */
diff --git a/tubes/README b/tubes/README
deleted file mode 100644
index 8619a1a72ca3..000000000000
--- a/tubes/README
+++ /dev/null
@@ -1,82 +0,0 @@
-Interface to Telepathy Tubes.
-
-The idea is to provide 1-1 collaboration between contacts and many-many
-collaboration via MUCs, using Telepathy DBus Tubes over Jabber/XMPP.
-
-To enable configure LibO with --enable-telepathy
-
-Currently (2012-04-14) at least telepathy-glib 0.18 is needed, which doesn't
-come with distributions. Download it from
-http://telepathy.freedesktop.org/releases/telepathy-glib/
-and make install it locally, e.g. with --prefix=$HOME/usr
-For LibO configure then use PKG_CONFIG_PATH="$HOME/usr/lib/pkgconfig
-To not have tubes and sc cppunittests stumble (LD_LIBRARY_PATH is not evaluated
-in unit tests and thus not a solution) copy the libs to the solver, i.e.
-cp -p $HOME/usr/lib/libtelepathy-glib.* $SRCDIR/solver/$INPATH/lib/
-
-If you have a Telepathy-enabled LibreOffice installed to /usr (including
-liboapprover) you may also want to install the .service and .client files to
-make everything service-activatable. Currently this does not seem to work.
-
- mkdir -p $HOME/.local/share/telepathy/clients
- ln -s $PWD/tubes/LibreOffice.client \
- $PWD/tubes/LibreOfficeApprover.client \
- $HOME/.local/share/telepathy/clients
-
- mkdir -p $HOME/.local/share/dbus-1/services
- ln -s $PWD/tubes/org.freedesktop.Telepathy.Client.LibreOfficeApprover.service \
- $PWD/tubes/org.freedesktop.Telepathy.Client.LibreOffice.service \
- $HOME/.local/share/dbus-1/services
-
-
-* liboapprover
-
-You may run it in the background. When someone wants to collaborate with you,
-you then get a confirmation dialog.
-
-* Demo modes
-
-To play with the interposing without having an online account connected, create
-a bit of a document, go to File -> Collaboration -> startDemoSession and bingo.
-
-
-* To do interesting things with this code build and run calc thus:
-
- SAL_LOG=1 ./soffice --calc
-
- Now type simple strings into cells, rename sheets, or go to
- File -> Collaboration; Listen; startBuddySession;
- to transfer your document as-is to the other side ...
-
-
-* for the cppunittest needed:
- * Configure two Jabber accounts in Empathy
- * Both must be online and on each other's contact list
- * Copy qa/test-config.ini.example to qa/test-config.ini, and specify those
- two accounts' JIDs in it.
-
-
-* TODOs:
-
-* TeleConference is not deleted anywhere
-* dialog to pick own account
-* dialog to pick contact or MUC to work with
-* dialog to accept/reject collaboration requests
-* make the .service and .client files work reliably
-
-
-In applications, e.g. Calc:
-
-* stricter model,view,controller
-* disable all actions we cannot process collaboratively
-* separate input from view
-* preprocess input to determine data type (text, number, date, ...)
-* send typed/categorized data over wire before actually processing in model
-* process serialized input as received
-* Calc specific:
- * use existing shared document feature with change-tracking enabled to
- visualize changes
- * may have the benefit of having already only a subset of trackable change
- actions available
- * let ScDocFunc handle also received changes
-* have dialogs send their result item sets over the wire
diff --git a/tubes/UIConfig_tubes.mk b/tubes/UIConfig_tubes.mk
deleted file mode 100644
index 43a0febe52f4..000000000000
--- a/tubes/UIConfig_tubes.mk
+++ /dev/null
@@ -1,16 +0,0 @@
-# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
-#
-# 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/.
-#
-
-$(eval $(call gb_UIConfig_UIConfig,tubes))
-
-$(eval $(call gb_UIConfig_add_uifiles,tubes,\
- tubes/uiconfig/ui/contacts \
-))
-
-# vim: set noet sw=4 ts=4:
diff --git a/tubes/org.freedesktop.Telepathy.Client.LibreOffice.service b/tubes/org.freedesktop.Telepathy.Client.LibreOffice.service
deleted file mode 100644
index d1257242ab17..000000000000
--- a/tubes/org.freedesktop.Telepathy.Client.LibreOffice.service
+++ /dev/null
@@ -1,3 +0,0 @@
-[D-BUS Service]
-Name=org.freedesktop.Telepathy.Client.LibreOffice
-Exec=/usr/bin/libreoffice --calc
diff --git a/tubes/org.freedesktop.Telepathy.Client.LibreOfficeApprover.service b/tubes/org.freedesktop.Telepathy.Client.LibreOfficeApprover.service
deleted file mode 100644
index 89e4acf668fb..000000000000
--- a/tubes/org.freedesktop.Telepathy.Client.LibreOfficeApprover.service
+++ /dev/null
@@ -1,3 +0,0 @@
-[D-BUS Service]
-Name=org.freedesktop.Telepathy.Client.LibreOfficeApprover
-Exec=/usr/bin/liboapprover
diff --git a/tubes/qa/test-config.ini.example b/tubes/qa/test-config.ini.example
deleted file mode 100644
index 2d03ca8f3bb1..000000000000
--- a/tubes/qa/test-config.ini.example
+++ /dev/null
@@ -1,5 +0,0 @@
-# Locally-configured Jabber accounts used by Tubes test suite. These accounts
-# must both be signed in and on each others' contact lists for the tests to
-# work.
-offerer=libo1@localhost.localdomain
-accepter=libo2@localhost.localdomain
diff --git a/tubes/qa/test_manager.cxx b/tubes/qa/test_manager.cxx
deleted file mode 100644
index 11b653eb0ce1..000000000000
--- a/tubes/qa/test_manager.cxx
+++ /dev/null
@@ -1,192 +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 <sal/types.h>
-
-#include <cppunit/TestFixture.h>
-#include <cppunit/extensions/HelperMacros.h>
-#include <cppunit/plugin/TestPlugIn.h>
-
-#include <rtl/bootstrap.hxx>
-#include <rtl/string.hxx>
-#include <rtl/ustring.hxx>
-#include <tubes/collaboration.hxx>
-#include <tubes/manager.hxx>
-#include <unotools/localfilehelper.hxx>
-
-#include <telepathy-glib/telepathy-glib.h>
-
-class TeleConference;
-
-namespace {
-
-class TestTeleTubes: public CppUnit::TestFixture
-{
-public:
-
- virtual void setUp() override;
- virtual void tearDown() override;
-
- void testSession();
-
- // There is only one method because the code in setUp
- // and tearDown is expected to be executed only once.
- CPPUNIT_TEST_SUITE( TestTeleTubes );
- CPPUNIT_TEST( testSession );
- CPPUNIT_TEST_SUITE_END();
-};
-
-class TestCollaboration;
-// static, not members, so they actually survive cppunit test iteration
-static TestCollaboration* mpCollaboration1 = nullptr;
-static TestCollaboration* mpCollaboration2 = nullptr;
-//static bool mbFileSentSuccess = false;
-static bool mbPacketReceived = false;
-static OUString maTestConfigIniURL;
-static OString maOffererIdentifier;
-static OString maAccepterIdentifier;
-
-class TestCollaboration : public Collaboration
-{
- virtual void EndCollaboration() const override {}
- virtual void PacketReceived( const OString& rPacket ) const override
- {
- CPPUNIT_ASSERT( rPacket == "from 1 to 2");
- mbPacketReceived = true;
- }
- virtual void SaveAndSendFile( TpContact* ) const override {}
- virtual void StartCollaboration( TeleConference* ) override {}
-};
-
-gboolean timed_out( void * )
-{
- CPPUNIT_ASSERT_MESSAGE( "Test took longer than ten seconds!", false);
-
- return FALSE;
-}
-
-void TestTeleTubes::setUp()
-{
- g_timeout_add_seconds (10, timed_out, nullptr);
- maTestConfigIniURL = "file://" +
- OUString::createFromAscii( getenv("SRCDIR") ) + "/tubes/qa/test-config.ini";
- rtl::Bootstrap aTestConfig( maTestConfigIniURL );
-
- TeleManager::addSuffixToNames( "TeleTest");
-
- OUString aOffererIdentifier;
- CPPUNIT_ASSERT_MESSAGE( "See README for how to set up test-config.ini",
- aTestConfig.getFrom("offerer", aOffererIdentifier));
- maOffererIdentifier = OUStringToOString( aOffererIdentifier, RTL_TEXTENCODING_UTF8);
-
- OUString aAccepterIdentifier;
- CPPUNIT_ASSERT_MESSAGE( "See README for how to set up test-config.ini",
- aTestConfig.getFrom("accepter", aAccepterIdentifier));
- maAccepterIdentifier = OUStringToOString( aAccepterIdentifier, RTL_TEXTENCODING_UTF8);
-
- mpCollaboration1 = new TestCollaboration();
- mpCollaboration2 = new TestCollaboration();
-
- CPPUNIT_ASSERT( TeleManager::init( true));
-}
-
-/* FIXME: do we need the possibility to pass function to Collaboration::SendFile() ?
-static void lcl_FileSent( bool success, void * )
-{
- mbFileSentSuccess = success;
-}
-*/
-
-void TestTeleTubes::testSession()
-{
- // First try to get account and contact
- AccountContactPairV pairs = TeleManager::getContacts();
- /* Both our accounts are meant to be signed in, and they both should be
- * capable of LibreOffice tubes because this test runs after we register
- * our handler. */
- CPPUNIT_ASSERT_MESSAGE(
- "Make sure both your test accounts are signed in "
- "and are on each other's contact lists",
- pairs.size() > 0 );
-
- TpAccount* mpOffererAccount = nullptr;
- TpContact* mpAccepterContact = nullptr;
-
- for (AccountContactPairV::size_type i = 0; i < pairs.size(); i++)
- {
- AccountContactPair pair = pairs[i];
-
- if (tp_account_get_normalized_name (pair.first) == maOffererIdentifier &&
- tp_contact_get_identifier (pair.second) == maAccepterIdentifier)
- {
- mpOffererAccount = pair.first;
- g_object_ref (mpOffererAccount);
- mpAccepterContact = pair.second;
- g_object_ref (mpAccepterContact);
- }
- g_object_unref (pair.first);
- g_object_unref (pair.second);
- }
-
- CPPUNIT_ASSERT_MESSAGE(
- "Couldn't find offerer account. "
- "Make sure both your test accounts are signed in "
- "and are on each other's contact lists",
- mpOffererAccount);
- CPPUNIT_ASSERT_MESSAGE(
- "Couldn't find accepter contact. "
- "Make sure both your test accounts are signed in "
- "and are on each other's contact lists",
- mpAccepterContact);
-
- // Now we can start session
- TeleConference* pConference = nullptr;
- pConference = TeleManager::startBuddySession( mpOffererAccount, mpAccepterContact);
- CPPUNIT_ASSERT( pConference != nullptr);
- mpCollaboration1->SetConference( pConference );
- mpCollaboration1->SendFile( mpAccepterContact, maTestConfigIniURL );
-
- g_object_unref(mpOffererAccount);
- mpOffererAccount = nullptr;
- g_object_unref(mpAccepterContact);
- mpAccepterContact = nullptr;
-
- //while (!mbFileSentSuccess)
- // g_main_context_iteration( NULL, TRUE);
-
- // This checks that the file was received and msCurrentUUID set (see manager.cxx)
- while (!TeleManager::hasWaitingConference())
- g_main_context_iteration( nullptr, TRUE);
-
- pConference = TeleManager::getConference();
- CPPUNIT_ASSERT( pConference != nullptr);
- mpCollaboration2->SetConference( pConference );
-
- mpCollaboration1->SendPacket( "from 1 to 2");
-
- while (!mbPacketReceived)
- g_main_context_iteration( nullptr, TRUE);
-}
-
-void TestTeleTubes::tearDown()
-{
- // Closes the TeleConference in destructor:
- delete mpCollaboration1;
- delete mpCollaboration2;
-
- TeleManager::finalize();
-}
-
-CPPUNIT_TEST_SUITE_REGISTRATION( TestTeleTubes);
-
-}
-
-CPPUNIT_PLUGIN_IMPLEMENT();
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tubes/source/approver.c b/tubes/source/approver.c
deleted file mode 100644
index 6d6e28050d71..000000000000
--- a/tubes/source/approver.c
+++ /dev/null
@@ -1,235 +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 <glib.h>
-#include <stdio.h>
-
-#include <gtk/gtk.h>
-
-#include <telepathy-glib/telepathy-glib.h>
-#include <telepathy-glib/debug.h>
-#include <telepathy-glib/simple-approver.h>
-
-#include <constants.h>
-
-GMainLoop *mainloop = NULL;
-
-static void
-handle_with_cb (GObject *source,
- GAsyncResult *result,
- gpointer user_data)
-{
- TpChannelDispatchOperation *cdo = TP_CHANNEL_DISPATCH_OPERATION (source);
- GtkMessageDialog *dialog = GTK_MESSAGE_DIALOG (user_data);
- GError *error = NULL;
-
- if (!tp_channel_dispatch_operation_handle_with_finish (cdo, result, &error))
- {
- g_print ("HandleWith() failed: %s\n", error->message);
- gtk_message_dialog_format_secondary_markup (dialog,
- "<b>Error</b>\n\nAsking LibreOffice to accept the session failed: <i>%s</i>",
- error->message);
- g_error_free (error);
- return;
- }
-
- g_print ("HandleWith() succeeded\n");
- gtk_widget_destroy (GTK_WIDGET (dialog));
-}
-
-static void
-close_cb (GObject *source,
- GAsyncResult *result,
- gpointer user_data)
-
-{
- TpChannelDispatchOperation *cdo = TP_CHANNEL_DISPATCH_OPERATION (source);
- GError *error = NULL;
-
- (void)user_data; /* suppress unused-parameter warning */
-
- if (!tp_channel_dispatch_operation_close_channels_finish (cdo, result, &error))
- {
- g_print ("Rejecting channels failed: %s\n", error->message);
- g_error_free (error);
- return;
- }
-
- g_print ("Rejected all the things!\n");
-}
-
-static void
-dialog_response_cb (
- GtkWidget *dialog,
- gint response_id,
- gpointer user_data)
-{
- TpSimpleApprover *self = TP_SIMPLE_APPROVER (g_object_get_data (G_OBJECT (dialog), "client"));
- TpChannelDispatchOperation *cdo = TP_CHANNEL_DISPATCH_OPERATION (user_data);
-
- (void)self; /* suppress unused-parameter warning (could remove TP_SIMPLE_APPROVER above?) */
-
- if (response_id == GTK_RESPONSE_ACCEPT)
- {
- g_print ("Approve channels\n");
-
- tp_channel_dispatch_operation_handle_with_async (cdo, NULL,
- handle_with_cb, dialog);
-
- gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT, FALSE);
- gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_REJECT, FALSE);
- }
- else
- {
- g_print ("Reject channels\n");
-
- tp_channel_dispatch_operation_close_channels_async (cdo, close_cb, dialog);
- gtk_widget_destroy (dialog);
- }
-
- g_object_unref (cdo);
-}
-
-static void
-show_dialog (
- TpSimpleApprover *self,
- TpChannelDispatchOperation *cdo,
- TpContact *target)
-{
- GFile *avatar_file = tp_contact_get_avatar_file (target);
- GtkWidget *dialog = gtk_message_dialog_new_with_markup (NULL,
- 0, /* flags */
- GTK_MESSAGE_QUESTION,
- GTK_BUTTONS_NONE,
- "<b>%s</b> (<i>%s</i>) would like to edit a spreadsheet in LibreOffice "
- "with you.",
- tp_contact_get_alias (target),
- tp_contact_get_identifier (target));
-
- if (avatar_file != NULL)
- {
- GtkWidget *avatar = gtk_image_new_from_file (g_file_get_path (avatar_file));
-
- gtk_message_dialog_set_image (GTK_MESSAGE_DIALOG (dialog), avatar);
- }
-
- gtk_dialog_add_buttons (GTK_DIALOG (dialog),
- "_Reject", GTK_RESPONSE_REJECT,
- "_Accept", GTK_RESPONSE_ACCEPT,
- NULL);
-
- g_object_set_data_full (G_OBJECT (dialog), "client", g_object_ref (self), g_object_unref);
- g_signal_connect (dialog, "response", G_CALLBACK (dialog_response_cb), g_object_ref (cdo));
-
- gtk_window_set_skip_taskbar_hint (GTK_WINDOW (dialog), FALSE);
-
- gtk_widget_show_all (dialog);
-}
-
-static void
-add_dispatch_operation_cb (TpSimpleApprover *self,
- TpAccount *account,
- TpConnection *connection,
- GList *channels,
- TpChannelDispatchOperation *cdo,
- TpAddDispatchOperationContext *context,
- gpointer user_data)
-{
- TpContact *target = NULL;
- GList *l;
-
- (void)account; /* suppress unused-parameter warning */
- (void)connection; /* suppress unused-parameter warning */
- (void)user_data; /* suppress unused-parameter warning */
-
- g_print ("Approving this batch of channels:\n");
-
- for (l = channels; l != NULL; l = g_list_next (l))
- {
- TpChannel *channel = l->data;
-
- if (TP_IS_DBUS_TUBE_CHANNEL (channel))
- {
- target = tp_channel_get_target_contact (channel);
- break;
- }
- }
-
- if (target == NULL)
- {
- g_critical ("Hmm. No 1-1 D-Bus tube in cdo %s, so why did we get it?",
- tp_proxy_get_object_path (cdo));
- g_return_if_reached ();
- }
-
- tp_add_dispatch_operation_context_accept (context);
- show_dialog (self, cdo, target);
-}
-
-int
-main (int argc,
- char **argv)
-{
- TpAccountManager *manager;
- TpSimpleClientFactory *factory;
- TpBaseClient *approver;
- GError *error = NULL;
-
- gtk_init (&argc, &argv);
- tp_debug_set_flags (g_getenv ("LIBO_APPROVER_DEBUG"));
-
- manager = tp_account_manager_dup ();
-
- factory = tp_proxy_get_factory (manager);
- /* We want the target contact on channels to be available... */
- tp_simple_client_factory_add_channel_features_varargs (factory,
- TP_CHANNEL_FEATURE_CONTACTS,
- 0);
- /* ...and for it to have its alias and avatar available */
- tp_simple_client_factory_add_contact_features_varargs (factory,
- TP_CONTACT_FEATURE_ALIAS,
- TP_CONTACT_FEATURE_AVATAR_DATA,
- TP_CONTACT_FEATURE_INVALID);
-
- approver = tp_simple_approver_new_with_am (manager, "LibreOfficeApprover",
- FALSE, add_dispatch_operation_cb, NULL, NULL);
-
- tp_base_client_take_approver_filter (approver, 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,
- LIBO_DTUBE_SERVICE,
- NULL));
-
- if (!tp_base_client_register (approver, &error))
- {
- g_warning ("Failed to register Approver: %s\n", error->message);
- g_error_free (error);
- goto out;
- }
-
- g_print ("Start approving\n");
-
- mainloop = g_main_loop_new (NULL, FALSE);
- g_main_loop_run (mainloop);
- /* TODO: time out after 5 seconds of inactivity? */
-
- if (mainloop != NULL)
- g_main_loop_unref (mainloop);
-
-out:
- g_object_unref (manager);
- g_object_unref (approver);
-
- return 0;
-}
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tubes/source/collaboration.cxx b/tubes/source/collaboration.cxx
deleted file mode 100644
index fe397f8381fd..000000000000
--- a/tubes/source/collaboration.cxx
+++ /dev/null
@@ -1,68 +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 <contacts.hxx>
-
-Collaboration::Collaboration() :
- mpConference( nullptr )
-{
- TeleManager::registerCollaboration( this );
-}
-
-Collaboration::~Collaboration()
-{
- TeleManager::unregisterCollaboration( this );
- if (mpConference)
- mpConference->close();
-}
-
-sal_uInt64 Collaboration::GetId() const
-{
- return reinterpret_cast<sal_uInt64> (this);
-}
-
-void Collaboration::Invite( TpContact* pContact ) const
-{
- if (mpConference)
- {
- mpConference->invite( pContact );
- SaveAndSendFile( pContact );
- }
-}
-
-void Collaboration::DisplayContacts()
-{
- if (!mpContacts)
- mpContacts = VclPtr<tubes::TubeContacts>::Create( this );
- mpContacts->Populate();
-}
-
-void Collaboration::SendFile( TpContact* pContact, const OUString& rURL ) const
-{
- if (mpConference)
- mpConference->sendFile( pContact, rURL, nullptr, nullptr );
-}
-
-void Collaboration::SendPacket( const OString& rPacket ) const
-{
- if (mpConference)
- mpConference->sendPacket( rPacket );
-}
-
-void Collaboration::SetConference( TeleConference* pConference )
-{
- mpConference = pConference;
- mpConference->setCollaboration( this );
-}
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tubes/source/conference.cxx b/tubes/source/conference.cxx
deleted file mode 100644
index 373a564692b0..000000000000
--- a/tubes/source/conference.cxx
+++ /dev/null
@@ -1,574 +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 <gtk/gtk.h>
-#include <telepathy-glib/telepathy-glib.h>
-
-#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))
-#define INFO_LOGGER(s) InfoLogger aLogger(this,(s))
-#else
-#define INFO_LOGGER_F(s)
-#define INFO_LOGGER(s)
-#endif // SAL_LOG_INFO
-
-class TeleConferenceImpl
-{
-public:
- guint maObjectRegistrationId;
- GDBusConnection* mpTube;
- bool mbTubeOfferedHandlerInvoked : 1;
-
- TeleConferenceImpl() :
- mpTube( nullptr ),
- mbTubeOfferedHandlerInvoked( false )
- {}
-
- ~TeleConferenceImpl() {}
-};
-
-static void TeleConference_MethodCallHandler(
- GDBusConnection* /*pConnection*/,
- const gchar* pSender,
- const gchar* /*pObjectPath*/,
- const gchar* pInterfaceName,
- const gchar* pMethodName,
- GVariant* pParameters,
- GDBusMethodInvocation* pInvocation,
- void* pUserData)
-{
- INFO_LOGGER_F( "TeleConference_MethodCallHandler");
-
- TeleConference* pConference = static_cast<TeleConference*>(pUserData);
- SAL_WARN_IF( !pConference, "tubes", "TeleConference_MethodCallHandler: no conference");
- if (!pConference)
- return;
-
- if (tp_strdiff (pMethodName, LIBO_TUBES_DBUS_MSG_METHOD))
- {
- g_dbus_method_invocation_return_error ( pInvocation,
- G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD,
- "Unknown method '%s' on interface %s",
- pMethodName, pInterfaceName );
- return;
- }
-
- if (!g_variant_is_of_type ( pParameters, G_VARIANT_TYPE ("(ay)")))
- {
- g_dbus_method_invocation_return_error ( pInvocation,
- G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
- "'%s' takes an array of bytes, not %s",
- pMethodName,
- g_variant_get_type_string (pParameters));
- return;
- }
-
- GVariant *ay;
- g_variant_get( pParameters, "(@ay)", &ay);
- const char* pPacketData = static_cast<const char*>( g_variant_get_data( ay));
- gsize nPacketSize = g_variant_get_size( ay);
-
- SAL_WARN_IF( !pPacketData, "tubes", "TeleConference_MethodCallHandler: couldn't get packet data");
- if (!pPacketData)
- return;
-
- SAL_INFO( "tubes", "TeleConference_MethodCallHandler: received packet from sender "
- << (pSender ? pSender : "(null)") << " with size " << nPacketSize);
- OString aPacket( pPacketData, nPacketSize );
- if (pConference->getCollaboration())
- pConference->getCollaboration()->PacketReceived( aPacket );
- // Master needs to send the packet back to impose ordering,
- // so the slave can execute his command.
- if (pConference->isMaster())
- pConference->sendPacket( aPacket );
-
- g_dbus_method_invocation_return_value( pInvocation, nullptr );
-
- g_variant_unref( ay);
-}
-
-
-static void TeleConference_ChannelCloseHandler(
- TpChannel* /*proxy*/,
- const GError* pError,
- gpointer pUserData,
- GObject* /*weak_object*/
- )
-{
- INFO_LOGGER_F( "TeleConference_ChannelCloseHandler");
-
- TeleConference* pConference = static_cast<TeleConference*>(pUserData);
- SAL_WARN_IF( !pConference, "tubes", "TeleConference_ChannelCloseHandler: no conference");
- if (!pConference)
- return;
-
- if (pError)
- {
- SAL_WARN( "tubes", "TeleConference_ChannelCloseHandler: entered with error: " << pError->message);
- pConference->finalize();
- return;
- }
-
- pConference->finalize();
-}
-
-
-static void TeleConference_TubeOfferedHandler(
- GObject* pSource,
- GAsyncResult* pResult,
- gpointer pUserData)
-{
- INFO_LOGGER_F( "TeleConference_TubeOfferedHandler");
-
- TeleConference* pConference = static_cast<TeleConference*>(pUserData);
- SAL_WARN_IF( !pConference, "tubes", "TeleConference_TubeOfferedHandler: no conference");
- if (!pConference)
- return;
-
- pConference->setTubeOfferedHandlerInvoked( true);
-
- TpDBusTubeChannel* pChannel = TP_DBUS_TUBE_CHANNEL( pSource);
- GError* pError = nullptr;
- GDBusConnection* pTube = tp_dbus_tube_channel_offer_finish(
- pChannel, pResult, &pError);
-
- // "can't find contact ... presence" means contact is not a contact.
- /* FIXME: detect and handle */
- SAL_WARN_IF( !pTube, "tubes", "TeleConference_TubeOfferedHandler: entered with error: " << pError->message);
- if (pError) {
- g_error_free( pError);
- return;
- }
-
- pConference->setTube( pTube);
-}
-
-
-static void TeleConference_TubeAcceptedHandler(
- GObject* pSource,
- GAsyncResult* pResult,
- gpointer pUserData)
-{
- INFO_LOGGER_F( "TeleConference_TubeAcceptedHandler");
-
- TeleConference* pConference = static_cast<TeleConference*>(pUserData);
- SAL_WARN_IF( !pConference, "tubes", "TeleConference_TubeAcceptedHandler: no conference");
- if (!pConference)
- return;
-
- pConference->setTubeOfferedHandlerInvoked( true);
-
- TpDBusTubeChannel* pChannel = TP_DBUS_TUBE_CHANNEL( pSource);
- GError* pError = nullptr;
- GDBusConnection* pTube = tp_dbus_tube_channel_accept_finish(
- pChannel, pResult, &pError);
-
- SAL_WARN_IF( !pTube, "tubes", "TeleConference_TubeAcceptedHandler: entered with error: " << pError->message);
- if (pError) {
- g_error_free( pError);
- return;
- }
- GHashTable* pParameters = tp_dbus_tube_channel_get_parameters( pChannel);
- const char* sUuid = tp_asv_get_string( pParameters, LIBO_TUBES_UUID);
- pConference->setUuid( OString( sUuid));
-
- pConference->setTube( pTube);
-}
-
-
-TeleConference::TeleConference( TpAccount* pAccount,
- TpDBusTubeChannel* pChannel, const OString & sUuid, bool bMaster )
- :
- mpCollaboration( nullptr ),
- mpAccount( nullptr ),
- mpChannel( nullptr ),
- msUuid( sUuid ),
- mbMaster( bMaster ),
- pImpl( new TeleConferenceImpl() )
-{
- setChannel( pAccount, pChannel );
-}
-
-
-TeleConference::~TeleConference()
-{
- // We're destructed from finalize()
- delete pImpl;
-}
-
-static void channel_closed_cb( TpChannel *channel, gpointer user_data, GObject * /* weak_object */ )
-{
- Collaboration* pCollaboration = static_cast<Collaboration*> (user_data);
- if (TeleManager::existsCollaboration( pCollaboration ))
- {
- GtkWidget *dialog = gtk_message_dialog_new( nullptr, static_cast<GtkDialogFlags> (0),
- GTK_MESSAGE_WARNING, GTK_BUTTONS_CLOSE,
- "Contact %s lost, you'll now be working locally.",
- tp_contact_get_alias (tp_channel_get_target_contact (channel)) );
- g_signal_connect_swapped (dialog, "response",
- G_CALLBACK (gtk_widget_destroy), dialog);
- gtk_widget_show_all (dialog);
-
- pCollaboration->EndCollaboration();
- }
-}
-
-
-void TeleConference::setChannel( TpAccount *pAccount, TpDBusTubeChannel* pChannel )
-{
- SAL_WARN_IF( mpChannel, "tubes", "TeleConference::setChannel: already have channel");
- if (mpChannel)
- g_object_unref( mpChannel);
- if (mpAccount)
- g_object_unref( mpAccount);
-
- mpChannel = pChannel;
- if (mpChannel)
- g_object_ref( mpChannel);
-
- mpAccount = pAccount;
- if (mpAccount)
- g_object_ref( mpAccount);
-}
-
-
-bool TeleConference::spinUntilTubeEstablished()
-{
- while (!isTubeOfferedHandlerInvoked())
- {
- g_main_context_iteration( nullptr, TRUE );
- }
-
- bool bOpen = pImpl->mpTube != nullptr;
- 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( pImpl->mpTube, "tubes", "TeleConference::acceptTube: already tubed");
- if (!mpChannel || pImpl->mpTube)
- return false;
-
- tp_dbus_tube_channel_accept_async( mpChannel,
- TeleConference_TubeAcceptedHandler,
- this);
- return spinUntilTubeEstablished();
-}
-
-
-bool TeleConference::offerTube()
-{
- INFO_LOGGER( "TeleConference::offerTube");
-
- SAL_WARN_IF( !mpChannel, "tubes", "TeleConference::offerTube: no channel");
- if (!mpChannel)
- return false;
-
- GHashTable* pParameters = tp_asv_new (
- LIBO_TUBES_UUID, G_TYPE_STRING, msUuid.getStr(),
- nullptr);
-
- tp_dbus_tube_channel_offer_async(
- mpChannel,
- pParameters,
- TeleConference_TubeOfferedHandler,
- this);
-
- return spinUntilTubeEstablished();
-}
-
-
-bool TeleConference::setTube( GDBusConnection* pTube)
-{
- INFO_LOGGER( "TeleConference::setTube");
-
- SAL_WARN_IF( pImpl->mpTube, "tubes", "TeleConference::setTube: already tubed");
-
- pImpl->mpTube = pTube;
-
- GDBusNodeInfo *introspection_data;
- static const GDBusInterfaceVTable interface_vtable =
- {
- TeleConference_MethodCallHandler,
- nullptr,
- nullptr,
- { nullptr },
- };
- static const gchar introspection_xml[] =
- "<node>"
- " <interface name='" LIBO_TUBES_DBUS_INTERFACE "'>"
- " <method name='" LIBO_TUBES_DBUS_MSG_METHOD "'>"
- " <arg type='ay' name='packet' direction='in'/>"
- " </method>"
- " </interface>"
- "</node>";
-
- introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, nullptr);
- g_assert (introspection_data != nullptr);
-
- pImpl->maObjectRegistrationId = g_dbus_connection_register_object( pImpl->mpTube,
- LIBO_TUBES_DBUS_PATH, introspection_data->interfaces[0],
- &interface_vtable, this, nullptr, nullptr);
- g_assert (pImpl->maObjectRegistrationId > 0);
-
- g_dbus_node_info_unref (introspection_data);
-
- return true;
-}
-
-void TeleConference::setTubeOfferedHandlerInvoked( bool b )
-{
- pImpl->mbTubeOfferedHandlerInvoked = b;
-}
-
-bool TeleConference::isTubeOfferedHandlerInvoked() const
-{
- return pImpl->mbTubeOfferedHandlerInvoked;
-}
-
-bool TeleConference::isReady() const
-{
- return mpChannel && pImpl->mpTube;
-}
-
-void TeleConference::close()
-{
- INFO_LOGGER( "TeleConference::close");
-
- if (mpChannel)
- tp_cli_channel_call_close( TP_CHANNEL( mpChannel), 5000, TeleConference_ChannelCloseHandler, this, nullptr, nullptr);
- else
- finalize();
-}
-
-
-void TeleConference::finalize()
-{
- INFO_LOGGER( "TeleConference::finalize");
-
- TeleManager::unregisterDemoConference( this );
-
- if (mpChannel)
- {
- g_object_unref( mpChannel);
- mpChannel = nullptr;
- }
-
- if (mpAccount)
- {
- g_object_unref( mpAccount);
- mpAccount = nullptr;
- }
-
- if (pImpl->mpTube)
- {
- g_dbus_connection_unregister_object( pImpl->mpTube, pImpl->maObjectRegistrationId);
- g_dbus_connection_close_sync( pImpl->mpTube, nullptr, nullptr );
- g_object_unref( pImpl->mpTube );
- pImpl->mpTube = nullptr;
- }
-
- //! *this gets destructed here!
-}
-
-
-bool TeleConference::sendPacket( const OString& rPacket )
-{
- INFO_LOGGER( "TeleConference::sendPacket");
-
- if (!mpChannel && !pImpl->mpTube)
- {
- TeleManager::broadcastPacket( rPacket );
- return true;
- }
-
- SAL_WARN_IF( !pImpl->mpTube, "tubes", "TeleConference::sendPacket: no tube");
- if (!pImpl->mpTube)
- return false;
-
- /* FIXME: in GLib 2.32 we can use g_variant_new_fixed_array(). It does
- * essentially this.
- */
- void* pData = g_memdup( rPacket.getStr(), rPacket.getLength() );
- GVariant *pParameters = g_variant_new_from_data( G_VARIANT_TYPE("(ay)"),
- pData, rPacket.getLength(),
- FALSE,
- g_free, pData);
-
- g_dbus_connection_call( pImpl->mpTube,
- nullptr, /* bus name; in multi-user case we'd address this to the master. */
- LIBO_TUBES_DBUS_PATH,
- LIBO_TUBES_DBUS_INTERFACE,
- LIBO_TUBES_DBUS_MSG_METHOD,
- pParameters, /* consumes the floating reference */
- nullptr,
- G_DBUS_CALL_FLAGS_NONE,
- -1, nullptr, nullptr, nullptr);
-
- // If we started the session, we can execute commands immediately.
- if (mbMaster && mpCollaboration)
- mpCollaboration->PacketReceived( rPacket );
-
- return true;
-}
-
-bool TeleConference::isMaster() const
-{
- return mbMaster;
-}
-
-Collaboration* TeleConference::getCollaboration() const
-{
- return mpCollaboration;
-}
-
-void TeleConference::setCollaboration( Collaboration* pCollaboration )
-{
- mpCollaboration = pCollaboration;
- if (mpChannel)
- {
- GError *error = nullptr;
- if (!tp_cli_channel_connect_to_closed( TP_CHANNEL (mpChannel),
- channel_closed_cb, mpCollaboration, nullptr, nullptr, &error ))
- {
- SAL_WARN( "tubes", "Error when connecting to signal closed: " << error->message );
- g_error_free (error);
- }
- }
-}
-
-void TeleConference::invite( TpContact *pContact )
-{
- INFO_LOGGER( "TeleConference::invite" );
- TpHandle aHandle = tp_contact_get_handle( pContact );
- GArray handles = { reinterpret_cast<gchar *> (&aHandle), 1 };
- tp_cli_channel_interface_group_call_add_members( TP_CHANNEL( mpChannel ),
- -1, &handles, nullptr, nullptr, nullptr, nullptr, nullptr );
-}
-
-namespace {
-class SendFileRequest {
-public:
- SendFileRequest( TeleConference::FileSentCallback pCallback, void* pUserData, const char* sUuid )
- : mpCallback(pCallback)
- , mpUserData(pUserData)
- , msUuid(sUuid)
- {}
-
- TeleConference::FileSentCallback mpCallback;
- void* mpUserData;
- const char* msUuid;
-};
-}
-
-static void TeleConference_TransferDone( EmpathyFTHandler *handler, TpFileTransferChannel *, gpointer user_data)
-{
- SendFileRequest *request = static_cast<SendFileRequest *>(user_data);
-
- if (request->mpCallback)
- request->mpCallback(true, request->mpUserData);
- delete request;
- g_object_unref (handler);
-}
-
-static void TeleConference_TransferError( EmpathyFTHandler *handler, const GError *error, gpointer user_data)
-{
- SendFileRequest *request = static_cast<SendFileRequest *>(user_data);
-
- SAL_INFO( "tubes", "TeleConference_TransferError: " << error->message);
-
- if (request->mpCallback)
- request->mpCallback(false, request->mpUserData);
- delete request;
- g_object_unref (handler);
-}
-
-static void TeleConference_FTReady( EmpathyFTHandler *handler, GError *error, gpointer user_data)
-{
- SendFileRequest *request = static_cast<SendFileRequest *>(user_data);
-
- if ( error != nullptr )
- {
- if (request->mpCallback)
- request->mpCallback(error == nullptr, request->mpUserData);
- delete request;
- g_object_unref (handler);
- }
- else
- {
- g_signal_connect(handler, "transfer-done",
- G_CALLBACK (TeleConference_TransferDone), request);
- g_signal_connect(handler, "transfer-error",
- G_CALLBACK (TeleConference_TransferError), request);
- empathy_ft_handler_set_service_name(handler, TeleManager::getFullServiceName().getStr());
- empathy_ft_handler_set_description(handler, request->msUuid);
- empathy_ft_handler_start_transfer(handler);
- }
-}
-
-// TODO: move sending file to TeleManager
-void TeleConference::sendFile( TpContact* pContact, const OUString& localUri, FileSentCallback pCallback, void* pUserData)
-{
- INFO_LOGGER( "TeleConference::sendFile");
-
- if (!pContact)
- {
- // used in demo mode
- TeleManager_fileReceived( localUri, "demo" );
- return;
- }
-
- SAL_WARN_IF( ( !mpAccount || !mpChannel), "tubes",
- "can't send a file before the tube is set up");
- if ( !mpAccount || !mpChannel)
- return;
-
- GFile *pSource = g_file_new_for_uri(
- OUStringToOString( localUri, RTL_TEXTENCODING_UTF8).getStr() );
- SendFileRequest *pReq = new SendFileRequest( pCallback, pUserData, msUuid.getStr() );
-
- empathy_ft_handler_new_outgoing( mpAccount,
- pContact,
- pSource,
- 0,
- TeleConference_FTReady, pReq);
-}
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tubes/source/conference.hxx b/tubes/source/conference.hxx
deleted file mode 100644
index b39b8fbf79c9..000000000000
--- a/tubes/source/conference.hxx
+++ /dev/null
@@ -1,81 +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/.
- */
-
-#ifndef INCLUDED_TUBES_CONFERENCE_HXX
-#define INCLUDED_TUBES_CONFERENCE_HXX
-
-#include <sal/config.h>
-#include <rtl/ustring.hxx>
-
-#include <telepathy-glib/telepathy-glib.h>
-
-class Collaboration;
-class TeleConferenceImpl;
-
-/** Conference setup by TeleManager */
-class TeleConference
-{
-public:
-
- TeleConference( TpAccount* pAccount,
- TpDBusTubeChannel* pChannel,
- const OString & sUuid = OString(),
- bool bMaster = false );
- ~TeleConference();
-
- /// Close channel and call finalize()
- void close();
-
- /// Unrefs, unregisters from manager and calls dtor if last reference!
- void finalize();
-
- bool sendPacket( const OString& rPacket );
-
- void invite( TpContact *pContact );
-
- typedef void (*FileSentCallback)( bool aSuccess, void* pUserData);
- void sendFile( TpContact* pContact, const OUString& rURL, FileSentCallback pCallback, void* pUserData);
- const OString& getUuid() const { return msUuid; }
-
- Collaboration* getCollaboration() const;
- void setCollaboration( Collaboration* pCollaboration );
-
- // --- following only to be called only by manager's callbacks ---
- // TODO: make friends instead
- void setChannel( TpAccount* pAccount, TpDBusTubeChannel* pChannel );
- bool offerTube();
- bool acceptTube();
-
- // Only for callbacks.
- bool setTube( GDBusConnection* pTube );
- void setTubeOfferedHandlerInvoked( bool b );
- bool isTubeOfferedHandlerInvoked() const;
- bool isMaster() const;
- void setUuid( const OString& rUuid ) { msUuid = rUuid; }
-
-private:
- friend class TeleManager;
- // Used only by TeleManager:
- /// got tube accepted on other end as well?
- bool isReady() const;
-
- // Private:
- bool spinUntilTubeEstablished();
-
- Collaboration* mpCollaboration;
- TpAccount* mpAccount;
- TpDBusTubeChannel* mpChannel;
- OString msUuid;
- bool mbMaster;
- TeleConferenceImpl* pImpl;
-};
-
-#endif // INCLUDED_TUBES_CONFERENCE_HXX
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tubes/source/constants.h b/tubes/source/constants.h
deleted file mode 100644
index 5f861e5ea738..000000000000
--- a/tubes/source/constants.h
+++ /dev/null
@@ -1,35 +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/.
- */
-
-#ifndef INCLUDED_TUBES_CONSTANTS_H
-#define INCLUDED_TUBES_CONSTANTS_H
-
-/* DBusTube.ServiceName.
- *
- * FIXME: Should be something like
- *
- * org.libreoffice.calc
- * org.libreoffice.writer
- *
- * etc. This does not need to include the org.freedesktop.Telepathy.Client
- * stuff.
- */
-#define LIBO_DTUBE_SERVICE "org.libreoffice.calc"
-
-/* Client name suffix, for passing as 'name' to
- * tp_simple_handler_new_with_am(). */
-#define LIBO_CLIENT_SUFFIX "LibreOffice"
-
-/* Key value storing UUID for TeleConference
- */
-#define LIBO_TUBES_UUID "LIBO_TUBES_UUID"
-
-#endif // INCLUDED_TUBES_CONSTANTS_H
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tubes/source/contacts.cxx b/tubes/source/contacts.cxx
deleted file mode 100644
index 96a1b25b9d45..000000000000
--- a/tubes/source/contacts.cxx
+++ /dev/null
@@ -1,191 +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 <sal/config.h>
-
-#include <vcl/graphicfilter.hxx>
-#include <tubes/collaboration.hxx>
-
-#include <telepathy-glib/telepathy-glib.h>
-
-#include <conference.hxx>
-#include <contacts.hxx>
-
-void tubes::TubeContacts::Invite()
-{
- if (mpList->GetSelectEntryCount())
- {
- sal_uInt16 i = mpList->GetSelectEntryPos();
- TpContact* pContact = maACs[i].second;
- mpCollaboration->Invite( pContact );
- }
-}
-
-void tubes::TubeContacts::StartDemoSession()
-{
- TeleConference* pConference = TeleManager::startDemoSession();
- if (!pConference)
- SAL_WARN( "tubes", "Could not start demo session!" );
- else
- {
- mpCollaboration->StartCollaboration( pConference );
- mpCollaboration->SaveAndSendFile( nullptr );
- }
-}
-
-void tubes::TubeContacts::StartBuddySession()
-{
- if (mpList->GetSelectEntryCount())
- {
- sal_uInt16 i = mpList->GetSelectEntryPos();
- TpAccount* pAccount = maACs[i].first;
- TpContact* pContact = maACs[i].second;
- SAL_INFO( "tubes", "picked " << tp_contact_get_identifier( pContact ) );
- TeleConference* pConference = TeleManager::startBuddySession( pAccount, pContact );
- if (!pConference)
- SAL_WARN( "tubes", "Could not start session with " <<
- tp_contact_get_identifier( pContact ) );
- else
- {
- mpCollaboration->StartCollaboration( pConference );
- mpCollaboration->SaveAndSendFile( pContact );
- }
- }
-}
-
-void tubes::TubeContacts::StartGroupSession()
-{
- if (mpList->GetSelectEntryCount())
- {
- sal_uInt16 i = mpList->GetSelectEntryPos();
- TpAccount* pAccount = maACs[i].first;
- SAL_INFO( "tubes", "picked " << tp_account_get_display_name( pAccount ) );
- TeleConference* pConference = TeleManager::startGroupSession( pAccount,
- "liboroom", "conference.jabber.org" );
- if (!pConference)
- SAL_WARN( "tubes", "Could not start group session." );
- else
- {
- mpCollaboration->StartCollaboration( pConference );
- }
- }
-}
-
-tubes::TubeContacts::TubeContacts( Collaboration* pCollaboration ) :
- ModelessDialog( nullptr, "ContactsDialog", "tubes/ui/contacts.ui" ),
- mpCollaboration( pCollaboration )
-{
- get( mpBtnListen, "listen");
- get( mpBtnInvite, "invite");
- get( mpBtnDemo, "demo");
- get( mpBtnBuddy, "buddy");
- get( mpBtnGroup, "group");
- get( mpList, "contacts");
- mpBtnListen->SetClickHdl( LINK( this, TubeContacts, BtnListenHdl ) );
- mpBtnInvite->SetClickHdl( LINK( this, TubeContacts, BtnInviteHdl ) );
- mpBtnDemo->SetClickHdl( LINK( this, TubeContacts, BtnDemoHdl ) );
- mpBtnBuddy->SetClickHdl( LINK( this, TubeContacts, BtnConnectHdl ) );
- mpBtnGroup->SetClickHdl( LINK( this, TubeContacts, BtnGroupHdl ) );
-}
-
-tubes::TubeContacts::~TubeContacts()
-{
- disposeOnce();
-}
-
-void tubes::TubeContacts::dispose()
-{
- mpBtnListen.disposeAndClear();
- mpBtnInvite.disposeAndClear();
- mpBtnDemo.disposeAndClear();
- mpBtnBuddy.disposeAndClear();
- mpBtnGroup.disposeAndClear();
- mpList.disposeAndClear();
- ModelessDialog::dispose();
-}
-
-namespace {
-
-OUString fromUTF8( const char *pStr )
-{
- return OStringToOUString( OString( pStr, strlen( pStr ) ),
- RTL_TEXTENCODING_UTF8 );
-}
-
-}
-
-void tubes::TubeContacts::Populate()
-{
- SAL_INFO( "tubes", "Populating contact list dialog" );
- mpList->Clear();
- maACs.clear();
-
- AccountContactPairV aPairs = TeleManager::getContacts();
- AccountContactPairV::iterator it;
- // make sure we have enough memory to not need re-allocation
- // which would invalidate pointers stored in mpList entries
- maACs.reserve( aPairs.size() );
- for( it = aPairs.begin(); it != aPairs.end(); ++it )
- {
- Image aImage;
- GFile *pAvatarFile = tp_contact_get_avatar_file( it->second );
- if( pAvatarFile )
- {
- const OUString sAvatarFileUrl = fromUTF8( g_file_get_path ( pAvatarFile ) );
- Graphic aGraphic;
- if( GRFILTER_OK == GraphicFilter::LoadGraphic( sAvatarFileUrl, "", aGraphic ) )
- {
- BitmapEx aBitmap = aGraphic.GetBitmapEx();
- double fScale = 30.0 / aBitmap.GetSizePixel().Height();
- aBitmap.Scale( fScale, fScale );
- aImage = Image( aBitmap );
- }
- }
- OUStringBuffer aEntry( 128 );
- aEntry.append( " " );
- aEntry.append( fromUTF8 ( tp_contact_get_alias( it->second ) ) );
- aEntry.append( " - " );
- aEntry.append( fromUTF8 ( tp_contact_get_identifier( it->second ) ) );
- mpList->InsertEntry( aEntry.makeStringAndClear(), aImage);
- // FIXME: ref the TpAccount, TpContact ...
- maACs.push_back( AccountContactPair( it->first, it->second ) );
-
- g_object_unref (it->first);
- g_object_unref (it->second);
- }
- Show();
-}
-
-IMPL_LINK_NOARG( tubes::TubeContacts, BtnDemoHdl, Button*, void )
-{
- StartDemoSession();
-}
-
-IMPL_LINK_NOARG( tubes::TubeContacts, BtnConnectHdl, Button*, void )
-{
- StartBuddySession();
-}
-
-IMPL_LINK_NOARG( tubes::TubeContacts, BtnGroupHdl, Button*, void )
-{
- StartGroupSession();
-}
-
-IMPL_LINK_NOARG( tubes::TubeContacts, BtnInviteHdl, Button*, void )
-{
- Invite();
-}
-
-IMPL_STATIC_LINK_NOARG( tubes::TubeContacts, BtnListenHdl, Button*, void )
-{
- if (!TeleManager::registerClients())
- SAL_INFO( "tubes", "Could not register client handlers." );
-}
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tubes/source/contacts.hxx b/tubes/source/contacts.hxx
deleted file mode 100644
index 7684db962d22..000000000000
--- a/tubes/source/contacts.hxx
+++ /dev/null
@@ -1,64 +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/.
- */
-
-#ifndef INCLUDED_TUBES_SOURCE_CONTACTS_HXX
-#define INCLUDED_TUBES_SOURCE_CONTACTS_HXX
-
-#include <sal/config.h>
-
-#include <tubes/manager.hxx>
-#include <vcl/button.hxx>
-#include <vcl/dialog.hxx>
-#include <vcl/lstbox.hxx>
-
-class Collaboration;
-
-namespace tubes {
-
-class TubeContacts : public ModelessDialog
-{
- VclPtr<PushButton> mpBtnDemo;
- VclPtr<PushButton> mpBtnBuddy;
- VclPtr<PushButton> mpBtnGroup;
- VclPtr<PushButton> mpBtnInvite;
- VclPtr<PushButton> mpBtnListen;
- VclPtr<ListBox> mpList;
- Collaboration* mpCollaboration;
-
- DECL_LINK( BtnDemoHdl, Button*, void );
- DECL_LINK( BtnConnectHdl, Button*, void );
- DECL_LINK( BtnGroupHdl, Button*, void );
- DECL_LINK( BtnInviteHdl, Button*, void );
- DECL_STATIC_LINK( TubeContacts, BtnListenHdl, Button*, void );
-
- AccountContactPairV maACs;
-
- void Invite();
-
- void StartDemoSession();
-
- void StartBuddySession();
-
- void StartGroupSession();
-
-public:
- explicit TubeContacts( Collaboration* pCollaboration );
-
- virtual ~TubeContacts() override;
-
- virtual void dispose() override;
-
- void Populate();
-};
-
-}
-
-#endif
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/tubes/source/file-transfer-helper.c b/tubes/source/file-transfer-helper.c
deleted file mode 100644
index 043d464df820..000000000000
--- a/tubes/source/file-transfer-helper.c
+++ /dev/null
@@ -1,1853 +0,0 @@
-/*
- * empathy-ft-handler.c - Source for EmpathyFTHandler
- * Copyright © 2009, 2012 Collabora Ltd.
- * Copyright © 2009 Frédéric Péters
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Author: Cosimo Cecchi <cosimo.cecchi@collabora.co.uk>
- */
-
-/* empathy-ft-handler.c */
-
-#include <glib.h>
-#include <glib/gi18n.h>
-#include <telepathy-glib/account-channel-request.h>
-#include <telepathy-glib/util.h>
-#include <telepathy-glib/dbus.h>
-#include <telepathy-glib/interfaces.h>
-
-#include <file-transfer-helper.h>
-
-#define DEBUG(...)
-
-/**
- * SECTION:empathy-ft-handler
- * @title: EmpathyFTHandler
- * @short_description: an object representing a File Transfer
- * @include: libempathy/empathy-ft-handler
- *
- * #EmpathyFTHandler is the object which represents a File Transfer with all
- * its properties.
- * The creation of an #EmpathyFTHandler is done with
- * empathy_ft_handler_new_outgoing() or empathy_ft_handler_new_incoming(),
- * even though clients should not need to call them directly, as
- * #EmpathyFTFactory does it for them. Remember that for the file transfer
- * to work with an incoming handler,
- * empathy_ft_handler_incoming_set_destination() should be called after
- * empathy_ft_handler_new_incoming(). #EmpathyFTFactory does this
- * automatically.
- * It's important to note that, as the creation of the handlers is async, once
- * an handler is created, it already has all the interesting properties set,
- * like filename, total bytes, content type and so on, making it useful
- * to be displayed in an UI.
- * The transfer API works like a state machine; it has three signals,
- * ::transfer-started, ::transfer-progress, ::transfer-done, which will be
- * emitted in the relevant phases.
- * In addition, if the handler is created with checksumming enabled,
- * other three signals (::hashing-started, ::hashing-progress, ::hashing-done)
- * will be emitted before or after the transfer, depending on the direction
- * (respectively outgoing and incoming) of the handler.
- * At any time between the call to empathy_ft_handler_start_transfer() and
- * the last signal, a ::transfer-error can be emitted, indicating that an
- * error has happened in the operation. The message of the error is localized
- * to use in an UI.
- */
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-function"
-#endif
-G_DEFINE_TYPE (EmpathyFTHandler, empathy_ft_handler, G_TYPE_OBJECT)
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
-
-#define BUFFER_SIZE 4096
-
-enum {
- PROP_CHANNEL = 1,
- PROP_G_FILE,
- PROP_ACCOUNT,
- PROP_CONTACT,
- PROP_CONTENT_TYPE,
- PROP_DESCRIPTION,
- PROP_FILENAME,
- PROP_MODIFICATION_TIME,
- PROP_TOTAL_BYTES,
- PROP_TRANSFERRED_BYTES,
- PROP_USER_ACTION_TIME
-};
-
-enum {
- HASHING_STARTED,
- HASHING_PROGRESS,
- HASHING_DONE,
- TRANSFER_STARTED,
- TRANSFER_PROGRESS,
- TRANSFER_DONE,
- TRANSFER_ERROR,
- LAST_SIGNAL
-};
-
-typedef struct {
- GInputStream *stream;
- GError *error /* comment to make the style checker happy */;
- guchar *buffer;
- GChecksum *checksum;
- gssize total_read;
- guint64 total_bytes;
- EmpathyFTHandler *handler;
-} HashingData;
-
-typedef struct {
- EmpathyFTHandlerReadyCallback callback;
- gpointer user_data;
- EmpathyFTHandler *handler;
-} CallbacksData;
-
-/* private data */
-struct EmpathyFTHandlerPriv_ {
- gboolean dispose_run;
-
- GFile *gfile;
- TpFileTransferChannel *channel;
- GCancellable *cancellable;
- gboolean use_hash;
-
- /* request for the new transfer */
- GHashTable *request;
-
- /* transfer properties */
- TpAccount *account;
- TpContact *contact;
- gchar *content_type;
- gchar *filename;
- gchar *description;
- guint64 total_bytes;
- guint64 transferred_bytes;
- guint64 mtime;
- gchar *content_hash;
- TpFileHashType content_hash_type;
- gchar *service_name;
-
- gint64 user_action_time;
-
- /* time and speed */
- gdouble speed;
- guint remaining_time;
- gint64 last_update_time;
-
- gboolean is_completed;
-};
-
-static guint signals[LAST_SIGNAL] = { 0 };
-
-static gboolean do_hash_job_incoming (GIOSchedulerJob *job,
- GCancellable *cancellable, gpointer user_data);
-
-/* GObject implementations */
-static void
-do_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
-{
- EmpathyFTHandler *self = EMPATHY_FT_HANDLER (object);
- EmpathyFTHandlerPriv *priv = self->priv;
-
- switch (property_id)
- {
- case PROP_ACCOUNT:
- g_value_set_object (value, priv->account);
- break;
- case PROP_CONTACT:
- g_value_set_object (value, priv->contact);
- break;
- case PROP_CONTENT_TYPE:
- g_value_set_string (value, priv->content_type);
- break;
- case PROP_DESCRIPTION:
- g_value_set_string (value, priv->description);
- break;
- case PROP_FILENAME:
- g_value_set_string (value, priv->filename);
- break;
- case PROP_MODIFICATION_TIME:
- g_value_set_uint64 (value, priv->mtime);
- break;
- case PROP_TOTAL_BYTES:
- g_value_set_uint64 (value, priv->total_bytes);
- break;
- case PROP_TRANSFERRED_BYTES:
- g_value_set_uint64 (value, priv->transferred_bytes);
- break;
- case PROP_G_FILE:
- g_value_set_object (value, priv->gfile);
- break;
- case PROP_CHANNEL:
- g_value_set_object (value, priv->channel);
- break;
- case PROP_USER_ACTION_TIME:
- g_value_set_int64 (value, priv->user_action_time);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- }
-}
-
-static void
-do_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- EmpathyFTHandler *self = EMPATHY_FT_HANDLER (object);
- EmpathyFTHandlerPriv *priv = self->priv;
-
- switch (property_id)
- {
- case PROP_ACCOUNT:
- priv->account = g_value_dup_object (value);
- break;
- case PROP_CONTACT:
- priv->contact = g_value_dup_object (value);
- break;
- case PROP_CONTENT_TYPE:
- priv->content_type = g_value_dup_string (value);
- break;
- case PROP_DESCRIPTION:
- priv->description = g_value_dup_string (value);
- break;
- case PROP_FILENAME:
- priv->filename = g_value_dup_string (value);
- break;
- case PROP_MODIFICATION_TIME:
- priv->mtime = g_value_get_uint64 (value);
- break;
- case PROP_TOTAL_BYTES:
- priv->total_bytes = g_value_get_uint64 (value);
- break;
- case PROP_TRANSFERRED_BYTES:
- priv->transferred_bytes = g_value_get_uint64 (value);
- break;
- case PROP_G_FILE:
- priv->gfile = g_value_dup_object (value);
- break;
- case PROP_CHANNEL:
- priv->channel = g_value_dup_object (value);
- break;
- case PROP_USER_ACTION_TIME:
- priv->user_action_time = g_value_get_int64 (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- }
-}
-
-static void
-do_dispose (GObject *object)
-{
- EmpathyFTHandler *self = EMPATHY_FT_HANDLER (object);
- EmpathyFTHandlerPriv *priv = self->priv;
-
- if (priv->dispose_run)
- return;
-
- priv->dispose_run = TRUE;
-
- if (priv->account != NULL) {
- g_object_unref (priv->account);
- priv->account = NULL;
- }
-
- if (priv->contact != NULL) {
- g_object_unref (priv->contact);
- priv->contact = NULL;
- }
-
- if (priv->gfile != NULL) {
- g_object_unref (priv->gfile);
- priv->gfile = NULL;
- }
-
- if (priv->channel != NULL) {
- tp_channel_close_async (TP_CHANNEL (priv->channel), NULL, NULL);
- g_object_unref (priv->channel);
- priv->channel = NULL;
- }
-
- if (priv->cancellable != NULL) {
- g_object_unref (priv->cancellable);
- priv->cancellable = NULL;
- }
-
- if (priv->request != NULL)
- {
- g_hash_table_unref (priv->request);
- priv->request = NULL;
- }
-
- G_OBJECT_CLASS (empathy_ft_handler_parent_class)->dispose (object);
-}
-
-static void
-do_finalize (GObject *object)
-{
- EmpathyFTHandler *self = EMPATHY_FT_HANDLER (object);
- EmpathyFTHandlerPriv *priv = self->priv;
-
- DEBUG ("%p", object);
-
- g_free (priv->content_type);
- priv->content_type = NULL;
-
- g_free (priv->filename);
- priv->filename = NULL;
-
- g_free (priv->description);
- priv->description = NULL;
-
- g_free (priv->content_hash);
- priv->content_hash = NULL;
-
- g_free (priv->service_name);
- priv->service_name = NULL;
-
- G_OBJECT_CLASS (empathy_ft_handler_parent_class)->finalize (object);
-}
-
-static void
-empathy_ft_handler_class_init (EmpathyFTHandlerClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GParamSpec *param_spec;
-
- g_type_class_add_private (klass, sizeof (EmpathyFTHandlerPriv));
-
- object_class->get_property = do_get_property;
- object_class->set_property = do_set_property;
- object_class->dispose = do_dispose;
- object_class->finalize = do_finalize;
-
- /* properties */
-
- /**
- * EmpathyFTHandler:account:
- *
- * The local #TpAccount for the file transfer
- */
- param_spec = g_param_spec_object ("account",
- "account", "The remote account",
- TP_TYPE_ACCOUNT,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY);
- g_object_class_install_property (object_class, PROP_ACCOUNT, param_spec);
-
- /**
- * EmpathyFTHandler:contact:
- *
- * The remote #TpContact for the transfer
- */
- param_spec = g_param_spec_object ("contact",
- "contact", "The remote contact",
- TP_TYPE_CONTACT,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY);
- g_object_class_install_property (object_class, PROP_CONTACT, param_spec);
-
- /**
- * EmpathyFTHandler:content-type:
- *
- * The content type of the file being transferred
- */
- param_spec = g_param_spec_string ("content-type",
- "content-type", "The content type of the file", NULL,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class,
- PROP_CONTENT_TYPE, param_spec);
-
- /**
- * EmpathyFTHandler:description:
- *
- * The description of the file being transferred
- */
- param_spec = g_param_spec_string ("description",
- "description", "The description of the file", NULL,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class,
- PROP_DESCRIPTION, param_spec);
-
- /**
- * EmpathyFTHandler:filename:
- *
- * The name of the file being transferred
- */
- param_spec = g_param_spec_string ("filename",
- "filename", "The name of the file", NULL,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class,
- PROP_FILENAME, param_spec);
-
- /**
- * EmpathyFTHandler:modification-time:
- *
- * The modification time of the file being transferred
- */
- param_spec = g_param_spec_uint64 ("modification-time",
- "modification-time", "The mtime of the file", 0,
- G_MAXUINT64, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class,
- PROP_MODIFICATION_TIME, param_spec);
-
- /**
- * EmpathyFTHandler:total-bytes:
- *
- * The size (in bytes) of the file being transferred
- */
- param_spec = g_param_spec_uint64 ("total-bytes",
- "total-bytes", "The size of the file", 0,
- G_MAXUINT64, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class,
- PROP_TOTAL_BYTES, param_spec);
-
- /**
- * EmpathyFTHandler:transferred-bytes:
- *
- * The number of the bytes already transferred
- */
- param_spec = g_param_spec_uint64 ("transferred-bytes",
- "transferred-bytes", "The number of bytes already transferred", 0,
- G_MAXUINT64, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class,
- PROP_TRANSFERRED_BYTES, param_spec);
-
- /**
- * EmpathyFTHandler:gfile:
- *
- * The #GFile object where the transfer actually happens
- */
- param_spec = g_param_spec_object ("gfile",
- "gfile", "The GFile we're handling",
- G_TYPE_FILE,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_G_FILE, param_spec);
-
- /**
- * EmpathyFTHandler:channel:
- *
- * The underlying #TpFileTransferChannel managing the transfer
- */
- param_spec = g_param_spec_object ("channel",
- "channel", "The file transfer channel",
- TP_TYPE_FILE_TRANSFER_CHANNEL,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY);
- g_object_class_install_property (object_class, PROP_CHANNEL, param_spec);
-
- param_spec = g_param_spec_int64 ("user-action-time", "user action time",
- "User action time",
- 0, G_MAXINT64, 0,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY);
- g_object_class_install_property (object_class, PROP_USER_ACTION_TIME,
- param_spec);
-
- /* signals */
-
- /**
- * EmpathyFTHandler::transfer-started
- * @handler: the object which has received the signal
- * @channel: the #TpFileTransferChannel for which the transfer has started
- *
- * This signal is emitted when the actual transfer starts.
- */
- signals[TRANSFER_STARTED] =
- g_signal_new ("transfer-started", G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST, 0, NULL, NULL,
- g_cclosure_marshal_generic,
- G_TYPE_NONE,
- 1, TP_TYPE_FILE_TRANSFER_CHANNEL);
-
- /**
- * EmpathyFTHandler::transfer-done
- * @handler: the object which has received the signal
- * @channel: the #TpFileTransferChannel for which the transfer has started
- *
- * This signal will be emitted when the actual transfer is completed
- * successfully.
- */
- signals[TRANSFER_DONE] =
- g_signal_new ("transfer-done", G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST, 0, NULL, NULL,
- g_cclosure_marshal_generic,
- G_TYPE_NONE,
- 1, TP_TYPE_FILE_TRANSFER_CHANNEL);
-
- /**
- * EmpathyFTHandler::transfer-error
- * @handler: the object which has received the signal
- * @error: a #GError
- *
- * This signal can be emitted anytime between the call to
- * empathy_ft_handler_start_transfer() and the last expected signal
- * (::transfer-done or ::hashing-done), and it's guaranteed to be the last
- * signal coming from the handler, meaning that no other operation will
- * take place after this signal.
- */
- signals[TRANSFER_ERROR] =
- g_signal_new ("transfer-error", G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST, 0, NULL, NULL,
- g_cclosure_marshal_generic,
- G_TYPE_NONE,
- 1, G_TYPE_POINTER);
-
- /**
- * EmpathyFTHandler::transfer-progress
- * @handler: the object which has received the signal
- * @current_bytes: the bytes currently transferred
- * @total_bytes: the total bytes of the handler
- * @remaining_time: the number of seconds remaining for the transfer
- * to be completed
- * @speed: the current speed of the transfer (in KB/s)
- *
- * This signal is emitted to notify clients of the progress of the
- * transfer.
- */
- signals[TRANSFER_PROGRESS] =
- g_signal_new ("transfer-progress", G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST, 0, NULL, NULL,
- g_cclosure_marshal_generic,
- G_TYPE_NONE,
- 4, G_TYPE_UINT64, G_TYPE_UINT64, G_TYPE_UINT, G_TYPE_DOUBLE);
-
- /**
- * EmpathyFTHandler::hashing-started
- * @handler: the object which has received the signal
- *
- * This signal is emitted when the hashing operation of the handler
- * is started. Note that this might happen or not, depending on the CM
- * and remote contact capabilities. Clients should use
- * empathy_ft_handler_get_use_hash() before calling
- * empathy_ft_handler_start_transfer() to know whether they should connect
- * to this signal.
- */
- signals[HASHING_STARTED] =
- g_signal_new ("hashing-started", G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST, 0, NULL, NULL,
- g_cclosure_marshal_generic,
- G_TYPE_NONE, 0);
-
- /**
- * EmpathyFTHandler::hashing-progress
- * @handler: the object which has received the signal
- * @current_bytes: the bytes currently hashed
- * @total_bytes: the total bytes of the handler
- *
- * This signal is emitted to notify clients of the progress of the
- * hashing operation.
- */
- signals[HASHING_PROGRESS] =
- g_signal_new ("hashing-progress", G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST, 0, NULL, NULL,
- g_cclosure_marshal_generic,
- G_TYPE_NONE,
- 2, G_TYPE_UINT64, G_TYPE_UINT64);
-
- /**
- * EmpathyFTHandler::hashing-done
- * @handler: the object which has received the signal
- *
- * This signal is emitted when the hashing operation of the handler
- * is completed.
- */
- signals[HASHING_DONE] =
- g_signal_new ("hashing-done", G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST, 0, NULL, NULL,
- g_cclosure_marshal_generic,
- G_TYPE_NONE, 0);
-}
-
-static void
-empathy_ft_handler_init (EmpathyFTHandler *self)
-{
- EmpathyFTHandlerPriv *priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
- EMPATHY_TYPE_FT_HANDLER, EmpathyFTHandlerPriv);
-
- self->priv = priv;
- priv->cancellable = g_cancellable_new ();
-}
-
-/* private functions */
-
-static void
-hash_data_free (HashingData *data)
-{
- g_free (data->buffer);
-
- if (data->stream != NULL)
- g_object_unref (data->stream);
-
- if (data->checksum != NULL)
- g_checksum_free (data->checksum);
-
- if (data->error != NULL)
- g_error_free (data->error);
-
- if (data->handler != NULL)
- g_object_unref (data->handler);
-
- g_slice_free (HashingData, data);
-}
-
-static GChecksumType
-tp_file_hash_to_g_checksum (TpFileHashType type)
-{
- GChecksumType retval;
-
- switch (type)
- {
- case TP_FILE_HASH_TYPE_MD5:
- retval = G_CHECKSUM_MD5;
- break;
- case TP_FILE_HASH_TYPE_SHA1:
- retval = G_CHECKSUM_SHA1;
- break;
- case TP_FILE_HASH_TYPE_SHA256:
- retval = G_CHECKSUM_SHA256;
- break;
- case TP_FILE_HASH_TYPE_NONE:
- default:
- g_assert_not_reached ();
- break;
- }
-
- return retval;
-}
-
-static void
-check_hash_incoming (EmpathyFTHandler *handler)
-{
- EmpathyFTHandlerPriv *priv = handler->priv;
-
- if (!tp_str_empty (priv->content_hash))
- {
- HashingData *hash_data;
- hash_data = g_slice_new0 (HashingData);
- hash_data->total_bytes = priv->total_bytes;
- hash_data->handler = g_object_ref (handler);
- hash_data->checksum = g_checksum_new
- (tp_file_hash_to_g_checksum (priv->content_hash_type));
-
- g_signal_emit (handler, signals[HASHING_STARTED], 0);
-
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
- g_io_scheduler_push_job (do_hash_job_incoming, hash_data, NULL,
- G_PRIORITY_DEFAULT, priv->cancellable);
- #pragma GCC diagnostic pop
- }
-}
-
-static void
-emit_error_signal (EmpathyFTHandler *handler,
- const GError *error)
-{
- EmpathyFTHandlerPriv *priv = handler->priv;
-
- DEBUG ("Error in transfer: %s\n", error->message);
-
- if (!g_cancellable_is_cancelled (priv->cancellable))
- g_cancellable_cancel (priv->cancellable);
-
- g_signal_emit (handler, signals[TRANSFER_ERROR], 0, error);
-}
-
-static gint64
-time_get_current (void)
-{
- GDateTime *now;
- gint64 result;
-
- now = g_date_time_new_now_utc ();
- result = g_date_time_to_unix (now);
- g_date_time_unref (now);
-
- return result;
-}
-
-static void
-update_remaining_time_and_speed (EmpathyFTHandler *handler,
- guint64 transferred_bytes)
-{
- EmpathyFTHandlerPriv *priv = handler->priv;
- gint64 elapsed_time, current_time;
- guint64 transferred, last_transferred_bytes;
- gdouble speed;
- gint remaining_time;
-
- last_transferred_bytes = priv->transferred_bytes;
- priv->transferred_bytes = transferred_bytes;
-
- current_time = time_get_current ();
- elapsed_time = current_time - priv->last_update_time;
-
- if (elapsed_time >= 1)
- {
- transferred = transferred_bytes - last_transferred_bytes;
- speed = (gdouble) transferred / (gdouble) elapsed_time;
- remaining_time = (priv->total_bytes - priv->transferred_bytes) / speed;
- priv->speed = speed;
- priv->remaining_time = remaining_time;
- priv->last_update_time = current_time;
- }
-}
-
-static void
-ft_transfer_transferred_bytes_cb (TpFileTransferChannel *channel,
- GParamSpec *pspec,
- EmpathyFTHandler *handler)
-{
- EmpathyFTHandlerPriv *priv = handler->priv;
- guint64 bytes;
-
- (void)pspec; /* suppress unused-parameter warning */
-
- if (empathy_ft_handler_is_cancelled (handler))
- return;
-
- bytes = tp_file_transfer_channel_get_transferred_bytes (channel);
-
- if (priv->transferred_bytes == 0)
- {
- priv->last_update_time = time_get_current ();
- g_signal_emit (handler, signals[TRANSFER_STARTED], 0, channel);
- }
-
- if (priv->transferred_bytes != bytes)
- {
- update_remaining_time_and_speed (handler, bytes);
-
- g_signal_emit (handler, signals[TRANSFER_PROGRESS], 0,
- bytes, priv->total_bytes, priv->remaining_time,
- priv->speed);
- }
-}
-
-static void
-ft_transfer_provide_cb (GObject *source,
- GAsyncResult *result,
- gpointer user_data)
-{
- TpFileTransferChannel *channel = TP_FILE_TRANSFER_CHANNEL (source);
- EmpathyFTHandler *handler = user_data;
- GError *error = NULL;
-
- if (!tp_file_transfer_channel_provide_file_finish (channel, result, &error))
- {
- emit_error_signal (handler, error);
- g_clear_error (&error);
- }
-}
-
-static void
-ft_transfer_accept_cb (GObject *source,
- GAsyncResult *result,
- gpointer user_data)
-{
- TpFileTransferChannel *channel = TP_FILE_TRANSFER_CHANNEL (source);
- EmpathyFTHandler *handler = user_data;
- GError *error = NULL;
-
- if (!tp_file_transfer_channel_accept_file_finish (channel, result, &error))
- {
- emit_error_signal (handler, error);
- g_clear_error (&error);
- }
-}
-
-static GError *
-error_from_state_change_reason (TpFileTransferStateChangeReason reason)
-{
- const char *string;
- GError *retval = NULL;
-
- string = NULL;
-
- switch (reason)
- {
- case TP_FILE_TRANSFER_STATE_CHANGE_REASON_NONE:
- string = _("No reason was specified");
- break;
- case TP_FILE_TRANSFER_STATE_CHANGE_REASON_REQUESTED:
- string = _("The change in state was requested");
- break;
- case TP_FILE_TRANSFER_STATE_CHANGE_REASON_LOCAL_STOPPED:
- string = _("You canceled the file transfer");
- break;
- case TP_FILE_TRANSFER_STATE_CHANGE_REASON_REMOTE_STOPPED:
- string = _("The other participant canceled the file transfer");
- break;
- case TP_FILE_TRANSFER_STATE_CHANGE_REASON_LOCAL_ERROR:
- string = _("Error while trying to transfer the file");
- break;
- case TP_FILE_TRANSFER_STATE_CHANGE_REASON_REMOTE_ERROR:
- string = _("The other participant is unable to transfer the file");
- break;
- default:
- string = _("Unknown reason");
- break;
- }
-
- retval = g_error_new_literal (EMPATHY_FT_ERROR_QUARK,
- EMPATHY_FT_ERROR_TP_ERROR, string);
-
- return retval;
-}
-
-static void
-ft_transfer_state_cb (TpFileTransferChannel *channel,
- GParamSpec *pspec,
- EmpathyFTHandler *handler)
-{
- EmpathyFTHandlerPriv *priv = handler->priv;
- TpFileTransferStateChangeReason reason;
- TpFileTransferState state = tp_file_transfer_channel_get_state (
- channel, &reason);
-
- (void)pspec; /* suppress unused-parameter warning */
-
- if (state == TP_FILE_TRANSFER_STATE_COMPLETED)
- {
- priv->is_completed = TRUE;
- g_signal_emit (handler, signals[TRANSFER_DONE], 0, channel);
-
- tp_channel_close_async (TP_CHANNEL (channel), NULL, NULL);
-
- if (empathy_ft_handler_is_incoming (handler) && priv->use_hash)
- {
- check_hash_incoming (handler);
- }
- }
- else if (state == TP_FILE_TRANSFER_STATE_CANCELLED)
- {
- GError *error = error_from_state_change_reason (reason);
- emit_error_signal (handler, error);
- g_clear_error (&error);
- }
-}
-
-static void
-ft_handler_create_channel_cb (GObject *source,
- GAsyncResult *result,
- gpointer user_data)
-{
- EmpathyFTHandler *handler = user_data;
- EmpathyFTHandlerPriv *priv = handler->priv;
- GError *error = NULL;
- TpChannel *channel;
-
- DEBUG ("Dispatcher create channel CB");
-
- channel = tp_account_channel_request_create_and_handle_channel_finish (
- TP_ACCOUNT_CHANNEL_REQUEST (source), result, NULL, &error);
-
- if (channel == NULL)
- DEBUG ("Failed to request FT channel: %s", error->message);
- else
- g_cancellable_set_error_if_cancelled (priv->cancellable, &error);
-
- if (error != NULL)
- {
- emit_error_signal (handler, error);
-
- g_clear_object (&channel);
- g_error_free (error);
- return;
- }
-
- priv->channel = TP_FILE_TRANSFER_CHANNEL (channel);
-
- tp_g_signal_connect_object (priv->channel, "notify::state",
- G_CALLBACK (ft_transfer_state_cb), handler, 0);
- tp_g_signal_connect_object (priv->channel, "notify::transferred-bytes",
- G_CALLBACK (ft_transfer_transferred_bytes_cb), handler, 0);
-
- tp_file_transfer_channel_provide_file_async (priv->channel, priv->gfile,
- ft_transfer_provide_cb, handler);
-}
-
-static void
-ft_handler_push_to_dispatcher (EmpathyFTHandler *handler)
-{
- EmpathyFTHandlerPriv *priv = handler->priv;
- TpAccountChannelRequest *req;
-
- DEBUG ("Pushing request to the dispatcher");
-
- req = tp_account_channel_request_new (priv->account, priv->request,
- priv->user_action_time);
-
- tp_account_channel_request_create_and_handle_channel_async (req, NULL,
- ft_handler_create_channel_cb, handler);
-
- g_object_unref (req);
-}
-
-static void
-ft_handler_populate_outgoing_request (EmpathyFTHandler *handler)
-{
- guint contact_handle;
- EmpathyFTHandlerPriv *priv = handler->priv;
- gchar *uri;
-
- contact_handle = tp_contact_get_handle (priv->contact);
- uri = g_file_get_uri (priv->gfile);
-
- priv->request = 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_TARGET_HANDLE, G_TYPE_UINT,
- contact_handle,
- TP_PROP_CHANNEL_TYPE_FILE_TRANSFER_CONTENT_TYPE, G_TYPE_STRING,
- priv->content_type,
- TP_PROP_CHANNEL_TYPE_FILE_TRANSFER_FILENAME, G_TYPE_STRING,
- priv->filename,
- TP_PROP_CHANNEL_TYPE_FILE_TRANSFER_SIZE, G_TYPE_UINT64,
- priv->total_bytes,
- TP_PROP_CHANNEL_TYPE_FILE_TRANSFER_DATE, G_TYPE_UINT64,
- priv->mtime,
- TP_PROP_CHANNEL_TYPE_FILE_TRANSFER_URI, G_TYPE_STRING, uri,
- NULL);
-
- if (priv->service_name != NULL)
- tp_asv_set_string (priv->request, TP_PROP_CHANNEL_INTERFACE_FILE_TRANSFER_METADATA_SERVICE_NAME, priv->service_name);
-
- if (priv->description != NULL)
- tp_asv_set_string (priv->request, TP_PROP_CHANNEL_TYPE_FILE_TRANSFER_DESCRIPTION, priv->description);
-
- g_free (uri);
-}
-
-static gboolean
-hash_job_done (gpointer user_data)
-{
- HashingData *hash_data = user_data;
- EmpathyFTHandler *handler = hash_data->handler;
- EmpathyFTHandlerPriv *priv;
- GError *error = NULL;
-
- DEBUG ("Closing stream after hashing.");
-
- priv = handler->priv;
-
- if (hash_data->error != NULL)
- {
- error = hash_data->error;
- hash_data->error = NULL;
- goto cleanup;
- }
-
- DEBUG ("Got file hash %s", g_checksum_get_string (hash_data->checksum));
-
- if (empathy_ft_handler_is_incoming (handler))
- {
- if (g_strcmp0 (g_checksum_get_string (hash_data->checksum),
- priv->content_hash))
- {
- DEBUG ("Hash mismatch when checking incoming handler: "
- "received %s, calculated %s", priv->content_hash,
- g_checksum_get_string (hash_data->checksum));
-
- error = g_error_new_literal (EMPATHY_FT_ERROR_QUARK,
- EMPATHY_FT_ERROR_HASH_MISMATCH,
- _("File transfer completed, but the file was corrupted"));
- goto cleanup;
- }
- else
- {
- DEBUG ("Hash verification matched, received %s, calculated %s",
- priv->content_hash,
- g_checksum_get_string (hash_data->checksum));
- }
- }
- else
- {
- /* set the checksum in the request...
- * org.freedesktop.Telepathy.Channel.Type.FileTransfer.ContentHash
- */
- tp_asv_set_string (priv->request,
- TP_PROP_CHANNEL_TYPE_FILE_TRANSFER_CONTENT_HASH,
- g_checksum_get_string (hash_data->checksum));
- }
-
-cleanup:
-
- if (error != NULL)
- {
- emit_error_signal (handler, error);
- g_clear_error (&error);
- }
- else
- {
- g_signal_emit (handler, signals[HASHING_DONE], 0);
-
- if (!empathy_ft_handler_is_incoming (handler))
- /* the request is complete now, push it to the dispatcher */
- ft_handler_push_to_dispatcher (handler);
- }
-
- hash_data_free (hash_data);
-
- return FALSE;
-}
-
-static gboolean
-emit_hashing_progress (gpointer user_data)
-{
- HashingData *hash_data = user_data;
-
- g_signal_emit (hash_data->handler, signals[HASHING_PROGRESS], 0,
- (guint64) hash_data->total_read, (guint64) hash_data->total_bytes);
-
- return FALSE;
-}
-
-static gboolean
-do_hash_job (GIOSchedulerJob *job,
- GCancellable *cancellable,
- gpointer user_data)
-{
- HashingData *hash_data = user_data;
- gssize bytes_read;
- GError *error = NULL;
-
-again:
- if (hash_data->buffer == NULL)
- hash_data->buffer = g_malloc0 (BUFFER_SIZE);
-
- bytes_read = g_input_stream_read (hash_data->stream, hash_data->buffer,
- BUFFER_SIZE, cancellable, &error);
- if (error != NULL)
- goto out;
-
- hash_data->total_read += bytes_read;
-
- /* we now have the chunk */
- if (bytes_read > 0)
- {
- g_checksum_update (hash_data->checksum, hash_data->buffer, bytes_read);
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
- g_io_scheduler_job_send_to_mainloop_async (job, emit_hashing_progress,
- hash_data, NULL);
- #pragma GCC diagnostic pop
- g_free (hash_data->buffer);
- hash_data->buffer = NULL;
-
- goto again;
- }
- else
- {
- g_input_stream_close (hash_data->stream, cancellable, &error);
- }
-
-out:
- if (error != NULL)
- hash_data->error = error;
-
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
- g_io_scheduler_job_send_to_mainloop_async (job, hash_job_done,
- hash_data, NULL);
- #pragma GCC diagnostic pop
-
- return FALSE;
-}
-
-static gboolean
-do_hash_job_incoming (GIOSchedulerJob *job,
- GCancellable *cancellable,
- gpointer user_data)
-{
- HashingData *hash_data = user_data;
- EmpathyFTHandler *handler = hash_data->handler;
- EmpathyFTHandlerPriv *priv = handler->priv;
- GError *error = NULL;
-
- DEBUG ("checking integrity for incoming handler");
-
- /* need to get the stream first */
- hash_data->stream =
- G_INPUT_STREAM (g_file_read (priv->gfile, cancellable, &error));
-
- if (error != NULL)
- {
- hash_data->error = error;
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
- g_io_scheduler_job_send_to_mainloop_async (job, hash_job_done,
- hash_data, NULL);
- #pragma GCC diagnostic pop
- return FALSE;
- }
-
- return do_hash_job (job, cancellable, user_data);
-}
-
-static void
-ft_handler_read_async_cb (GObject *source,
- GAsyncResult *res,
- gpointer user_data)
-{
- GFileInputStream *stream;
- GError *error = NULL;
- HashingData *hash_data;
- EmpathyFTHandler *handler = user_data;
- EmpathyFTHandlerPriv *priv = handler->priv;
-
- (void)source; /* suppress unused-parameter warning */
-
- DEBUG ("GFile read async CB.");
-
- stream = g_file_read_finish (priv->gfile, res, &error);
- if (error != NULL)
- {
- emit_error_signal (handler, error);
- g_clear_error (&error);
-
- return;
- }
-
- hash_data = g_slice_new0 (HashingData);
- hash_data->stream = G_INPUT_STREAM (stream);
- hash_data->total_bytes = priv->total_bytes;
- hash_data->handler = g_object_ref (handler);
- /* FIXME: MD5 is the only ContentHashType supported right now */
- hash_data->checksum = g_checksum_new (G_CHECKSUM_MD5);
-
- tp_asv_set_uint32 (priv->request,
- TP_PROP_CHANNEL_TYPE_FILE_TRANSFER_CONTENT_HASH_TYPE,
- TP_FILE_HASH_TYPE_MD5);
-
- g_signal_emit (handler, signals[HASHING_STARTED], 0);
-
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
- g_io_scheduler_push_job (do_hash_job, hash_data, NULL,
- G_PRIORITY_DEFAULT, priv->cancellable);
- #pragma GCC diagnostic pop
-}
-
-static void
-callbacks_data_free (gpointer user_data)
-{
- CallbacksData *data = user_data;
-
- if (data->handler != NULL)
- g_object_unref (data->handler);
-
- g_slice_free (CallbacksData, data);
-}
-
-static gint
-cmp_uint (
- gconstpointer a,
- gconstpointer b)
-{
- return *(guint *) a - *(guint *) b;
-}
-
-static gboolean
-set_content_hash_type_from_classes (EmpathyFTHandler *handler,
- GPtrArray *classes)
-{
- GArray *possible_values;
- guint value;
- gboolean valid;
- EmpathyFTHandlerPriv *priv = handler->priv;
- gboolean support_ft = FALSE;
- guint i;
-
- possible_values = g_array_new (TRUE, TRUE, sizeof (guint));
-
- for (i = 0; i < classes->len; i++)
- {
- GHashTable *fixed;
- GStrv allowed;
- const gchar *chan_type;
-
- tp_value_array_unpack (g_ptr_array_index (classes, i), 2,
- &fixed, &allowed);
-
- chan_type = tp_asv_get_string (fixed, TP_PROP_CHANNEL_CHANNEL_TYPE);
-
- if (tp_strdiff (chan_type, TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER))
- continue;
-
- if (tp_asv_get_uint32 (fixed, TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, NULL) !=
- TP_HANDLE_TYPE_CONTACT)
- continue;
-
- support_ft = TRUE;
-
- value = tp_asv_get_uint32
- (fixed, TP_PROP_CHANNEL_TYPE_FILE_TRANSFER_CONTENT_HASH_TYPE,
- &valid);
-
- if (valid)
- g_array_append_val (possible_values, value);
- }
-
- if (!support_ft)
- {
- g_array_unref (possible_values);
- return FALSE;
- }
-
- if (possible_values->len == 0)
- {
- /* there are no channel classes with hash support, disable it. */
- priv->use_hash = FALSE;
- priv->content_hash_type = TP_FILE_HASH_TYPE_NONE;
-
- goto out;
- }
-
- priv->use_hash = TRUE;
-
- if (possible_values->len == 1)
- {
- priv->content_hash_type = g_array_index (possible_values, guint, 0);
- }
- else
- {
- /* order the array and pick the first non zero, so that MD5
- * is the preferred value.
- */
- g_array_sort (possible_values, cmp_uint);
-
- if (g_array_index (possible_values, guint, 0) == 0)
- priv->content_hash_type = g_array_index (possible_values, guint, 1);
- else
- priv->content_hash_type = g_array_index (possible_values, guint, 0);
- }
-
-out:
- g_array_unref (possible_values);
-
- DEBUG ("Hash enabled %s; setting content hash type as %u",
- priv->use_hash ? "True" : "False", priv->content_hash_type);
-
- return TRUE;
-}
-
-static void
-check_hashing (CallbacksData *data)
-{
- EmpathyFTHandler *handler = data->handler;
- EmpathyFTHandlerPriv *priv = handler->priv;
- GError *myerr = NULL;
- TpCapabilities *caps;
- GPtrArray *classes;
- TpConnection *conn;
-
- conn = tp_account_get_connection (priv->account);
-
- caps = tp_connection_get_capabilities (conn);
- if (caps == NULL)
- {
- data->callback (handler, NULL, data->user_data);
- goto out;
- }
-
- classes = tp_capabilities_get_channel_classes (caps);
-
- /* set whether we support hash and the type of it */
- if (!set_content_hash_type_from_classes (handler, classes))
- {
- g_set_error_literal (&myerr, EMPATHY_FT_ERROR_QUARK,
- EMPATHY_FT_ERROR_NOT_SUPPORTED,
- _("File transfer not supported by remote contact"));
-
- if (!g_cancellable_is_cancelled (priv->cancellable))
- g_cancellable_cancel (priv->cancellable);
-
- data->callback (handler, myerr, data->user_data);
- g_clear_error (&myerr);
- }
- else
- {
- /* get back to the caller now */
- data->callback (handler, NULL, data->user_data);
- }
-
-out:
- callbacks_data_free (data);
-}
-
-static void
-ft_handler_complete_request (EmpathyFTHandler *handler)
-{
- EmpathyFTHandlerPriv *priv = handler->priv;
-
- /* populate the request table with all the known properties */
- ft_handler_populate_outgoing_request (handler);
-
- if (priv->use_hash)
- /* start hashing the file */
- g_file_read_async (priv->gfile, G_PRIORITY_DEFAULT,
- priv->cancellable, ft_handler_read_async_cb, handler);
- else
- /* push directly the handler to the dispatcher */
- ft_handler_push_to_dispatcher (handler);
-}
-
-static void
-ft_handler_gfile_ready_cb (GObject *source,
- GAsyncResult *res,
- CallbacksData *cb_data)
-{
- GFileInfo *info;
- GError *error = NULL;
- GTimeVal mtime;
- EmpathyFTHandlerPriv *priv = cb_data->handler->priv;
-
- (void)source; /* suppress unused-parameter warning */
-
- DEBUG ("Got GFileInfo.");
-
- info = g_file_query_info_finish (priv->gfile, res, &error);
-
- if (error != NULL)
- goto out;
-
- if (g_file_info_get_file_type (info) != G_FILE_TYPE_REGULAR)
- {
- error = g_error_new_literal (EMPATHY_FT_ERROR_QUARK,
- EMPATHY_FT_ERROR_INVALID_SOURCE_FILE,
- _("The selected file is not a regular file"));
- goto out;
- }
-
- priv->total_bytes = g_file_info_get_size (info);
- if (priv->total_bytes == 0)
- {
- error = g_error_new_literal (EMPATHY_FT_ERROR_QUARK,
- EMPATHY_FT_ERROR_EMPTY_SOURCE_FILE,
- _("The selected file is empty"));
- goto out;
- }
-
- priv->content_type = g_strdup (g_file_info_get_content_type (info));
- priv->filename = g_strdup (g_file_info_get_display_name (info));
- g_file_info_get_modification_time (info, &mtime);
- priv->mtime = mtime.tv_sec;
- priv->transferred_bytes = 0;
- priv->description = NULL;
-
- g_object_unref (info);
-
-out:
- if (error != NULL)
- {
- if (!g_cancellable_is_cancelled (priv->cancellable))
- g_cancellable_cancel (priv->cancellable);
-
- cb_data->callback (cb_data->handler, error, cb_data->user_data);
- g_error_free (error);
-
- callbacks_data_free (cb_data);
- }
- else
- {
- /* see if FT/hashing are allowed */
- check_hashing (cb_data);
- }
-}
-
-static void
-channel_prepared_cb (
- GObject *source,
- GAsyncResult *result,
- gpointer user_data)
-{
- TpFileTransferChannel *channel = TP_FILE_TRANSFER_CHANNEL (source);
- CallbacksData *cb_data = user_data;
- EmpathyFTHandler *handler = cb_data->handler;
- EmpathyFTHandlerPriv *priv = handler->priv;
- GHashTable *properties;
- GError *error = NULL;
-
- if (!tp_proxy_prepare_finish (channel, result, &error))
- {
- if (!g_cancellable_is_cancelled (priv->cancellable))
- g_cancellable_cancel (priv->cancellable);
-
- cb_data->callback (handler, error, cb_data->user_data);
- g_clear_error (&error);
- callbacks_data_free (cb_data);
- return;
- }
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
- properties = tp_channel_borrow_immutable_properties (TP_CHANNEL (channel));
- #pragma GCC diagnostic pop
-
- priv->content_hash = g_strdup (
- tp_asv_get_string (properties, "ContentHash"));
-
- priv->content_hash_type = tp_asv_get_uint32 (
- properties, "ContentHashType", NULL);
-
- priv->contact = g_object_ref (tp_channel_get_target_contact (TP_CHANNEL (channel)));
-
- cb_data->callback (handler, NULL, cb_data->user_data);
-}
-
-
-/* public methods */
-
-/**
- * empathy_ft_handler_new_outgoing:
- * @account: the #TpAccount to send @source to
- * @contact: the #TpContact to send @source to
- * @source: the #GFile to send
- * @callback: callback to be called when the handler has been created
- * @user_data: user data to be passed to @callback
- *
- * Triggers the creation of a new #EmpathyFTHandler for an outgoing transfer.
- */
-void
-empathy_ft_handler_new_outgoing (
- TpAccount *account,
- TpContact *contact,
- GFile *source,
- gint64 action_time,
- EmpathyFTHandlerReadyCallback callback,
- gpointer user_data)
-{
- EmpathyFTHandler *handler;
- CallbacksData *data;
- EmpathyFTHandlerPriv *priv;
-
- DEBUG ("New handler outgoing");
-
- g_return_if_fail (TP_IS_ACCOUNT (account));
- g_return_if_fail (TP_IS_CONTACT (contact));
- g_return_if_fail (G_IS_FILE (source));
-
- handler = g_object_new (EMPATHY_TYPE_FT_HANDLER,
- "account", account,
- "contact", contact,
- "gfile", source,
- "user-action-time", action_time,
- NULL);
-
- priv = handler->priv;
-
- data = g_slice_new0 (CallbacksData);
- data->callback = callback;
- data->user_data = user_data;
- data->handler = g_object_ref (handler);
-
- /* start collecting info about the file */
- g_file_query_info_async (priv->gfile,
- G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME ","
- G_FILE_ATTRIBUTE_STANDARD_SIZE ","
- G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE ","
- G_FILE_ATTRIBUTE_STANDARD_TYPE ","
- G_FILE_ATTRIBUTE_TIME_MODIFIED,
- G_FILE_QUERY_INFO_NONE, G_PRIORITY_DEFAULT,
- NULL, (GAsyncReadyCallback) ft_handler_gfile_ready_cb, data);
-}
-
-void
-empathy_ft_handler_set_service_name (
- EmpathyFTHandler *self,
- const gchar *service_name)
-{
- g_free (self->priv->service_name);
- self->priv->service_name = g_strdup (service_name);
-}
-
-void
-empathy_ft_handler_set_description (
- EmpathyFTHandler *self,
- const gchar *description)
-{
- g_free (self->priv->description);
- self->priv->description = g_strdup (description);
-}
-
-/**
- * empathy_ft_handler_new_incoming:
- * @channel: the #TpFileTransferChannel proxy to the incoming channel
- * @callback: callback to be called when the handler has been created
- * @user_data: user data to be passed to @callback
- *
- * Triggers the creation of a new #EmpathyFTHandler for an incoming transfer.
- * Note that for the handler to be useful, you will have to set a destination
- * file with empathy_ft_handler_incoming_set_destination() after the handler
- * is ready.
- */
-void
-empathy_ft_handler_new_incoming (TpFileTransferChannel *channel,
- EmpathyFTHandlerReadyCallback callback,
- gpointer user_data)
-{
- EmpathyFTHandler *handler;
- CallbacksData *data;
- EmpathyFTHandlerPriv *priv;
- GQuark features[] = { TP_CHANNEL_FEATURE_CONTACTS, 0 };
-
- g_return_if_fail (TP_IS_FILE_TRANSFER_CHANNEL (channel));
-
- handler = g_object_new (EMPATHY_TYPE_FT_HANDLER,
- "channel", channel, NULL);
-
- priv = handler->priv;
-
- data = g_slice_new0 (CallbacksData);
- data->callback = callback;
- data->user_data = user_data;
- data->handler = g_object_ref (handler);
-
- priv->total_bytes = tp_file_transfer_channel_get_size (channel);
-
- priv->transferred_bytes = tp_file_transfer_channel_get_transferred_bytes (
- channel);
-
- priv->filename = g_strdup (tp_file_transfer_channel_get_filename (channel));
-
- priv->content_type = g_strdup (tp_file_transfer_channel_get_mime_type (
- channel));
-
- priv->description = g_strdup (tp_file_transfer_channel_get_description (
- channel));
-
- tp_proxy_prepare_async (channel, features,
- channel_prepared_cb, data);
-}
-
-/**
- * empathy_ft_handler_start_transfer:
- * @handler: an #EmpathyFTHandler
- *
- * Starts the transfer machinery. After this call, the transfer and hashing
- * signals will be emitted by the handler.
- */
-void
-empathy_ft_handler_start_transfer (EmpathyFTHandler *handler)
-{
- EmpathyFTHandlerPriv *priv;
-
- g_return_if_fail (EMPATHY_IS_FT_HANDLER (handler));
-
- priv = handler->priv;
-
- if (priv->channel == NULL)
- {
- ft_handler_complete_request (handler);
- }
- else
- {
- /* TODO: add support for resume. */
- tp_file_transfer_channel_accept_file_async (priv->channel,
- priv->gfile, 0, ft_transfer_accept_cb, handler);
-
- tp_g_signal_connect_object (priv->channel, "notify::state",
- G_CALLBACK (ft_transfer_state_cb), handler, 0);
- tp_g_signal_connect_object (priv->channel, "notify::transferred-bytes",
- G_CALLBACK (ft_transfer_transferred_bytes_cb), handler, 0);
- }
-}
-
-/**
- * empathy_ft_handler_cancel_transfer:
- * @handler: an #EmpathyFTHandler
- *
- * Cancels an ongoing handler operation. Note that this doesn't destroy
- * the object, which will keep all the properties, although it won't be able
- * to do any more I/O.
- */
-void
-empathy_ft_handler_cancel_transfer (EmpathyFTHandler *handler)
-{
- EmpathyFTHandlerPriv *priv;
-
- g_return_if_fail (EMPATHY_IS_FT_HANDLER (handler));
-
- priv = handler->priv;
-
- /* if we don't have a channel, we are hashing, so
- * we can just cancel the GCancellable to stop it.
- */
- if (priv->channel == NULL)
- g_cancellable_cancel (priv->cancellable);
- else
- tp_channel_close_async (TP_CHANNEL (priv->channel), NULL, NULL);
-}
-
-/**
- * empathy_ft_handler_incoming_set_destination:
- * @handler: an #EmpathyFTHandler
- * @destination: the #GFile where the transfer should be saved
- *
- * Sets the destination of the incoming handler to be @destination.
- * Note that calling this method is mandatory before starting the transfer
- * for incoming handlers.
- */
-void
-empathy_ft_handler_incoming_set_destination (EmpathyFTHandler *handler,
- GFile *destination)
-{
- EmpathyFTHandlerPriv *priv;
-
- g_return_if_fail (EMPATHY_IS_FT_HANDLER (handler));
- g_return_if_fail (G_IS_FILE (destination));
-
- priv = handler->priv;
-
- g_object_set (handler, "gfile", destination, NULL);
-
- /* check if hash is supported. if it isn't, set use_hash to FALSE
- * anyway, so that clients won't be expecting us to checksum.
- */
- if (tp_str_empty (priv->content_hash) ||
- priv->content_hash_type == TP_FILE_HASH_TYPE_NONE)
- priv->use_hash = FALSE;
- else
- priv->use_hash = TRUE;
-}
-
-/**
- * empathy_ft_handler_get_filename:
- * @handler: an #EmpathyFTHandler
- *
- * Returns the name of the file being transferred.
- *
- * Return value: the name of the file being transferred
- */
-const char *
-empathy_ft_handler_get_filename (EmpathyFTHandler *handler)
-{
- EmpathyFTHandlerPriv *priv;
-
- g_return_val_if_fail (EMPATHY_IS_FT_HANDLER (handler), NULL);
-
- priv = handler->priv;
-
- return priv->filename;
-}
-
-const char *
-empathy_ft_handler_get_description (EmpathyFTHandler *handler)
-{
- EmpathyFTHandlerPriv *priv;
-
- g_return_val_if_fail (EMPATHY_IS_FT_HANDLER (handler), NULL);
-
- priv = handler->priv;
-
- return priv->description;
-}
-
-/**
- * empathy_ft_handler_get_content_type:
- * @handler: an #EmpathyFTHandler
- *
- * Returns the content type of the file being transferred.
- *
- * Return value: the content type of the file being transferred
- */
-const char *
-empathy_ft_handler_get_content_type (EmpathyFTHandler *handler)
-{
- EmpathyFTHandlerPriv *priv;
-
- g_return_val_if_fail (EMPATHY_IS_FT_HANDLER (handler), NULL);
-
- priv = handler->priv;
-
- return priv->content_type;
-}
-
-/**
- * empathy_ft_handler_get_contact:
- * @handler: an #EmpathyFTHandler
- *
- * Returns the remote #TpContact at the other side of the transfer.
- *
- * Return value: the remote #TpContact for @handler
- */
-TpContact *
-empathy_ft_handler_get_contact (EmpathyFTHandler *handler)
-{
- EmpathyFTHandlerPriv *priv;
-
- g_return_val_if_fail (EMPATHY_IS_FT_HANDLER (handler), NULL);
-
- priv = handler->priv;
-
- return priv->contact;
-}
-
-/**
- * empathy_ft_handler_get_gfile:
- * @handler: an #EmpathyFTHandler
- *
- * Returns the #GFile where the transfer is being read/saved.
- *
- * Return value: the #GFile where the transfer is being read/saved
- */
-GFile *
-empathy_ft_handler_get_gfile (EmpathyFTHandler *handler)
-{
- EmpathyFTHandlerPriv *priv;
-
- g_return_val_if_fail (EMPATHY_IS_FT_HANDLER (handler), NULL);
-
- priv = handler->priv;
-
- return priv->gfile;
-}
-
-/**
- * empathy_ft_handler_get_use_hash:
- * @handler: an #EmpathyFTHandler
- *
- * Returns whether @handler has checksumming enabled. This can depend on
- * the CM and the remote contact capabilities.
- *
- * Return value: %TRUE if the handler has checksumming enabled,
- * %FALSE otherwise.
- */
-gboolean
-empathy_ft_handler_get_use_hash (EmpathyFTHandler *handler)
-{
- EmpathyFTHandlerPriv *priv;
-
- g_return_val_if_fail (EMPATHY_IS_FT_HANDLER (handler), FALSE);
-
- priv = handler->priv;
-
- return priv->use_hash;
-}
-
-/**
- * empathy_ft_handler_is_incoming:
- * @handler: an #EmpathyFTHandler
- *
- * Returns whether @handler is incoming or outgoing.
- *
- * Return value: %TRUE if the handler is incoming, %FALSE otherwise.
- */
-gboolean
-empathy_ft_handler_is_incoming (EmpathyFTHandler *handler)
-{
- EmpathyFTHandlerPriv *priv;
-
- g_return_val_if_fail (EMPATHY_IS_FT_HANDLER (handler), FALSE);
-
- priv = handler->priv;
-
- if (priv->channel == NULL)
- return FALSE;
-
- return !tp_channel_get_requested ((TpChannel *) priv->channel);
-}
-
-/**
- * empathy_ft_handler_get_transferred_bytes:
- * @handler: an #EmpathyFTHandler
- *
- * Returns the number of bytes already transferred by the handler.
- *
- * Return value: the number of bytes already transferred by the handler.
- */
-guint64
-empathy_ft_handler_get_transferred_bytes (EmpathyFTHandler *handler)
-{
- EmpathyFTHandlerPriv *priv;
-
- g_return_val_if_fail (EMPATHY_IS_FT_HANDLER (handler), 0);
-
- priv = handler->priv;
-
- return priv->transferred_bytes;
-}
-
-/**
- * empathy_ft_handler_get_total_bytes:
- * @handler: an #EmpathyFTHandler
- *
- * Returns the total size of the file being transferred by the handler.
- *
- * Return value: a number of bytes indicating the total size of the file being
- * transferred by the handler.
- */
-guint64
-empathy_ft_handler_get_total_bytes (EmpathyFTHandler *handler)
-{
- EmpathyFTHandlerPriv *priv;
-
- g_return_val_if_fail (EMPATHY_IS_FT_HANDLER (handler), 0);
-
- priv = handler->priv;
-
- return priv->total_bytes;
-}
-
-/**
- * empathy_ft_handler_is_completed:
- * @handler: an #EmpathyFTHandler
- *
- * Returns whether the transfer for @handler has been completed successfully.
- *
- * Return value: %TRUE if the handler has been transferred correctly, %FALSE
- * otherwise
- */
-gboolean
-empathy_ft_handler_is_completed (EmpathyFTHandler *handler)
-{
- EmpathyFTHandlerPriv *priv;
-
- g_return_val_if_fail (EMPATHY_IS_FT_HANDLER (handler), FALSE);
-
- priv = handler->priv;
-
- return priv->is_completed;
-}
-
-/**
- * empathy_ft_handler_is_cancelled:
- * @handler: an #EmpathyFTHandler
- *
- * Returns whether the transfer for @handler has been cancelled or has stopped
- * due to an error.
- *
- * Return value: %TRUE if the transfer for @handler has been cancelled
- * or has stopped due to an error, %FALSE otherwise.
- */
-gboolean
-empathy_ft_handler_is_cancelled (EmpathyFTHandler *handler)
-{
- EmpathyFTHandlerPriv *priv;
-
- g_return_val_if_fail (EMPATHY_IS_FT_HANDLER (handler), FALSE);
-
- priv = handler->priv;
-
- return g_cancellable_is_cancelled (priv->cancellable);
-}
diff --git a/tubes/source/file-transfer-helper.h b/tubes/source/file-transfer-helper.h
deleted file mode 100644
index ffcbc4b19837..000000000000
--- a/tubes/source/file-transfer-helper.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * empathy-ft-handler.h - Header for EmpathyFTHandler
- * Copyright (C) 2009 Collabora Ltd.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Author: Cosimo Cecchi <cosimo.cecchi@collabora.co.uk>
- */
-
-/* empathy-ft-handler.h */
-
-#ifndef INCLUDED_TUBES_FILE_TRANSFER_HELPER_H
-#define INCLUDED_TUBES_FILE_TRANSFER_HELPER_H
-
-#include <config_lgpl.h>
-#include <glib-object.h>
-#include <gio/gio.h>
-
-#include <telepathy-glib/contact.h>
-#include <telepathy-glib/file-transfer-channel.h>
-
-G_BEGIN_DECLS
-
-#define EMPATHY_TYPE_FT_HANDLER empathy_ft_handler_get_type()
-#define EMPATHY_FT_HANDLER(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
- EMPATHY_TYPE_FT_HANDLER, EmpathyFTHandler))
-#define EMPATHY_IS_FT_HANDLER(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EMPATHY_TYPE_FT_HANDLER))
-
-typedef struct EmpathyFTHandlerPriv_ EmpathyFTHandlerPriv;
-
-typedef struct {
- GObject parent;
- EmpathyFTHandlerPriv *priv;
-} EmpathyFTHandler;
-
-typedef struct {
- GObjectClass parent_class;
-} EmpathyFTHandlerClass;
-
-#define EMPATHY_FT_ERROR_QUARK g_quark_from_static_string ("EmpathyFTError")
-
-typedef enum {
- EMPATHY_FT_ERROR_FAILED,
- EMPATHY_FT_ERROR_HASH_MISMATCH,
- EMPATHY_FT_ERROR_TP_ERROR,
- EMPATHY_FT_ERROR_SOCKET,
- EMPATHY_FT_ERROR_NOT_SUPPORTED,
- EMPATHY_FT_ERROR_INVALID_SOURCE_FILE,
- EMPATHY_FT_ERROR_EMPTY_SOURCE_FILE
-} EmpathyFTErrorEnum;
-
-/**
- * EmpathyFTHandlerReadyCallback:
- * @handler: the handler which is now ready
- * @error: a #GError if the operation failed, or %NULL
- * @user_data: user data passed to the callback
- */
-typedef void (* EmpathyFTHandlerReadyCallback) (EmpathyFTHandler *handler,
- GError *error,
- gpointer user_data);
-
-GType empathy_ft_handler_get_type (void);
-
-/* public methods */
-void empathy_ft_handler_new_outgoing (
- TpAccount *account,
- TpContact *contact,
- GFile *source,
- gint64 action_time,
- EmpathyFTHandlerReadyCallback callback,
- gpointer user_data);
-void empathy_ft_handler_set_service_name (
- EmpathyFTHandler *self,
- const gchar *service_name);
-void empathy_ft_handler_set_description (
- EmpathyFTHandler *self,
- const gchar *description);
-
-
-void empathy_ft_handler_new_incoming (TpFileTransferChannel *channel,
- EmpathyFTHandlerReadyCallback callback,
- gpointer user_data);
-void empathy_ft_handler_incoming_set_destination (EmpathyFTHandler *handler,
- GFile *destination);
-
-void empathy_ft_handler_start_transfer (EmpathyFTHandler *handler);
-void empathy_ft_handler_cancel_transfer (EmpathyFTHandler *handler);
-
-/* properties of the transfer */
-const char * empathy_ft_handler_get_filename (EmpathyFTHandler *handler);
-const char * empathy_ft_handler_get_content_type (EmpathyFTHandler *handler);
-TpContact * empathy_ft_handler_get_contact (EmpathyFTHandler *handler);
-GFile * empathy_ft_handler_get_gfile (EmpathyFTHandler *handler);
-const char *empathy_ft_handler_get_description(EmpathyFTHandler*);
-gboolean empathy_ft_handler_get_use_hash (EmpathyFTHandler *handler);
-gboolean empathy_ft_handler_is_incoming (EmpathyFTHandler *handler);
-guint64 empathy_ft_handler_get_transferred_bytes (EmpathyFTHandler *handler);
-guint64 empathy_ft_handler_get_total_bytes (EmpathyFTHandler *handler);
-gboolean empathy_ft_handler_is_completed (EmpathyFTHandler *handler);
-gboolean empathy_ft_handler_is_cancelled (EmpathyFTHandler *handler);
-
-G_END_DECLS
-
-#endif // INCLUDED_TUBES_FILE_TRANSFER_HELPER_H
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
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: */
diff --git a/tubes/uiconfig/ui/contacts.ui b/tubes/uiconfig/ui/contacts.ui
deleted file mode 100644
index 25fc40005230..000000000000
--- a/tubes/uiconfig/ui/contacts.ui
+++ /dev/null
@@ -1,143 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<interface>
- <!-- interface-requires gtk+ 3.0 -->
- <object class="GtkDialog" id="ContactsDialog">
- <property name="can_focus">False</property>
- <property name="border_width">6</property>
- <property name="type_hint">dialog</property>
- <child internal-child="vbox">
- <object class="GtkBox" id="dialog-vbox1">
- <property name="can_focus">False</property>
- <property name="orientation">vertical</property>
- <property name="spacing">12</property>
- <child internal-child="action_area">
- <object class="GtkButtonBox" id="dialog-action_area1">
- <property name="can_focus">False</property>
- <property name="layout_style">end</property>
- <child>
- <object class="GtkButton" id="listen">
- <property name="label" translatable="yes">Listen</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkButton" id="invite">
- <property name="label" translatable="yes">Invite</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkButton" id="demo">
- <property name="label" translatable="yes">StartDemoSession</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">2</property>
- </packing>
- </child>
- <child>
- <object class="GtkButton" id="buddy">
- <property name="label" translatable="yes">StartBuddySession</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">3</property>
- </packing>
- </child>
- <child>
- <object class="GtkButton" id="group">
- <property name="label" translatable="yes">StartGroupSession</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">4</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="pack_type">end</property>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkGrid" id="grid1">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="vexpand">True</property>
- <property name="row_spacing">6</property>
- <child>
- <object class="GtkTreeView" id="contacts">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="hexpand">True</property>
- <property name="vexpand">True</property>
- <child internal-child="selection">
- <object class="GtkTreeSelection" id="treeview-selection"/>
- </child>
- </object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">1</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label1">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="label" translatable="yes">Select a contact to collaborate with</property>
- </object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">0</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">2</property>
- </packing>
- </child>
- </object>
- </child>
- <action-widgets>
- <action-widget response="0">listen</action-widget>
- <action-widget response="0">invite</action-widget>
- <action-widget response="0">demo</action-widget>
- <action-widget response="0">buddy</action-widget>
- <action-widget response="0">group</action-widget>
- </action-widgets>
- </object>
-</interface>