Bug 100363 - [PATCH] Add connection property averaging and presence setting to AccountSet
Summary: [PATCH] Add connection property averaging and presence setting to AccountSet
Status: RESOLVED MOVED
Alias: None
Product: Telepathy
Classification: Unclassified
Component: tp-qt (show other bugs)
Version: git master
Hardware: All All
: medium enhancement
Assignee: Telepathy bugs list
QA Contact: Telepathy bugs list
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-03-23 23:04 UTC by James Smith
Modified: 2019-12-03 20:30 UTC (History)
0 users

See Also:
i915 platform:
i915 features:


Attachments
Add property averaging and presence setting to AccountSet, <> operators to Presence. (12.05 KB, patch)
2017-03-23 23:04 UTC, James Smith
Details | Splinter Review
Add property averaging, presence setting and account lookup by unique identifier to AccountSet, <> operators to Presence. (15.50 KB, patch)
2017-04-05 06:22 UTC, James Smith
Details | Splinter Review
Add property averaging, presence setting and account lookup by unique identifier to AccountSet, <> operators to Presence. (17.41 KB, patch)
2017-04-05 06:36 UTC, James Smith
Details | Splinter Review
Add property averaging, presence setting and account object export by unique identifier to AccountSet, <> operators to Presence (18.39 KB, patch)
2017-04-18 03:58 UTC, James Smith
Details | Splinter Review
Change the presence spec weighting for individual states (4.05 KB, patch)
2017-06-05 17:43 UTC, James Smith
Details | Splinter Review
Implement presence <> operators (1.67 KB, patch)
2017-06-05 17:47 UTC, James Smith
Details | Splinter Review
Add connection property averaging to AccountSet (13.33 KB, patch)
2017-06-05 17:49 UTC, James Smith
Details | Splinter Review
Export the AccountSet accounts as a QHash instead of a QList (5.90 KB, patch)
2017-06-05 17:56 UTC, James Smith
Details | Splinter Review
Add connection property averaging and presence setting to AccountSet (13.21 KB, patch)
2017-06-05 21:59 UTC, James Smith
Details | Splinter Review
Add connection property averaging and presence setting to AccountSet (15.52 KB, patch)
2018-02-26 02:17 UTC, James Smith
Details | Splinter Review

Description James Smith 2017-03-23 23:04:31 UTC
Created attachment 130405 [details] [review]
Add property averaging and presence setting to AccountSet, <> operators to Presence.

Add presence setting and account connection property averaging to AccountSet.
Comment 1 James Smith 2017-04-05 06:22:41 UTC
Created attachment 130684 [details] [review]
Add property averaging, presence setting and account lookup by unique identifier to AccountSet, <> operators to Presence.

Add account lookup by uniqueIdentifier(). This requires changing the lookup key from objectPath() to uniqueIdentifier(). Document all new connection presence functions and signals.
Comment 2 James Smith 2017-04-05 06:36:21 UTC
Created attachment 130685 [details] [review]
Add property averaging, presence setting and account lookup by unique identifier to AccountSet, <> operators to Presence.

Attach the correct patch.
Comment 3 James Smith 2017-04-18 03:58:00 UTC
Created attachment 130887 [details] [review]
Add property averaging, presence setting and account object export by unique identifier to AccountSet, <> operators to Presence

Turn the account object list export into a hash of the account uniqueIdentifier and AccountPtr, and remove the single-account lookup.

This breaks API compatibility, but is much nicer.
Comment 4 James Smith 2017-06-05 17:43:37 UTC
Created attachment 131717 [details] [review]
Change the presence spec weighting for individual states

Clean up the presence spec weighting to allow for presence comparison.
Comment 5 James Smith 2017-06-05 17:47:55 UTC
Created attachment 131718 [details] [review]
Implement presence <> operators

Implement <> operators to allow determining which presence of a set has the highest online state.
Comment 6 James Smith 2017-06-05 17:49:55 UTC
Created attachment 131719 [details] [review]
Add connection property averaging to AccountSet

Add connection property averaging and presence setting for all accounts of an account set.
Comment 7 James Smith 2017-06-05 17:56:33 UTC
Created attachment 131720 [details] [review]
Export the AccountSet accounts as a QHash instead of a QList

Change account use of objectPath() key for hash to uniqueIdentifier(). Export the entire QHash instead of a QList<AccountPtr>.
Comment 8 James Smith 2017-06-05 21:47:42 UTC
Comment on attachment 131719 [details] [review]
Add connection property averaging to AccountSet

From 13321669e387949ae904d0e8e2afef9fa1663efb Mon Sep 17 00:00:00 2001
From: "James D. Smith" <smithjd15@gmail.com>
Date: Sun, 4 Jun 2017 15:45:07 -0600
Subject: [PATCH] Add cumulative account connection information to AccountSet.
 Allow setting the requested presence of an entire account set.

---
 TelepathyQt/account-set-internal.h |  12 ++
 TelepathyQt/account-set.cpp        | 256 ++++++++++++++++++++++++++++++++++++-
 TelepathyQt/account-set.h          |  20 +++
 3 files changed, 287 insertions(+), 1 deletion(-)

diff --git TelepathyQt/account-set-internal.h TelepathyQt/account-set-internal.h
index f7dbf9e0..0d6ec175 100644
--- TelepathyQt/account-set-internal.h
+++ TelepathyQt/account-set-internal.h
@@ -43,6 +43,12 @@ struct TP_QT_NO_EXPORT AccountSet::Private
     void removeAccount(const AccountPtr &account);
     void wrapAccount(const AccountPtr &account);
     void filterAccount(const AccountPtr &account);
+    void accountPropertiesChanged();
+    void requestedPresenceChanged();
+    void currentPresenceChanged();
+    void connectionStatusChanged();
+    void changingPresence();
+    void onlinenessChanged();
     bool accountMatchFilter(AccountWrapper *account);
 
     AccountSet *parent;
@@ -50,6 +56,12 @@ struct TP_QT_NO_EXPORT AccountSet::Private
     AccountFilterConstPtr filter;
     QHash<QString, AccountWrapper *> wrappers;
     QHash<QString, AccountPtr> accounts;
+
+    Tp::Presence requestedPresence;
+    Tp::Presence currentPresence;
+    Tp::ConnectionStatus connectionStatus;
+    bool isChangingPresence;
+    bool isOnline;
     bool ready;
 };
 
diff --git TelepathyQt/account-set.cpp TelepathyQt/account-set.cpp
index fce92a39..4552bd5e 100644
--- TelepathyQt/account-set.cpp
+++ TelepathyQt/account-set.cpp
@@ -33,6 +33,7 @@
 #include <TelepathyQt/AccountManager>
 #include <TelepathyQt/ConnectionCapabilities>
 #include <TelepathyQt/ConnectionManager>
+#include <TelepathyQt/Presence>
 
 namespace Tp
 {
@@ -69,6 +70,7 @@ void AccountSet::Private::init()
     if (filter->isValid()) {
         connectSignals();
         insertAccounts();
+        accountPropertiesChanged();
         ready = true;
     }
 }
@@ -93,6 +95,10 @@ void AccountSet::Private::insertAccount(const Tp::AccountPtr &account)
     Q_ASSERT(!wrappers.contains(accountPath));
     wrapAccount(account);
     filterAccount(account);
+
+    if (ready) {
+        accountPropertiesChanged();
+    }
 }
 
 void AccountSet::Private::removeAccount(const Tp::AccountPtr &account)
@@ -106,6 +112,104 @@ void AccountSet::Private::removeAccount(const Tp::AccountPtr &account)
     wrapper->deleteLater();
 
     emit parent->accountRemoved(account);
+
+    if (ready) {
+        accountPropertiesChanged();
+    }
+}
+
+void AccountSet::Private::accountPropertiesChanged()
+{
+    requestedPresenceChanged();
+    currentPresenceChanged();
+    connectionStatusChanged();
+    changingPresence();
+    onlinenessChanged();
+}
+
+void AccountSet::Private::requestedPresenceChanged()
+{
+    Tp::Presence highestRequestedPresence = Tp::PresenceSpec::offline().presence();
+
+    foreach (const Tp::AccountPtr &account, accounts.values()) {
+        if (account->requestedPresence() > highestRequestedPresence) {
+            highestRequestedPresence = account->requestedPresence();
+        }
+    }
+
+    if (requestedPresence != highestRequestedPresence) {
+        requestedPresence = highestRequestedPresence;
+        emit parent->requestedPresenceChanged(requestedPresence);
+    }
+}
+
+void AccountSet::Private::currentPresenceChanged()
+{
+    Tp::Presence highestCurrentPresence = Tp::PresenceSpec::offline().presence();
+
+    foreach (const Tp::AccountPtr &account, accounts.values()) {
+        if (account->currentPresence() > highestCurrentPresence) {
+            highestCurrentPresence = account->currentPresence();
+        }
+    }
+
+    if (currentPresence != highestCurrentPresence) {
+        currentPresence = highestCurrentPresence;
+        emit parent->currentPresenceChanged(currentPresence);
+    }
+}
+
+void AccountSet::Private::connectionStatusChanged()
+{
+    Tp::ConnectionStatus status = Tp::ConnectionStatusDisconnected;
+    QList<Tp::ConnectionStatus> allConnectionStatuses;
+
+    foreach (const Tp::AccountPtr &account, accounts.values()) {
+        allConnectionStatuses << account->connectionStatus();
+    }
+
+    if (allConnectionStatuses.contains(Tp::ConnectionStatusConnecting)) {
+        status = Tp::ConnectionStatusConnecting;
+    } else if (allConnectionStatuses.contains(Tp::ConnectionStatusConnected)) {
+        status = Tp::ConnectionStatusConnected;
+    }
+
+    if (connectionStatus != status) {
+        connectionStatus = status;
+        emit parent->connectionStatusChanged(connectionStatus);
+    }
+}
+
+void AccountSet::Private::changingPresence()
+{
+    bool changing = false;
+    foreach (const Tp::AccountPtr &account, accounts.values()) {
+        changing = account->isChangingPresence();
+        if (account->isChangingPresence()) {
+            break;
+        }
+    }
+
+    if (isChangingPresence != changing) {
+        isChangingPresence = changing;
+        emit parent->isChangingPresence(isChangingPresence);
+    }
+}
+
+void AccountSet::Private::onlinenessChanged()
+{
+    bool online = false;
+    foreach (const Tp::AccountPtr &account, accounts.values()) {
+        online = account->isOnline();
+        if (!account->isOnline()) {
+            break;
+        }
+    }
+
+    if (isOnline != online) {
+        isOnline = online;
+        emit parent->onlinenessChanged(isOnline);
+    }
 }
 
 void AccountSet::Private::wrapAccount(const AccountPtr &account)
@@ -116,7 +220,7 @@ void AccountSet::Private::wrapAccount(const AccountPtr &account)
             SLOT(onAccountRemoved(Tp::AccountPtr)));
     parent->connect(wrapper,
             SIGNAL(accountPropertyChanged(Tp::AccountPtr,QString)),
-            SLOT(onAccountChanged(Tp::AccountPtr)));
+            SLOT(onAccountPropertyChanged(Tp::AccountPtr,QString)));
     parent->connect(wrapper,
             SIGNAL(accountCapabilitiesChanged(Tp::AccountPtr,Tp::ConnectionCapabilities)),
             SLOT(onAccountChanged(Tp::AccountPtr)));
@@ -381,6 +485,84 @@ QList<AccountPtr> AccountSet::accounts() const
 }
 
 /**
+ * Set the requested presence of all accounts that match filter.
+ *
+ * \param presence The requested presence.
+ */
+void AccountSet::setPresence(const Tp::Presence &presence)
+{
+    foreach (const Tp::AccountPtr &account, mPriv->accounts.values()) {
+        account->setRequestedPresence(presence);
+    }
+}
+
+/**
+ * The requested presence of all accounts that match filter.
+ *
+ * Change notification is via the requestedPresenceChanged() signal.
+ *
+ * \return The highest requested presence of the accounts that match filter.
+ * \sa requestedPresenceChanged()
+ */
+Tp::Presence AccountSet::requestedPresence() const
+{
+    return mPriv->requestedPresence;
+}
+
+/**
+ * The current presence of all accounts that match filter.
+ *
+ * Change notification is via the currentPresenceChanged() signal.
+ *
+ * \return The highest current presence of the accounts that match filter.
+ * \sa currentPresenceChanged()
+ */
+Tp::Presence AccountSet::currentPresence() const
+{
+    return mPriv->currentPresence;
+}
+
+/**
+ * The connection status of all accounts that match filter.
+ *
+ * Change notification is via the connectionStatusChanged() signal.
+ *
+ * \return connecting if any account is connecting, connected if at
+ * least one account is connected, or disconnected.
+ * \sa connectionStatusChanged()
+*/
+Tp::ConnectionStatus AccountSet::connectionStatus() const
+{
+    return mPriv->connectionStatus;
+}
+
+/**
+ * Of all accounts that match filter, if any are changing presence.
+ *
+ * Change notification is via the isChangingPresence() signal.
+ *
+ * \return true if any accounts that match filter are changing presence.
+ * \sa isChangingPresence()
+ */
+bool AccountSet::changingPresence() const
+{
+    return mPriv->isChangingPresence;
+}
+
+/**
+ * Of all accounts that match filter, if all are online.
+ *
+ * Change notification is via the onlinenessChanged() signal.
+ *
+ * \return false if all accounts that match filter are not online.
+ * \sa onlinenessChanged()
+ */
+bool AccountSet::online() const
+{
+    return mPriv->isOnline;
+}
+
+/**
  * \fn void AccountSet::accountAdded(const Tp::AccountPtr &account)
  *
  * Emitted whenever an account that matches filter is added to
@@ -400,6 +582,51 @@ QList<AccountPtr> AccountSet::accounts() const
  * \sa accounts()
  */
 
+/**
+ * \fn void AccountSet::requestedPresenceChanged(const Tp::Presence &requestedPresence)
+ *
+ * Emitted whenever the highest requested presence of this set of accounts changes.
+ *
+ * \param requestedPresence The highest requested presence.
+ * \sa requestedPresence()
+ */
+
+/**
+ * \fn void AccountSet::currentPresenceChanged(const Tp::Presence &currentPresence)
+ *
+ * Emitted whenever the highest current presence of this set of accounts changes.
+ *
+ * \param requestedPresence The highest requested presence.
+ * \sa currentPresence()
+ */
+
+/**
+ * \fn void AccountSet::connectionStatusChanged(Tp::ConnectionStatus connectionStatus)
+ *
+ * Emitted whenever the connection status of this set of accounts changes.
+ *
+ * \param connectionStatus The connection status.
+ * \sa connectionStatus()
+ */
+
+/**
+ * \fn void AccountSet::isChangingPresence(bool changingPresence)
+ *
+ * Emitted whenever any of this set of accounts are changing presence.
+ *
+ * \param changingPresence If any account is changing presence.
+ * \sa changingPresence()
+ */
+
+/**
+ * \fn void AccountSet::onlinenessChanged(bool online)
+ *
+ * Emitted whenever any of this set of accounts onlineness changes.
+ *
+ * \param online If all accounts are online.
+ * \sa online()
+ */
+
 void AccountSet::onNewAccount(const AccountPtr &account)
 {
     mPriv->insertAccount(account);
@@ -415,4 +642,31 @@ void AccountSet::onAccountChanged(const AccountPtr &account)
     mPriv->filterAccount(account);
 }
 
+void AccountSet::onAccountPropertyChanged(const Tp::AccountPtr &account, const QString &propertyName)
+{
+    mPriv->filterAccount(account);
+
+    if (propertyName == QLatin1String("requestedPresence")) {
+        if (mPriv->requestedPresence != account->requestedPresence()) {
+            mPriv->requestedPresenceChanged();
+        }
+    } else if (propertyName == QLatin1String("currentPresence")) {
+        if (mPriv->currentPresence != account->currentPresence()) {
+            mPriv->currentPresenceChanged();
+        }
+    } else if (propertyName == QLatin1String("connectionStatus")) {
+        if (mPriv->connectionStatus != account->connectionStatus()) {
+            mPriv->connectionStatusChanged();
+        }
+    } else if (propertyName == QLatin1String("changingPresence")) {
+        if (mPriv->isChangingPresence != account->isChangingPresence()) {
+            mPriv->changingPresence();
+        }
+    } else if (propertyName == QLatin1String("online")) {
+        if (mPriv->isOnline != account->isOnline()) {
+            mPriv->onlinenessChanged();
+        }
+    }
+}
+
 } // Tp
diff --git TelepathyQt/account-set.h TelepathyQt/account-set.h
index 40dd79af..c0681c32 100644
--- TelepathyQt/account-set.h
+++ TelepathyQt/account-set.h
@@ -30,6 +30,7 @@
 #include <TelepathyQt/Filter>
 #include <TelepathyQt/Object>
 #include <TelepathyQt/Types>
+#include <TelepathyQt/Presence>
 
 #include <QList>
 #include <QString>
@@ -45,6 +46,11 @@ class TP_QT_EXPORT AccountSet : public Object
     Q_PROPERTY(AccountManagerPtr accountManager READ accountManager)
     Q_PROPERTY(AccountFilterConstPtr filter READ filter)
     Q_PROPERTY(QList<AccountPtr> accounts READ accounts)
+    Q_PROPERTY(Tp::Presence requestedPresence READ requestedPresence WRITE setPresence NOTIFY requestedPresenceChanged)
+    Q_PROPERTY(Tp::Presence currentPresence READ currentPresence NOTIFY currentPresenceChanged)
+    Q_PROPERTY(Tp::ConnectionStatus connectionStatus READ connectionStatus NOTIFY connectionStatusChanged)
+    Q_PROPERTY(bool changingPresence READ changingPresence NOTIFY isChangingPresence)
+    Q_PROPERTY(bool online READ online NOTIFY onlinenessChanged)
 
 public:
     AccountSet(const AccountManagerPtr &accountManager,
@@ -59,14 +65,28 @@ public:
 
     QList<AccountPtr> accounts() const;
 
+    void setPresence(const Tp::Presence &presence);
+
+    Tp::Presence requestedPresence() const;
+    Tp::Presence currentPresence() const;
+    Tp::ConnectionStatus connectionStatus() const;
+    bool changingPresence() const;
+    bool online() const;
+
 Q_SIGNALS:
     void accountAdded(const Tp::AccountPtr &account);
     void accountRemoved(const Tp::AccountPtr &account);
+    void requestedPresenceChanged(const Tp::Presence &requestedPresence);
+    void currentPresenceChanged(const Tp::Presence &currentPresence);
+    void connectionStatusChanged(Tp::ConnectionStatus connectionStatus);
+    void isChangingPresence(bool changingPresence);
+    void onlinenessChanged(bool online);
 
 private Q_SLOTS:
     TP_QT_NO_EXPORT void onNewAccount(const Tp::AccountPtr &account);
     TP_QT_NO_EXPORT void onAccountRemoved(const Tp::AccountPtr &account);
     TP_QT_NO_EXPORT void onAccountChanged(const Tp::AccountPtr &account);
+    TP_QT_NO_EXPORT void onAccountPropertyChanged(const Tp::AccountPtr &account, const QString &propertyName);
 
 private:
     struct Private;
-- 
2.12.3
Comment 9 James Smith 2017-06-05 21:59:43 UTC
Created attachment 131728 [details] [review]
Add connection property averaging and presence setting to AccountSet

Add connection property averaging and presence setting for all accounts of an account set.

v2: Optimize init
Comment 10 James Smith 2018-02-26 02:17:49 UTC
Created attachment 137599 [details] [review]
Add connection property averaging and presence setting to AccountSet

v3:

Add automaticPresence property.
Small cleanups, including documentation typos.
Comment 11 GitLab Migration User 2019-12-03 20:30:15 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to freedesktop.org's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.freedesktop.org/telepathy/telepathy-qt/issues/52.


Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.