diff options
author | Andre Moreira Magalhaes (andrunko) <andre.magalhaes@collabora.co.uk> | 2011-10-03 12:22:31 -0300 |
---|---|---|
committer | Andre Moreira Magalhaes (andrunko) <andre.magalhaes@collabora.co.uk> | 2011-10-03 12:22:39 -0300 |
commit | e7dec8d0386afeaf0f4f6b02c3510e7f478bf4b1 (patch) | |
tree | dfb57702d8afdaf506a999aba9d25a5670694566 | |
parent | e33555a4be1bda334690ecdf20b1675d545efa14 (diff) | |
parent | dbbfddbbd74a37ddda262efc7067778049d84edc (diff) |
Merge branch 'contact-info-refresh-0.6' into telepathy-qt4-0.6
Reviewed-by: Olli Salli (oggis) <olli.salli@collabora.co.uk>
-rw-r--r-- | TelepathyQt4/contact-manager-internal.h | 20 | ||||
-rw-r--r-- | TelepathyQt4/contact-manager.cpp | 82 | ||||
-rw-r--r-- | TelepathyQt4/contact-manager.h | 6 | ||||
-rw-r--r-- | TelepathyQt4/contact.cpp | 17 | ||||
-rw-r--r-- | tests/dbus/contacts-info.cpp | 73 | ||||
-rw-r--r-- | tests/lib/glib/contacts-conn.c | 11 | ||||
-rw-r--r-- | tests/lib/glib/contacts-conn.h | 2 |
7 files changed, 177 insertions, 34 deletions
diff --git a/TelepathyQt4/contact-manager-internal.h b/TelepathyQt4/contact-manager-internal.h index bd208169..fde85003 100644 --- a/TelepathyQt4/contact-manager-internal.h +++ b/TelepathyQt4/contact-manager-internal.h @@ -327,6 +327,26 @@ private Q_SLOTS: void onChannelClosed(Tp::PendingOperation *); }; +class TELEPATHY_QT4_NO_EXPORT ContactManager::PendingRefreshContactInfo : public PendingOperation +{ + Q_OBJECT + +public: + PendingRefreshContactInfo(const ConnectionPtr &conn); + ~PendingRefreshContactInfo(); + + void addContact(Contact *contact); + + void refreshInfo(); + +private Q_SLOTS: + void onRefreshInfoFinished(Tp::PendingOperation *op); + +private: + ConnectionPtr mConn; + QSet<uint> mToRequest; +}; + } // Tp #endif diff --git a/TelepathyQt4/contact-manager.cpp b/TelepathyQt4/contact-manager.cpp index 98ea76c6..ae633e23 100644 --- a/TelepathyQt4/contact-manager.cpp +++ b/TelepathyQt4/contact-manager.cpp @@ -67,18 +67,23 @@ struct TELEPATHY_QT4_NO_EXPORT ContactManager::Private // avatar UIntList requestAvatarsQueue; bool requestAvatarsIdle; + + // contact info + PendingRefreshContactInfo *refreshInfoOp; }; ContactManager::Private::Private(ContactManager *parent, Connection *connection) : parent(parent), connection(connection), roster(new ContactManager::Roster(parent)), - requestAvatarsIdle(false) + requestAvatarsIdle(false), + refreshInfoOp(0) { } ContactManager::Private::~Private() { + delete refreshInfoOp; delete roster; } @@ -104,6 +109,61 @@ bool ContactManager::Private::buildAvatarFileName(QString token, bool createDir, return true; } +ContactManager::PendingRefreshContactInfo::PendingRefreshContactInfo(const ConnectionPtr &conn) + : PendingOperation(conn), + mConn(conn) +{ +} + +ContactManager::PendingRefreshContactInfo::~PendingRefreshContactInfo() +{ +} + +void ContactManager::PendingRefreshContactInfo::addContact(Contact *contact) +{ + mToRequest.insert(contact->handle()[0]); +} + +void ContactManager::PendingRefreshContactInfo::refreshInfo() +{ + Q_ASSERT(!mToRequest.isEmpty()); + + if (!mConn->isValid()) { + setFinishedWithError(TP_QT4_ERROR_NOT_AVAILABLE, + QLatin1String("Connection is invalid")); + return; + } + + if (!mConn->hasInterface(TP_QT4_IFACE_CONNECTION_INTERFACE_CONTACT_INFO)) { + setFinishedWithError(TP_QT4_ERROR_NOT_IMPLEMENTED, + QLatin1String("Connection does not support ContactInfo interface")); + return; + } + + debug() << "Calling ContactInfo.RefreshContactInfo for" << mToRequest.size() << "handles"; + Client::ConnectionInterfaceContactInfoInterface *contactInfoInterface = + mConn->interface<Client::ConnectionInterfaceContactInfoInterface>(); + Q_ASSERT(contactInfoInterface); + PendingVoid *nested = new PendingVoid( + contactInfoInterface->RefreshContactInfo(mToRequest.toList()), + mConn); + connect(nested, + SIGNAL(finished(Tp::PendingOperation*)), + SLOT(onRefreshInfoFinished(Tp::PendingOperation*))); +} + +void ContactManager::PendingRefreshContactInfo::onRefreshInfoFinished(PendingOperation *op) +{ + if (op->isError()) { + warning() << "ContactInfo.RefreshContactInfo failed with" << + op->errorName() << "-" << op->errorMessage(); + setFinishedWithError(op->errorName(), op->errorMessage()); + } else { + debug() << "Got reply to ContactInfo.RefreshContactInfo"; + setFinished(); + } +} + /** * \class ContactManager * \ingroup clientconn @@ -1156,6 +1216,14 @@ void ContactManager::onContactInfoChanged(uint handle, const Tp::ContactInfoFiel } } +void ContactManager::doRefreshInfo() +{ + PendingRefreshContactInfo *op = mPriv->refreshInfoOp; + Q_ASSERT(op); + mPriv->refreshInfoOp = 0; + op->refreshInfo(); +} + ContactPtr ContactManager::ensureContact(const ReferencedHandles &handle, const Features &features, const QVariantMap &attributes) { @@ -1300,6 +1368,18 @@ void ContactManager::resetRoster() mPriv->roster->reset(); } +PendingOperation *ContactManager::refreshContactInfo(Contact *contact) +{ + if (!mPriv->refreshInfoOp) { + mPriv->refreshInfoOp = new PendingRefreshContactInfo(connection()); + QTimer::singleShot(0, this, SLOT(doRefreshInfo())); + } + + mPriv->refreshInfoOp->addContact(contact); + + return mPriv->refreshInfoOp; +} + /** * \fn void ContactManager::presencePublicationRequested(const Tp::Contacts &contacts) * diff --git a/TelepathyQt4/contact-manager.h b/TelepathyQt4/contact-manager.h index bb39df5a..87864157 100644 --- a/TelepathyQt4/contact-manager.h +++ b/TelepathyQt4/contact-manager.h @@ -157,11 +157,15 @@ private Q_SLOTS: TELEPATHY_QT4_NO_EXPORT void onCapabilitiesChanged(const Tp::ContactCapabilitiesMap &); TELEPATHY_QT4_NO_EXPORT void onLocationUpdated(uint, const QVariantMap &); TELEPATHY_QT4_NO_EXPORT void onContactInfoChanged(uint, const Tp::ContactInfoFieldList &); + TELEPATHY_QT4_NO_EXPORT void doRefreshInfo(); private: + class PendingRefreshContactInfo; class Roster; friend class Connection; + friend class Contact; friend class PendingContacts; + friend class PendingRefreshContactInfo; friend class Roster; TELEPATHY_QT4_NO_EXPORT ContactManager(Connection *parent); @@ -179,6 +183,8 @@ private: TELEPATHY_QT4_NO_EXPORT PendingOperation *introspectRosterGroups(); TELEPATHY_QT4_NO_EXPORT void resetRoster(); + TELEPATHY_QT4_NO_EXPORT PendingOperation *refreshContactInfo(Contact *contact); + struct Private; friend struct Private; Private *mPriv; diff --git a/TelepathyQt4/contact.cpp b/TelepathyQt4/contact.cpp index 89d4dffd..e7b26715 100644 --- a/TelepathyQt4/contact.cpp +++ b/TelepathyQt4/contact.cpp @@ -621,7 +621,8 @@ Contact::InfoFields Contact::infoFields() const */ PendingOperation *Contact::refreshInfo() { - if (!mPriv->requestedFeatures.contains(FeatureInfo)) { + ConnectionPtr conn = manager()->connection(); + if (!mPriv->requestedFeatures.contains(FeatureInfo)) { warning() << "Contact::refreshInfo() used on" << this << "for which FeatureInfo hasn't been requested - failing"; return new PendingFailure(QLatin1String(TELEPATHY_ERROR_NOT_AVAILABLE), @@ -630,19 +631,7 @@ PendingOperation *Contact::refreshInfo() ContactPtr(this)); } - ConnectionPtr connection = manager()->connection(); - if (!connection->hasInterface(TP_QT4_IFACE_CONNECTION_INTERFACE_CONTACT_INFO)) { - return new PendingFailure(QLatin1String(TELEPATHY_ERROR_NOT_IMPLEMENTED), - QLatin1String("Connection does not support ContactInfo interface"), - ContactPtr(this)); - } - - Client::ConnectionInterfaceContactInfoInterface *contactInfoInterface = - connection->interface<Client::ConnectionInterfaceContactInfoInterface>(); - return new PendingVoid( - contactInfoInterface->RefreshContactInfo( - UIntList() << mPriv->handle[0]), - ContactPtr(this)); + return manager()->refreshContactInfo(this); } /** diff --git a/tests/dbus/contacts-info.cpp b/tests/dbus/contacts-info.cpp index c8c1e076..af5f297f 100644 --- a/tests/dbus/contacts-info.cpp +++ b/tests/dbus/contacts-info.cpp @@ -20,11 +20,14 @@ class TestContactsInfo : public Test public: TestContactsInfo(QObject *parent = 0) - : Test(parent), mConn(0), mContactsInfoFieldsUpdated(0) + : Test(parent), mConn(0), + mContactsInfoFieldsUpdated(0), + mRefreshInfoFinished(0) { } protected Q_SLOTS: void onContactInfoFieldsChanged(const Tp::Contact::InfoFields &); + void onRefreshInfoFinished(Tp::PendingOperation *); private Q_SLOTS: void initTestCase(); @@ -38,12 +41,23 @@ private Q_SLOTS: private: TestConnHelper *mConn; int mContactsInfoFieldsUpdated; + int mRefreshInfoFinished; }; void TestContactsInfo::onContactInfoFieldsChanged(const Tp::Contact::InfoFields &info) { Q_UNUSED(info); mContactsInfoFieldsUpdated++; +} + +void TestContactsInfo::onRefreshInfoFinished(PendingOperation *op) +{ + if (op->isError()) { + mLoop->exit(1); + return; + } + + mRefreshInfoFinished++; mLoop->exit(0); } @@ -68,6 +82,7 @@ void TestContactsInfo::init() { initImpl(); mContactsInfoFieldsUpdated = 0; + mRefreshInfoFinished = 0; } void TestContactsInfo::testInfo() @@ -93,6 +108,21 @@ void TestContactsInfo::testInfo() SLOT(onContactInfoFieldsChanged(const Tp::Contact::InfoFields &)))); } + GPtrArray *info_default = (GPtrArray *) dbus_g_type_specialized_construct ( + TP_ARRAY_TYPE_CONTACT_INFO_FIELD_LIST); + { + const gchar * const field_values[2] = { + "FooBar", NULL + }; + g_ptr_array_add (info_default, tp_value_array_build (3, + G_TYPE_STRING, "n", + G_TYPE_STRV, NULL, + G_TYPE_STRV, field_values, + G_TYPE_INVALID)); + } + tp_tests_contacts_connection_set_default_contact_info(TP_TESTS_CONTACTS_CONNECTION(mConn->service()), + info_default); + GPtrArray *info_1 = (GPtrArray *) dbus_g_type_specialized_construct ( TP_ARRAY_TYPE_CONTACT_INFO_FIELD_LIST); { @@ -133,7 +163,7 @@ void TestContactsInfo::testInfo() handles[1], info_2); while (mContactsInfoFieldsUpdated != 2) { - QCOMPARE(mLoop->exec(), 0); + mLoop->processEvents(); } QCOMPARE(mContactsInfoFieldsUpdated, 2); @@ -151,23 +181,35 @@ void TestContactsInfo::testInfo() QCOMPARE(contactBar->infoFields().allFields()[0].fieldName, QLatin1String("n")); QCOMPARE(contactBar->infoFields().allFields()[0].fieldValue[0], QLatin1String("Bar")); + TpTestsContactsConnection *serviceConn = TP_TESTS_CONTACTS_CONNECTION(mConn->service()); + QCOMPARE(serviceConn->refresh_contact_info_called, static_cast<uint>(0)); + + mContactsInfoFieldsUpdated = 0; + mRefreshInfoFinished = 0; Q_FOREACH (const ContactPtr &contact, contacts) { - PendingOperation *op = contact->refreshInfo(); - QVERIFY(connect(op, + QVERIFY(connect(contact->refreshInfo(), SIGNAL(finished(Tp::PendingOperation*)), - SLOT(expectSuccessfulCall(Tp::PendingOperation*)))); + SLOT(onRefreshInfoFinished(Tp::PendingOperation*)))); + } + while (mRefreshInfoFinished != contacts.size()) { QCOMPARE(mLoop->exec(), 0); } + QCOMPARE(mRefreshInfoFinished, contacts.size()); + + while (mContactsInfoFieldsUpdated != contacts.size()) { + mLoop->processEvents(); + } + + QCOMPARE(mContactsInfoFieldsUpdated, contacts.size()); - /* nothing changed */ - QCOMPARE(mContactsInfoFieldsUpdated, 0); + QCOMPARE(serviceConn->refresh_contact_info_called, static_cast<uint>(1)); for (int i = 0; i < contacts.size(); i++) { ContactPtr contact = contacts[i]; - disconnect(contact.data(), - SIGNAL(infoChanged(const Tp::ContactInfoFieldList &)), - this, - SLOT(onContactInfoChanged(const Tp::ContactInfoFieldList &))); + QVERIFY(disconnect(contact.data(), + SIGNAL(infoFieldsChanged(const Tp::Contact::InfoFields &)), + this, + SLOT(onContactInfoFieldsChanged(const Tp::Contact::InfoFields &)))); } PendingContactInfo *pci = contactFoo->requestInfo(); @@ -181,12 +223,11 @@ void TestContactsInfo::testInfo() QCOMPARE(pci->infoFields().isValid(), true); QCOMPARE(pci->infoFields().allFields().size(), 1); QCOMPARE(pci->infoFields().allFields()[0].fieldName, QLatin1String("n")); - QCOMPARE(pci->infoFields().allFields()[0].fieldValue[0], QLatin1String("Foo")); + QCOMPARE(pci->infoFields().allFields()[0].fieldValue[0], QLatin1String("FooBar")); - g_boxed_free (TP_ARRAY_TYPE_CONTACT_INFO_FIELD_LIST, info_1); - g_ptr_array_unref (info_1); - g_boxed_free (TP_ARRAY_TYPE_CONTACT_INFO_FIELD_LIST, info_2); - g_ptr_array_unref (info_2); + g_boxed_free(TP_ARRAY_TYPE_CONTACT_INFO_FIELD_LIST, info_default); + g_boxed_free(TP_ARRAY_TYPE_CONTACT_INFO_FIELD_LIST, info_1); + g_boxed_free(TP_ARRAY_TYPE_CONTACT_INFO_FIELD_LIST, info_2); } void TestContactsInfo::cleanup() diff --git a/tests/lib/glib/contacts-conn.c b/tests/lib/glib/contacts-conn.c index c49d268a..9b349db5 100644 --- a/tests/lib/glib/contacts-conn.c +++ b/tests/lib/glib/contacts-conn.c @@ -159,6 +159,8 @@ tp_tests_contacts_connection_init (TpTestsContactsConnection *self) g_direct_equal, NULL, (GDestroyNotify) free_rcc_list); self->priv->contact_info = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify) g_ptr_array_unref); + self->priv->default_contact_info = (GPtrArray *) dbus_g_type_specialized_construct ( + TP_ARRAY_TYPE_CONTACT_INFO_FIELD_LIST); } static void @@ -1154,14 +1156,17 @@ my_refresh_contact_info (TpSvcConnectionInterfaceContactInfo *obj, return; } + self->refresh_contact_info_called++; + for (i = 0; i < contacts->len; i++) { TpHandle handle = g_array_index (contacts, guint, i); - GPtrArray *arr = lookup_contact_info (self, handle); + // actually update the info (if not using the default info) so there is an actual change + g_hash_table_insert (self->priv->contact_info, GUINT_TO_POINTER (handle), + g_ptr_array_ref (self->priv->default_contact_info)); tp_svc_connection_interface_contact_info_emit_contact_info_changed (self, - handle, arr); - g_ptr_array_unref (arr); + handle, self->priv->default_contact_info); } tp_svc_connection_interface_contact_info_return_from_refresh_contact_info ( diff --git a/tests/lib/glib/contacts-conn.h b/tests/lib/glib/contacts-conn.h index 832c2ba3..e848b4f6 100644 --- a/tests/lib/glib/contacts-conn.h +++ b/tests/lib/glib/contacts-conn.h @@ -40,6 +40,8 @@ struct _TpTestsContactsConnection { TpPresenceMixin presence_mixin; TpContactsMixin contacts_mixin; + guint refresh_contact_info_called; + TpTestsContactsConnectionPrivate *priv; }; |