[Merge] lp:~boiko/telephony-service/support_non_phone_accounts into lp:telephony-service
Tiago Salem Herrmann
tiago.herrmann at canonical.com
Thu Mar 26 20:34:54 UTC 2015
Review: Needs Information
Diff comments:
> === modified file 'Ubuntu/Telephony/contactwatcher.cpp'
> --- Ubuntu/Telephony/contactwatcher.cpp 2014-09-02 17:42:20 +0000
> +++ Ubuntu/Telephony/contactwatcher.cpp 2015-03-25 22:11:52 +0000
> @@ -1,7 +1,8 @@
> /*
> - * Copyright (C) 2013 Canonical, Ltd.
> + * Copyright (C) 2013-2015 Canonical, Ltd.
> *
> * Authors:
> + * Gustavo Pichorim Boiko <gustavo.boiko at canonical.com>
> * Tiago Salem Herrmann <tiago.herrmann at canonical.com>
> *
> * This file is part of telephony-service.
> @@ -22,12 +23,17 @@
> #include "contactwatcher.h"
> #include "contactutils.h"
> #include "phoneutils.h"
> +#include "accountentry.h"
> +#include "telepathyhelper.h"
> #include <QContactManager>
> #include <QContactFetchByIdRequest>
> #include <QContactFetchRequest>
> #include <QContactAvatar>
> +#include <QContactExtendedDetail>
> +#include <QContactPhoneNumber>
> #include <QContactDetailFilter>
> -#include <QContactPhoneNumber>
> +#include <QContactIntersectionFilter>
> +#include <QContactUnionFilter>
>
> namespace C {
> #include <libintl.h>
> @@ -36,6 +42,8 @@
> ContactWatcher::ContactWatcher(QObject *parent) :
> QObject(parent), mRequest(0), mInteractive(false), mCompleted(false)
> {
> + // addressable VCard fields defaults to "tel" only
> + mAddressableFields << "tel";
> connect(ContactUtils::sharedManager(),
> SIGNAL(contactsAdded(QList<QContactId>)),
> SLOT(onContactsAdded(QList<QContactId>)));
> @@ -55,10 +63,10 @@
> }
> }
>
> -void ContactWatcher::searchByPhoneNumber(const QString &phoneNumber)
> +void ContactWatcher::startSearching()
> {
> - if (!mCompleted) {
> - // componenty is not ready yet
> + if (!mCompleted || mIdentifier.isEmpty()) {
> + // componenty is not ready yet or no identifier given
> return;
> }
>
> @@ -68,15 +76,60 @@
> mRequest->deleteLater();
> }
>
> + // FIXME: search for all the fields
> mRequest = new QContactFetchRequest(this);
> - mRequest->setFilter(QContactPhoneNumber::match(phoneNumber));
> +
> + QContactUnionFilter topLevelFilter;
> + Q_FOREACH(const QString &field, mAddressableFields) {
> + if (field == "tel") {
> + topLevelFilter.append(QContactPhoneNumber::match(mIdentifier));
> + } else {
> + // FIXME: handle more fields
> + // rely on a generic field filter
> + QContactDetailFilter nameFilter = QContactDetailFilter();
> + nameFilter.setDetailType(QContactExtendedDetail::Type, QContactExtendedDetail::FieldName);
> + nameFilter.setMatchFlags(QContactFilter::MatchExactly);
> + nameFilter.setValue(field);
> +
> + QContactDetailFilter valueFilter = QContactDetailFilter();
> + valueFilter.setDetailType(QContactExtendedDetail::Type, QContactExtendedDetail::FieldData);
> + valueFilter.setMatchFlags(QContactFilter::MatchExactly);
> + valueFilter.setValue(mIdentifier);
> +
> + QContactIntersectionFilter intersectionFilter;
> + intersectionFilter.append(nameFilter);
> + intersectionFilter.append(valueFilter);
> +
> + topLevelFilter.append(intersectionFilter);
> + }
> + }
> +
> + mRequest->setFilter(topLevelFilter);
> connect(mRequest, SIGNAL(stateChanged(QContactAbstractRequest::State)),
> SLOT(onRequestStateChanged(QContactAbstractRequest::State)));
> - connect(mRequest, SIGNAL(resultsAvailable()), SLOT(resultsAvailable()));
> + connect(mRequest, SIGNAL(resultsAvailable()), SLOT(onResultsAvailable()));
> mRequest->setManager(ContactUtils::sharedManager());
> mRequest->start();
> }
>
> +QVariantList ContactWatcher::wrapIntList(const QList<int> &list)
> +{
> + QVariantList resultList;
> + Q_FOREACH(int value, list) {
> + resultList << value;
> + }
> + return resultList;
> +}
> +
> +QList<int> ContactWatcher::unwrapIntList(const QVariantList &list)
> +{
> + QList<int> resultList;
> + Q_FOREACH(const QVariant &value, list) {
> + resultList << value.toInt();
> + }
> + return resultList;
> +}
> +
> QString ContactWatcher::contactId() const
> {
> QString id = mContactId.toString();
> @@ -97,40 +150,30 @@
> return mAlias;
> }
>
> -QString ContactWatcher::phoneNumber() const
> -{
> - return mPhoneNumber;
> -}
> -
> -QList<int> ContactWatcher::phoneNumberSubTypes() const
> -{
> - return mPhoneNumberSubTypes;
> -}
> -
> -QList<int> ContactWatcher::phoneNumberContexts() const
> -{
> - return mPhoneNumberContexts;
> -}
> -
> -void ContactWatcher::setPhoneNumber(const QString &phoneNumber)
> -{
> - if (mPhoneNumber == phoneNumber) {
> +QString ContactWatcher::identifier() const
> +{
> + return mIdentifier;
> +}
> +
> +void ContactWatcher::setIdentifier(const QString &identifier)
> +{
> + if (mIdentifier == identifier) {
> return;
> }
>
> - const bool isPrivate = phoneNumber.startsWith("x-ofono-private");
> - const bool isUnknown = phoneNumber.startsWith("x-ofono-unknown");
> - const bool isInteractive = !phoneNumber.isEmpty() && !isPrivate && !isUnknown;
> -
> - mPhoneNumber = phoneNumber;
> - Q_EMIT phoneNumberChanged();
> -
> - if (mPhoneNumber.isEmpty() || isPrivate || isUnknown) {
> + // FIXME: ofono stuff, maybe move somewhere else?
> + const bool isPrivate = identifier.startsWith("x-ofono-private");
> + const bool isUnknown = identifier.startsWith("x-ofono-unknown");
> + const bool isInteractive = !identifier.isEmpty() && !isPrivate && !isUnknown;
> +
> + mIdentifier = identifier;
> + Q_EMIT identifierChanged();
> +
> + if (mIdentifier.isEmpty() || isPrivate || isUnknown) {
> mAlias.clear();
> mContactId = QContactId();
> mAvatar.clear();
> - mPhoneNumberSubTypes.clear();
> - mPhoneNumberContexts.clear();
> + mDetailProperties.clear();
>
> if (isPrivate) {
> mAlias = C::gettext("Private Number");
> @@ -141,11 +184,10 @@
> Q_EMIT contactIdChanged();
> Q_EMIT avatarChanged();
> Q_EMIT aliasChanged();
> - Q_EMIT phoneNumberSubTypesChanged();
> - Q_EMIT phoneNumberContextsChanged();
> + Q_EMIT detailPropertiesChanged();
> Q_EMIT isUnknownChanged();
> } else {
> - searchByPhoneNumber(mPhoneNumber);
> + startSearching();
> }
>
> if (isInteractive != mInteractive) {
> @@ -154,6 +196,11 @@
> }
> }
>
> +QVariantMap ContactWatcher::detailProperties() const
> +{
> + return mDetailProperties;
> +}
> +
> bool ContactWatcher::isUnknown() const
> {
> return mContactId.isNull();
> @@ -164,6 +211,19 @@
> return mInteractive;
> }
>
> +QStringList ContactWatcher::addressableFields() const
> +{
> + return mAddressableFields;
> +}
> +
> +void ContactWatcher::setAddressableFields(const QStringList &fields)
> +{
> + mAddressableFields = fields;
> + Q_EMIT addressableFieldsChanged();
> +
> + startSearching();
> +}
> +
> void ContactWatcher::classBegin()
> {
> }
> @@ -171,30 +231,25 @@
> void ContactWatcher::componentComplete()
> {
> mCompleted = true;
> - // query for phone if the phone number was initialized
> - if (!mPhoneNumber.isEmpty()) {
> - searchByPhoneNumber(mPhoneNumber);
> - }
> + startSearching();
> }
>
> void ContactWatcher::onContactsAdded(QList<QContactId> ids)
> {
> // ignore this signal if we have a contact already
> // or if we have no phone number set
> - if (!mContactId.isNull() || mPhoneNumber.isEmpty()) {
> + if (!mContactId.isNull() || mIdentifier.isEmpty()) {
> return;
> }
>
> - searchByPhoneNumber(mPhoneNumber);
> + startSearching();
> }
>
> void ContactWatcher::onContactsChanged(QList<QContactId> ids)
> {
> // check for changes even if we have this contact already,
> // as the number might have changed, thus invalidating the current contact
> - if (!mPhoneNumber.isEmpty() || ids.contains(mContactId)) {
> - searchByPhoneNumber(mPhoneNumber);
> - }
> + startSearching();
> }
>
> void ContactWatcher::onContactsRemoved(QList<QContactId> ids)
> @@ -204,22 +259,18 @@
> mAlias.clear();
> mContactId = QContactId();
> mAvatar.clear();
> - mPhoneNumberSubTypes.clear();
> - mPhoneNumberContexts.clear();
> + mDetailProperties.clear();
> Q_EMIT contactIdChanged();
> Q_EMIT avatarChanged();
> Q_EMIT aliasChanged();
> - Q_EMIT phoneNumberSubTypesChanged();
> - Q_EMIT phoneNumberContextsChanged();
> + Q_EMIT detailPropertiesChanged();
> Q_EMIT isUnknownChanged();
>
> - if (!mPhoneNumber.isEmpty()) {
> - searchByPhoneNumber(mPhoneNumber);
> - }
> + startSearching();
> }
> }
>
> -void ContactWatcher::resultsAvailable()
> +void ContactWatcher::onResultsAvailable()
> {
> QContactFetchRequest *request = qobject_cast<QContactFetchRequest*>(sender());
> if (request && request->contacts().size() > 0) {
> @@ -243,18 +294,19 @@
> Q_EMIT isUnknownChanged();
> }
>
> - Q_FOREACH(const QContactPhoneNumber phoneNumber, contact.details(QContactDetail::TypePhoneNumber)) {
> - if (PhoneUtils::comparePhoneNumbers(phoneNumber.number(), mPhoneNumber)) {
> - QList<int> newSubTypes = phoneNumber.subTypes();
> - if (newSubTypes != mPhoneNumberSubTypes) {
> - mPhoneNumberSubTypes = phoneNumber.subTypes();
> - Q_EMIT phoneNumberSubTypesChanged();
> - }
> - QList<int> newContexts = phoneNumber.contexts();
> - if (newContexts != mPhoneNumberContexts) {
> - mPhoneNumberContexts = newContexts;
> - Q_EMIT phoneNumberContextsChanged();
> - }
> + Q_FOREACH(const QString &field, mAddressableFields) {
> + if (field == "tel") {
> + Q_FOREACH(const QContactPhoneNumber phoneNumber, contact.details(QContactDetail::TypePhoneNumber)) {
> + if (PhoneUtils::comparePhoneNumbers(phoneNumber.number(), mIdentifier)) {
> + mDetailProperties["type"] = (int)QContactDetail::TypePhoneNumber;
> + mDetailProperties["phoneNumberSubTypes"] = wrapIntList(phoneNumber.subTypes());
> + mDetailProperties["phoneNumberContexts"] = wrapIntList(phoneNumber.contexts());
> + Q_EMIT detailPropertiesChanged();
> + break;
> + }
> + }
> + } else {
> + // FIXME: add proper support for more fields
> }
> }
> }
> @@ -272,14 +324,12 @@
> mAlias.clear();
> mContactId = QContactId();
> mAvatar.clear();
> - mPhoneNumberSubTypes.clear();
> - mPhoneNumberContexts.clear();
> + mDetailProperties.clear();
>
> Q_EMIT contactIdChanged();
> Q_EMIT avatarChanged();
> Q_EMIT aliasChanged();
> - Q_EMIT phoneNumberSubTypesChanged();
> - Q_EMIT phoneNumberContextsChanged();
> + Q_EMIT detailPropertiesChanged();
> Q_EMIT isUnknownChanged();
> }
> }
>
> === modified file 'Ubuntu/Telephony/contactwatcher.h'
> --- Ubuntu/Telephony/contactwatcher.h 2014-09-02 17:42:20 +0000
> +++ Ubuntu/Telephony/contactwatcher.h 2015-03-25 22:11:52 +0000
> @@ -1,7 +1,8 @@
> /*
> - * Copyright (C) 2013 Canonical, Ltd.
> + * Copyright (C) 2013-2015 Canonical, Ltd.
> *
> * Authors:
> + * Gustavo Pichorim Boiko <gustavo.boiko at canonical.com>
> * Tiago Salem Herrmann <tiago.herrmann at canonical.com>
> *
> * This file is part of telephony-service.
> @@ -38,11 +39,15 @@
> Q_PROPERTY(QString contactId READ contactId NOTIFY contactIdChanged)
> Q_PROPERTY(QString avatar READ avatar NOTIFY avatarChanged)
> Q_PROPERTY(QString alias READ alias NOTIFY aliasChanged)
> - Q_PROPERTY(QString phoneNumber READ phoneNumber WRITE setPhoneNumber NOTIFY phoneNumberChanged)
> - Q_PROPERTY(QList<int> phoneNumberSubTypes READ phoneNumberSubTypes NOTIFY phoneNumberSubTypesChanged)
> - Q_PROPERTY(QList<int> phoneNumberContexts READ phoneNumberContexts NOTIFY phoneNumberContextsChanged)
> + Q_PROPERTY(QString identifier READ identifier WRITE setIdentifier NOTIFY identifierChanged)
> + Q_PROPERTY(QString phoneNumber READ identifier WRITE setIdentifier NOTIFY identifierChanged)
> + // The details property changes according to the detail type.
> + // One property is always present on the map though, the "detailType" property.
> + Q_PROPERTY(QVariantMap detailProperties READ detailProperties NOTIFY detailPropertiesChanged)
> Q_PROPERTY(bool isUnknown READ isUnknown NOTIFY isUnknownChanged)
> Q_PROPERTY(bool interactive READ interactive NOTIFY interactiveChanged)
> + Q_PROPERTY(QStringList addressableFields READ addressableFields WRITE setAddressableFields NOTIFY addressableFieldsChanged)
> +
> public:
> explicit ContactWatcher(QObject *parent = 0);
> ~ContactWatcher();
> @@ -50,46 +55,52 @@
> QString contactId() const;
> QString avatar() const;
> QString alias() const;
> - QString phoneNumber() const;
> - void setPhoneNumber(const QString &phoneNumber);
> - QList<int> phoneNumberSubTypes() const;
> - QList<int> phoneNumberContexts() const;
> + QString identifier() const;
> + void setIdentifier(const QString &identifier);
> + QVariantMap detailProperties() const;
> bool isUnknown() const;
> bool interactive() const;
>
> + // defaults to only phone number searching
> + QStringList addressableFields() const;
> + void setAddressableFields(const QStringList &fields);
> +
> void classBegin();
> void componentComplete();
>
> + // helpers
> + Q_INVOKABLE QVariantList wrapIntList(const QList<int> &list);
> + Q_INVOKABLE QList<int> unwrapIntList(const QVariantList &list);
> +
> Q_SIGNALS:
> void contactIdChanged();
> void avatarChanged();
> void aliasChanged();
> - void phoneNumberChanged();
> - void phoneNumberSubTypesChanged();
> - void phoneNumberContextsChanged();
> + void identifierChanged();
> + void detailPropertiesChanged();
> void isUnknownChanged();
> void interactiveChanged();
> + void addressableFieldsChanged();
>
> protected Q_SLOTS:
> void onContactsAdded(QList<QContactId> ids);
> void onContactsChanged(QList<QContactId> ids);
> void onContactsRemoved(QList<QContactId> ids);
> - void resultsAvailable();
> + void onResultsAvailable();
> void onRequestStateChanged(QContactAbstractRequest::State state);
>
> private:
> - void searchByPhoneNumber(const QString &phoneNumber);
> + void startSearching();
>
> QContactFetchRequest *mRequest;
> QContactId mContactId;
> QString mAvatar;
> QString mAlias;
> - QString mPhoneNumber;
> - QList<int> mPhoneNumberSubTypes;
> - QList<int> mPhoneNumberContexts;
> + QString mIdentifier;
> + QVariantMap mDetailProperties;
> bool mInteractive;
> bool mCompleted;
> -
> + QStringList mAddressableFields;
> };
>
> #endif // CONTACTWATCHER_H
>
> === modified file 'Ubuntu/Telephony/tests/ContactWatcherTest.cpp'
> --- Ubuntu/Telephony/tests/ContactWatcherTest.cpp 2014-09-02 17:42:20 +0000
> +++ Ubuntu/Telephony/tests/ContactWatcherTest.cpp 2015-03-25 22:11:52 +0000
> @@ -1,5 +1,5 @@
> /*
> - * Copyright (C) 2013 Canonical, Ltd.
> + * Copyright (C) 2013-2015 Canonical, Ltd.
> *
> * This file is part of telephony-service.
> *
> @@ -24,6 +24,7 @@
> #include <QContactName>
> #include <QContactAvatar>
> #include <QContactPhoneNumber>
> +#include <QContactExtendedDetail>
>
> QTCONTACTS_USE_NAMESPACE
>
> @@ -33,7 +34,7 @@
>
> private Q_SLOTS:
> void initTestCase();
> - void testPhoneNumber();
> + void testIdentifier();
> void testMatchExistingContact();
> void testMatchNewContact();
> void testMatchContactChanged();
> @@ -43,6 +44,8 @@
> void testInteractiveProperty_data();
> void testInteractiveProperty();
> void testLateSearch();
> + void testAddressableFields();
> + void testExtendedFieldMatch();
>
> private:
> QContact createContact(const QString &firstName,
> @@ -61,24 +64,24 @@
> mManager = ContactUtils::sharedManager("memory");
> }
>
> -void ContactWatcherTest::testPhoneNumber()
> +void ContactWatcherTest::testIdentifier()
> {
> - QString phoneNumber("123456");
> + QString identifier("123456");
> ContactWatcher watcher;
> - QSignalSpy spy(&watcher, SIGNAL(phoneNumberChanged()));
> - watcher.setPhoneNumber(phoneNumber);
> + QSignalSpy spy(&watcher, SIGNAL(identifierChanged()));
> + watcher.setIdentifier(identifier);
>
> QCOMPARE(spy.count(), 1);
> - QCOMPARE(watcher.phoneNumber(), phoneNumber);
> + QCOMPARE(watcher.identifier(), identifier);
> }
>
> void ContactWatcherTest::testMatchExistingContact()
> {
> - QString phoneNumber("12345");
> + QString identifier("12345");
> QContact contact = createContact("FirstName",
> "LastName",
> "file://some_file",
> - QStringList() << phoneNumber,
> + QStringList() << identifier,
> QList<int>() << 0 << 1 << 2,
> QList<int>() << 3 << 4 << 5);
> ContactWatcher watcher;
> @@ -86,12 +89,11 @@
> QSignalSpy contactIdSpy(&watcher, SIGNAL(contactIdChanged()));
> QSignalSpy aliasSpy(&watcher, SIGNAL(aliasChanged()));
> QSignalSpy avatarSpy(&watcher, SIGNAL(avatarChanged()));
> - QSignalSpy contextsSpy(&watcher, SIGNAL(phoneNumberContextsChanged()));
> - QSignalSpy subTypesSpy(&watcher, SIGNAL(phoneNumberSubTypesChanged()));
> + QSignalSpy detailPropertiesSpy(&watcher, SIGNAL(detailPropertiesChanged()));
> QSignalSpy unknownSpy(&watcher, SIGNAL(isUnknownChanged()));
>
> // set the phone number and wait for the match to happen
> - watcher.setPhoneNumber(phoneNumber);
> + watcher.setIdentifier(identifier);
>
>
> // contact fetching is asynchronous so use QTRY_COMPARE for the first signal spy
> @@ -99,16 +101,15 @@
> QTRY_COMPARE(contactIdSpy.count(), 1);
> QCOMPARE(aliasSpy.count(), 1);
> QCOMPARE(avatarSpy.count(), 1);
> - QCOMPARE(contextsSpy.count(), 1);
> - QCOMPARE(subTypesSpy.count(), 1);
> + QCOMPARE(detailPropertiesSpy.count(), 1);
> QCOMPARE(unknownSpy.count(), 1);
>
> // and verify that the values are properly set
> QCOMPARE(watcher.contactId(), contact.id().toString());
> QCOMPARE(watcher.alias(), ContactUtils::formatContactName(contact));
> QCOMPARE(watcher.avatar(), contact.detail<QContactAvatar>().imageUrl().toString());
> - QCOMPARE(watcher.phoneNumberContexts(), contact.detail<QContactPhoneNumber>().contexts());
> - QCOMPARE(watcher.phoneNumberSubTypes(), contact.detail<QContactPhoneNumber>().subTypes());
> + QCOMPARE(watcher.unwrapIntList(watcher.detailProperties()["phoneNumberContexts"].toList()), contact.detail<QContactPhoneNumber>().contexts());
> + QCOMPARE(watcher.unwrapIntList(watcher.detailProperties()["phoneNumberSubTypes"].toList()), contact.detail<QContactPhoneNumber>().subTypes());
> QCOMPARE(watcher.isUnknown(), false);
>
> clearManager();
> @@ -116,24 +117,23 @@
>
> void ContactWatcherTest::testMatchNewContact()
> {
> - QString phoneNumber("1234567");
> + QString identifier("1234567");
> ContactWatcher watcher;
> watcher.componentComplete();
> QSignalSpy contactIdSpy(&watcher, SIGNAL(contactIdChanged()));
> QSignalSpy aliasSpy(&watcher, SIGNAL(aliasChanged()));
> QSignalSpy avatarSpy(&watcher, SIGNAL(avatarChanged()));
> - QSignalSpy contextsSpy(&watcher, SIGNAL(phoneNumberContextsChanged()));
> - QSignalSpy subTypesSpy(&watcher, SIGNAL(phoneNumberSubTypesChanged()));
> + QSignalSpy detailPropertiesSpy(&watcher, SIGNAL(detailPropertiesChanged()));
> QSignalSpy unknownSpy(&watcher, SIGNAL(isUnknownChanged()));
>
> - watcher.setPhoneNumber(phoneNumber);
> + watcher.setIdentifier(identifier);
>
> // now create the contact and wait to see if it gets matched
> QContact contact = createContact("FirstName",
> "LastName",
> "file://some_file",
> // just to make it a little more complicated, use a prefixed phone number
> - QStringList() << phoneNumber.prepend("+1"),
> + QStringList() << identifier.prepend("+1"),
> QList<int>() << 0 << 1 << 2,
> QList<int>() << 3 << 4 << 5);
>
> @@ -142,16 +142,15 @@
> QTRY_COMPARE(contactIdSpy.count(), 1);
> QCOMPARE(aliasSpy.count(), 1);
> QCOMPARE(avatarSpy.count(), 1);
> - QCOMPARE(contextsSpy.count(), 1);
> - QCOMPARE(subTypesSpy.count(), 1);
> + QCOMPARE(detailPropertiesSpy.count(), 1);
> QCOMPARE(unknownSpy.count(), 1);
>
> // and verify that the values are properly set
> QCOMPARE(watcher.contactId(), contact.id().toString());
> QCOMPARE(watcher.alias(), ContactUtils::formatContactName(contact));
> QCOMPARE(watcher.avatar(), contact.detail<QContactAvatar>().imageUrl().toString());
> - QCOMPARE(watcher.phoneNumberContexts(), contact.detail<QContactPhoneNumber>().contexts());
> - QCOMPARE(watcher.phoneNumberSubTypes(), contact.detail<QContactPhoneNumber>().subTypes());
> + QCOMPARE(watcher.unwrapIntList(watcher.detailProperties()["phoneNumberContexts"].toList()), contact.detail<QContactPhoneNumber>().contexts());
> + QCOMPARE(watcher.unwrapIntList(watcher.detailProperties()["phoneNumberSubTypes"].toList()), contact.detail<QContactPhoneNumber>().subTypes());
> QCOMPARE(watcher.isUnknown(), false);
>
> clearManager();
> @@ -159,7 +158,7 @@
>
> void ContactWatcherTest::testMatchContactChanged()
> {
> - QString phoneNumber("12345");
> + QString identifier("12345");
> QContact contact = createContact("FirstName",
> "LastName",
> "file://some_file",
> @@ -168,18 +167,17 @@
> QList<int>() << 3 << 4 << 5);
> ContactWatcher watcher;
> watcher.componentComplete();
> - watcher.setPhoneNumber(phoneNumber);
> + watcher.setIdentifier(identifier);
>
> QSignalSpy contactIdSpy(&watcher, SIGNAL(contactIdChanged()));
> QSignalSpy aliasSpy(&watcher, SIGNAL(aliasChanged()));
> QSignalSpy avatarSpy(&watcher, SIGNAL(avatarChanged()));
> - QSignalSpy contextsSpy(&watcher, SIGNAL(phoneNumberContextsChanged()));
> - QSignalSpy subTypesSpy(&watcher, SIGNAL(phoneNumberSubTypesChanged()));
> + QSignalSpy detailPropertiesSpy(&watcher, SIGNAL(detailPropertiesChanged()));
> QSignalSpy unknownSpy(&watcher, SIGNAL(isUnknownChanged()));
>
> // now modify the contact´s phone number so that it matches
> QContactPhoneNumber number = contact.detail<QContactPhoneNumber>();
> - number.setNumber(phoneNumber);
> + number.setNumber(identifier);
> contact.saveDetail(&number);
> mManager->saveContact(&contact);
>
> @@ -188,16 +186,15 @@
> QTRY_COMPARE(contactIdSpy.count(), 1);
> QCOMPARE(aliasSpy.count(), 1);
> QCOMPARE(avatarSpy.count(), 1);
> - QCOMPARE(contextsSpy.count(), 1);
> - QCOMPARE(subTypesSpy.count(), 1);
> + QCOMPARE(detailPropertiesSpy.count(), 1);
> QCOMPARE(unknownSpy.count(), 1);
>
> // and verify that the values are properly set
> QCOMPARE(watcher.contactId(), contact.id().toString());
> QCOMPARE(watcher.alias(), ContactUtils::formatContactName(contact));
> QCOMPARE(watcher.avatar(), contact.detail<QContactAvatar>().imageUrl().toString());
> - QCOMPARE(watcher.phoneNumberContexts(), contact.detail<QContactPhoneNumber>().contexts());
> - QCOMPARE(watcher.phoneNumberSubTypes(), contact.detail<QContactPhoneNumber>().subTypes());
> + QCOMPARE(watcher.unwrapIntList(watcher.detailProperties()["phoneNumberContexts"].toList()), contact.detail<QContactPhoneNumber>().contexts());
> + QCOMPARE(watcher.unwrapIntList(watcher.detailProperties()["phoneNumberSubTypes"].toList()), contact.detail<QContactPhoneNumber>().subTypes());
> QCOMPARE(watcher.isUnknown(), false);
>
> clearManager();
> @@ -207,11 +204,11 @@
> {
> // after modifying a contact, if the phone number doesn´t match anymore, the data should be cleared
> // verify that this happens, but first we need to make sure the match actually happened
> - QString phoneNumber("12345");
> + QString identifier("12345");
> QContact contact = createContact("FirstName",
> "LastName",
> "file://some_file",
> - QStringList() << phoneNumber,
> + QStringList() << identifier,
> QList<int>() << 0 << 1 << 2,
> QList<int>() << 3 << 4 << 5);
> ContactWatcher watcher;
> @@ -219,7 +216,7 @@
> QSignalSpy contactIdSpy(&watcher, SIGNAL(contactIdChanged()));
>
> // set the phone number and wait for the match to happen
> - watcher.setPhoneNumber(phoneNumber);
> + watcher.setIdentifier(identifier);
>
> // at this point we just need to make sure the contactId is correct, the other fields
> // are tested in a separate test
> @@ -229,8 +226,7 @@
>
> QSignalSpy aliasSpy(&watcher, SIGNAL(aliasChanged()));
> QSignalSpy avatarSpy(&watcher, SIGNAL(avatarChanged()));
> - QSignalSpy contextsSpy(&watcher, SIGNAL(phoneNumberContextsChanged()));
> - QSignalSpy subTypesSpy(&watcher, SIGNAL(phoneNumberSubTypesChanged()));
> + QSignalSpy detailPropertiesSpy(&watcher, SIGNAL(detailPropertiesChanged()));
> QSignalSpy unknownSpy(&watcher, SIGNAL(isUnknownChanged()));
>
> // now modify the contact´s phone number so that it doesn´t match anymore
> @@ -242,17 +238,15 @@
> QTRY_COMPARE(contactIdSpy.count(), 1);
> QCOMPARE(aliasSpy.count(), 1);
> QCOMPARE(avatarSpy.count(), 1);
> - QCOMPARE(contextsSpy.count(), 1);
> - QCOMPARE(subTypesSpy.count(), 1);
> + QCOMPARE(detailPropertiesSpy.count(), 1);
> QCOMPARE(unknownSpy.count(), 1);
>
> // and verify that the values are properly cleared
> - QCOMPARE(watcher.contactId(), QString(""));
> - QCOMPARE(watcher.alias(), QString(""));
> - QCOMPARE(watcher.avatar(), QString(""));
> - QCOMPARE(watcher.phoneNumberContexts().count(), 0);
> - QCOMPARE(watcher.phoneNumberSubTypes().count(), 0);
> - QCOMPARE(watcher.isUnknown(), true);
> + QVERIFY(watcher.contactId().isEmpty());
> + QVERIFY(watcher.alias().isEmpty());
> + QVERIFY(watcher.avatar().isEmpty());
> + QVERIFY(watcher.detailProperties().isEmpty());
> + QVERIFY(watcher.isUnknown());
>
> clearManager();
> }
> @@ -261,11 +255,11 @@
> {
> // after removing a contact, the contact match should be cleared
> // verify that this happens, but first we need to make sure the match actually happened
> - QString phoneNumber("12345");
> + QString identifier("12345");
> QContact contact = createContact("FirstName",
> "LastName",
> "file://some_file",
> - QStringList() << phoneNumber,
> + QStringList() << identifier,
> QList<int>() << 0 << 1 << 2,
> QList<int>() << 3 << 4 << 5);
> ContactWatcher watcher;
> @@ -273,7 +267,7 @@
> QSignalSpy contactIdSpy(&watcher, SIGNAL(contactIdChanged()));
>
> // set the phone number and wait for the match to happen
> - watcher.setPhoneNumber(phoneNumber);
> + watcher.setIdentifier(identifier);
>
> // at this point we just need to make sure the contactId is correct, the other fields
> // are tested in a separate test
> @@ -283,8 +277,7 @@
>
> QSignalSpy aliasSpy(&watcher, SIGNAL(aliasChanged()));
> QSignalSpy avatarSpy(&watcher, SIGNAL(avatarChanged()));
> - QSignalSpy contextsSpy(&watcher, SIGNAL(phoneNumberContextsChanged()));
> - QSignalSpy subTypesSpy(&watcher, SIGNAL(phoneNumberSubTypesChanged()));
> + QSignalSpy detailPropertiesSpy(&watcher, SIGNAL(detailPropertiesChanged()));
> QSignalSpy unknownSpy(&watcher, SIGNAL(isUnknownChanged()));
>
> // now remove the contact
> @@ -293,17 +286,15 @@
> QTRY_COMPARE(contactIdSpy.count(), 1);
> QCOMPARE(aliasSpy.count(), 1);
> QCOMPARE(avatarSpy.count(), 1);
> - QCOMPARE(contextsSpy.count(), 1);
> - QCOMPARE(subTypesSpy.count(), 1);
> + QCOMPARE(detailPropertiesSpy.count(), 1);
> QCOMPARE(unknownSpy.count(), 1);
>
> // and verify that the values are properly cleared
> - QCOMPARE(watcher.contactId(), QString(""));
> - QCOMPARE(watcher.alias(), QString(""));
> - QCOMPARE(watcher.avatar(), QString(""));
> - QCOMPARE(watcher.phoneNumberContexts().count(), 0);
> - QCOMPARE(watcher.phoneNumberSubTypes().count(), 0);
> - QCOMPARE(watcher.isUnknown(), true);
> + QVERIFY(watcher.contactId().isEmpty());
> + QVERIFY(watcher.alias().isEmpty());
> + QVERIFY(watcher.avatar().isEmpty());
> + QVERIFY(watcher.detailProperties().isEmpty());
> + QVERIFY(watcher.isUnknown());
>
> clearManager();
> }
> @@ -313,11 +304,11 @@
> // clearing a phone number should trigger the contact data to be cleared too
> // after removing a contact, the contact match should be cleared
> // verify that this happens, but first we need to make sure the match actually happened
> - QString phoneNumber("12345");
> + QString identifier("12345");
> QContact contact = createContact("FirstName",
> "LastName",
> "file://some_file",
> - QStringList() << phoneNumber,
> + QStringList() << identifier,
> QList<int>() << 0 << 1 << 2,
> QList<int>() << 3 << 4 << 5);
> ContactWatcher watcher;
> @@ -325,7 +316,7 @@
> QSignalSpy contactIdSpy(&watcher, SIGNAL(contactIdChanged()));
>
> // set the phone number and wait for the match to happen
> - watcher.setPhoneNumber(phoneNumber);
> + watcher.setIdentifier(identifier);
>
> // at this point we just need to make sure the contactId is correct, the other fields
> // are tested in a separate test
> @@ -335,34 +326,31 @@
>
> QSignalSpy aliasSpy(&watcher, SIGNAL(aliasChanged()));
> QSignalSpy avatarSpy(&watcher, SIGNAL(avatarChanged()));
> - QSignalSpy contextsSpy(&watcher, SIGNAL(phoneNumberContextsChanged()));
> - QSignalSpy subTypesSpy(&watcher, SIGNAL(phoneNumberSubTypesChanged()));
> + QSignalSpy detailPropertiesSpy(&watcher, SIGNAL(detailPropertiesChanged()));
> QSignalSpy unknownSpy(&watcher, SIGNAL(isUnknownChanged()));
>
> // now clear the phone number
> - watcher.setPhoneNumber("");
> + watcher.setIdentifier("");
>
> QCOMPARE(contactIdSpy.count(), 1);
> QCOMPARE(aliasSpy.count(), 1);
> QCOMPARE(avatarSpy.count(), 1);
> - QCOMPARE(contextsSpy.count(), 1);
> - QCOMPARE(subTypesSpy.count(), 1);
> + QCOMPARE(detailPropertiesSpy.count(), 1);
> QCOMPARE(unknownSpy.count(), 1);
>
> // and verify that the values are properly cleared
> - QCOMPARE(watcher.contactId(), QString(""));
> - QCOMPARE(watcher.alias(), QString(""));
> - QCOMPARE(watcher.avatar(), QString(""));
> - QCOMPARE(watcher.phoneNumberContexts().count(), 0);
> - QCOMPARE(watcher.phoneNumberSubTypes().count(), 0);
> - QCOMPARE(watcher.isUnknown(), true);
> + QVERIFY(watcher.contactId().isEmpty());
> + QVERIFY(watcher.alias().isEmpty());
> + QVERIFY(watcher.avatar().isEmpty());
> + QVERIFY(watcher.detailProperties().isEmpty());
> + QVERIFY(watcher.isUnknown());
>
> clearManager();
> }
>
> void ContactWatcherTest::testInteractiveProperty_data()
> {
> - QTest::addColumn<QString>("phoneNumber");
> + QTest::addColumn<QString>("identifier");
> QTest::addColumn<int>("signalCount");
> QTest::addColumn<bool>("interactive");
>
> @@ -374,7 +362,7 @@
>
> void ContactWatcherTest::testInteractiveProperty()
> {
> - QFETCH(QString, phoneNumber);
> + QFETCH(QString, identifier);
> QFETCH(int, signalCount);
> QFETCH(bool, interactive);
>
> @@ -382,7 +370,7 @@
> watcher.componentComplete();
> QSignalSpy spy(&watcher, SIGNAL(interactiveChanged()));
>
> - watcher.setPhoneNumber(phoneNumber);
> + watcher.setIdentifier(identifier);
> // the initial interactive value is false it will not change in case of invalid phones
> QTRY_COMPARE(spy.count(), signalCount);
> QCOMPARE(watcher.interactive(), interactive);
> @@ -391,30 +379,28 @@
>
> void ContactWatcherTest::testLateSearch()
> {
> - QString phoneNumber("12345");
> + QString identifier("12345");
> QContact contact = createContact("FirstName",
> "LastName",
> "file://some_file",
> - QStringList() << phoneNumber,
> + QStringList() << identifier,
> QList<int>() << 0 << 1 << 2,
> QList<int>() << 3 << 4 << 5);
> ContactWatcher watcher;
> QSignalSpy contactIdSpy(&watcher, SIGNAL(contactIdChanged()));
> QSignalSpy aliasSpy(&watcher, SIGNAL(aliasChanged()));
> QSignalSpy avatarSpy(&watcher, SIGNAL(avatarChanged()));
> - QSignalSpy contextsSpy(&watcher, SIGNAL(phoneNumberContextsChanged()));
> - QSignalSpy subTypesSpy(&watcher, SIGNAL(phoneNumberSubTypesChanged()));
> + QSignalSpy detailPropertiesSpy(&watcher, SIGNAL(detailPropertiesChanged()));
> QSignalSpy unknownSpy(&watcher, SIGNAL(isUnknownChanged()));
>
> // set the phone number and wait for the match to happen
> - watcher.setPhoneNumber(phoneNumber);
> + watcher.setIdentifier(identifier);
>
> // component not complete yet
> QTRY_COMPARE(contactIdSpy.count(), 0);
> QCOMPARE(aliasSpy.count(), 0);
> QCOMPARE(avatarSpy.count(), 0);
> - QCOMPARE(contextsSpy.count(), 0);
> - QCOMPARE(subTypesSpy.count(), 0);
> + QCOMPARE(detailPropertiesSpy.count(), 0);
> QCOMPARE(unknownSpy.count(), 0);
>
> // mark as complete
> @@ -424,21 +410,65 @@
> QTRY_COMPARE(contactIdSpy.count(), 1);
> QCOMPARE(aliasSpy.count(), 1);
> QCOMPARE(avatarSpy.count(), 1);
> - QCOMPARE(contextsSpy.count(), 1);
> - QCOMPARE(subTypesSpy.count(), 1);
> + QCOMPARE(detailPropertiesSpy.count(), 1);
> QCOMPARE(unknownSpy.count(), 1);
>
> // and verify that the values are properly set
> QCOMPARE(watcher.contactId(), contact.id().toString());
> QCOMPARE(watcher.alias(), ContactUtils::formatContactName(contact));
> QCOMPARE(watcher.avatar(), contact.detail<QContactAvatar>().imageUrl().toString());
> - QCOMPARE(watcher.phoneNumberContexts(), contact.detail<QContactPhoneNumber>().contexts());
> - QCOMPARE(watcher.phoneNumberSubTypes(), contact.detail<QContactPhoneNumber>().subTypes());
> + QCOMPARE(watcher.unwrapIntList(watcher.detailProperties()["phoneNumberContexts"].toList()), contact.detail<QContactPhoneNumber>().contexts());
> + QCOMPARE(watcher.unwrapIntList(watcher.detailProperties()["phoneNumberSubTypes"].toList()), contact.detail<QContactPhoneNumber>().subTypes());
> QCOMPARE(watcher.isUnknown(), false);
>
> clearManager();
> }
>
> +void ContactWatcherTest::testAddressableFields()
> +{
> + ContactWatcher watcher;
> +
> + // check that addressable fields contains "tel" by default
> + QCOMPARE(watcher.addressableFields().count(), 1);
> + QCOMPARE(watcher.addressableFields()[0], QString("tel"));
> +
> + QSignalSpy addressableFieldsSpy(&watcher, SIGNAL(addressableFieldsChanged()));
> + QStringList addressableFields;
> + addressableFields << "x-jabber" << "tel" << "x-sip";
> + watcher.setAddressableFields(addressableFields);
> + QCOMPARE(addressableFieldsSpy.count(), 1);
> + QCOMPARE(watcher.addressableFields(), addressableFields);
> +}
> +
> +void ContactWatcherTest::testExtendedFieldMatch()
> +{
> + QString field("x-jabber");
> + QString identifier("foo.bar at someserver.jabber");
> + QContact contact = createContact("FirstName",
> + "LastName",
> + "file://some_file",
> + QStringList() << "12345",
> + QList<int>() << 0 << 1 << 2,
> + QList<int>() << 3 << 4 << 5);
> +
> + // now add the extended info to the contact
> + QContactExtendedDetail detail;
> + detail.setName(field);
> + detail.setData(identifier);
> + contact.appendDetail(detail);
> + mManager->saveContact(&contact);
> +
> + // now create the watcher and check that it matches this field
> + ContactWatcher watcher;
> + QSignalSpy contactIdSpy(&watcher, SIGNAL(contactIdChanged()));
> + watcher.setIdentifier(identifier);
> + watcher.setAddressableFields(QStringList() << field);
> + watcher.componentComplete();
> +
> + QTRY_COMPARE(contactIdSpy.count(), 1);
> + QCOMPARE(watcher.contactId(), contact.id().toString());
> +}
> +
> QContact ContactWatcherTest::createContact(const QString &firstName,
> const QString &lastName,
> const QString &avatarUrl,
>
> === modified file 'approver/approver.cpp'
> --- approver/approver.cpp 2015-02-09 20:32:32 +0000
> +++ approver/approver.cpp 2015-03-25 22:11:52 +0000
> @@ -33,6 +33,7 @@
> #include "callentry.h"
> #include "tonegenerator.h"
> #include "telepathyhelper.h"
> +#include "accountentry.h"
>
> #include <QContactAvatar>
> #include <QContactDisplayLabel>
> @@ -321,6 +322,12 @@
> showSnapDecision(dispatchOp, channel);
> GreeterContacts::instance()->setContactFilter(QContactPhoneNumber::match(contact->id()));
> } else {
> + AccountEntry *account = TelepathyHelper::instance()->accountForConnection(callChannel->connection());
> + if (!account) {
> + qCritical() << "Call exists with no account for connection";
> + return;
> + }
> +
> // try to match the contact info
> QContactFetchRequest *request = new QContactFetchRequest(this);
> request->setFilter(QContactPhoneNumber::match(contact->id()));
> @@ -345,8 +352,14 @@
> showSnapDecision(dispatchOp, channel, contact);
> });
>
> - request->setManager(ContactUtils::sharedManager());
> - request->start();
> + // FIXME: For accounts not based on phone numbers, don't try to match contacts for now
> + if (account->type() == AccountEntry::PhoneAccount) {
> + request->setManager(ContactUtils::sharedManager());
> + request->start();
> + } else {
> + // just emit the signal to pretend we did a contact search
> + Q_EMIT request->stateChanged(QContactAbstractRequest::FinishedState);
> + }
> }
> }
>
> @@ -397,8 +410,8 @@
> void Approver::onRejectMessage(Tp::ChannelDispatchOperationPtr dispatchOp, const char *action)
> {
> if (mRejectActions.contains(action)) {
> - QString phoneNumber = dispatchOp->channels().first()->targetContact()->id();
> - ChatManager::instance()->sendMessage(QStringList() << phoneNumber, mRejectActions[action],
> + QString targetId = dispatchOp->channels().first()->targetContact()->id();
> + ChatManager::instance()->sendMessage(QStringList() << targetId, mRejectActions[action],
> dispatchOp->account()->uniqueIdentifier());
> }
>
>
> === modified file 'handler/callhandler.cpp'
> --- handler/callhandler.cpp 2015-02-17 17:01:36 +0000
> +++ handler/callhandler.cpp 2015-03-25 22:11:52 +0000
> @@ -92,7 +92,7 @@
> {
> }
>
> -void CallHandler::startCall(const QString &phoneNumber, const QString &accountId)
> +void CallHandler::startCall(const QString &targetId, const QString &accountId)
> {
> // Request the contact to start audio call
> AccountEntry *accountEntry = TelepathyHelper::instance()->accountForId(accountId);
> @@ -105,7 +105,7 @@
> return;
> }
>
> - connect(connection->contactManager()->contactsForIdentifiers(QStringList() << phoneNumber),
> + connect(connection->contactManager()->contactsForIdentifiers(QStringList() << targetId),
> SIGNAL(finished(Tp::PendingOperation*)),
> SLOT(onContactsAvailable(Tp::PendingOperation*)));
> }
> @@ -354,7 +354,7 @@
> }
> }
>
> -Tp::CallChannelPtr CallHandler::existingCall(const QString &phoneNumber)
> +Tp::CallChannelPtr CallHandler::existingCall(const QString &targetId)
> {
> Tp::CallChannelPtr channel;
> Q_FOREACH(const Tp::CallChannelPtr &ch, mCallChannels) {
> @@ -362,7 +362,12 @@
> continue;
> }
>
> - if (PhoneUtils::comparePhoneNumbers(ch->targetContact()->id(), phoneNumber)) {
> + AccountEntry *account = TelepathyHelper::instance()->accountForConnection(ch->connection());
> + if (!account) {
> + continue;
> + }
> +
> + if (account->compareIds(ch->targetContact()->id(), targetId)) {
> channel = ch;
> break;
> }
>
> === modified file 'handler/callhandler.h'
> --- handler/callhandler.h 2015-02-17 17:01:36 +0000
> +++ handler/callhandler.h 2015-03-25 22:11:52 +0000
> @@ -40,7 +40,7 @@
>
> public Q_SLOTS:
> void onCallChannelAvailable(Tp::CallChannelPtr channel);
> - void startCall(const QString &phoneNumber, const QString &accountId);
> + void startCall(const QString &targetId, const QString &accountId);
> void hangUpCall(const QString &objectPath);
> void setHold(const QString &objectPath, bool hold);
> void setMuted(const QString &objectPath, bool muted);
> @@ -58,7 +58,7 @@
> void callHoldingFailed(const QString &objectPath);
>
> protected:
> - Tp::CallChannelPtr existingCall(const QString &phoneNumber);
> + Tp::CallChannelPtr existingCall(const QString &targetId);
> Tp::CallChannelPtr callFromObjectPath(const QString &objectPath);
>
> protected Q_SLOTS:
>
> === modified file 'handler/texthandler.cpp'
> --- handler/texthandler.cpp 2015-01-15 15:52:44 +0000
> +++ handler/texthandler.cpp 2015-03-25 22:11:52 +0000
> @@ -77,20 +77,20 @@
>
> if (mPendingMessages.contains(accountId)) {
> // create text channels to send the pending messages
> - Q_FOREACH(const QStringList& phoneNumbers, mPendingMessages[accountId].keys()) {
> - startChat(phoneNumbers, accountId);
> + Q_FOREACH(const QStringList& recipients, mPendingMessages[accountId].keys()) {
> + startChat(recipients, accountId);
> }
> }
> if (mPendingMMSs.contains(accountId)) {
> // create text channels to send the pending MMSs
> - Q_FOREACH(const QStringList& phoneNumbers, mPendingMMSs[accountId].keys()) {
> - startChat(phoneNumbers, accountId);
> + Q_FOREACH(const QStringList& recipients, mPendingMMSs[accountId].keys()) {
> + startChat(recipients, accountId);
> }
> }
> if (mPendingSilentMessages.contains(accountId)) {
> // create text channels to send the pending silent messages
> - Q_FOREACH(const QStringList& phoneNumbers, mPendingSilentMessages[accountId].keys()) {
> - startChat(phoneNumbers, accountId);
> + Q_FOREACH(const QStringList& recipients, mPendingSilentMessages[accountId].keys()) {
> + startChat(recipients, accountId);
> }
> }
>
> @@ -103,7 +103,7 @@
> return handler;
> }
>
> -void TextHandler::startChat(const QStringList &phoneNumbers, const QString &accountId)
> +void TextHandler::startChat(const QStringList &recipients, const QString &accountId)
> {
> // Request the contact to start chatting to
> // FIXME: make it possible to select which account to use, for now, pick the first one
> @@ -113,7 +113,7 @@
> return;
> }
>
> - connect(account->account()->connection()->contactManager()->contactsForIdentifiers(phoneNumbers),
> + connect(account->account()->connection()->contactManager()->contactsForIdentifiers(recipients),
> SIGNAL(finished(Tp::PendingOperation*)),
> SLOT(onContactsAvailable(Tp::PendingOperation*)));
> }
> @@ -205,21 +205,21 @@
> return message;
> }
>
> -void TextHandler::sendMMS(const QStringList &phoneNumbers, const AttachmentList &attachments, const QString &accountId) {
> +void TextHandler::sendMMS(const QStringList &recipients, const AttachmentList &attachments, const QString &accountId) {
> AccountEntry *account = TelepathyHelper::instance()->accountForId(accountId);
> if (!account) {
> // account does not exist
> return;
> }
> if (!account->connected()) {
> - mPendingMMSs[accountId][phoneNumbers].append(attachments);
> + mPendingMMSs[accountId][recipients].append(attachments);
> return;
> }
>
> - Tp::TextChannelPtr channel = existingChat(phoneNumbers, accountId);
> + Tp::TextChannelPtr channel = existingChat(recipients, accountId);
> if (channel.isNull()) {
> - mPendingMMSs[accountId][phoneNumbers].append(attachments);
> - startChat(phoneNumbers, accountId);
> + mPendingMMSs[accountId][recipients].append(attachments);
> + startChat(recipients, accountId);
> return;
> }
>
> @@ -230,7 +230,7 @@
> SLOT(onMessageSent(Tp::PendingOperation*)));
> }
>
> -void TextHandler::sendSilentMessage(const QStringList &phoneNumbers, const QString &message, const QString &accountId)
> +void TextHandler::sendSilentMessage(const QStringList &recipients, const QString &message, const QString &accountId)
> {
> AccountEntry *account = TelepathyHelper::instance()->accountForId(accountId);
> if (!account) {
> @@ -238,13 +238,13 @@
> return;
> }
> if (!account->connected()) {
> - mPendingSilentMessages[accountId][phoneNumbers].append(message);
> + mPendingSilentMessages[accountId][recipients].append(message);
> return;
> }
> - Tp::TextChannelPtr channel = existingChat(phoneNumbers, accountId);
> + Tp::TextChannelPtr channel = existingChat(recipients, accountId);
> if (channel.isNull()) {
> - mPendingSilentMessages[accountId][phoneNumbers].append(message);
> - startChat(phoneNumbers, accountId);
> + mPendingSilentMessages[accountId][recipients].append(message);
> + startChat(recipients, accountId);
> return;
> }
>
> @@ -263,7 +263,7 @@
> SLOT(onMessageSent(Tp::PendingOperation*)));
> }
>
> -void TextHandler::sendMessage(const QStringList &phoneNumbers, const QString &message, const QString &accountId)
> +void TextHandler::sendMessage(const QStringList &recipients, const QString &message, const QString &accountId)
> {
> AccountEntry *account = TelepathyHelper::instance()->accountForId(accountId);
> if (!account) {
> @@ -271,14 +271,14 @@
> return;
> }
> if (!account->connected()) {
> - mPendingMessages[accountId][phoneNumbers].append(message);
> + mPendingMessages[accountId][recipients].append(message);
> return;
> }
>
> - Tp::TextChannelPtr channel = existingChat(phoneNumbers, accountId);
> + Tp::TextChannelPtr channel = existingChat(recipients, accountId);
> if (channel.isNull()) {
> - mPendingMessages[accountId][phoneNumbers].append(message);
> - startChat(phoneNumbers, accountId);
> + mPendingMessages[accountId][recipients].append(message);
> + startChat(recipients, accountId);
> return;
> }
>
> @@ -287,9 +287,9 @@
> SLOT(onMessageSent(Tp::PendingOperation*)));
> }
>
> -void TextHandler::acknowledgeMessages(const QStringList &phoneNumbers, const QStringList &messageIds, const QString &accountId)
> +void TextHandler::acknowledgeMessages(const QStringList &recipients, const QStringList &messageIds, const QString &accountId)
> {
> - Tp::TextChannelPtr channel = existingChat(phoneNumbers, accountId);
> + Tp::TextChannelPtr channel = existingChat(recipients, accountId);
> if (channel.isNull()) {
> return;
> }
> @@ -321,8 +321,8 @@
> return;
> }
>
> - Q_FOREACH(const Tp::ContactPtr &phoneNumberOld, channel->groupContacts(false)) {
> - recipients << phoneNumberOld->id();
> + Q_FOREACH(const Tp::ContactPtr &channelContact, channel->groupContacts(false)) {
> + recipients << channelContact->id();
> }
>
> QMap<QStringList, QStringList> &pendingMessages = mPendingMessages[accountId];
> @@ -377,25 +377,25 @@
> }
> }
>
> -Tp::TextChannelPtr TextHandler::existingChat(const QStringList &phoneNumbers, const QString &accountId)
> +Tp::TextChannelPtr TextHandler::existingChat(const QStringList &targetIds, const QString &accountId)
> {
> Tp::TextChannelPtr channel;
>
> Q_FOREACH(const Tp::TextChannelPtr &channel, mChannels) {
> int count = 0;
> AccountEntry *channelAccount = TelepathyHelper::instance()->accountForConnection(channel->connection());
> - if (!channelAccount || channel->groupContacts(false).size() != phoneNumbers.size()
> + if (!channelAccount || channel->groupContacts(false).size() != targetIds.size()
> || channelAccount->accountId() != accountId) {
> continue;
> }
> - Q_FOREACH(const QString &phoneNumberNew, phoneNumbers) {
> - Q_FOREACH(const Tp::ContactPtr &phoneNumberOld, channel->groupContacts(false)) {
> - if (PhoneUtils::comparePhoneNumbers(phoneNumberOld->id(), phoneNumberNew)) {
> + Q_FOREACH(const QString &targetId, targetIds) {
> + Q_FOREACH(const Tp::ContactPtr &channelContact, channel->groupContacts(false)) {
> + if (channelAccount->compareIds(channelContact->id(), targetId)) {
> count++;
> }
> }
> }
> - if (count == phoneNumbers.size()) {
> + if (count == targetIds.size()) {
> return channel;
> }
> }
>
> === modified file 'handler/texthandler.h'
> --- handler/texthandler.h 2014-09-10 04:27:25 +0000
> +++ handler/texthandler.h 2015-03-25 22:11:52 +0000
> @@ -33,14 +33,14 @@
> Q_OBJECT
> public:
> static TextHandler *instance();
> - void startChat(const QStringList &phoneNumber, const QString &accountId);
> + void startChat(const QStringList &recipients, const QString &accountId);
> void startChat(const Tp::AccountPtr &account, const Tp::Contacts &contacts);
>
> public Q_SLOTS:
> - void sendMessage(const QStringList &phoneNumber, const QString &message, const QString &accountId);
> - void sendSilentMessage(const QStringList &phoneNumber, const QString &message, const QString &accountId);
> - void sendMMS(const QStringList &phoneNumbers, const AttachmentList &attachments, const QString &accountId);
> - void acknowledgeMessages(const QStringList &phoneNumber, const QStringList &messageIds, const QString &accountId);
> + void sendMessage(const QStringList &recipients, const QString &message, const QString &accountId);
> + void sendSilentMessage(const QStringList &recipients, const QString &message, const QString &accountId);
> + void sendMMS(const QStringList &recipients, const AttachmentList &attachments, const QString &accountId);
> + void acknowledgeMessages(const QStringList &recipients, const QStringList &messageIds, const QString &accountId);
>
> protected Q_SLOTS:
> void onTextChannelAvailable(Tp::TextChannelPtr channel);
> @@ -49,7 +49,7 @@
> void onConnectedChanged();
>
> protected:
> - Tp::TextChannelPtr existingChat(const QStringList &phoneNumber, const QString &accountId);
> + Tp::TextChannelPtr existingChat(const QStringList &targetIds, const QString &accountId);
>
> private:
> explicit TextHandler(QObject *parent = 0);
>
> === modified file 'indicator/messagingmenu.cpp'
> --- indicator/messagingmenu.cpp 2015-02-04 20:42:14 +0000
> +++ indicator/messagingmenu.cpp 2015-03-25 22:11:52 +0000
> @@ -27,6 +27,7 @@
> #include "messagingmenu.h"
> #include "telepathyhelper.h"
> #include "accountentry.h"
> +#include "ofonoaccountentry.h"
> #include <QContactAvatar>
> #include <QContactFetchRequest>
> #include <QContactFilter>
> @@ -110,6 +111,14 @@
> QUrl iconPath = QUrl::fromLocalFile(telephonyServiceDir() + "/assets/avatar-default at 18.png");
> QString contactAlias = senderId;
>
> + AccountEntry *account = TelepathyHelper::instance()->accountForId(accountId);
> + if (!account) {
> + return;
> + }
> +
> + // FIXME: for accounts not based on phone number, we need to match other fields.
> + // Right now we don't even bother trying to match contact data
> +
> // try to match the contact info
> QContactFetchRequest *request = new QContactFetchRequest(this);
> request->setFilter(QContactPhoneNumber::match(senderId));
> @@ -182,8 +191,14 @@
> g_object_unref(message);
> });
>
> - request->setManager(ContactUtils::sharedManager());
> - request->start();
> + // FIXME: For accounts not based on phone numbers, don't try to match contacts for now
> + if (account->type() == AccountEntry::PhoneAccount) {
> + request->setManager(ContactUtils::sharedManager());
> + request->start();
> + } else {
> + // just emit the signal to pretend we did a contact search
> + Q_EMIT request->stateChanged(QContactAbstractRequest::FinishedState);
> + }
> }
>
> void MessagingMenu::removeMessage(const QString &messageId)
> @@ -201,7 +216,7 @@
> GVariant *messages = NULL;
> GFile *file = g_file_new_for_uri(call.contactIcon.toString().toUtf8().data());
> GIcon *icon = g_file_icon_new(file);
> - MessagingMenuMessage *message = messaging_menu_message_new(call.number.toUtf8().data(),
> + MessagingMenuMessage *message = messaging_menu_message_new(call.targetId.toUtf8().data(),
> icon,
> call.contactAlias.toUtf8().data(),
> NULL,
> @@ -209,7 +224,7 @@
> call.timestamp.toMSecsSinceEpoch() * 1000); // the value is expected to be in microseconds
>
> call.messageId = messaging_menu_message_get_id(message);
> - if (call.number != "x-ofono-private" && call.number != "x-ofono-unknown") {
> + if (call.targetId != "x-ofono-private" && call.targetId != "x-ofono-unknown") {
> messaging_menu_message_add_action(message,
> "callBack",
> C::gettext("Call back"), // label
> @@ -242,12 +257,18 @@
> g_object_unref(message);
> }
>
> -void MessagingMenu::addCall(const QString &phoneNumber, const QString &accountId, const QDateTime ×tamp)
> +void MessagingMenu::addCall(const QString &targetId, const QString &accountId, const QDateTime ×tamp)
> {
> Call call;
> bool found = false;
> + AccountEntry *account = TelepathyHelper::instance()->accountForId(accountId);
> + if (!account) {
> + return;
> + }
> +
> Q_FOREACH(Call callMessage, mCalls) {
> - if (PhoneUtils::comparePhoneNumbers(callMessage.number, phoneNumber)) {
> + // FIXME: we need a better strategy to group calls from different accounts
> + if (account->compareIds(callMessage.targetId, targetId)) {
> call = callMessage;
> found = true;
> mCalls.removeOne(callMessage);
> @@ -259,10 +280,10 @@
> }
>
> if (!found) {
> - call.contactAlias = phoneNumber;
> + call.contactAlias = targetId;
> call.accountId = accountId;
> call.contactIcon = QUrl::fromLocalFile(telephonyServiceDir() + "/assets/avatar-default at 18.png");
> - call.number = phoneNumber;
> + call.targetId = targetId;
> call.count = 0;
> }
>
> @@ -272,19 +293,22 @@
> QString text;
> text = QString::fromUtf8(C::ngettext("%1 missed call", "%1 missed calls", call.count)).arg(call.count);
>
> - if (phoneNumber.startsWith("x-ofono-private")) {
> + if (targetId.startsWith("x-ofono-private")) {
> call.contactAlias = C::gettext("Private number");
> addCallToMessagingMenu(call, text);
> return;
> - } else if (phoneNumber.startsWith("x-ofono-unknown")) {
> + } else if (targetId.startsWith("x-ofono-unknown")) {
> call.contactAlias = C::gettext("Unknown number");
> addCallToMessagingMenu(call, text);
> return;
> }
>
> + // FIXME: we need to match other fields for accounts not based on phone numbers.
> + // For now we are not even trying to match contact data
> +
> // try to match the contact info
> QContactFetchRequest *request = new QContactFetchRequest(this);
> - request->setFilter(QContactPhoneNumber::match(phoneNumber));
> + request->setFilter(QContactPhoneNumber::match(targetId));
>
> // place the messaging-menu item only after the contact fetch request is finished, as we can´t simply update
> QObject::connect(request, &QContactAbstractRequest::stateChanged, [request, call, text, this]() {
> @@ -310,17 +334,28 @@
> addCallToMessagingMenu(newCall, text);
> });
>
> - request->setManager(ContactUtils::sharedManager());
> - request->start();
> + // FIXME: For accounts not based on phone numbers, don't try to match contacts for now
> + if (account->type() == AccountEntry::PhoneAccount) {
> + request->setManager(ContactUtils::sharedManager());
> + request->start();
> + } else {
> + // just emit the signal to pretend we did a contact search
> + Q_EMIT request->stateChanged(QContactAbstractRequest::FinishedState);
> + }
> }
>
> void MessagingMenu::showVoicemailEntry(AccountEntry *account)
> {
> + OfonoAccountEntry *ofonoAccount = qobject_cast<OfonoAccountEntry*>(account);
Sip accounts can also show voicemail. This is not specific to ofono, but not sure how to proceed in such case.
> + if (!ofonoAccount) {
> + return;
> + }
> +
> messaging_menu_app_remove_message_by_id(mCallsApp, account->accountId().toUtf8().data());
> mVoicemailIds.removeAll(account->accountId());
>
> QString messageBody = C::gettext("Voicemail messages");
> - uint count = account->voicemailCount();
> + uint count = ofonoAccount->voicemailCount();
> if (count != 0) {
> messageBody = QString::fromUtf8(C::ngettext("%1 voicemail message", "%1 voicemail messages", count)).arg(count);
> }
> @@ -340,7 +375,7 @@
> QDateTime::currentDateTime().toMSecsSinceEpoch() * 1000); // the value is expected to be in microseconds
> g_signal_connect(message, "activate", G_CALLBACK(&MessagingMenu::callsActivateCallback), this);
> messaging_menu_app_append_message(mCallsApp, message, SOURCE_ID, true);
> - mVoicemailIds.append(account->accountId());
> + mVoicemailIds.append(ofonoAccount->accountId());
>
> g_object_unref(icon);
> g_object_unref(message);
> @@ -411,10 +446,13 @@
> void MessagingMenu::saveFlashMessage(const QString &messageId)
> {
> QVariantMap details = mMessages[messageId];
> + AccountEntry *account = TelepathyHelper::instance()->accountForId(details["accountId"].toString());
> + bool phoneNumberBased = account && (account->type() == AccountEntry::PhoneAccount);
> History::Thread thread = History::Manager::instance()->threadForParticipants(details["accountId"].toString(),
> History::EventTypeText,
> QStringList() << details["senderId"].toString(),
> - History::MatchPhoneNumber,
> + phoneNumberBased ? History::MatchPhoneNumber :
> + History::MatchCaseSensitive,
> true);
> History::TextEvent textEvent(details["accountId"].toString(),
> thread.threadId(),
> @@ -447,30 +485,37 @@
>
> void MessagingMenu::callBack(const QString &messageId)
> {
> - QString phoneNumber = callFromMessageId(messageId).number;
> - qDebug() << "TelephonyService/MessagingMenu: Calling back" << phoneNumber;
> - ApplicationUtils::openUrl(QString("tel:///%1").arg(QString(QUrl::toPercentEncoding(phoneNumber))));
> + Call call = callFromMessageId(messageId);
> + AccountEntry *account = TelepathyHelper::instance()->accountForId(call.accountId);
> + if (!account) {
> + qWarning() << "Could not find the account originating the call";
> + }
> + qDebug() << "TelephonyService/MessagingMenu: Calling back" << call.targetId;
> + // FIXME: support accounts not based on phone numbers
> + if (account->type() == AccountEntry::PhoneAccount) {
> + ApplicationUtils::openUrl(QString("tel:///%1").arg(QString(QUrl::toPercentEncoding(call.targetId))));
> + }
> }
>
> void MessagingMenu::replyWithMessage(const QString &messageId, const QString &reply)
> {
> Call call = callFromMessageId(messageId);
> - qDebug() << "TelephonyService/MessagingMenu: Replying to call" << call.number << "with text" << reply;
> - Q_EMIT replyReceived(QStringList() << call.number, call.accountId, reply);
> + qDebug() << "TelephonyService/MessagingMenu: Replying to call" << call.targetId << "with text" << reply;
> + Q_EMIT replyReceived(QStringList() << call.targetId, call.accountId, reply);
> }
>
> void MessagingMenu::callVoicemail(const QString &messageId)
> {
> QString voicemailNumber;
> - Q_FOREACH(AccountEntry *accountEntry, TelepathyHelper::instance()->accounts()) {
> - if (!accountEntry->voicemailNumber().isEmpty() && messageId == accountEntry->accountId()) {
> - voicemailNumber = accountEntry->voicemailNumber();
> - break;
> - }
> + // get the corresponding account
> + OfonoAccountEntry *ofonoAccount = qobject_cast<OfonoAccountEntry*>(TelepathyHelper::instance()->accountForId(messageId));
Same here. We can also call voicemail on sip accounts.
> + if (ofonoAccount) {
> + voicemailNumber = ofonoAccount->voicemailNumber();
> }
>
> qDebug() << "TelephonyService/MessagingMenu: Calling voicemail for messageId" << messageId;
> if (!voicemailNumber.isEmpty()) {
> + // FIXME: we need to specify which account to use
> ApplicationUtils::openUrl(QUrl(QString("tel:///%1").arg(voicemailNumber)));
> }
> }
>
> === modified file 'indicator/messagingmenu.h'
> --- indicator/messagingmenu.h 2014-11-19 21:45:35 +0000
> +++ indicator/messagingmenu.h 2015-03-25 22:11:52 +0000
> @@ -32,7 +32,7 @@
> {
> public:
> Call() : count(0) { }
> - QString number;
> + QString targetId;
> int count;
> QString contactAlias;
> QUrl contactIcon;
> @@ -41,7 +41,7 @@
> QDateTime timestamp;
>
> bool operator==(const Call &other) {
> - return other.number == number;
> + return other.targetId == targetId;
> }
> };
>
> @@ -56,7 +56,7 @@
> void addFlashMessage(const QString &senderId, const QString &accountId, const QString &messageId, const QDateTime ×tamp, const QString &text);
> void removeMessage(const QString &messageId);
>
> - void addCall(const QString &phoneNumber, const QString &accountId, const QDateTime ×tamp);
> + void addCall(const QString &targetId, const QString &accountId, const QDateTime ×tamp);
> void addCallToMessagingMenu(Call call, const QString &text);
>
> static void flashMessageActivateCallback(MessagingMenuMessage *message, const char *actionId, GVariant *param, MessagingMenu *instance);
> @@ -68,7 +68,7 @@
>
> Q_SIGNALS:
> void replyReceived(const QStringList &recipients, const QString &accountId, const QString &reply);
> - void messageRead(const QStringList &phoneNumber, const QString &accountId, const QString &messageId);
> + void messageRead(const QStringList &recipients, const QString &accountId, const QString &messageId);
>
> private Q_SLOTS:
> void sendMessageReply(const QString &messageId, const QString &reply);
>
> === modified file 'indicator/textchannelobserver.cpp'
> --- indicator/textchannelobserver.cpp 2015-02-20 20:51:48 +0000
> +++ indicator/textchannelobserver.cpp 2015-03-25 22:11:52 +0000
> @@ -32,6 +32,7 @@
> #include "telepathyhelper.h"
> #include "phoneutils.h"
> #include "accountentry.h"
> +#include "ofonoaccountentry.h"
> #include <TelepathyQt/AvatarData>
> #include <TelepathyQt/TextChannel>
> #include <TelepathyQt/ReceivedMessage>
> @@ -88,12 +89,15 @@
> if (action == QLatin1String("notification_save_action")) {
> NotificationData *notificationData = (NotificationData*) data;
> if (notificationData != NULL) {
> + AccountEntry *account = TelepathyHelper::instance()->accountForId(notificationData->accountId);
> + bool phoneNumberBased = account && (account->type() == AccountEntry::PhoneAccount);
> QStringList recipients;
> recipients << notificationData->senderId << notificationData->participantIds;
> History::Thread thread = History::Manager::instance()->threadForParticipants(notificationData->accountId,
> History::EventTypeText,
> recipients,
> - History::MatchPhoneNumber,
> + phoneNumberBased ? History::MatchPhoneNumber :
> + History::MatchCaseSensitive,
> true);
> History::TextEvent textEvent(notificationData->accountId,
> thread.threadId(),
> @@ -191,10 +195,12 @@
>
> // check if the account is available
> if (!account->connected()) {
> + bool phoneNumberBased = account->type() == AccountEntry::PhoneAccount;
> History::Thread thread = History::Manager::instance()->threadForParticipants(account->accountId(),
> History::EventTypeText,
> recipients,
> - History::MatchPhoneNumber,
> + phoneNumberBased ? History::MatchPhoneNumber :
> + History::MatchCaseSensitive,
> true);
> History::TextEvent textEvent(account->accountId(),
> thread.threadId(),
> @@ -211,7 +217,10 @@
> History::Manager::instance()->writeEvents(events);
>
> QString failureMessage;
> - if (account->simLocked()) {
> + OfonoAccountEntry *ofonoAccount = qobject_cast<OfonoAccountEntry*>(account);
> + bool simLocked = (ofonoAccount && ofonoAccount->simLocked());
> +
> + if (simLocked) {
> failureMessage = C::gettext("Unlock your sim card and try again from the messaging application.");
> } else if (TelepathyHelper::instance()->flightMode()) {
we have to check if this is an ofono account here as well. We might be in flight mode but manually enable wifi and try to reply to an IM message.
> failureMessage = C::gettext("Deactivate flight mode and try again from the messaging application.");
> @@ -319,6 +328,11 @@
> // in greeter mode we show the notification right away as the contact data might not be received
> showNotificationForMessage(message, accountId, participantIds);
> } else {
> + AccountEntry *account = TelepathyHelper::instance()->accountForId(accountId);
> + if (!account) {
> + return;
> + }
> +
> // try to match the contact info
> QContactFetchRequest *request = new QContactFetchRequest(this);
> request->setFilter(QContactPhoneNumber::match(contact->id()));
> @@ -341,8 +355,14 @@
> showNotificationForMessage(message, accountId, participantIds, contact);
> });
>
> - request->setManager(ContactUtils::sharedManager());
> - request->start();
> + // FIXME: For accounts not based on phone numbers, don't try to match contacts for now
> + if (account->type() == AccountEntry::PhoneAccount) {
> + request->setManager(ContactUtils::sharedManager());
> + request->start();
> + } else {
> + // just emit the signal to pretend we did a contact search
> + Q_EMIT request->stateChanged(QContactAbstractRequest::FinishedState);
> + }
> }
>
> }
> @@ -458,6 +478,13 @@
> while (i != mNotifications.constEnd()) {
> NotifyNotification *notification = i.key();
> NotificationData *data = i.value();
> +
> + AccountEntry *account = TelepathyHelper::instance()->accountForId(data->accountId);
> + if (!account || account->type() != AccountEntry::PhoneAccount) {
> + return;
> + }
> +
> + // FIXME: add support for contact matching for non phone number based accounts
> Q_FOREACH(const QContactPhoneNumber phoneNumber, contact.details(QContactDetail::TypePhoneNumber)) {
> if (PhoneUtils::comparePhoneNumbers(data->senderId, phoneNumber.number())) {
> QString displayLabel = contact.detail<QContactDisplayLabel>().label();
>
> === modified file 'indicator/textchannelobserver.h'
> --- indicator/textchannelobserver.h 2014-11-24 15:07:19 +0000
> +++ indicator/textchannelobserver.h 2015-03-25 22:11:52 +0000
> @@ -41,7 +41,7 @@
>
> public Q_SLOTS:
> void onTextChannelAvailable(Tp::TextChannelPtr textChannel);
> - void sendMessage(const QStringList &phoneNumbers, const QString &text, const QString &accountId);
> + void sendMessage(const QStringList &recipients, const QString &text, const QString &accountId);
>
> protected:
> void showNotificationForFlashMessage(const Tp::ReceivedMessage &message, const QString &accountId);
>
> === modified file 'indicator/voicemailindicator.cpp'
> --- indicator/voicemailindicator.cpp 2014-09-16 15:35:04 +0000
> +++ indicator/voicemailindicator.cpp 2015-03-25 22:11:52 +0000
> @@ -23,6 +23,7 @@
> #include "telepathyhelper.h"
> #include "messagingmenu.h"
> #include "accountentry.h"
> +#include "ofonoaccountentry.h"
> #include <QDebug>
> #include <QDBusReply>
>
> @@ -37,13 +38,17 @@
> void VoiceMailIndicator::onAccountReady()
> {
> Q_FOREACH(AccountEntry *account, TelepathyHelper::instance()->accounts()) {
> + OfonoAccountEntry *ofonoAccount = qobject_cast<OfonoAccountEntry*>(account);
> + if (!ofonoAccount) {
> + continue;
> + }
> // disconnect previous signals if any
> - disconnect(account, SIGNAL(voicemailIndicatorChanged()), this, SLOT(onVoicemailIndicatorChanged()));
> - disconnect(account, SIGNAL(voicemailCountChanged()), this, SLOT(onVoicemailIndicatorChanged()));
> + disconnect(ofonoAccount, SIGNAL(voicemailIndicatorChanged()), this, SLOT(onVoicemailIndicatorChanged()));
> + disconnect(ofonoAccount, SIGNAL(voicemailCountChanged()), this, SLOT(onVoicemailIndicatorChanged()));
>
> - connect(account, SIGNAL(voicemailIndicatorChanged()), this, SLOT(onVoicemailIndicatorChanged()));
> - connect(account, SIGNAL(voicemailCountChanged()), this, SLOT(onVoicemailIndicatorChanged()));
> - if (account->voicemailIndicator()) {
> + connect(ofonoAccount, SIGNAL(voicemailIndicatorChanged()), this, SLOT(onVoicemailIndicatorChanged()));
> + connect(ofonoAccount, SIGNAL(voicemailCountChanged()), this, SLOT(onVoicemailIndicatorChanged()));
> + if (ofonoAccount->voicemailIndicator()) {
> MessagingMenu::instance()->showVoicemailEntry(account);
> } else {
> MessagingMenu::instance()->hideVoicemailEntry(account);
> @@ -53,14 +58,14 @@
>
> void VoiceMailIndicator::onVoicemailIndicatorChanged()
> {
> - AccountEntry *account = qobject_cast<AccountEntry*>(sender());
> - if (!account) {
> + OfonoAccountEntry *ofonoAccount = qobject_cast<OfonoAccountEntry*>(sender());
> + if (!ofonoAccount) {
> return;
> }
>
> - if (account->voicemailIndicator()) {
> - MessagingMenu::instance()->showVoicemailEntry(account);
> + if (ofonoAccount->voicemailIndicator()) {
> + MessagingMenu::instance()->showVoicemailEntry(ofonoAccount);
> } else {
> - MessagingMenu::instance()->hideVoicemailEntry(account);
> + MessagingMenu::instance()->hideVoicemailEntry(ofonoAccount);
> }
> }
>
> === modified file 'libtelephonyservice/CMakeLists.txt'
> --- libtelephonyservice/CMakeLists.txt 2014-08-25 14:49:53 +0000
> +++ libtelephonyservice/CMakeLists.txt 2015-03-25 22:11:52 +0000
> @@ -1,5 +1,6 @@
> set(library_SRCS
> accountentry.cpp
> + accountentryfactory.cpp
> audiooutput.cpp
> applicationutils.cpp
> callentry.cpp
> @@ -9,6 +10,7 @@
> chatmanager.cpp
> contactutils.cpp
> greetercontacts.cpp
> + ofonoaccountentry.cpp
> phoneutils.cpp
> ringtone.cpp
> telepathyhelper.cpp
>
> === modified file 'libtelephonyservice/accountentry.cpp'
> --- libtelephonyservice/accountentry.cpp 2015-02-20 18:46:14 +0000
> +++ libtelephonyservice/accountentry.cpp 2015-03-25 22:11:52 +0000
> @@ -1,5 +1,5 @@
> /*
> - * Copyright (C) 2013 Canonical, Ltd.
> + * Copyright (C) 2013-2015 Canonical, Ltd.
> *
> * Authors:
> * Gustavo Pichorim Boiko <gustavo.boiko at canonical.com>
> @@ -25,7 +25,7 @@
> #include "telepathyhelper.h"
>
> AccountEntry::AccountEntry(const Tp::AccountPtr &account, QObject *parent) :
> - QObject(parent), mAccount(account), mVoicemailCount(0), mVoicemailIndicator(false)
> + QObject(parent), mAccount(account)
> {
> initialize();
> }
> @@ -55,6 +55,27 @@
> return mAccount->displayName();
> }
>
> +QString AccountEntry::status() const
> +{
> + if (mAccount.isNull() || mAccount->connection().isNull() || mAccount->connection()->selfContact().isNull()) {
> + return QString::null;
> + }
> + Tp::Presence presence = mAccount->connection()->selfContact()->presence();
> + return presence.status();
> +}
> +
> +QString AccountEntry::statusMessage() const
> +{
> + if (mAccount.isNull() || mAccount->connection().isNull() || mAccount->connection()->selfContact().isNull()) {
> + return QString::null;
> + }
> + Tp::Presence presence = mAccount->connection()->selfContact()->presence();
> + if (presence.type() == Tp::ConnectionPresenceTypeAvailable) {
> + return presence.statusMessage();
> + }
> + return QString::null;
> +}
> +
> QString AccountEntry::selfContactId() const
> {
> if (!mAccount.isNull() && !mAccount->connection().isNull() &&
> @@ -64,27 +85,6 @@
> return QString();
> }
>
> -QString AccountEntry::networkName() const
> -{
> - if (mAccount.isNull() || mAccount->connection().isNull() || mAccount->connection()->selfContact().isNull()) {
> - return QString::null;
> - }
> - Tp::Presence presence = mAccount->connection()->selfContact()->presence();
> - if (presence.type() == Tp::ConnectionPresenceTypeAvailable) {
> - return presence.statusMessage();
> - }
> - return QString::null;
> -}
> -
> -bool AccountEntry::simLocked() const
> -{
> - if (mAccount.isNull() || mAccount->connection().isNull() || mAccount->connection()->selfContact().isNull()) {
> - return false;
> - }
> - Tp::Presence presence = mAccount->connection()->selfContact()->presence();
> - return (presence.type() == Tp::ConnectionPresenceTypeAway && presence.status() == "simlocked");
> -}
> -
> void AccountEntry::setDisplayName(const QString &name)
> {
> if (mAccount.isNull()) {
> @@ -100,44 +100,24 @@
> mAccount->connection()->selfContact()->presence().type() == Tp::ConnectionPresenceTypeAvailable;
> }
>
> -QStringList AccountEntry::emergencyNumbers() const
> -{
> - return mEmergencyNumbers;
> -}
> -
> -QString AccountEntry::voicemailNumber() const
> -{
> - return mVoicemailNumber;
> -}
> -
> -bool AccountEntry::voicemailIndicator() const
> -{
> - return mVoicemailIndicator;
> -}
> -
> -uint AccountEntry::voicemailCount() const
> -{
> - return mVoicemailCount;
> -}
> -
> Tp::AccountPtr AccountEntry::account() const
> {
> return mAccount;
> }
>
> -bool AccountEntry::emergencyCallsAvailable() const
> -{
> - if (mAccount.isNull() || mAccount->connection().isNull() || mAccount->connection()->selfContact().isNull()) {
> - return false;
> - }
> -
> - QString status = mAccount->connection()->selfContact()->presence().status();
> - return status != "flightmode" && status != "nomodem" && status != "";
> -}
> -
> -QString AccountEntry::serial() const
> -{
> - return mSerial;
> +AccountEntry::AccountType AccountEntry::type() const
> +{
> + return GenericAccount;
> +}
> +
> +QStringList AccountEntry::addressableVCardFields() const
> +{
> + return mAccount->protocolInfo().addressableVCardFields();
> +}
> +
> +bool AccountEntry::compareIds(const QString &first, const QString &second) const
> +{
> + return first == second;
> }
>
> void AccountEntry::initialize()
> @@ -208,36 +188,28 @@
> SIGNAL(connectedChanged()));
> connect(mAccount->connection()->selfContact().data(),
> SIGNAL(presenceChanged(Tp::Presence)),
> - SIGNAL(networkNameChanged()));
> - connect(mAccount->connection()->selfContact().data(),
> - SIGNAL(presenceChanged(Tp::Presence)),
> - SIGNAL(emergencyCallsAvailableChanged()));
> - connect(mAccount->connection()->selfContact().data(),
> - SIGNAL(presenceChanged(Tp::Presence)),
> - SIGNAL(simLockedChanged()));
> + SIGNAL(statusMessageChanged()));
> + connect(mAccount->connection()->selfContact().data(),
> + SIGNAL(presenceChanged(Tp::Presence)),
> + SIGNAL(statusChanged()));
> }
>
> void AccountEntry::onSelfHandleChanged(uint handle)
> {
> + Q_UNUSED(handle)
> watchSelfContactPresence();
>
> - Q_EMIT networkNameChanged();
> + Q_EMIT statusChanged();
> + Q_EMIT statusMessageChanged();
> Q_EMIT connectedChanged();
> - Q_EMIT simLockedChanged();
> Q_EMIT selfContactIdChanged();
> Q_EMIT activeChanged();
> }
>
> void AccountEntry::onConnectionChanged()
> {
> - QDBusConnection dbusConnection = QDBusConnection::sessionBus();
> if (!mAccount->connection()) {
> - // disconnect any previous dbus connections
> - if (!mConnectionInfo.objectPath.isEmpty()) {
> - dbusConnection.disconnect(mConnectionInfo.busName, mConnectionInfo.objectPath,
> - CANONICAL_TELEPHONY_EMERGENCYMODE_IFACE, "EmergencyNumbersChanged",
> - this, SLOT(onEmergencyNumbersChanged(QStringList)));
> - }
> +
>
> // and ensure the account gets connected
> ensureConnected();
> @@ -245,91 +217,14 @@
> mConnectionInfo.busName = mAccount->connection()->busName();
> mConnectionInfo.objectPath = mAccount->connection()->objectPath();
>
> - // connect the emergency numbers changed signal
> - dbusConnection.connect(mConnectionInfo.busName, mConnectionInfo.objectPath,
> - CANONICAL_TELEPHONY_EMERGENCYMODE_IFACE, "EmergencyNumbersChanged",
> - this, SLOT(onEmergencyNumbersChanged(QStringList)));
> -
> - // and get the current value of the emergency numbers
> - QDBusInterface connIface(mConnectionInfo.busName, mConnectionInfo.objectPath, CANONICAL_TELEPHONY_EMERGENCYMODE_IFACE);
> - QDBusReply<QStringList> replyNumbers = connIface.call("EmergencyNumbers");
> - if (replyNumbers.isValid()) {
> - mEmergencyNumbers = replyNumbers.value();
> - Q_EMIT emergencyNumbersChanged();
> - }
> -
> - // connect the voicemail number changed signal
> - dbusConnection.connect(mConnectionInfo.busName, mConnectionInfo.objectPath,
> - CANONICAL_TELEPHONY_VOICEMAIL_IFACE, "VoicemailNumberChanged",
> - this, SLOT(onVoicemailNumberChanged(QString)));
> -
> - QDBusInterface voicemailIface(mConnectionInfo.busName, mConnectionInfo.objectPath, CANONICAL_TELEPHONY_VOICEMAIL_IFACE);
> - QDBusReply<QString> replyNumber = voicemailIface.call("VoicemailNumber");
> - if (replyNumber.isValid()) {
> - mVoicemailNumber = replyNumber.value();
> - Q_EMIT voicemailNumberChanged();
> - }
> -
> - // connect the voicemail count changed signal
> - dbusConnection.connect(mConnectionInfo.busName, mConnectionInfo.objectPath,
> - CANONICAL_TELEPHONY_VOICEMAIL_IFACE, "VoicemailCountChanged",
> - this, SLOT(onVoicemailCountChanged(uint)));
> -
> - QDBusReply<uint> replyCount = voicemailIface.call("VoicemailCount");
> - if (replyCount.isValid()) {
> - mVoicemailCount = replyCount.value();
> - Q_EMIT voicemailCountChanged();
> - }
> -
> - // connect the voicemail indicator changed signal
> - dbusConnection.connect(mConnectionInfo.busName, mConnectionInfo.objectPath,
> - CANONICAL_TELEPHONY_VOICEMAIL_IFACE, "VoicemailIndicatorChanged",
> - this, SLOT(onVoicemailIndicatorChanged(bool)));
> -
> - QDBusReply<bool> replyIndicator = voicemailIface.call("VoicemailIndicator");
> - if (replyIndicator.isValid()) {
> - mVoicemailIndicator = replyIndicator.value();
> - Q_EMIT voicemailIndicatorChanged();
> - }
> -
> connect(mAccount->connection().data(),
> SIGNAL(selfHandleChanged(uint)),
> SLOT(onSelfHandleChanged(uint)));
> - // and get the serial
> - QDBusInterface ussdIface(mConnectionInfo.busName, mConnectionInfo.objectPath, CANONICAL_TELEPHONY_USSD_IFACE);
> - mSerial = ussdIface.property("Serial").toString();
>
> watchSelfContactPresence();
> }
>
> - Q_EMIT networkNameChanged();
> Q_EMIT connectedChanged();
> - Q_EMIT simLockedChanged();
> Q_EMIT selfContactIdChanged();
> - Q_EMIT serialChanged();
> Q_EMIT activeChanged();
> }
> -
> -void AccountEntry::onEmergencyNumbersChanged(const QStringList &numbers)
> -{
> - mEmergencyNumbers = numbers;
> - Q_EMIT emergencyNumbersChanged();
> -}
> -
> -void AccountEntry::onVoicemailNumberChanged(const QString &number)
> -{
> - mVoicemailNumber = number;
> - Q_EMIT voicemailNumberChanged();
> -}
> -
> -void AccountEntry::onVoicemailCountChanged(uint count)
> -{
> - mVoicemailCount = count;
> - Q_EMIT voicemailCountChanged();
> -}
> -
> -void AccountEntry::onVoicemailIndicatorChanged(bool visible)
> -{
> - mVoicemailIndicator = visible;
> - Q_EMIT voicemailIndicatorChanged();
> -}
>
> === modified file 'libtelephonyservice/accountentry.h'
> --- libtelephonyservice/accountentry.h 2015-02-20 18:46:14 +0000
> +++ libtelephonyservice/accountentry.h 2015-03-25 22:11:52 +0000
> @@ -1,5 +1,5 @@
> /*
> - * Copyright (C) 2013 Canonical, Ltd.
> + * Copyright (C) 2013-2015 Canonical, Ltd.
> *
> * Authors:
> * Gustavo Pichorim Boiko <gustavo.boiko at canonical.com>
> @@ -25,7 +25,6 @@
> #include <QObject>
> #include <TelepathyQt/Account>
>
> -
> typedef struct {
> QString busName;
> QString objectPath;
> @@ -37,74 +36,59 @@
> Q_PROPERTY(QString accountId READ accountId NOTIFY accountIdChanged)
> Q_PROPERTY(bool active READ active NOTIFY activeChanged)
> Q_PROPERTY(QString displayName READ displayName WRITE setDisplayName NOTIFY displayNameChanged)
> + Q_PROPERTY(QString status READ status NOTIFY statusChanged)
> + Q_PROPERTY(QString statusMessage READ statusMessage NOTIFY statusMessageChanged)
> Q_PROPERTY(QString selfContactId READ selfContactId NOTIFY selfContactIdChanged)
> Q_PROPERTY(bool connected READ connected NOTIFY connectedChanged)
> - Q_PROPERTY(QStringList emergencyNumbers READ emergencyNumbers NOTIFY emergencyNumbersChanged)
> - Q_PROPERTY(QString voicemailNumber READ voicemailNumber NOTIFY voicemailNumberChanged)
> - Q_PROPERTY(uint voicemailCount READ voicemailCount NOTIFY voicemailCountChanged)
> - Q_PROPERTY(bool voicemailIndicator READ voicemailIndicator NOTIFY voicemailIndicatorChanged)
> - Q_PROPERTY(QString networkName READ networkName NOTIFY networkNameChanged)
> - Q_PROPERTY(bool emergencyCallsAvailable READ emergencyCallsAvailable NOTIFY emergencyCallsAvailableChanged)
> - Q_PROPERTY(bool simLocked READ simLocked NOTIFY simLockedChanged)
> - Q_PROPERTY(QString serial READ serial NOTIFY serialChanged)
> + Q_PROPERTY(QStringList addressableVCardFields READ addressableVCardFields NOTIFY addressableVCardFieldsChanged)
> + Q_ENUMS(AccountType)
> + friend class AccountEntryFactory;
>
> public:
> - explicit AccountEntry(const Tp::AccountPtr &account, QObject *parent = 0);
> + enum AccountType {
> + PhoneAccount,
> + GenericAccount
> + };
> +
> QString accountId() const;
> bool active() const;
> QString displayName() const;
> + QString status() const;
> + QString statusMessage() const;
> QString selfContactId() const;
> - QString networkName() const;
> - bool simLocked() const;
> void setDisplayName(const QString &name);
> - bool connected() const;
> - QStringList emergencyNumbers() const;
> - QString voicemailNumber() const;
> - uint voicemailCount() const;
> - bool voicemailIndicator() const;
> + virtual bool connected() const;
> Tp::AccountPtr account() const;
> - bool emergencyCallsAvailable() const;
> - QString serial() const;
> + virtual AccountType type() const;
> + virtual QStringList addressableVCardFields() const;
> +
> + virtual bool compareIds(const QString &first, const QString &second) const;
>
> Q_SIGNALS:
> void accountReady();
> void accountIdChanged();
> void activeChanged();
> void displayNameChanged();
> + void statusChanged();
> + void statusMessageChanged();
> void selfContactIdChanged();
> - void networkNameChanged();
> - void simLockedChanged();
> void connectedChanged();
> - void emergencyNumbersChanged();
> - void voicemailNumberChanged();
> - void voicemailCountChanged();
> - void voicemailIndicatorChanged();
> - void emergencyCallsAvailableChanged();
> - void serialChanged();
> + void addressableVCardFieldsChanged();
> void removed();
>
> protected Q_SLOTS:
> - void initialize();
> - void ensureEnabled();
> - void ensureConnected();
> - void watchSelfContactPresence();
> -
> -private Q_SLOTS:
> - void onConnectionChanged();
> - void onEmergencyNumbersChanged(const QStringList &numbers);
> - void onVoicemailNumberChanged(const QString &number);
> - void onVoicemailCountChanged(uint count);
> - void onVoicemailIndicatorChanged(bool visible);
> - void onSelfHandleChanged(uint handle);
> -
> -private:
> + virtual void initialize();
> + virtual void ensureEnabled();
> + virtual void ensureConnected();
> + virtual void watchSelfContactPresence();
> + virtual void onConnectionChanged();
> + virtual void onSelfHandleChanged(uint handle);
> +
> +protected:
> + explicit AccountEntry(const Tp::AccountPtr &account, QObject *parent = 0);
> +
> Tp::AccountPtr mAccount;
> - QStringList mEmergencyNumbers;
> - QString mVoicemailNumber;
> - uint mVoicemailCount;
> - bool mVoicemailIndicator;
> ConnectionInfo mConnectionInfo;
> - QString mSerial;
> };
>
> #endif // ACCOUNTENTRY_H
>
> === added file 'libtelephonyservice/accountentryfactory.cpp'
> --- libtelephonyservice/accountentryfactory.cpp 1970-01-01 00:00:00 +0000
> +++ libtelephonyservice/accountentryfactory.cpp 2015-03-25 22:11:52 +0000
> @@ -0,0 +1,40 @@
> +/*
> + * Copyright (C) 2015 Canonical, Ltd.
> + *
> + * Authors:
> + * Gustavo Pichorim Boiko <gustavo.boiko at canonical.com>
> + *
> + * This file is part of telephony-service.
> + *
> + * telephony-service is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; version 3.
> + *
> + * telephony-service is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include "accountentryfactory.h"
> +#include "accountentry.h"
> +#include "ofonoaccountentry.h"
> +
> +AccountEntry *AccountEntryFactory::createEntry(const Tp::AccountPtr &account, QObject *parent)
> +{
> + QString protocol = account->protocolName();
> +
> + // FIXME: check what other accounts need extra properties/methods
> + if (protocol == "ofono") {
> + return new OfonoAccountEntry(account, parent);
> + }
> +
> + return new AccountEntry(account, parent);
> +}
> +
> +AccountEntryFactory::AccountEntryFactory()
> +{
> +}
>
> === added file 'libtelephonyservice/accountentryfactory.h'
> --- libtelephonyservice/accountentryfactory.h 1970-01-01 00:00:00 +0000
> +++ libtelephonyservice/accountentryfactory.h 2015-03-25 22:11:52 +0000
> @@ -0,0 +1,38 @@
> +/*
> + * Copyright (C) 2015 Canonical, Ltd.
> + *
> + * Authors:
> + * Gustavo Pichorim Boiko <gustavo.boiko at canonical.com>
> + *
> + * This file is part of telephony-service.
> + *
> + * telephony-service is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; version 3.
> + *
> + * telephony-service is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#ifndef ACCOUNTENTRYFACTORY_H
> +#define ACCOUNTENTRYFACTORY_H
> +
> +#include <TelepathyQt/Account>
> +
> +class AccountEntry;
> +
> +class AccountEntryFactory
> +{
> +public:
> + static AccountEntry *createEntry(const Tp::AccountPtr &account, QObject *parent = 0);
> +
> +private:
> + explicit AccountEntryFactory();
> +};
> +
> +#endif // ACCOUNTENTRYFACTORY_H
>
> === modified file 'libtelephonyservice/callentry.cpp'
> --- libtelephonyservice/callentry.cpp 2015-01-19 21:14:26 +0000
> +++ libtelephonyservice/callentry.cpp 2015-03-25 22:11:52 +0000
> @@ -24,6 +24,7 @@
> #include "callmanager.h"
> #include "telepathyhelper.h"
> #include "accountentry.h"
> +#include "ofonoaccountentry.h"
>
> #include <QDBusReply>
> #include <QTime>
> @@ -76,8 +77,10 @@
> SIGNAL(CallHoldingFailed(QString)),
> SLOT(onCallHoldingFailed(QString)));
>
> - if (mAccount && !mAccount->voicemailNumber().isEmpty()) {
> - setVoicemail(phoneNumber() == mAccount->voicemailNumber());
> + // in case the account is an ofono account, we can check the voicemail number
> + OfonoAccountEntry *ofonoAccount = qobject_cast<OfonoAccountEntry*>(mAccount);
> + if (ofonoAccount && ofonoAccount->voicemailNumber().isEmpty()) {
> + setVoicemail(phoneNumber() == ofonoAccount->voicemailNumber());
> }
>
> Q_EMIT incomingChanged();
>
> === modified file 'libtelephonyservice/callentry.h'
> --- libtelephonyservice/callentry.h 2015-01-19 21:14:26 +0000
> +++ libtelephonyservice/callentry.h 2015-03-25 22:11:52 +0000
> @@ -48,6 +48,7 @@
> NOTIFY voicemailChanged)
> Q_PROPERTY(AccountEntry *account READ account)
>
> + // FIXME: replace this by a more generic identifier to support accounts not based on phone numbers
> // this property is only filled for 1-1 calls
> Q_PROPERTY(QString phoneNumber
> READ phoneNumber
>
> === modified file 'libtelephonyservice/chatmanager.cpp'
> --- libtelephonyservice/chatmanager.cpp 2015-02-04 21:01:09 +0000
> +++ libtelephonyservice/chatmanager.cpp 2015-03-25 22:11:52 +0000
> @@ -146,13 +146,7 @@
> connect(channel.data(),
> SIGNAL(messageSent(Tp::Message,Tp::MessageSendingFlags,QString)),
> SLOT(onMessageSent(Tp::Message,Tp::MessageSendingFlags,QString)));
> - connect(channel.data(),
> - SIGNAL(pendingMessageRemoved(const Tp::ReceivedMessage&)),
> - SLOT(onPendingMessageRemoved(const Tp::ReceivedMessage&)));
>
> - if (!channel->targetContact().isNull()){
> - Q_EMIT unreadMessagesChanged(channel->targetContact()->id());
> - }
> Q_FOREACH(const Tp::ReceivedMessage &message, channel->messageQueue()) {
> onMessageReceived(message);
> }
> @@ -167,13 +161,6 @@
> }
>
> Q_EMIT messageReceived(message.sender()->id(), message.text(), message.received(), message.messageToken(), true);
> - Q_EMIT unreadMessagesChanged(message.sender()->id());
> -}
> -
> -void ChatManager::onPendingMessageRemoved(const Tp::ReceivedMessage &message)
> -{
> - // emit the signal saying the unread messages for a specific number has changed
> - Q_EMIT unreadMessagesChanged(message.sender()->id());
> }
>
> void ChatManager::onMessageSent(const Tp::Message &sentMessage, const Tp::MessageSendingFlags flags, const QString &message)
> @@ -191,33 +178,6 @@
> }
> }
>
> -Tp::TextChannelPtr ChatManager::existingChat(const QStringList &recipients, const QString &accountId)
> -{
> - Tp::TextChannelPtr channel;
> -
> - Q_FOREACH(const Tp::TextChannelPtr &channel, mChannels) {
> - AccountEntry *channelAccount = TelepathyHelper::instance()->accountForConnection(channel->connection());
> - int count = 0;
> - if (!channelAccount || channelAccount->accountId() != accountId
> - || channel->groupContacts(false).size() != recipients.size()) {
> - continue;
> - }
> - Q_FOREACH(const QString &recipientNew, recipients) {
> - Q_FOREACH(const Tp::ContactPtr &recipientOld, channel->groupContacts(false)) {
> - if (PhoneUtils::comparePhoneNumbers(recipientOld->id(), recipientNew)) {
> - count++;
> - }
> - }
> - }
> - if (count == recipients.size()) {
> - return channel;
> - }
> -
> - }
> -
> - return channel;
> -}
> -
> void ChatManager::acknowledgeMessage(const QStringList &recipients, const QString &messageId, const QString &accountId)
> {
> AccountEntry *account = NULL;
>
> === modified file 'libtelephonyservice/chatmanager.h'
> --- libtelephonyservice/chatmanager.h 2015-02-04 21:01:09 +0000
> +++ libtelephonyservice/chatmanager.h 2015-03-25 22:11:52 +0000
> @@ -40,20 +40,15 @@
> Q_SIGNALS:
> void messageReceived(const QString &recipient, const QString &message, const QDateTime ×tamp, const QString &messageId, bool unread);
> void messageSent(const QString &recipient, const QString &message);
> - void unreadMessagesChanged(const QString &recipient);
>
> public Q_SLOTS:
> void onTextChannelAvailable(Tp::TextChannelPtr channel);
> void onConnectedChanged();
> void onMessageReceived(const Tp::ReceivedMessage &message);
> - void onPendingMessageRemoved(const Tp::ReceivedMessage &message);
> void onMessageSent(const Tp::Message &sentMessage, const Tp::MessageSendingFlags flags, const QString &message);
>
> void acknowledgeMessage(const QStringList &recipients, const QString &messageId, const QString &accountId = QString::null);
>
> -protected:
> - Tp::TextChannelPtr existingChat(const QStringList &recipients, const QString &accountId);
> -
> protected Q_SLOTS:
> void onAckTimerTriggered();
>
>
> === added file 'libtelephonyservice/ofonoaccountentry.cpp'
> --- libtelephonyservice/ofonoaccountentry.cpp 1970-01-01 00:00:00 +0000
> +++ libtelephonyservice/ofonoaccountentry.cpp 2015-03-25 22:11:52 +0000
> @@ -0,0 +1,208 @@
> +/*
> + * Copyright (C) 2013-2015 Canonical, Ltd.
> + *
> + * Authors:
> + * Gustavo Pichorim Boiko <gustavo.boiko at canonical.com>
> + *
> + * This file is part of telephony-service.
> + *
> + * telephony-service is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; version 3.
> + *
> + * telephony-service is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include "ofonoaccountentry.h"
> +#include "telepathyhelper.h"
> +#include "phoneutils.h"
> +
> +OfonoAccountEntry::OfonoAccountEntry(const Tp::AccountPtr &account, QObject *parent) :
> + AccountEntry(account, parent), mVoicemailCount(0), mVoicemailIndicator(false)
> +{
> + // the sim lock detection is based on the status message, so whenever it
> + // changes, it might mean the sim lock state changed too
> + connect(this,
> + SIGNAL(statusChanged()),
> + SIGNAL(simLockedChanged()));
> + connect(this,
> + SIGNAL(statusMessageChanged()),
> + SIGNAL(networkNameChanged()));
> + connect(this,
> + SIGNAL(statusMessageChanged()),
> + SIGNAL(emergencyCallsAvailableChanged()));
> +}
> +
> +QStringList OfonoAccountEntry::emergencyNumbers() const
> +{
> + return mEmergencyNumbers;
> +}
> +
> +QString OfonoAccountEntry::voicemailNumber() const
> +{
> + return mVoicemailNumber;
> +}
> +
> +uint OfonoAccountEntry::voicemailCount() const
> +{
> + return mVoicemailCount;
> +}
> +
> +bool OfonoAccountEntry::voicemailIndicator() const
> +{
> + return mVoicemailIndicator;
> +}
> +
> +QString OfonoAccountEntry::networkName() const
> +{
> + // FIXME: maybe it is safer to reimplement here, but for ofono accounts the status message really is the
> + // network name
> + return statusMessage();
> +}
> +
> +bool OfonoAccountEntry::emergencyCallsAvailable() const
> +{
> + if (mAccount.isNull() || mAccount->connection().isNull() || mAccount->connection()->selfContact().isNull()) {
> + return false;
> + }
> +
> + QString status = mAccount->connection()->selfContact()->presence().status();
> + return status != "flightmode" && status != "nomodem" && status != "";
> +}
> +
> +bool OfonoAccountEntry::simLocked() const
> +{
> + if (mAccount.isNull() || mAccount->connection().isNull() || mAccount->connection()->selfContact().isNull()) {
> + return false;
> + }
> + Tp::Presence presence = mAccount->connection()->selfContact()->presence();
> + return (presence.type() == Tp::ConnectionPresenceTypeAway && presence.status() == "simlocked");
> +}
> +
> +QString OfonoAccountEntry::serial() const
> +{
> + return mSerial;
> +}
> +
> +AccountEntry::AccountType OfonoAccountEntry::type() const
> +{
> + return AccountEntry::PhoneAccount;
> +}
> +
> +bool OfonoAccountEntry::connected() const
> +{
> + return !mAccount.isNull() && !mAccount->connection().isNull() &&
> + !mAccount->connection()->selfContact().isNull() &&
> + mAccount->connection()->selfContact()->presence().type() == Tp::ConnectionPresenceTypeAvailable;
> +}
> +
> +bool OfonoAccountEntry::compareIds(const QString &first, const QString &second) const
> +{
> + return PhoneUtils::comparePhoneNumbers(first, second);
> +}
> +
> +QStringList OfonoAccountEntry::addressableVCardFields()
> +{
> + return mAccount->protocolInfo().addressableVCardFields();
> +}
> +
> +void OfonoAccountEntry::onEmergencyNumbersChanged(const QStringList &numbers)
> +{
> + mEmergencyNumbers = numbers;
> + Q_EMIT emergencyNumbersChanged();
> +}
> +
> +void OfonoAccountEntry::onVoicemailNumberChanged(const QString &number)
> +{
> + mVoicemailNumber = number;
> + Q_EMIT voicemailNumberChanged();
> +}
> +
> +void OfonoAccountEntry::onVoicemailCountChanged(uint count)
> +{
> + mVoicemailCount = count;
> + Q_EMIT voicemailCountChanged();
> +}
> +
> +void OfonoAccountEntry::onVoicemailIndicatorChanged(bool visible)
> +{
> + mVoicemailIndicator = visible;
> + Q_EMIT voicemailIndicatorChanged();
> +}
> +
> +void OfonoAccountEntry::onConnectionChanged()
> +{
> + // make sure the generic code is also run
> + AccountEntry::onConnectionChanged();
> +
> + QDBusConnection dbusConnection = QDBusConnection::sessionBus();
> +
> + if (!mAccount->connection()) {
> + // disconnect any previous dbus connections
> + if (!mConnectionInfo.objectPath.isEmpty()) {
> + dbusConnection.disconnect(mConnectionInfo.busName, mConnectionInfo.objectPath,
> + CANONICAL_TELEPHONY_EMERGENCYMODE_IFACE, "EmergencyNumbersChanged",
> + this, SLOT(onEmergencyNumbersChanged(QStringList)));
> + }
> + } else {
> + // connect the emergency numbers changed signal
> + dbusConnection.connect(mConnectionInfo.busName, mConnectionInfo.objectPath,
> + CANONICAL_TELEPHONY_EMERGENCYMODE_IFACE, "EmergencyNumbersChanged",
> + this, SLOT(onEmergencyNumbersChanged(QStringList)));
> +
> + // and get the current value of the emergency numbers
> + QDBusInterface connIface(mConnectionInfo.busName, mConnectionInfo.objectPath, CANONICAL_TELEPHONY_EMERGENCYMODE_IFACE);
> + QDBusReply<QStringList> replyNumbers = connIface.call("EmergencyNumbers");
> + if (replyNumbers.isValid()) {
> + mEmergencyNumbers = replyNumbers.value();
> + Q_EMIT emergencyNumbersChanged();
> + }
> +
> + // connect the voicemail number changed signal
> + dbusConnection.connect(mConnectionInfo.busName, mConnectionInfo.objectPath,
> + CANONICAL_TELEPHONY_VOICEMAIL_IFACE, "VoicemailNumberChanged",
> + this, SLOT(onVoicemailNumberChanged(QString)));
> +
> + QDBusInterface voicemailIface(mConnectionInfo.busName, mConnectionInfo.objectPath, CANONICAL_TELEPHONY_VOICEMAIL_IFACE);
> + QDBusReply<QString> replyNumber = voicemailIface.call("VoicemailNumber");
> + if (replyNumber.isValid()) {
> + mVoicemailNumber = replyNumber.value();
> + Q_EMIT voicemailNumberChanged();
> + }
> +
> + // connect the voicemail count changed signal
> + dbusConnection.connect(mConnectionInfo.busName, mConnectionInfo.objectPath,
> + CANONICAL_TELEPHONY_VOICEMAIL_IFACE, "VoicemailCountChanged",
> + this, SLOT(onVoicemailCountChanged(uint)));
> +
> + QDBusReply<uint> replyCount = voicemailIface.call("VoicemailCount");
> + if (replyCount.isValid()) {
> + mVoicemailCount = replyCount.value();
> + Q_EMIT voicemailCountChanged();
> + }
> +
> + // connect the voicemail indicator changed signal
> + dbusConnection.connect(mConnectionInfo.busName, mConnectionInfo.objectPath,
> + CANONICAL_TELEPHONY_VOICEMAIL_IFACE, "VoicemailIndicatorChanged",
> + this, SLOT(onVoicemailIndicatorChanged(bool)));
> +
> + QDBusReply<bool> replyIndicator = voicemailIface.call("VoicemailIndicator");
> + if (replyIndicator.isValid()) {
> + mVoicemailIndicator = replyIndicator.value();
> + Q_EMIT voicemailIndicatorChanged();
> + }
> +
> + // and get the serial
> + QDBusInterface ussdIface(mConnectionInfo.busName, mConnectionInfo.objectPath, CANONICAL_TELEPHONY_USSD_IFACE);
> + mSerial = ussdIface.property("Serial").toString();
> + }
> +
> + Q_EMIT simLockedChanged();
> + Q_EMIT serialChanged();
> +}
>
> === added file 'libtelephonyservice/ofonoaccountentry.h'
> --- libtelephonyservice/ofonoaccountentry.h 1970-01-01 00:00:00 +0000
> +++ libtelephonyservice/ofonoaccountentry.h 2015-03-25 22:11:52 +0000
> @@ -0,0 +1,86 @@
> +/*
> + * Copyright (C) 2013-2015 Canonical, Ltd.
> + *
> + * Authors:
> + * Gustavo Pichorim Boiko <gustavo.boiko at canonical.com>
> + *
> + * This file is part of telephony-service.
> + *
> + * telephony-service is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; version 3.
> + *
> + * telephony-service is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#ifndef OFONOACCOUNTENTRY_H
> +#define OFONOACCOUNTENTRY_H
> +
> +#include "accountentry.h"
> +
> +class OfonoAccountEntry : public AccountEntry
> +{
> + Q_OBJECT
> + Q_PROPERTY(QStringList emergencyNumbers READ emergencyNumbers NOTIFY emergencyNumbersChanged)
> + Q_PROPERTY(QString voicemailNumber READ voicemailNumber NOTIFY voicemailNumberChanged)
> + Q_PROPERTY(uint voicemailCount READ voicemailCount NOTIFY voicemailCountChanged)
> + Q_PROPERTY(bool voicemailIndicator READ voicemailIndicator NOTIFY voicemailIndicatorChanged)
> + Q_PROPERTY(QString networkName READ networkName NOTIFY networkNameChanged)
> + Q_PROPERTY(bool emergencyCallsAvailable READ emergencyCallsAvailable NOTIFY emergencyCallsAvailableChanged)
> + Q_PROPERTY(bool simLocked READ simLocked NOTIFY simLockedChanged)
> + Q_PROPERTY(QString serial READ serial NOTIFY serialChanged)
> + friend class AccountEntryFactory;
> +
> +public:
> + QStringList emergencyNumbers() const;
> + QString voicemailNumber() const;
> + uint voicemailCount() const;
> + bool voicemailIndicator() const;
> + QString networkName() const;
> + bool emergencyCallsAvailable() const;
> + bool simLocked() const;
> + QString serial() const;
> +
> + // reimplemented from AccountEntry
> + virtual AccountEntry::AccountType type() const;
> + virtual bool connected() const;
> + virtual bool compareIds(const QString &first, const QString &second) const;
> + virtual QStringList addressableVCardFields();
> +
> +Q_SIGNALS:
> + void emergencyNumbersChanged();
> + void voicemailNumberChanged();
> + void voicemailCountChanged();
> + void voicemailIndicatorChanged();
> + void networkNameChanged();
> + void emergencyCallsAvailableChanged();
> + void simLockedChanged();
> + void serialChanged();
> +
> +private Q_SLOTS:
> + void onEmergencyNumbersChanged(const QStringList &numbers);
> + void onVoicemailNumberChanged(const QString &number);
> + void onVoicemailCountChanged(uint count);
> + void onVoicemailIndicatorChanged(bool visible);
> +
> + // reimplemented from AccountEntry
> + void onConnectionChanged();
> +
> +protected:
> + explicit OfonoAccountEntry(const Tp::AccountPtr &account, QObject *parent = 0);
> +
> +private:
> + QStringList mEmergencyNumbers;
> + QString mVoicemailNumber;
> + uint mVoicemailCount;
> + bool mVoicemailIndicator;
> + QString mSerial;
> +};
> +
> +#endif // OFONOACCOUNTENTRY_H
>
> === modified file 'libtelephonyservice/telepathyhelper.cpp'
> --- libtelephonyservice/telepathyhelper.cpp 2015-02-20 18:46:14 +0000
> +++ libtelephonyservice/telepathyhelper.cpp 2015-03-25 22:11:52 +0000
> @@ -22,6 +22,8 @@
>
> #include "telepathyhelper.h"
> #include "accountentry.h"
> +#include "ofonoaccountentry.h"
> +#include "accountentryfactory.h"
> #include "chatmanager.h"
> #include "callmanager.h"
> #include "config.h"
> @@ -269,11 +271,21 @@
> SIGNAL(connectedChanged()),
> SLOT(updateConnectedStatus()));
> connect(entry,
> + SIGNAL(connectedChanged()),
> + SIGNAL(activeAccountsChanged()));
> + connect(entry,
> SIGNAL(accountReady()),
> SLOT(onAccountReady()));
> connect(entry,
> SIGNAL(removed()),
> SLOT(onAccountRemoved()));
> +
> + OfonoAccountEntry *ofonoAccount = qobject_cast<OfonoAccountEntry*>(entry);
> + if (ofonoAccount) {
> + connect(ofonoAccount,
> + SIGNAL(emergencyCallsAvailableChanged()),
> + SIGNAL(emergencyCallsAvailableChanged()));
> + }
> }
>
> bool TelepathyHelper::registerClient(Tp::AbstractClient *client, QString name)
> @@ -379,15 +391,8 @@
>
> void TelepathyHelper::onNewAccount(const Tp::AccountPtr &account)
> {
> - AccountEntry *accountEntry = new AccountEntry(account, this);
> - connect(accountEntry,
> - SIGNAL(connectedChanged()),
> - SIGNAL(activeAccountsChanged()));
> - connect(accountEntry,
> - SIGNAL(emergencyCallsAvailableChanged()),
> - SIGNAL(emergencyCallsAvailableChanged()));
> + AccountEntry *accountEntry = AccountEntryFactory::createEntry(account, this);
> setupAccountEntry(accountEntry);
> -
> mAccounts.append(accountEntry);
>
> QMap<QString, AccountEntry *> sortedOfonoAccounts;
> @@ -501,8 +506,10 @@
>
> bool TelepathyHelper::emergencyCallsAvailable() const
> {
> + // FIXME: this is really ofono specific, so maybe move somewhere else?
> Q_FOREACH(const AccountEntry *account, mAccounts) {
> - if (account->emergencyCallsAvailable()) {
> + const OfonoAccountEntry *ofonoAccount = qobject_cast<const OfonoAccountEntry*>(account);
> + if (ofonoAccount && ofonoAccount->emergencyCallsAvailable()) {
> return true;
> }
> }
>
--
https://code.launchpad.net/~boiko/telephony-service/support_non_phone_accounts/+merge/251796
Your team Ubuntu Phablet Team is subscribed to branch lp:telephony-service.
More information about the Ubuntu-reviews
mailing list