~ubuntu-branches/ubuntu/wily/telepathy-qt5/wily

« back to all changes in this revision

Viewing changes to .pc/10-emit_selfHandleChanged.patch/TelepathyQt/base-connection.cpp

  • Committer: Package Import Robot
  • Author(s): Ricardo Salveti de Araujo, Tiago Salem Herrmann
  • Date: 2015-01-28 12:16:15 UTC
  • Revision ID: package-import@ubuntu.com-20150128121615-kxv733dg71gmh33n
Tags: 0.9.3-0ubuntu14
[ Tiago Salem Herrmann ]
debian/patches/10-emit_selfHandleChanged.patch: emit selfHandleChanged on
setSelfHandle() (LP: #1415458)

Show diffs side-by-side

added added

removed removed

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