File indexing completed on 2023-05-30 11:40:28

0001 /*
0002     Status managing and auto connect class
0003     Copyright (C) 2017  James D. Smith <smithjd15@gmail.com>
0004 
0005     This library is free software; you can redistribute it and/or
0006     modify it under the terms of the GNU Lesser General Public
0007     License as published by the Free Software Foundation; either
0008     version 2.1 of the License, or (at your option) any later version.
0009 
0010     This library is distributed in the hope that it will be useful,
0011     but WITHOUT ANY WARRANTY; without even the implied warranty of
0012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0013     Lesser General Public License for more details.
0014 
0015     You should have received a copy of the GNU Lesser General Public
0016     License along with this library; if not, write to the Free Software
0017     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
0018 */
0019 
0020 #include "account-status-helper.h"
0021 #include "ktp_kded_debug.h"
0022 
0023 #include <KTp/types.h>
0024 
0025 #include <KConfig>
0026 #include <KConfigGroup>
0027 #include <KSharedConfig>
0028 #include <KActivities/kactivities/consumer.h>
0029 
0030 #include <QVariant>
0031 
0032 #include <TelepathyQt/AccountManager>
0033 #include <TelepathyQt/AccountSet>
0034 #include <TelepathyQt/Account>
0035 #include <TelepathyQt/Constants>
0036 #include <TelepathyQt/Types>
0037 
0038 AccountStatusHelper::AccountStatusHelper(QObject *parent)
0039     : QDBusAbstractAdaptor(parent),
0040     m_enabledAccounts(KTp::accountManager()->enabledAccounts()),
0041     m_telepathyConfig(KSharedConfig::openConfig(QLatin1String("ktelepathyrc"))),
0042     m_activities(new KActivities::Consumer())
0043 {
0044     Tp::registerTypes();
0045     reloadConfig();
0046 
0047     QDBusConnection::sessionBus().connect(QString(), QLatin1String("/Telepathy"),
0048                                           QLatin1String("org.kde.Telepathy"),
0049                                           QLatin1String("settingsChange"), this, SLOT(reloadConfig()));
0050 
0051     connect(m_enabledAccounts.data(), &Tp::AccountSet::accountAdded, [&] (const Tp::AccountPtr &account) {
0052         Tp::SimplePresence accountPresence = getDiskPresence(account->uniqueIdentifier(), m_activities->currentActivity());
0053 
0054         m_requestedAccountPresences[account->uniqueIdentifier()] = QVariant::fromValue<Tp::SimplePresence>(accountPresence);
0055         Q_EMIT statusChange(account->uniqueIdentifier());
0056     });
0057     connect(m_enabledAccounts.data(), &Tp::AccountSet::accountRemoved, [&] (const Tp::AccountPtr &account) {
0058         m_requestedAccountPresences.remove(account->uniqueIdentifier());
0059     });
0060 
0061     auto loadActivity = [=] (const QString &id) {
0062         m_requestedGlobalPresence = getDiskPresence(QLatin1String("LastPresence"), id);
0063 
0064         for (const Tp::AccountPtr &account : m_enabledAccounts->accounts()) {
0065             Tp::SimplePresence accountPresence = getDiskPresence(account->uniqueIdentifier(), id);
0066 
0067             m_requestedAccountPresences[account->uniqueIdentifier()] = QVariant::fromValue<Tp::SimplePresence>(accountPresence);
0068         }
0069     };
0070 
0071     auto activityServiceStatusChanged = [=] (KActivities::Consumer::ServiceStatus status) {
0072         if (status == KActivities::Consumer::Running) {
0073             loadActivity(m_activities->currentActivity());
0074 
0075             if (m_autoConnect) {
0076                 for (const Tp::AccountPtr &account : m_enabledAccounts->accounts()) {
0077                     Q_EMIT statusChange(account->uniqueIdentifier());
0078                 }
0079             }
0080         } else if (status == KActivities::Consumer::NotRunning) {
0081             qCWarning(KTP_KDED_MODULE) << "activity service not running, user account presences won't load or save";
0082         }
0083     };
0084 
0085     connect(m_activities, &KActivities::Consumer::serviceStatusChanged, this, activityServiceStatusChanged);
0086     connect(m_activities, &KActivities::Consumer::currentActivityChanged, [=] (const QString &id) {
0087         if (m_activities->serviceStatus() == KActivities::Consumer::Running) {
0088             if (getDiskPresence(QLatin1String("LastPresence"), id).type == Tp::ConnectionPresenceTypeUnset) {
0089                 setDiskPresence(QLatin1String("LastPresence"), m_requestedGlobalPresence, id);
0090             }
0091 
0092             loadActivity(id);
0093 
0094             for (const Tp::AccountPtr &account : m_enabledAccounts->accounts()) {
0095                 Q_EMIT statusChange(account->uniqueIdentifier());
0096             }
0097         }
0098     });
0099 
0100     connect(m_activities, &KActivities::Consumer::activityRemoved, [this] (const QString &id) {
0101         KConfigGroup activityGroup = m_telepathyConfig->group(id);
0102         activityGroup.deleteGroup();
0103         activityGroup.sync();
0104     });
0105 
0106     activityServiceStatusChanged(m_activities->serviceStatus());
0107 }
0108 
0109 AccountStatusHelper::~AccountStatusHelper()
0110 {
0111 }
0112 
0113 QHash<QString, QVariant> AccountStatusHelper::requestedAccountPresences() const
0114 {
0115     return m_requestedAccountPresences;
0116 }
0117 
0118 Tp::SimplePresence AccountStatusHelper::requestedGlobalPresence() const
0119 {
0120     return m_requestedGlobalPresence;
0121 }
0122 
0123 void AccountStatusHelper::setRequestedGlobalPresence(const Tp::SimplePresence &presence, uint presenceClass)
0124 {
0125     if (PresenceClass(presenceClass) == PresenceClass::Session) {
0126         if (presence.type == Tp::ConnectionPresenceTypeUnset) {
0127             m_requestedGlobalPresence = getDiskPresence(QLatin1String("LastPresence"), m_activities->currentActivity());
0128         } else if (presence.type == Tp::ConnectionPresenceTypeUnknown) {
0129             m_requestedGlobalPresence.statusMessage = presence.statusMessage;
0130         } else {
0131             m_requestedGlobalPresence = presence;
0132         }
0133     } else if (PresenceClass(presenceClass) == PresenceClass::Persistent) {
0134         m_requestedGlobalPresence = presence;
0135 
0136         if (m_requestedGlobalPresence.type != Tp::ConnectionPresenceTypeOffline) {
0137             setDiskPresence(QLatin1String("LastPresence"), presence, m_activities->currentActivity());
0138         }
0139     }
0140 
0141     qCDebug(KTP_KDED_MODULE) << "new requested global presence"
0142       << PresenceClass(presenceClass) << presence.status << "with status message"
0143       << presence.statusMessage;
0144 
0145     Q_EMIT statusChange();
0146 }
0147 
0148 void AccountStatusHelper::setRequestedAccountPresence(const QString &accountUID, const Tp::SimplePresence &presence, uint presenceClass)
0149 {
0150     if (PresenceClass(presenceClass) == PresenceClass::Session) {
0151         if (presence.type == Tp::ConnectionPresenceTypeUnset) {
0152             m_requestedAccountPresences[accountUID] = QVariant::fromValue<Tp::SimplePresence>(getDiskPresence(accountUID, m_activities->currentActivity()));
0153         } else if (presence.type == Tp::ConnectionPresenceTypeUnknown) {
0154             Tp::SimplePresence statusMessagePresence = qvariant_cast<Tp::SimplePresence>(m_requestedAccountPresences[accountUID]);
0155             statusMessagePresence.statusMessage = presence.statusMessage;
0156             m_requestedAccountPresences[accountUID] = QVariant::fromValue<Tp::SimplePresence>(statusMessagePresence);
0157         } else {
0158             m_requestedAccountPresences[accountUID] = QVariant::fromValue<Tp::SimplePresence>(presence);
0159         }
0160     } else if (PresenceClass(presenceClass) == PresenceClass::Persistent) {
0161         m_requestedAccountPresences[accountUID] = QVariant::fromValue<Tp::SimplePresence>(presence);
0162         setDiskPresence(accountUID, presence, m_activities->currentActivity());
0163     }
0164 
0165     qCDebug(KTP_KDED_MODULE) << "new requested account presence"
0166       << PresenceClass(presenceClass) << presence.status << "with status message"
0167       << presence.statusMessage << "for account" << accountUID;
0168 
0169     Q_EMIT statusChange(accountUID);
0170 }
0171 
0172 void AccountStatusHelper::reloadConfig()
0173 {
0174     KConfigGroup kdedConfig = m_telepathyConfig->group("KDED");
0175 
0176     m_autoConnect = kdedConfig.readEntry(QLatin1String("autoConnect"), false);
0177 }
0178 
0179 void AccountStatusHelper::setDiskPresence(const QString &presenceGroup, const Tp::SimplePresence &presence, const QString &activity)
0180 {
0181     KConfigGroup diskPresenceGroup = m_telepathyConfig->group(activity).group(presenceGroup);
0182 
0183     if (m_activities->serviceStatus() != KActivities::Consumer::Running) {
0184         return;
0185     }
0186 
0187     if (presence.type != Tp::ConnectionPresenceTypeUnset) {
0188         diskPresenceGroup.writeEntry(QLatin1String("PresenceType"), (uint)presence.type);
0189         diskPresenceGroup.writeEntry(QLatin1String("PresenceStatus"), presence.status);
0190         diskPresenceGroup.writeEntry(QLatin1String("PresenceMessage"), presence.statusMessage);
0191     } else if (diskPresenceGroup.exists()) {
0192         diskPresenceGroup.deleteGroup();
0193     }
0194 
0195     m_telepathyConfig->sync();
0196 }
0197 
0198 Tp::SimplePresence AccountStatusHelper::getDiskPresence(const QString &presenceGroup, const QString &activity) const
0199 {
0200     Tp::SimplePresence diskPresence;
0201     KConfigGroup diskPresenceGroup = m_telepathyConfig->group(activity).group(presenceGroup);
0202 
0203     diskPresence.type = diskPresenceGroup.readEntry<uint>(QLatin1String("PresenceType"), (uint)Tp::ConnectionPresenceTypeUnset);
0204     diskPresence.status = diskPresenceGroup.readEntry<QString>(QLatin1String("PresenceStatus"), QLatin1String("unset"));
0205     diskPresence.statusMessage = diskPresenceGroup.readEntry<QString>(QLatin1String("PresenceMessage"), QString());
0206 
0207     return diskPresence;
0208 }