[Telepathy-commits] [telepathy-qt4/master] Connection: Added initial roster support (FeatureRoster).
Andre Moreira Magalhaes (andrunko)
andre.magalhaes at collabora.co.uk
Tue Feb 24 09:26:10 PST 2009
---
TelepathyQt4/Client/connection.cpp | 107 +++++++++++++++++++++++++++++++
TelepathyQt4/Client/connection.h | 4 +
TelepathyQt4/Client/contact-manager.cpp | 28 ++++++++
TelepathyQt4/Client/contact-manager.h | 43 ++++++++++++
4 files changed, 182 insertions(+), 0 deletions(-)
diff --git a/TelepathyQt4/Client/connection.cpp b/TelepathyQt4/Client/connection.cpp
index 098e9ab..ff39a7e 100644
--- a/TelepathyQt4/Client/connection.cpp
+++ b/TelepathyQt4/Client/connection.cpp
@@ -36,8 +36,10 @@
#include <TelepathyQt4/Client/PendingFailure>
#include <TelepathyQt4/Client/PendingHandles>
#include <TelepathyQt4/Client/PendingReady>
+#include <TelepathyQt4/Client/PendingReadyChannel>
#include <TelepathyQt4/Client/PendingVoidMethodCall>
#include <TelepathyQt4/Client/ReadinessHelper>
+#include <TelepathyQt4/Client/ReferencedHandles>
#include <QMap>
#include <QMetaObject>
@@ -85,6 +87,7 @@ struct Connection::Private
void introspectContacts();
static void introspectSelfContact(Private *self);
static void introspectSimplePresence(Private *self);
+ static void introspectRoster(Private *self);
struct HandleContext;
@@ -115,6 +118,8 @@ struct Connection::Private
QSharedPointer<Contact> selfContact;
QStringList contactAttributeInterfaces;
uint selfHandle;
+ QMap<uint, ContactManager::ContactListChannel> contactListsChannels;
+ uint contactListsChannelsReady;
// (Bus connection name, service name) -> HandleContext
static QMap<QPair<QString, QString>, HandleContext *> handleContexts;
@@ -162,6 +167,7 @@ Connection::Private::Private(Connection *parent)
status(Connection::StatusUnknown),
statusReason(ConnectionStatusReasonNoneSpecified),
selfHandle(0),
+ contactListsChannelsReady(0),
handleContext(0),
contactManager(new ContactManager(parent))
{
@@ -191,6 +197,14 @@ Connection::Private::Private(Connection *parent)
this);
introspectables[FeatureSimplePresence] = introspectableSimplePresence;
+ ReadinessHelper::Introspectable introspectableRoster(
+ QSet<uint>() << Connection::StatusConnected, // makesSenseForStatuses
+ QSet<uint>() << 0, // dependsOnFeatures (core)
+ QStringList() << TELEPATHY_INTERFACE_CONNECTION_INTERFACE_CONTACTS, // dependsOnInterfaces
+ (ReadinessHelper::IntrospectFunc) &Private::introspectRoster,
+ this);
+ introspectables[FeatureRoster] = introspectableRoster;
+
readinessHelper = new ReadinessHelper(parent, status,
introspectables, parent);
parent->connect(readinessHelper,
@@ -353,6 +367,26 @@ void Connection::Private::introspectSelfHandle()
SLOT(gotSelfHandle(QDBusPendingCallWatcher *)));
}
+void Connection::Private::introspectRoster(Connection::Private *self)
+{
+ debug() << "Requesting handles for contact lists";
+
+ QStringList ids;
+ for (uint i = 0; i < ContactManager::ContactListChannel::LastType; ++i) {
+ self->contactListsChannels.insert(i,
+ ContactManager::ContactListChannel(
+ (ContactManager::ContactListChannel::Type) i));
+ ids << ContactManager::ContactListChannel::identifierForType(
+ (ContactManager::ContactListChannel::Type) i);
+ }
+
+ PendingHandles *pending = self->parent->requestHandles(
+ Telepathy::HandleTypeList, ids);
+ self->parent->connect(pending,
+ SIGNAL(finished(Telepathy::Client::PendingOperation*)),
+ SLOT(gotContactListsHandles(Telepathy::Client::PendingOperation*)));
+}
+
Connection::PendingConnect::PendingConnect(Connection *parent, const QSet<uint> &requestedFeatures)
: PendingOperation(parent),
requestedFeatures(requestedFeatures)
@@ -897,6 +931,79 @@ void Connection::gotSelfHandle(QDBusPendingCallWatcher *watcher)
watcher->deleteLater();
}
+void Connection::gotContactListsHandles(PendingOperation *op)
+{
+ if (op->isError()) {
+ // let's not fail, because the contact lists are not supported
+ mPriv->readinessHelper->setIntrospectCompleted(FeatureRoster, true);
+ return;
+ }
+
+ debug() << "Got handles for contact lists";
+ PendingHandles *pending = qobject_cast<PendingHandles*>(op);
+
+ debug() << "Requesting channels for contact lists";
+ QVariantMap request;
+ request.insert(QLatin1String(TELEPATHY_INTERFACE_CHANNEL ".ChannelType"),
+ TELEPATHY_INTERFACE_CHANNEL_TYPE_CONTACT_LIST);
+ request.insert(QLatin1String(TELEPATHY_INTERFACE_CHANNEL ".TargetHandleType"),
+ Telepathy::HandleTypeList);
+
+ ReferencedHandles handles = pending->handles();
+ uint handle;
+ for (int i = 0; i < ContactManager::ContactListChannel::LastType; ++i) {
+ handle = handles[i];
+
+ if (handle == 0) {
+ debug() << "Unable to request handle for contact list" <<
+ ContactManager::ContactListChannel::identifierForType(
+ (ContactManager::ContactListChannel::Type) i);
+ // let's not fail, because the contact lists are not supported
+ contactListChannelReady();
+ continue;
+ }
+
+ mPriv->contactListsChannels[i].handle = handle;
+ request[QLatin1String(TELEPATHY_INTERFACE_CHANNEL ".TargetHandle")] = handle;
+
+ connect(ensureChannel(request),
+ SIGNAL(finished(Telepathy::Client::PendingOperation*)),
+ SLOT(gotContactListChannel(Telepathy::Client::PendingOperation*)));
+ }
+}
+
+void Connection::gotContactListChannel(PendingOperation *op)
+{
+ if (op->isError()) {
+ contactListChannelReady();
+ return;
+ }
+
+ PendingChannel *pending = qobject_cast<PendingChannel*>(op);
+ QSharedPointer<Channel> channel = pending->channel();
+ uint handle = pending->handle();
+ Q_ASSERT(!channel.isNull());
+ Q_ASSERT(handle);
+ for (int i = 0; i < ContactManager::ContactListChannel::LastType; ++i) {
+ if (mPriv->contactListsChannels[i].handle == handle) {
+ Q_ASSERT(mPriv->contactListsChannels[i].channel.isNull());
+ mPriv->contactListsChannels[i].channel = channel;
+ connect(channel->becomeReady(),
+ SIGNAL(finished(Telepathy::Client::PendingOperation *)),
+ SLOT(contactListChannelReady()));
+ }
+ }
+}
+
+void Connection::contactListChannelReady()
+{
+ if (++mPriv->contactListsChannelsReady ==
+ ContactManager::ContactListChannel::LastType) {
+ mPriv->contactManager->setContactListChannels(mPriv->contactListsChannels);
+ mPriv->readinessHelper->setIntrospectCompleted(FeatureRoster, true);
+ }
+}
+
/**
* Get the ConnectionInterface for this Connection. This
* method is protected since the convenience methods provided by this
diff --git a/TelepathyQt4/Client/connection.h b/TelepathyQt4/Client/connection.h
index 38033bf..48dd5dd 100644
--- a/TelepathyQt4/Client/connection.h
+++ b/TelepathyQt4/Client/connection.h
@@ -66,6 +66,7 @@ public:
FeatureCore = 0,
FeatureSelfContact = 1,
FeatureSimplePresence = 2,
+ FeatureRoster = 4,
_Padding = 0xFFFFFFFF
};
Q_DECLARE_FLAGS(Features, Feature)
@@ -198,6 +199,9 @@ private Q_SLOTS:
void gotSimpleStatuses(QDBusPendingCallWatcher *watcher);
void gotSelfContact(Telepathy::Client::PendingOperation *);
void gotSelfHandle(QDBusPendingCallWatcher *watcher);
+ void gotContactListsHandles(Telepathy::Client::PendingOperation *);
+ void gotContactListChannel(Telepathy::Client::PendingOperation *);
+ void contactListChannelReady();
void doReleaseSweep(uint type);
diff --git a/TelepathyQt4/Client/contact-manager.cpp b/TelepathyQt4/Client/contact-manager.cpp
index 21b5d5f..ec20af4 100644
--- a/TelepathyQt4/Client/contact-manager.cpp
+++ b/TelepathyQt4/Client/contact-manager.cpp
@@ -74,6 +74,8 @@ struct ContactManager::Private
void ensureTracking(Contact::Feature feature);
QSet<Contact::Feature> supportedFeatures;
+
+ QMap<uint, ContactListChannel> contactListsChannels;
};
Connection *ContactManager::connection() const
@@ -140,6 +142,22 @@ QSet<Contact::Feature> ContactManager::supportedFeatures() const
return mPriv->supportedFeatures;
}
+PendingContacts *ContactManager::allKnownContacts(
+ const QSet<Contact::Feature> &features)
+{
+ QSet<QSharedPointer<Contact> > contacts;
+ foreach (const ContactListChannel &contactListChannel, mPriv->contactListsChannels) {
+ QSharedPointer<Channel> channel = contactListChannel.channel;
+ if (!channel) {
+ continue;
+ }
+ contacts.unite(channel->groupContacts().toSet());
+ contacts.unite(channel->groupLocalPendingContacts().toSet());
+ contacts.unite(channel->groupRemotePendingContacts().toSet());
+ }
+ return upgradeContacts(contacts.toList(), features);
+}
+
PendingContacts *ContactManager::contactsForHandles(const UIntList &handles,
const QSet<Contact::Feature> &features)
{
@@ -296,6 +314,16 @@ QSharedPointer<Contact> ContactManager::ensureContact(const ReferencedHandles &h
return contact;
}
+void ContactManager::setContactListChannels(
+ const QMap<uint, ContactListChannel> &contactListsChannels)
+{
+ Q_ASSERT(mPriv->contactListsChannels.isEmpty());
+ mPriv->contactListsChannels = contactListsChannels;
+
+ // TODO update contacts subscription, publish state
+ // connect to groupMembersChanged signal
+}
+
QSharedPointer<Contact> ContactManager::Private::lookupContactByHandle(uint handle)
{
QSharedPointer<Contact> contact;
diff --git a/TelepathyQt4/Client/contact-manager.h b/TelepathyQt4/Client/contact-manager.h
index 917136c..e800aa1 100644
--- a/TelepathyQt4/Client/contact-manager.h
+++ b/TelepathyQt4/Client/contact-manager.h
@@ -34,6 +34,7 @@
#include <TelepathyQt4/Types>
#include <TelepathyQt4/Client/Contact>
+#include <TelepathyQt4/Client/Channel>
namespace Telepathy
{
@@ -55,6 +56,9 @@ class ContactManager : public QObject
bool isSupported() const;
QSet<Contact::Feature> supportedFeatures() const;
+ PendingContacts *allKnownContacts(
+ const QSet<Contact::Feature> &features = QSet<Contact::Feature>());
+
PendingContacts *contactsForHandles(const UIntList &handles,
const QSet<Contact::Feature> &features = QSet<Contact::Feature>());
PendingContacts *contactsForHandles(const ReferencedHandles &handles,
@@ -72,12 +76,51 @@ class ContactManager : public QObject
void onPresencesChanged(const Telepathy::SimpleContactPresences &);
private:
+ struct ContactListChannel
+ {
+ enum Type {
+ TypeSubscribe = 0,
+ TypePublish,
+ TypeStored,
+ LastType
+ };
+
+ ContactListChannel()
+ : type((Type) -1), handle(0)
+ {
+ }
+
+ ContactListChannel(Type type, uint handle = 0)
+ : type(type), handle(handle)
+ {
+ }
+
+ ~ContactListChannel()
+ {
+ channel.clear();
+ }
+
+ static QString identifierForType(Type type)
+ {
+ static QString identifiers[LastType] = {
+ "subscribe", "publish", "stored"
+ };
+ return identifiers[type];
+ }
+
+ Type type;
+ uint handle;
+ QSharedPointer<Channel> channel;
+ };
+
ContactManager(Connection *parent);
~ContactManager();
QSharedPointer<Contact> ensureContact(const ReferencedHandles &handle,
const QSet<Contact::Feature> &features, const QVariantMap &attributes);
+ void setContactListChannels(const QMap<uint, ContactListChannel> &contactListsChannels);
+
struct Private;
friend struct Private;
friend class Connection;
--
1.5.6.5
More information about the telepathy-commits
mailing list