Merge lp:~tiagosh/ubuntu/vivid/telepathy-qt5/emit_selfHandleChanged into lp:ubuntu/vivid/telepathy-qt5

Proposed by Tiago Salem Herrmann on 2014-12-02
Status: Merged
Merged at revision: 10
Proposed branch: lp:~tiagosh/ubuntu/vivid/telepathy-qt5/emit_selfHandleChanged
Merge into: lp:ubuntu/vivid/telepathy-qt5
Diff against target: 1442 lines (+1366/-4)
6 files modified
.pc/10-emit_selfHandleChanged.patch/TelepathyQt/base-connection.cpp (+1337/-0)
.pc/applied-patches (+1/-0)
TelepathyQt/base-connection.cpp (+3/-0)
debian/libtelepathy-qt5-0.symbols (+4/-4)
debian/patches/10-emit_selfHandleChanged.patch (+20/-0)
debian/patches/series (+1/-0)
To merge this branch: bzr merge lp:~tiagosh/ubuntu/vivid/telepathy-qt5/emit_selfHandleChanged
Reviewer Review Type Date Requested Status
Gustavo Pichorim Boiko (community) Approve on 2015-01-28
Sebastien Bacher 2014-12-02 Needs Information on 2014-12-05
Review via email: mp+243435@code.launchpad.net

Commit Message

Emit SelfHandleChanged when requested by the connection manager.

Description of the Change

Emit SelfHandleChanged when requested by the connection manager.

To post a comment you must log in.
Sebastien Bacher (seb128) wrote :

Thanks, could you give some context on that change. Why is it needed? Why is not forwarded upstream? What issue does it resolve?

review: Needs Information
Tiago Salem Herrmann (tiagosh) wrote :

Hi, sorry the delay to reply.
This is needed for the mms group chat support.

https://code.launchpad.net/~tiagosh/telepathy-ofono/mms-group-chat/+merge/243431

In the previous implementation we used to set the SelfHandle in the constructor even before the CM was exposed to dbus and no changes after that could happen. Now this might change as we use the phone number coming from the sim card, and this can be dynamically updated by ofono.

Tp-qt was not emitting the proper signal, and this piece of the patch does the trick:

void BaseConnection::setSelfHandle(uint selfHandle)
{
+ bool changed = (selfHandle != mPriv->selfHandle);
     mPriv->selfHandle = selfHandle;
+ if (changed)
+ emit mPriv->adaptee->selfHandleChanged(mPriv->selfHandle);
}

Gustavo Pichorim Boiko (boiko) wrote :

Looks good and works as expected!

review: Approve
Sebastien Bacher (seb128) wrote :

Thanks Tiago, you didn't address the "why is that not worked or sent upstream" question though

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added directory '.pc/10-emit_selfHandleChanged.patch'
2=== added file '.pc/10-emit_selfHandleChanged.patch/.timestamp'
3=== added directory '.pc/10-emit_selfHandleChanged.patch/TelepathyQt'
4=== added file '.pc/10-emit_selfHandleChanged.patch/TelepathyQt/base-connection.cpp'
5--- .pc/10-emit_selfHandleChanged.patch/TelepathyQt/base-connection.cpp 1970-01-01 00:00:00 +0000
6+++ .pc/10-emit_selfHandleChanged.patch/TelepathyQt/base-connection.cpp 2014-12-02 17:21:36 +0000
7@@ -0,0 +1,1337 @@
8+/**
9+ * This file is part of TelepathyQt
10+ *
11+ * @copyright Copyright (C) 2012 Collabora Ltd. <http://www.collabora.co.uk/>
12+ * @copyright Copyright (C) 2012 Nokia Corporation
13+ * @license LGPL 2.1
14+ *
15+ * This library is free software; you can redistribute it and/or
16+ * modify it under the terms of the GNU Lesser General Public
17+ * License as published by the Free Software Foundation; either
18+ * version 2.1 of the License, or (at your option) any later version.
19+ *
20+ * This library is distributed in the hope that it will be useful,
21+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
22+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23+ * Lesser General Public License for more details.
24+ *
25+ * You should have received a copy of the GNU Lesser General Public
26+ * License along with this library; if not, write to the Free Software
27+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28+ */
29+
30+#include <TelepathyQt/BaseConnection>
31+#include "TelepathyQt/base-connection-internal.h"
32+
33+#include "TelepathyQt/_gen/base-connection.moc.hpp"
34+#include "TelepathyQt/_gen/base-connection-internal.moc.hpp"
35+
36+#include "TelepathyQt/debug-internal.h"
37+
38+#include <TelepathyQt/BaseChannel>
39+#include <TelepathyQt/Constants>
40+#include <TelepathyQt/DBusObject>
41+#include <TelepathyQt/Utils>
42+#include <TelepathyQt/AbstractProtocolInterface>
43+#include <QString>
44+#include <QVariantMap>
45+
46+namespace Tp
47+{
48+
49+struct TP_QT_NO_EXPORT BaseConnection::Private {
50+ Private(BaseConnection *parent, const QDBusConnection &dbusConnection,
51+ const QString &cmName, const QString &protocolName,
52+ const QVariantMap &parameters)
53+ : parent(parent),
54+ cmName(cmName),
55+ protocolName(protocolName),
56+ parameters(parameters),
57+ status(Tp::ConnectionStatusDisconnected),
58+ selfHandle(0),
59+ adaptee(new BaseConnection::Adaptee(dbusConnection, parent)) {
60+ }
61+
62+ BaseConnection *parent;
63+ QString cmName;
64+ QString protocolName;
65+ QVariantMap parameters;
66+ uint status;
67+ QHash<QString, AbstractConnectionInterfacePtr> interfaces;
68+ QSet<BaseChannelPtr> channels;
69+ CreateChannelCallback createChannelCB;
70+ RequestHandlesCallback requestHandlesCB;
71+ ConnectCallback connectCB;
72+ InspectHandlesCallback inspectHandlesCB;
73+ uint selfHandle;
74+ BaseConnection::Adaptee *adaptee;
75+};
76+
77+BaseConnection::Adaptee::Adaptee(const QDBusConnection &dbusConnection,
78+ BaseConnection *connection)
79+ : QObject(connection),
80+ mConnection(connection)
81+{
82+ mAdaptor = new Service::ConnectionAdaptor(dbusConnection, this, connection->dbusObject());
83+}
84+
85+BaseConnection::Adaptee::~Adaptee()
86+{
87+}
88+
89+void BaseConnection::Adaptee::disconnect(const Tp::Service::ConnectionAdaptor::DisconnectContextPtr &context)
90+{
91+ debug() << "BaseConnection::Adaptee::disconnect";
92+ /* This will remove the connection from the connection manager
93+ * and destroy this object. */
94+ emit mConnection->disconnected();
95+ context->setFinished();
96+}
97+
98+void BaseConnection::Adaptee::getSelfHandle(const Tp::Service::ConnectionAdaptor::GetSelfHandleContextPtr &context)
99+{
100+ context->setFinished(mConnection->mPriv->selfHandle);
101+}
102+
103+uint BaseConnection::Adaptee::selfHandle() const
104+{
105+ return mConnection->mPriv->selfHandle;
106+}
107+
108+void BaseConnection::Adaptee::getStatus(const Tp::Service::ConnectionAdaptor::GetStatusContextPtr &context)
109+{
110+ context->setFinished(mConnection->status());
111+}
112+
113+void BaseConnection::Adaptee::connect(const Tp::Service::ConnectionAdaptor::ConnectContextPtr &context)
114+{
115+ if (!mConnection->mPriv->connectCB.isValid()) {
116+ context->setFinishedWithError(TP_QT_ERROR_NOT_IMPLEMENTED, QLatin1String("Not implemented"));
117+ return;
118+ }
119+ DBusError error;
120+ mConnection->mPriv->connectCB(&error);
121+ if (error.isValid()) {
122+ context->setFinishedWithError(error.name(), error.message());
123+ return;
124+ }
125+ context->setFinished();
126+}
127+
128+void BaseConnection::Adaptee::inspectHandles(uint handleType,
129+ const Tp::UIntList &handles,
130+ const Tp::Service::ConnectionAdaptor::InspectHandlesContextPtr &context)
131+{
132+ if (!mConnection->mPriv->inspectHandlesCB.isValid()) {
133+ context->setFinishedWithError(TP_QT_ERROR_NOT_IMPLEMENTED, QLatin1String("Not implemented"));
134+ return;
135+ }
136+ DBusError error;
137+ QStringList ret = mConnection->mPriv->inspectHandlesCB(handleType, handles, &error);
138+ if (error.isValid()) {
139+ context->setFinishedWithError(error.name(), error.message());
140+ return;
141+ }
142+ context->setFinished(ret);
143+}
144+QStringList BaseConnection::Adaptee::interfaces() const
145+{
146+ QStringList ret;
147+ foreach(const AbstractConnectionInterfacePtr & iface, mConnection->interfaces()) {
148+ ret << iface->interfaceName();
149+ }
150+ return ret;
151+}
152+
153+void BaseConnection::Adaptee::requestChannel(const QString &type, uint handleType, uint handle, bool suppressHandler,
154+ const Tp::Service::ConnectionAdaptor::RequestChannelContextPtr &context)
155+{
156+ debug() << "BaseConnection::Adaptee::requestChannel (deprecated)";
157+ DBusError error;
158+ bool yours;
159+ BaseChannelPtr channel = mConnection->ensureChannel(type,
160+ handleType,
161+ handle,
162+ yours,
163+ selfHandle(),
164+ suppressHandler,
165+ QVariantMap(),
166+ &error);
167+ if (error.isValid() || !channel) {
168+ context->setFinishedWithError(error.name(), error.message());
169+ return;
170+ }
171+ context->setFinished(QDBusObjectPath(channel->objectPath()));
172+}
173+
174+void BaseConnection::Adaptee::requestHandles(uint handleType, const QStringList &identifiers,
175+ const Tp::Service::ConnectionAdaptor::RequestHandlesContextPtr &context)
176+{
177+ DBusError error;
178+ Tp::UIntList handles = mConnection->requestHandles(handleType, identifiers, &error);
179+ if (error.isValid()) {
180+ context->setFinishedWithError(error.name(), error.message());
181+ return;
182+ }
183+ context->setFinished(handles);
184+}
185+
186+/**
187+ * \class BaseConnection
188+ * \ingroup serviceconn
189+ * \headerfile TelepathyQt/base-connection.h <TelepathyQt/BaseConnection>
190+ *
191+ * \brief Base class for Connection implementations.
192+ */
193+
194+/**
195+ * Construct a BaseConnection.
196+ *
197+ * \param dbusConnection The D-Bus connection that will be used by this object.
198+ * \param cmName The name of the connection manager associated with this connection.
199+ * \param protocolName The name of the protocol associated with this connection.
200+ * \param parameters The parameters of this connection.
201+ */
202+BaseConnection::BaseConnection(const QDBusConnection &dbusConnection,
203+ const QString &cmName, const QString &protocolName,
204+ const QVariantMap &parameters)
205+ : DBusService(dbusConnection),
206+ mPriv(new Private(this, dbusConnection, cmName, protocolName, parameters))
207+{
208+}
209+
210+/**
211+ * Class destructor.
212+ */
213+BaseConnection::~BaseConnection()
214+{
215+ delete mPriv;
216+}
217+
218+/**
219+ * Return the name of the connection manager associated with this connection.
220+ *
221+ * \return The name of the connection manager associated with this connection.
222+ */
223+QString BaseConnection::cmName() const
224+{
225+ return mPriv->cmName;
226+}
227+
228+/**
229+ * Return the name of the protocol associated with this connection.
230+ *
231+ * \return The name of the protocol associated with this connection.
232+ */
233+QString BaseConnection::protocolName() const
234+{
235+ return mPriv->protocolName;
236+}
237+
238+/**
239+ * Return the parameters of this connection.
240+ *
241+ * \return The parameters of this connection.
242+ */
243+QVariantMap BaseConnection::parameters() const
244+{
245+ return mPriv->parameters;
246+}
247+
248+/**
249+ * Return the immutable properties of this connection object.
250+ *
251+ * Immutable properties cannot change after the object has been registered
252+ * on the bus with registerObject().
253+ *
254+ * \return The immutable properties of this connection object.
255+ */
256+QVariantMap BaseConnection::immutableProperties() const
257+{
258+ // FIXME
259+ return QVariantMap();
260+}
261+
262+/**
263+ * Return a unique name for this connection.
264+ *
265+ * \return A unique name for this connection.
266+ */
267+QString BaseConnection::uniqueName() const
268+{
269+ return QString(QLatin1String("_%1")).arg((quintptr) this, 0, 16);
270+}
271+
272+uint BaseConnection::status() const
273+{
274+ debug() << "BaseConnection::status = " << mPriv->status << " " << this;
275+ return mPriv->status;
276+}
277+
278+void BaseConnection::setStatus(uint newStatus, uint reason)
279+{
280+ debug() << "BaseConnection::setStatus " << newStatus << " " << reason << " " << this;
281+ bool changed = (newStatus != mPriv->status);
282+ mPriv->status = newStatus;
283+ if (changed)
284+ emit mPriv->adaptee->statusChanged(newStatus, reason);
285+}
286+
287+void BaseConnection::setCreateChannelCallback(const CreateChannelCallback &cb)
288+{
289+ mPriv->createChannelCB = cb;
290+}
291+
292+Tp::BaseChannelPtr BaseConnection::createChannel(const QString &channelType,
293+ uint targetHandleType,
294+ uint targetHandle,
295+ uint initiatorHandle,
296+ bool suppressHandler,
297+ const QVariantMap &hints,
298+ DBusError *error)
299+{
300+ if (!mPriv->createChannelCB.isValid()) {
301+ error->set(TP_QT_ERROR_NOT_IMPLEMENTED, QLatin1String("Not implemented"));
302+ return BaseChannelPtr();
303+ }
304+ if (!mPriv->inspectHandlesCB.isValid()) {
305+ error->set(TP_QT_ERROR_NOT_IMPLEMENTED, QLatin1String("Not implemented"));
306+ return BaseChannelPtr();
307+ }
308+
309+ BaseChannelPtr channel = mPriv->createChannelCB(channelType, targetHandleType, targetHandle, hints, error);
310+ if (error->isValid())
311+ return BaseChannelPtr();
312+
313+ QString targetID;
314+ if (targetHandle != 0) {
315+ QStringList list = mPriv->inspectHandlesCB(targetHandleType, UIntList() << targetHandle, error);
316+ if (error->isValid()) {
317+ debug() << "BaseConnection::createChannel: could not resolve handle " << targetHandle;
318+ return BaseChannelPtr();
319+ } else {
320+ debug() << "BaseConnection::createChannel: found targetID " << *list.begin();
321+ targetID = *list.begin();
322+ }
323+ }
324+ QString initiatorID;
325+ if (initiatorHandle != 0) {
326+ QStringList list = mPriv->inspectHandlesCB(HandleTypeContact, UIntList() << initiatorHandle, error);
327+ if (error->isValid()) {
328+ debug() << "BaseConnection::createChannel: could not resolve handle " << initiatorHandle;
329+ return BaseChannelPtr();
330+ } else {
331+ debug() << "BaseConnection::createChannel: found initiatorID " << *list.begin();
332+ initiatorID = *list.begin();
333+ }
334+ }
335+ channel->setInitiatorHandle(initiatorHandle);
336+ channel->setInitiatorID(initiatorID);
337+ channel->setTargetID(targetID);
338+ channel->setRequested(initiatorHandle == mPriv->selfHandle);
339+
340+ channel->registerObject(error);
341+ if (error->isValid())
342+ return BaseChannelPtr();
343+
344+ mPriv->channels.insert(channel);
345+
346+ BaseConnectionRequestsInterfacePtr reqIface =
347+ BaseConnectionRequestsInterfacePtr::dynamicCast(interface(TP_QT_IFACE_CONNECTION_INTERFACE_REQUESTS));
348+
349+ if (!reqIface.isNull())
350+ //emit after return
351+ QMetaObject::invokeMethod(reqIface.data(), "newChannels",
352+ Qt::QueuedConnection,
353+ Q_ARG(Tp::ChannelDetailsList, ChannelDetailsList() << channel->details()));
354+
355+
356+ //emit after return
357+ QMetaObject::invokeMethod(mPriv->adaptee, "newChannel",
358+ Qt::QueuedConnection,
359+ Q_ARG(QDBusObjectPath, QDBusObjectPath(channel->objectPath())),
360+ Q_ARG(QString, channel->channelType()),
361+ Q_ARG(uint, channel->targetHandleType()),
362+ Q_ARG(uint, channel->targetHandle()),
363+ Q_ARG(bool, suppressHandler));
364+
365+ QObject::connect(channel.data(),
366+ SIGNAL(closed()),
367+ SLOT(removeChannel()));
368+
369+ return channel;
370+}
371+
372+void BaseConnection::setRequestHandlesCallback(const RequestHandlesCallback &cb)
373+{
374+ mPriv->requestHandlesCB = cb;
375+}
376+
377+UIntList BaseConnection::requestHandles(uint handleType, const QStringList &identifiers, DBusError* error)
378+{
379+ if (!mPriv->requestHandlesCB.isValid()) {
380+ error->set(TP_QT_ERROR_NOT_IMPLEMENTED, QLatin1String("Not implemented"));
381+ return UIntList();
382+ }
383+ return mPriv->requestHandlesCB(handleType, identifiers, error);
384+}
385+
386+Tp::ChannelInfoList BaseConnection::channelsInfo()
387+{
388+ qDebug() << "BaseConnection::channelsInfo:";
389+ Tp::ChannelInfoList list;
390+ foreach(const BaseChannelPtr & c, mPriv->channels) {
391+ Tp::ChannelInfo info;
392+ info.channel = QDBusObjectPath(c->objectPath());
393+ info.channelType = c->channelType();
394+ info.handle = c->targetHandle();
395+ info.handleType = c->targetHandleType();
396+ qDebug() << "BaseConnection::channelsInfo " << info.channel.path();
397+ list << info;
398+ }
399+ return list;
400+}
401+
402+Tp::ChannelDetailsList BaseConnection::channelsDetails()
403+{
404+ Tp::ChannelDetailsList list;
405+ foreach(const BaseChannelPtr & c, mPriv->channels)
406+ list << c->details();
407+ return list;
408+}
409+
410+BaseChannelPtr BaseConnection::ensureChannel(const QString &channelType, uint targetHandleType,
411+ uint targetHandle, bool &yours, uint initiatorHandle,
412+ bool suppressHandler,
413+ const QVariantMap &hints,
414+ DBusError* error)
415+{
416+ foreach(BaseChannelPtr channel, mPriv->channels) {
417+ if (channel->channelType() == channelType
418+ && channel->targetHandleType() == targetHandleType
419+ && channel->targetHandle() == targetHandle) {
420+ yours = false;
421+ return channel;
422+ }
423+ }
424+ yours = true;
425+ return createChannel(channelType, targetHandleType, targetHandle, initiatorHandle, suppressHandler, hints, error);
426+}
427+
428+void BaseConnection::removeChannel()
429+{
430+ BaseChannelPtr channel = BaseChannelPtr(
431+ qobject_cast<BaseChannel*>(sender()));
432+ Q_ASSERT(channel);
433+ Q_ASSERT(mPriv->channels.contains(channel));
434+ mPriv->channels.remove(channel);
435+}
436+
437+/**
438+ * Return a list of interfaces that have been plugged into this Protocol
439+ * D-Bus object with plugInterface().
440+ *
441+ * This property is immutable and cannot change after this Protocol
442+ * object has been registered on the bus with registerObject().
443+ *
444+ * \return A list containing all the Protocol interface implementation objects.
445+ * \sa plugInterface(), interface()
446+ */
447+QList<AbstractConnectionInterfacePtr> BaseConnection::interfaces() const
448+{
449+ return mPriv->interfaces.values();
450+}
451+
452+/**
453+ * Return a pointer to the interface with the given name.
454+ *
455+ * \param interfaceName The D-Bus name of the interface,
456+ * ex. TP_QT_IFACE_CONNECTION_INTERFACE_ADDRESSING.
457+ * \return A pointer to the AbstractConnectionInterface object that implements
458+ * the D-Bus interface with the given name, or a null pointer if such an interface
459+ * has not been plugged into this object.
460+ * \sa plugInterface(), interfaces()
461+ */
462+AbstractConnectionInterfacePtr BaseConnection::interface(const QString &interfaceName) const
463+{
464+ return mPriv->interfaces.value(interfaceName);
465+}
466+
467+/**
468+ * Plug a new interface into this Connection D-Bus object.
469+ *
470+ * This property is immutable and cannot change after this Protocol
471+ * object has been registered on the bus with registerObject().
472+ *
473+ * \param interface An AbstractConnectionInterface instance that implements
474+ * the interface that is to be plugged.
475+ * \return \c true on success or \c false otherwise
476+ * \sa interfaces(), interface()
477+ */
478+bool BaseConnection::plugInterface(const AbstractConnectionInterfacePtr &interface)
479+{
480+ if (isRegistered()) {
481+ warning() << "Unable to plug protocol interface " << interface->interfaceName() <<
482+ "- protocol already registered";
483+ return false;
484+ }
485+
486+ if (interface->isRegistered()) {
487+ warning() << "Unable to plug protocol interface" << interface->interfaceName() <<
488+ "- interface already registered";
489+ return false;
490+ }
491+
492+ if (mPriv->interfaces.contains(interface->interfaceName())) {
493+ warning() << "Unable to plug protocol interface" << interface->interfaceName() <<
494+ "- another interface with same name already plugged";
495+ return false;
496+ }
497+
498+ debug() << "Interface" << interface->interfaceName() << "plugged";
499+ mPriv->interfaces.insert(interface->interfaceName(), interface);
500+ return true;
501+}
502+
503+/**
504+ * Register this connection object on the bus.
505+ *
506+ * If \a error is passed, any D-Bus error that may occur will
507+ * be stored there.
508+ *
509+ * \param error A pointer to an empty DBusError where any
510+ * possible D-Bus error will be stored.
511+ * \return \c true on success and \c false if there was an error
512+ * or this connection object is already registered.
513+ * \sa isRegistered()
514+ */
515+bool BaseConnection::registerObject(DBusError *error)
516+{
517+ if (isRegistered()) {
518+ return true;
519+ }
520+
521+ if (!checkValidProtocolName(mPriv->protocolName)) {
522+ if (error) {
523+ error->set(TP_QT_ERROR_INVALID_ARGUMENT,
524+ mPriv->protocolName + QLatin1String("is not a valid protocol name"));
525+ }
526+ debug() << "Unable to register connection - invalid protocol name";
527+ return false;
528+ }
529+
530+ QString escapedProtocolName = mPriv->protocolName;
531+ escapedProtocolName.replace(QLatin1Char('-'), QLatin1Char('_'));
532+ QString name = uniqueName();
533+ debug() << "cmName: " << mPriv->cmName << " escapedProtocolName: " << escapedProtocolName << " name:" << name;
534+ QString busName = QString(QLatin1String("%1%2.%3.%4"))
535+ .arg(TP_QT_CONNECTION_BUS_NAME_BASE, mPriv->cmName, escapedProtocolName, name);
536+ QString objectPath = QString(QLatin1String("%1%2/%3/%4"))
537+ .arg(TP_QT_CONNECTION_OBJECT_PATH_BASE, mPriv->cmName, escapedProtocolName, name);
538+ debug() << "busName: " << busName << " objectName: " << objectPath;
539+ DBusError _error;
540+
541+ debug() << "Connection: registering interfaces at " << dbusObject();
542+ foreach(const AbstractConnectionInterfacePtr & iface, mPriv->interfaces) {
543+ if (!iface->registerInterface(dbusObject())) {
544+ // lets not fail if an optional interface fails registering, lets warn only
545+ warning() << "Unable to register interface" << iface->interfaceName();
546+ }
547+ }
548+
549+ bool ret = registerObject(busName, objectPath, &_error);
550+ if (!ret && error) {
551+ error->set(_error.name(), _error.message());
552+ }
553+ return ret;
554+}
555+
556+/**
557+ * Reimplemented from DBusService.
558+ */
559+bool BaseConnection::registerObject(const QString &busName,
560+ const QString &objectPath, DBusError *error)
561+{
562+ return DBusService::registerObject(busName, objectPath, error);
563+}
564+
565+void BaseConnection::setSelfHandle(uint selfHandle)
566+{
567+ mPriv->selfHandle = selfHandle;
568+}
569+
570+uint BaseConnection::selfHandle() const
571+{
572+ return mPriv->selfHandle;
573+}
574+
575+void BaseConnection::setConnectCallback(const ConnectCallback &cb)
576+{
577+ mPriv->connectCB = cb;
578+}
579+
580+void BaseConnection::setInspectHandlesCallback(const InspectHandlesCallback &cb)
581+{
582+ mPriv->inspectHandlesCB = cb;
583+}
584+
585+/**
586+ * \fn void BaseConnection::disconnected()
587+ *
588+ * Emitted when this connection has been disconnected.
589+ */
590+
591+/**
592+ * \class AbstractConnectionInterface
593+ * \ingroup servicecm
594+ * \headerfile TelepathyQt/base-connection.h <TelepathyQt/BaseConnection>
595+ *
596+ * \brief Base class for all the Connection object interface implementations.
597+ */
598+
599+AbstractConnectionInterface::AbstractConnectionInterface(const QString &interfaceName)
600+ : AbstractDBusServiceInterface(interfaceName)
601+{
602+}
603+
604+AbstractConnectionInterface::~AbstractConnectionInterface()
605+{
606+}
607+
608+// Conn.I.Requests
609+BaseConnectionRequestsInterface::Adaptee::Adaptee(BaseConnectionRequestsInterface *interface)
610+ : QObject(interface),
611+ mInterface(interface)
612+{
613+}
614+
615+BaseConnectionRequestsInterface::Adaptee::~Adaptee()
616+{
617+}
618+
619+void BaseConnectionRequestsInterface::Adaptee::ensureChannel(const QVariantMap &request,
620+ const Tp::Service::ConnectionInterfaceRequestsAdaptor::EnsureChannelContextPtr &context)
621+{
622+ DBusError error;
623+ bool yours;
624+ QDBusObjectPath channel;
625+ QVariantMap details;
626+
627+ mInterface->ensureChannel(request, yours, channel, details, &error);
628+ if (error.isValid()) {
629+ context->setFinishedWithError(error.name(), error.message());
630+ return;
631+ }
632+ context->setFinished(yours, channel, details);
633+}
634+
635+void BaseConnectionRequestsInterface::Adaptee::createChannel(const QVariantMap &request,
636+ const Tp::Service::ConnectionInterfaceRequestsAdaptor::CreateChannelContextPtr &context)
637+{
638+ DBusError error;
639+ QDBusObjectPath channel;
640+ QVariantMap details;
641+
642+ mInterface->createChannel(request, channel, details, &error);
643+ if (error.isValid()) {
644+ context->setFinishedWithError(error.name(), error.message());
645+ return;
646+ }
647+ context->setFinished(channel, details);
648+}
649+
650+struct TP_QT_NO_EXPORT BaseConnectionRequestsInterface::Private {
651+ Private(BaseConnectionRequestsInterface *parent, BaseConnection *connection_)
652+ : connection(connection_), adaptee(new BaseConnectionRequestsInterface::Adaptee(parent)) {
653+ }
654+ BaseConnection *connection;
655+ BaseConnectionRequestsInterface::Adaptee *adaptee;
656+};
657+
658+/**
659+ * \class BaseConnectionRequestsInterface
660+ * \ingroup servicecm
661+ * \headerfile TelepathyQt/base-connection.h <TelepathyQt/BaseConnection>
662+ *
663+ * \brief Base class for implementations of Connection.Interface.Requests
664+ */
665+
666+/**
667+ * Class constructor.
668+ */
669+BaseConnectionRequestsInterface::BaseConnectionRequestsInterface(BaseConnection *connection)
670+ : AbstractConnectionInterface(TP_QT_IFACE_CONNECTION_INTERFACE_REQUESTS),
671+ mPriv(new Private(this, connection))
672+{
673+}
674+
675+/**
676+ * Class destructor.
677+ */
678+BaseConnectionRequestsInterface::~BaseConnectionRequestsInterface()
679+{
680+ delete mPriv;
681+}
682+
683+/**
684+ * Return the immutable properties of this interface.
685+ *
686+ * Immutable properties cannot change after the interface has been registered
687+ * on a service on the bus with registerInterface().
688+ *
689+ * \return The immutable properties of this interface.
690+ */
691+QVariantMap BaseConnectionRequestsInterface::immutableProperties() const
692+{
693+ QVariantMap map;
694+ map.insert(TP_QT_IFACE_CONNECTION_INTERFACE_REQUESTS + QLatin1String(".RequestableChannelClasses"),
695+ QVariant::fromValue(mPriv->adaptee->requestableChannelClasses()));
696+ return map;
697+}
698+
699+void BaseConnectionRequestsInterface::createAdaptor()
700+{
701+ (void) new Service::ConnectionInterfaceRequestsAdaptor(dbusObject()->dbusConnection(),
702+ mPriv->adaptee, dbusObject());
703+}
704+
705+Tp::ChannelDetailsList BaseConnectionRequestsInterface::Adaptee::channels() const
706+{
707+ return mInterface->mPriv->connection->channelsDetails();
708+}
709+
710+void BaseConnectionRequestsInterface::newChannels(const Tp::ChannelDetailsList &channels)
711+{
712+ mPriv->adaptee->newChannels(channels);
713+}
714+
715+void BaseConnectionRequestsInterface::ensureChannel(const QVariantMap &request, bool &yours,
716+ QDBusObjectPath &objectPath, QVariantMap &details, DBusError *error)
717+{
718+ if (!request.contains(TP_QT_IFACE_CHANNEL + QLatin1String(".ChannelType"))
719+ || !request.contains(TP_QT_IFACE_CHANNEL + QLatin1String(".TargetHandleType"))
720+ || (!request.contains(TP_QT_IFACE_CHANNEL + QLatin1String(".TargetHandle"))
721+ && !request.contains(TP_QT_IFACE_CHANNEL + QLatin1String(".TargetID")))) {
722+ error->set(TP_QT_ERROR_INVALID_ARGUMENT, QLatin1String("Missing parameters"));
723+ return;
724+ }
725+
726+ QString channelType = request[TP_QT_IFACE_CHANNEL + QLatin1String(".ChannelType")].toString();
727+ uint targetHandleType = request[TP_QT_IFACE_CHANNEL + QLatin1String(".TargetHandleType")].toUInt();
728+ uint targetHandle = request[TP_QT_IFACE_CHANNEL + QLatin1String(".TargetHandle")].toUInt();
729+
730+ bool suppressHandler = true;
731+ BaseChannelPtr channel = mPriv->connection->ensureChannel(channelType, targetHandleType,
732+ targetHandle, yours,
733+ mPriv->connection->selfHandle(),
734+ suppressHandler,
735+ request,
736+ error);
737+ if (error->isValid())
738+ return;
739+
740+ objectPath = QDBusObjectPath(channel->objectPath());
741+ details = channel->details().properties;
742+}
743+
744+void BaseConnectionRequestsInterface::createChannel(const QVariantMap &request,
745+ QDBusObjectPath &objectPath,
746+ QVariantMap &details, DBusError *error)
747+{
748+ if (!request.contains(TP_QT_IFACE_CHANNEL + QLatin1String(".ChannelType"))) {
749+ error->set(TP_QT_ERROR_INVALID_ARGUMENT, QLatin1String("Missing parameters"));
750+ return;
751+ }
752+
753+ QString channelType = request[TP_QT_IFACE_CHANNEL + QLatin1String(".ChannelType")].toString();
754+ uint targetHandleType = request[TP_QT_IFACE_CHANNEL + QLatin1String(".TargetHandleType")].toUInt();
755+ uint targetHandle = request[TP_QT_IFACE_CHANNEL + QLatin1String(".TargetHandle")].toUInt();
756+
757+ bool suppressHandler = true;
758+ BaseChannelPtr channel = mPriv->connection->createChannel(channelType, targetHandleType,
759+ targetHandle,
760+ mPriv->connection->selfHandle(),
761+ suppressHandler,
762+ request,
763+ error);
764+ if (error->isValid())
765+ return;
766+
767+ objectPath = QDBusObjectPath(channel->objectPath());
768+ details = channel->details().properties;
769+}
770+
771+
772+// Conn.I.Contacts
773+BaseConnectionContactsInterface::Adaptee::Adaptee(BaseConnectionContactsInterface *interface)
774+ : QObject(interface),
775+ mInterface(interface)
776+{
777+}
778+
779+BaseConnectionContactsInterface::Adaptee::~Adaptee()
780+{
781+}
782+
783+void BaseConnectionContactsInterface::Adaptee::getContactAttributes(const Tp::UIntList &handles,
784+ const QStringList &interfaces, bool /*hold*/,
785+ const Tp::Service::ConnectionInterfaceContactsAdaptor::GetContactAttributesContextPtr &context)
786+{
787+ DBusError error;
788+ ContactAttributesMap contactAttributes = mInterface->getContactAttributes(handles, interfaces, &error);
789+ if (error.isValid()) {
790+ context->setFinishedWithError(error.name(), error.message());
791+ return;
792+ }
793+ context->setFinished(contactAttributes);
794+}
795+
796+struct TP_QT_NO_EXPORT BaseConnectionContactsInterface::Private {
797+ Private(BaseConnectionContactsInterface *parent)
798+ : adaptee(new BaseConnectionContactsInterface::Adaptee(parent)) {
799+ }
800+ QStringList contactAttributeInterfaces;
801+ GetContactAttributesCallback getContactAttributesCallback;
802+ BaseConnectionContactsInterface::Adaptee *adaptee;
803+};
804+
805+QStringList BaseConnectionContactsInterface::Adaptee::contactAttributeInterfaces() const
806+{
807+ return mInterface->mPriv->contactAttributeInterfaces;
808+}
809+
810+/**
811+ * \class BaseConnectionContactsInterface
812+ * \ingroup servicecm
813+ * \headerfile TelepathyQt/base-connection.h <TelepathyQt/BaseConnection>
814+ *
815+ * \brief Base class for implementations of Connection.Interface.Contacts
816+ */
817+
818+/**
819+ * Class constructor.
820+ */
821+BaseConnectionContactsInterface::BaseConnectionContactsInterface()
822+ : AbstractConnectionInterface(TP_QT_IFACE_CONNECTION_INTERFACE_CONTACTS),
823+ mPriv(new Private(this))
824+{
825+}
826+
827+/**
828+ * Class destructor.
829+ */
830+BaseConnectionContactsInterface::~BaseConnectionContactsInterface()
831+{
832+ delete mPriv;
833+}
834+
835+/**
836+ * Return the immutable properties of this<interface.
837+ *
838+ * Immutable properties cannot change after the interface has been registered
839+ * on a service on the bus with registerInterface().
840+ *
841+ * \return The immutable properties of this interface.
842+ */
843+QVariantMap BaseConnectionContactsInterface::immutableProperties() const
844+{
845+ QVariantMap map;
846+ map.insert(TP_QT_IFACE_CONNECTION_INTERFACE_CONTACTS + QLatin1String(".ContactAttributeInterfaces"),
847+ QVariant::fromValue(mPriv->adaptee->contactAttributeInterfaces()));
848+ return map;
849+}
850+
851+void BaseConnectionContactsInterface::createAdaptor()
852+{
853+ (void) new Service::ConnectionInterfaceContactsAdaptor(dbusObject()->dbusConnection(),
854+ mPriv->adaptee, dbusObject());
855+}
856+
857+void BaseConnectionContactsInterface::setContactAttributeInterfaces(const QStringList &contactAttributeInterfaces)
858+{
859+ mPriv->contactAttributeInterfaces = contactAttributeInterfaces;
860+}
861+
862+void BaseConnectionContactsInterface::setGetContactAttributesCallback(const GetContactAttributesCallback &cb)
863+{
864+ mPriv->getContactAttributesCallback = cb;
865+}
866+
867+ContactAttributesMap BaseConnectionContactsInterface::getContactAttributes(const Tp::UIntList &handles,
868+ const QStringList &interfaces,
869+ DBusError *error)
870+{
871+ if (!mPriv->getContactAttributesCallback.isValid()) {
872+ error->set(TP_QT_ERROR_NOT_IMPLEMENTED, QLatin1String("Not implemented"));
873+ return ContactAttributesMap();
874+ }
875+ return mPriv->getContactAttributesCallback(handles, interfaces, error);
876+}
877+
878+// Conn.I.SimplePresence
879+BaseConnectionSimplePresenceInterface::Adaptee::Adaptee(BaseConnectionSimplePresenceInterface *interface)
880+ : QObject(interface),
881+ mInterface(interface)
882+{
883+}
884+
885+BaseConnectionSimplePresenceInterface::Adaptee::~Adaptee()
886+{
887+}
888+
889+struct TP_QT_NO_EXPORT BaseConnectionSimplePresenceInterface::Private {
890+ Private(BaseConnectionSimplePresenceInterface *parent)
891+ : maxmimumStatusMessageLength(0),
892+ adaptee(new BaseConnectionSimplePresenceInterface::Adaptee(parent)) {
893+ }
894+ SetPresenceCallback setPresenceCB;
895+ SimpleStatusSpecMap statuses;
896+ uint maxmimumStatusMessageLength;
897+ /* The current presences */
898+ SimpleContactPresences presences;
899+ BaseConnectionSimplePresenceInterface::Adaptee *adaptee;
900+};
901+
902+/**
903+ * \class BaseConnectionSimplePresenceInterface
904+ * \ingroup servicecm
905+ * \headerfile TelepathyQt/base-connection.h <TelepathyQt/BaseConnection>
906+ *
907+ * \brief Base class for implementations of Connection.Interface.SimplePresence
908+ */
909+
910+/**
911+ * Class constructor.
912+ */
913+BaseConnectionSimplePresenceInterface::BaseConnectionSimplePresenceInterface()
914+ : AbstractConnectionInterface(TP_QT_IFACE_CONNECTION_INTERFACE_SIMPLE_PRESENCE),
915+ mPriv(new Private(this))
916+{
917+}
918+
919+/**
920+ * Class destructor.
921+ */
922+BaseConnectionSimplePresenceInterface::~BaseConnectionSimplePresenceInterface()
923+{
924+ delete mPriv;
925+}
926+
927+/**
928+ * Return the immutable properties of this<interface.
929+ *
930+ * Immutable properties cannot change after the interface has been registered
931+ * on a service on the bus with registerInterface().
932+ *
933+ * \return The immutable properties of this interface.
934+ */
935+QVariantMap BaseConnectionSimplePresenceInterface::immutableProperties() const
936+{
937+ QVariantMap map;
938+ //FIXME
939+ return map;
940+}
941+
942+void BaseConnectionSimplePresenceInterface::createAdaptor()
943+{
944+ (void) new Service::ConnectionInterfaceSimplePresenceAdaptor(dbusObject()->dbusConnection(),
945+ mPriv->adaptee, dbusObject());
946+}
947+
948+
949+
950+void BaseConnectionSimplePresenceInterface::setPresences(const Tp::SimpleContactPresences &presences)
951+{
952+ foreach(uint handle, presences.keys()) {
953+ mPriv->presences[handle] = presences[handle];
954+ }
955+ emit mPriv->adaptee->presencesChanged(presences);
956+}
957+
958+void BaseConnectionSimplePresenceInterface::setSetPresenceCallback(const SetPresenceCallback &cb)
959+{
960+ mPriv->setPresenceCB = cb;
961+}
962+
963+void BaseConnectionSimplePresenceInterface::setStatuses(const SimpleStatusSpecMap &statuses)
964+{
965+ mPriv->statuses = statuses;
966+}
967+
968+void BaseConnectionSimplePresenceInterface::setMaxmimumStatusMessageLength(uint maxmimumStatusMessageLength)
969+{
970+ mPriv->maxmimumStatusMessageLength = maxmimumStatusMessageLength;
971+}
972+
973+
974+Tp::SimpleStatusSpecMap BaseConnectionSimplePresenceInterface::Adaptee::statuses() const
975+{
976+ return mInterface->mPriv->statuses;
977+}
978+
979+int BaseConnectionSimplePresenceInterface::Adaptee::maximumStatusMessageLength() const
980+{
981+ return mInterface->mPriv->maxmimumStatusMessageLength;
982+}
983+
984+void BaseConnectionSimplePresenceInterface::Adaptee::setPresence(const QString &status, const QString &statusMessage_,
985+ const Tp::Service::ConnectionInterfaceSimplePresenceAdaptor::SetPresenceContextPtr &context)
986+{
987+ if (!mInterface->mPriv->setPresenceCB.isValid()) {
988+ context->setFinishedWithError(TP_QT_ERROR_NOT_IMPLEMENTED, QLatin1String("Not implemented"));
989+ return;
990+ }
991+
992+ SimpleStatusSpecMap::Iterator i = mInterface->mPriv->statuses.find(status);
993+ if (i == mInterface->mPriv->statuses.end()) {
994+ warning() << "BaseConnectionSimplePresenceInterface::Adaptee::setPresence: status is not in statuses";
995+ context->setFinishedWithError(TP_QT_ERROR_INVALID_ARGUMENT, QLatin1String("status not in statuses"));
996+ return;
997+ }
998+
999+ QString statusMessage = statusMessage_;
1000+ if ((uint)statusMessage.length() > mInterface->mPriv->maxmimumStatusMessageLength) {
1001+ debug() << "BaseConnectionSimplePresenceInterface::Adaptee::setPresence: "
1002+ << "truncating status to " << mInterface->mPriv->maxmimumStatusMessageLength;
1003+ statusMessage = statusMessage.left(mInterface->mPriv->maxmimumStatusMessageLength);
1004+ }
1005+
1006+ DBusError error;
1007+ uint selfHandle = mInterface->mPriv->setPresenceCB(status, statusMessage, &error);
1008+ if (error.isValid()) {
1009+ context->setFinishedWithError(error.name(), error.message());
1010+ return;
1011+ }
1012+ Tp::SimplePresence presence;
1013+ presence.type = i->type;
1014+ presence.status = status;
1015+ presence.statusMessage = statusMessage;
1016+ mInterface->mPriv->presences[selfHandle] = presence;
1017+
1018+ /* Emit PresencesChanged */
1019+ SimpleContactPresences presences;
1020+ presences[selfHandle] = presence;
1021+ //emit after return
1022+ QMetaObject::invokeMethod(mInterface->mPriv->adaptee, "presencesChanged",
1023+ Qt::QueuedConnection,
1024+ Q_ARG(Tp::SimpleContactPresences, presences));
1025+ context->setFinished();
1026+}
1027+
1028+void BaseConnectionSimplePresenceInterface::Adaptee::getPresences(const Tp::UIntList &contacts,
1029+ const Tp::Service::ConnectionInterfaceSimplePresenceAdaptor::GetPresencesContextPtr &context)
1030+{
1031+ Tp::SimpleContactPresences presences;
1032+ foreach(uint handle, contacts) {
1033+ SimpleContactPresences::iterator i = mInterface->mPriv->presences.find(handle);
1034+ if (i == mInterface->mPriv->presences.end()) {
1035+ Tp::SimplePresence presence;
1036+ presence.type = ConnectionPresenceTypeUnknown;
1037+ presence.status = QLatin1String("unknown");
1038+ presences[handle] = presence;
1039+ } else
1040+ presences[handle] = *i;
1041+ }
1042+ context->setFinished(presences);
1043+}
1044+
1045+// Conn.I.ContactList
1046+BaseConnectionContactListInterface::Adaptee::Adaptee(BaseConnectionContactListInterface *interface)
1047+ : QObject(interface),
1048+ mInterface(interface)
1049+{
1050+}
1051+
1052+BaseConnectionContactListInterface::Adaptee::~Adaptee()
1053+{
1054+}
1055+
1056+struct TP_QT_NO_EXPORT BaseConnectionContactListInterface::Private {
1057+ Private(BaseConnectionContactListInterface *parent)
1058+ : contactListState(ContactListStateNone),
1059+ contactListPersists(false),
1060+ canChangeContactList(true),
1061+ requestUsesMessage(false),
1062+ downloadAtConnection(false),
1063+ adaptee(new BaseConnectionContactListInterface::Adaptee(parent)) {
1064+ }
1065+ uint contactListState;
1066+ bool contactListPersists;
1067+ bool canChangeContactList;
1068+ bool requestUsesMessage;
1069+ bool downloadAtConnection;
1070+ GetContactListAttributesCallback getContactListAttributesCB;
1071+ RequestSubscriptionCallback requestSubscriptionCB;
1072+ BaseConnectionContactListInterface::Adaptee *adaptee;
1073+};
1074+
1075+/**
1076+ * \class BaseConnectionContactListInterface
1077+ * \ingroup servicecm
1078+ * \headerfile TelepathyQt/base-connection.h <TelepathyQt/BaseConnection>
1079+ *
1080+ * \brief Base class for implementations of Connection.Interface.ContactList
1081+ */
1082+
1083+/**
1084+ * Class constructor.
1085+ */
1086+BaseConnectionContactListInterface::BaseConnectionContactListInterface()
1087+ : AbstractConnectionInterface(TP_QT_IFACE_CONNECTION_INTERFACE_CONTACT_LIST),
1088+ mPriv(new Private(this))
1089+{
1090+}
1091+
1092+/**
1093+ * Class destructor.
1094+ */
1095+BaseConnectionContactListInterface::~BaseConnectionContactListInterface()
1096+{
1097+ delete mPriv;
1098+}
1099+
1100+/**
1101+ * Return the immutable properties of this<interface.
1102+ *
1103+ * Immutable properties cannot change after the interface has been registered
1104+ * on a service on the bus with registerInterface().
1105+ *
1106+ * \return The immutable properties of this interface.
1107+ */
1108+QVariantMap BaseConnectionContactListInterface::immutableProperties() const
1109+{
1110+ QVariantMap map;
1111+ return map;
1112+}
1113+
1114+void BaseConnectionContactListInterface::createAdaptor()
1115+{
1116+ (void) new Service::ConnectionInterfaceContactListAdaptor(dbusObject()->dbusConnection(),
1117+ mPriv->adaptee, dbusObject());
1118+}
1119+
1120+void BaseConnectionContactListInterface::setContactListState(uint contactListState)
1121+{
1122+ bool changed = (contactListState != mPriv->contactListState);
1123+ mPriv->contactListState = contactListState;
1124+ if (changed)
1125+ //emit after return
1126+ QMetaObject::invokeMethod(mPriv->adaptee, "contactListStateChanged",
1127+ Qt::QueuedConnection,
1128+ Q_ARG(uint, contactListState));
1129+
1130+}
1131+
1132+void BaseConnectionContactListInterface::setContactListPersists(bool contactListPersists)
1133+{
1134+ mPriv->contactListPersists = contactListPersists;
1135+}
1136+
1137+void BaseConnectionContactListInterface::setCanChangeContactList(bool canChangeContactList)
1138+{
1139+ mPriv->canChangeContactList = canChangeContactList;
1140+}
1141+
1142+void BaseConnectionContactListInterface::setRequestUsesMessage(bool requestUsesMessage)
1143+{
1144+ mPriv->requestUsesMessage = requestUsesMessage;
1145+}
1146+
1147+void BaseConnectionContactListInterface::setDownloadAtConnection(bool downloadAtConnection)
1148+{
1149+ mPriv->downloadAtConnection = downloadAtConnection;
1150+}
1151+
1152+void BaseConnectionContactListInterface::setGetContactListAttributesCallback(const GetContactListAttributesCallback &cb)
1153+{
1154+ mPriv->getContactListAttributesCB = cb;
1155+}
1156+
1157+void BaseConnectionContactListInterface::setRequestSubscriptionCallback(const RequestSubscriptionCallback &cb)
1158+{
1159+ mPriv->requestSubscriptionCB = cb;
1160+}
1161+
1162+void BaseConnectionContactListInterface::contactsChangedWithID(const Tp::ContactSubscriptionMap &changes, const Tp::HandleIdentifierMap &identifiers, const Tp::HandleIdentifierMap &removals)
1163+{
1164+ emit mPriv->adaptee->contactsChangedWithID(changes, identifiers, removals);
1165+}
1166+
1167+uint BaseConnectionContactListInterface::Adaptee::contactListState() const
1168+{
1169+ return mInterface->mPriv->contactListState;
1170+}
1171+
1172+bool BaseConnectionContactListInterface::Adaptee::contactListPersists() const
1173+{
1174+ return mInterface->mPriv->contactListPersists;
1175+}
1176+
1177+bool BaseConnectionContactListInterface::Adaptee::canChangeContactList() const
1178+{
1179+ return mInterface->mPriv->canChangeContactList;
1180+}
1181+
1182+bool BaseConnectionContactListInterface::Adaptee::requestUsesMessage() const
1183+{
1184+ return mInterface->mPriv->requestUsesMessage;
1185+}
1186+
1187+bool BaseConnectionContactListInterface::Adaptee::downloadAtConnection() const
1188+{
1189+ return mInterface->mPriv->downloadAtConnection;
1190+}
1191+
1192+void BaseConnectionContactListInterface::Adaptee::getContactListAttributes(const QStringList &interfaces,
1193+ bool hold, const Tp::Service::ConnectionInterfaceContactListAdaptor::GetContactListAttributesContextPtr &context)
1194+{
1195+ if (!mInterface->mPriv->getContactListAttributesCB.isValid()) {
1196+ context->setFinishedWithError(TP_QT_ERROR_NOT_IMPLEMENTED, QLatin1String("Not implemented"));
1197+ return;
1198+ }
1199+ DBusError error;
1200+ Tp::ContactAttributesMap contactAttributesMap = mInterface->mPriv->getContactListAttributesCB(interfaces, hold, &error);
1201+ if (error.isValid()) {
1202+ context->setFinishedWithError(error.name(), error.message());
1203+ return;
1204+ }
1205+ context->setFinished(contactAttributesMap);
1206+}
1207+
1208+void BaseConnectionContactListInterface::Adaptee::requestSubscription(const Tp::UIntList &contacts,
1209+ const QString &message, const Tp::Service::ConnectionInterfaceContactListAdaptor::RequestSubscriptionContextPtr &context)
1210+{
1211+ if (!mInterface->mPriv->requestSubscriptionCB.isValid()) {
1212+ context->setFinishedWithError(TP_QT_ERROR_NOT_IMPLEMENTED, QLatin1String("Not implemented"));
1213+ return;
1214+ }
1215+ DBusError error;
1216+ mInterface->mPriv->requestSubscriptionCB(contacts, message, &error);
1217+ if (error.isValid()) {
1218+ context->setFinishedWithError(error.name(), error.message());
1219+ return;
1220+ }
1221+ context->setFinished();
1222+}
1223+
1224+// Conn.I.Addressing
1225+BaseConnectionAddressingInterface::Adaptee::Adaptee(BaseConnectionAddressingInterface *interface)
1226+ : QObject(interface),
1227+ mInterface(interface)
1228+{
1229+}
1230+
1231+BaseConnectionAddressingInterface::Adaptee::~Adaptee()
1232+{
1233+}
1234+
1235+struct TP_QT_NO_EXPORT BaseConnectionAddressingInterface::Private {
1236+ Private(BaseConnectionAddressingInterface *parent)
1237+ : adaptee(new BaseConnectionAddressingInterface::Adaptee(parent)) {
1238+ }
1239+ GetContactsByVCardFieldCallback getContactsByVCardFieldCB;
1240+ GetContactsByURICallback getContactsByURICB;
1241+ BaseConnectionAddressingInterface::Adaptee *adaptee;
1242+};
1243+
1244+/**
1245+ * \class BaseProtocolPresenceInterface
1246+ * \ingroup servicecm
1247+ * \headerfile TelepathyQt/base-protocol.h <TelepathyQt/BaseProtocolPresenceInterface>
1248+ *
1249+ * \brief Base class for implementations of Protocol.Interface.Presence
1250+ */
1251+
1252+/**
1253+ * Class constructor.
1254+ */
1255+BaseConnectionAddressingInterface::BaseConnectionAddressingInterface()
1256+ : AbstractConnectionInterface(TP_QT_IFACE_CONNECTION_INTERFACE_ADDRESSING),
1257+ mPriv(new Private(this))
1258+{
1259+}
1260+
1261+/**
1262+ * Class destructor.
1263+ */
1264+BaseConnectionAddressingInterface::~BaseConnectionAddressingInterface()
1265+{
1266+ delete mPriv;
1267+}
1268+
1269+/**
1270+ * Return the immutable properties of this<interface.
1271+ *
1272+ * Immutable properties cannot change after the interface has been registered
1273+ * on a service on the bus with registerInterface().
1274+ *
1275+ * \return The immutable properties of this interface.
1276+ */
1277+QVariantMap BaseConnectionAddressingInterface::immutableProperties() const
1278+{
1279+ QVariantMap map;
1280+ return map;
1281+}
1282+
1283+void BaseConnectionAddressingInterface::createAdaptor()
1284+{
1285+ (void) new Service::ConnectionInterfaceAddressingAdaptor(dbusObject()->dbusConnection(),
1286+ mPriv->adaptee, dbusObject());
1287+}
1288+
1289+void BaseConnectionAddressingInterface::setGetContactsByVCardFieldCallback(const GetContactsByVCardFieldCallback &cb)
1290+{
1291+ mPriv->getContactsByVCardFieldCB = cb;
1292+}
1293+
1294+void BaseConnectionAddressingInterface::setGetContactsByURICallback(const GetContactsByURICallback &cb)
1295+{
1296+ mPriv->getContactsByURICB = cb;
1297+}
1298+
1299+void BaseConnectionAddressingInterface::Adaptee::getContactsByVCardField(const QString &field,
1300+ const QStringList &addresses,
1301+ const QStringList &interfaces,
1302+ const Tp::Service::ConnectionInterfaceAddressingAdaptor::GetContactsByVCardFieldContextPtr &context)
1303+{
1304+ if (!mInterface->mPriv->getContactsByVCardFieldCB.isValid()) {
1305+ context->setFinishedWithError(TP_QT_ERROR_NOT_IMPLEMENTED, QLatin1String("Not implemented"));
1306+ return;
1307+ }
1308+ Tp::AddressingNormalizationMap addressingNormalizationMap;
1309+ Tp::ContactAttributesMap contactAttributesMap;
1310+
1311+ DBusError error;
1312+ mInterface->mPriv->getContactsByVCardFieldCB(field, addresses, interfaces,
1313+ addressingNormalizationMap, contactAttributesMap,
1314+ &error);
1315+ if (error.isValid()) {
1316+ context->setFinishedWithError(error.name(), error.message());
1317+ return;
1318+ }
1319+ context->setFinished(addressingNormalizationMap, contactAttributesMap);
1320+}
1321+
1322+void BaseConnectionAddressingInterface::Adaptee::getContactsByURI(const QStringList &URIs,
1323+ const QStringList &interfaces,
1324+ const Tp::Service::ConnectionInterfaceAddressingAdaptor::GetContactsByURIContextPtr &context)
1325+{
1326+ if (!mInterface->mPriv->getContactsByURICB.isValid()) {
1327+ context->setFinishedWithError(TP_QT_ERROR_NOT_IMPLEMENTED, QLatin1String("Not implemented"));
1328+ return;
1329+ }
1330+ Tp::AddressingNormalizationMap addressingNormalizationMap;
1331+ Tp::ContactAttributesMap contactAttributesMap;
1332+
1333+ DBusError error;
1334+ mInterface->mPriv->getContactsByURICB(URIs, interfaces,
1335+ addressingNormalizationMap, contactAttributesMap,
1336+ &error);
1337+ if (error.isValid()) {
1338+ context->setFinishedWithError(error.name(), error.message());
1339+ return;
1340+ }
1341+ context->setFinished(addressingNormalizationMap, contactAttributesMap);
1342+}
1343+
1344+}
1345
1346=== modified file '.pc/applied-patches'
1347--- .pc/applied-patches 2014-04-03 16:51:40 +0000
1348+++ .pc/applied-patches 2014-12-02 17:21:36 +0000
1349@@ -7,3 +7,4 @@
1350 07-fix_createChannel.patch
1351 08-add_conference_call_client_side.patch
1352 09-add_sms_iface_service_side.patch
1353+10-emit_selfHandleChanged.patch
1354
1355=== modified file 'TelepathyQt/base-connection.cpp'
1356--- TelepathyQt/base-connection.cpp 2014-03-12 11:47:23 +0000
1357+++ TelepathyQt/base-connection.cpp 2014-12-02 17:21:36 +0000
1358@@ -557,7 +557,10 @@
1359
1360 void BaseConnection::setSelfHandle(uint selfHandle)
1361 {
1362+ bool changed = (selfHandle != mPriv->selfHandle);
1363 mPriv->selfHandle = selfHandle;
1364+ if (changed)
1365+ emit mPriv->adaptee->selfHandleChanged(mPriv->selfHandle);
1366 }
1367
1368 uint BaseConnection::selfHandle() const
1369
1370=== modified file 'debian/libtelepathy-qt5-0.symbols'
1371--- debian/libtelepathy-qt5-0.symbols 2014-03-12 17:22:17 +0000
1372+++ debian/libtelepathy-qt5-0.symbols 2014-12-02 17:21:36 +0000
1373@@ -777,8 +777,6 @@
1374 _ZN2Tp17ConnectionManagerD0Ev@Base 0.9.3
1375 _ZN2Tp17ConnectionManagerD1Ev@Base 0.9.3
1376 _ZN2Tp17ConnectionManagerD2Ev@Base 0.9.3
1377- _ZN2Tp17NotDelegatedErrorD1Ev@Base 0.9.3
1378- _ZN2Tp17NotDelegatedErrorD2Ev@Base 0.9.3
1379 _ZN2Tp17PendingConnection11qt_metacallEN11QMetaObject4CallEiPPv@Base 0.9.3
1380 _ZN2Tp17PendingConnection11qt_metacastEPKc@Base 0.9.3
1381 _ZN2Tp17PendingConnection16staticMetaObjectE@Base 0.9.3
1382@@ -1343,8 +1341,6 @@
1383 _ZN2Tp5Debug19invokeDebugCallbackEv@Base 0.9.3
1384 (optional=templinst)_ZN2Tp5DebuglsINS_7FeatureEEERS0_T_@Base 0.9.3
1385 (optional=templinst)_ZN2Tp5DebuglsINS_8FeaturesEEERS0_T_@Base 0.9.3
1386- (optional=templinst)_ZN2Tp5DebuglsIPKNS_7ContactEEERS0_T_@Base 0.9.3
1387- (optional=templinst|arch=!arm64 !armhf !powerpc !ppc64el)_ZN2Tp5DebuglsIPNS_7ContactEEERS0_T_@Base 0.9.3
1388 _ZN2Tp6AvatarD1Ev@Base 0.9.3
1389 _ZN2Tp6AvatarD2Ev@Base 0.9.3
1390 _ZN2Tp6Client14DebugInterface10invalidateEPNS_9DBusProxyERK7QStringS6_@Base 0.9.3
1391@@ -3055,6 +3051,8 @@
1392 _ZN2Tp7Account19FeatureProtocolInfoE@Base 0.9.3
1393 _ZN2Tp7Account19capabilitiesChangedERKNS_22ConnectionCapabilitiesE@Base 0.9.3
1394 _ZN2Tp7Account19createContactSearchERK7QStringjRK9QDateTimeS3_RKNS_19ChannelRequestHintsE@Base 0.9.3
1395+ _ZN2Tp7Account20createConferenceCallERK5QListINS_9SharedPtrINS_7ChannelEEEERK11QStringListRK9QDateTimeRK7QStringRKNS_19ChannelRequestHintsE@Base 0.9.3
1396+ _ZN2Tp7Account20createConferenceCallERK5QListINS_9SharedPtrINS_7ChannelEEEERKS1_INS2_INS_7ContactEEEERK9QDateTimeRK7QStringRKNS_19ChannelRequestHintsE@Base 0.9.3
1397 _ZN2Tp7Account20ensureAudioVideoCallERK7QStringS3_S3_RK9QDateTimeS3_RKNS_19ChannelRequestHintsE@Base 0.9.3
1398 _ZN2Tp7Account20ensureAudioVideoCallERKNS_9SharedPtrINS_7ContactEEERK7QStringS8_RK9QDateTimeS8_RKNS_19ChannelRequestHintsE@Base 0.9.3
1399 _ZN2Tp7Account20setAutomaticPresenceERKNS_8PresenceE@Base 0.9.3
1400@@ -3091,6 +3089,8 @@
1401 _ZN2Tp7Account28ensureStreamedMediaAudioCallERKNS_9SharedPtrINS_7ContactEEERK9QDateTimeRK7QStringRKNS_19ChannelRequestHintsE@Base 0.9.3
1402 _ZN2Tp7Account28ensureStreamedMediaVideoCallERK7QStringbRK9QDateTimeS3_RKNS_19ChannelRequestHintsE@Base 0.9.3
1403 _ZN2Tp7Account28ensureStreamedMediaVideoCallERKNS_9SharedPtrINS_7ContactEEEbRK9QDateTimeRK7QStringRKNS_19ChannelRequestHintsE@Base 0.9.3
1404+ _ZN2Tp7Account29createAndHandleConferenceCallERK5QListINS_9SharedPtrINS_7ChannelEEEERK11QStringListRK9QDateTime@Base 0.9.3
1405+ _ZN2Tp7Account29createAndHandleConferenceCallERK5QListINS_9SharedPtrINS_7ChannelEEEERKS1_INS2_INS_7ContactEEEERK9QDateTime@Base 0.9.3
1406 _ZN2Tp7Account29ensureAndHandleAudioVideoCallERK7QStringS3_S3_RK9QDateTime@Base 0.9.3
1407 _ZN2Tp7Account29ensureAndHandleAudioVideoCallERKNS_9SharedPtrINS_7ContactEEERK7QStringS8_RK9QDateTime@Base 0.9.3
1408 _ZN2Tp7Account32ensureAndHandleStreamedMediaCallERK7QStringRK9QDateTime@Base 0.9.3
1409
1410=== added file 'debian/patches/10-emit_selfHandleChanged.patch'
1411--- debian/patches/10-emit_selfHandleChanged.patch 1970-01-01 00:00:00 +0000
1412+++ debian/patches/10-emit_selfHandleChanged.patch 2014-12-02 17:21:36 +0000
1413@@ -0,0 +1,20 @@
1414+Description: emit selfHandleChanged on setSelfHandle()
1415+Author: Tiago Salem Herrmann <tiago.herrmann@canonical.com>
1416+Forwarded: no
1417+
1418+diff:
1419+Index: telepathy-qt5-selfHandleChanged/TelepathyQt/base-connection.cpp
1420+===================================================================
1421+--- telepathy-qt5-selfHandleChanged.orig/TelepathyQt/base-connection.cpp
1422++++ telepathy-qt5-selfHandleChanged/TelepathyQt/base-connection.cpp
1423+@@ -557,7 +557,10 @@ bool BaseConnection::registerObject(cons
1424+
1425+ void BaseConnection::setSelfHandle(uint selfHandle)
1426+ {
1427++ bool changed = (selfHandle != mPriv->selfHandle);
1428+ mPriv->selfHandle = selfHandle;
1429++ if (changed)
1430++ emit mPriv->adaptee->selfHandleChanged(mPriv->selfHandle);
1431+ }
1432+
1433+ uint BaseConnection::selfHandle() const
1434
1435=== modified file 'debian/patches/series'
1436--- debian/patches/series 2014-04-03 16:51:40 +0000
1437+++ debian/patches/series 2014-12-02 17:21:36 +0000
1438@@ -7,3 +7,4 @@
1439 07-fix_createChannel.patch
1440 08-add_conference_call_client_side.patch
1441 09-add_sms_iface_service_side.patch
1442+10-emit_selfHandleChanged.patch

Subscribers

People subscribed via source and target branches