File indexing completed on 2024-05-12 17:08:50

0001 /*
0002     SPDX-FileCopyrightText: 2015 Marco Martin <mart@kde.org>
0003     SPDX-FileCopyrightText: 2020 Konrad Materka <materka@gmail.com>
0004 
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 #include "plasmoidregistry.h"
0009 #include "debug.h"
0010 
0011 #include "dbusserviceobserver.h"
0012 #include "systemtraysettings.h"
0013 
0014 #include <KPluginMetaData>
0015 #include <Plasma/PluginLoader>
0016 
0017 #include <QDBusConnection>
0018 
0019 PlasmoidRegistry::PlasmoidRegistry(QPointer<SystemTraySettings> settings, QObject *parent)
0020     : QObject(parent)
0021     , m_settings(settings)
0022     , m_dbusObserver(new DBusServiceObserver(settings, this))
0023 {
0024     connect(m_dbusObserver, &DBusServiceObserver::serviceStarted, this, &PlasmoidRegistry::plasmoidEnabled);
0025     connect(m_dbusObserver, &DBusServiceObserver::serviceStopped, this, &PlasmoidRegistry::plasmoidStopped);
0026 }
0027 
0028 void PlasmoidRegistry::init()
0029 {
0030     QDBusConnection::sessionBus().connect(QString(),
0031                                           QStringLiteral("/KPackage/Plasma/Applet"),
0032                                           QStringLiteral("org.kde.plasma.kpackage"),
0033                                           QStringLiteral("packageInstalled"),
0034                                           this,
0035                                           SLOT(packageInstalled(QString)));
0036     QDBusConnection::sessionBus().connect(QString(),
0037                                           QStringLiteral("/KPackage/Plasma/Applet"),
0038                                           QStringLiteral("org.kde.plasma.kpackage"),
0039                                           QStringLiteral("packageUpdated"),
0040                                           this,
0041                                           SLOT(packageInstalled(QString)));
0042     QDBusConnection::sessionBus().connect(QString(),
0043                                           QStringLiteral("/KPackage/Plasma/Applet"),
0044                                           QStringLiteral("org.kde.plasma.kpackage"),
0045                                           QStringLiteral("packageUninstalled"),
0046                                           this,
0047                                           SLOT(packageUninstalled(QString)));
0048 
0049     connect(m_settings, &SystemTraySettings::enabledPluginsChanged, this, &PlasmoidRegistry::onEnabledPluginsChanged);
0050 
0051     for (const auto &info : Plasma::PluginLoader::self()->listAppletMetaData(QString())) {
0052         registerPlugin(info);
0053     }
0054 
0055     m_dbusObserver->initDBusActivatables();
0056 
0057     sanitizeSettings();
0058 }
0059 
0060 QMap<QString, KPluginMetaData> PlasmoidRegistry::systemTrayApplets()
0061 {
0062     return m_systrayApplets;
0063 }
0064 
0065 bool PlasmoidRegistry::isSystemTrayApplet(const QString &pluginId)
0066 {
0067     return m_systrayApplets.contains(pluginId);
0068 }
0069 
0070 void PlasmoidRegistry::onEnabledPluginsChanged(const QStringList &enabledPlugins, const QStringList &disabledPlugins)
0071 {
0072     for (const QString &pluginId : enabledPlugins) {
0073         if (m_systrayApplets.contains(pluginId) && !m_dbusObserver->isDBusActivable(pluginId)) {
0074             Q_EMIT plasmoidEnabled(pluginId);
0075         }
0076     }
0077     for (const QString &pluginId : disabledPlugins) {
0078         if (m_systrayApplets.contains(pluginId)) {
0079             Q_EMIT plasmoidDisabled(pluginId);
0080         }
0081     }
0082 }
0083 
0084 void PlasmoidRegistry::packageInstalled(const QString &pluginId)
0085 {
0086     qCDebug(SYSTEM_TRAY) << "New package installed" << pluginId;
0087 
0088     if (m_systrayApplets.contains(pluginId)) {
0089         if (m_settings->isEnabledPlugin(pluginId) && !m_dbusObserver->isDBusActivable(pluginId)) {
0090             // restart plasmoid
0091             Q_EMIT plasmoidStopped(pluginId);
0092             Q_EMIT plasmoidEnabled(pluginId);
0093         }
0094         return;
0095     }
0096 
0097     for (const auto &info : Plasma::PluginLoader::self()->listAppletMetaData(QString())) {
0098         if (info.pluginId() == pluginId) {
0099             registerPlugin(info);
0100         }
0101     }
0102 }
0103 
0104 void PlasmoidRegistry::packageUninstalled(const QString &pluginId)
0105 {
0106     qCDebug(SYSTEM_TRAY) << "Package uninstalled" << pluginId;
0107     if (m_systrayApplets.contains(pluginId)) {
0108         unregisterPlugin(pluginId);
0109     }
0110 }
0111 
0112 void PlasmoidRegistry::registerPlugin(const KPluginMetaData &pluginMetaData)
0113 {
0114     if (!pluginMetaData.isValid() || pluginMetaData.value(QStringLiteral("X-Plasma-NotificationArea")) != QLatin1String("true")) {
0115         return;
0116     }
0117 
0118     const QString &pluginId = pluginMetaData.pluginId();
0119 
0120     m_systrayApplets[pluginId] = pluginMetaData;
0121     m_dbusObserver->registerPlugin(pluginMetaData);
0122 
0123     Q_EMIT pluginRegistered(pluginMetaData);
0124 
0125     // add plasmoid if is both not enabled explicitly and not already known
0126     if (pluginMetaData.isEnabledByDefault()) {
0127         const QString &candidate = pluginMetaData.pluginId();
0128         if (!m_settings->isKnownPlugin(candidate)) {
0129             m_settings->addKnownPlugin(candidate);
0130             if (!m_settings->isEnabledPlugin(candidate)) {
0131                 m_settings->addEnabledPlugin(candidate);
0132             }
0133         }
0134     }
0135 
0136     if (m_settings->isEnabledPlugin(pluginId) && !m_dbusObserver->isDBusActivable(pluginId)) {
0137         Q_EMIT plasmoidEnabled(pluginId);
0138     }
0139 }
0140 
0141 void PlasmoidRegistry::unregisterPlugin(const QString &pluginId)
0142 {
0143     Q_EMIT pluginUnregistered(pluginId);
0144 
0145     m_dbusObserver->unregisterPlugin(pluginId);
0146     m_systrayApplets.remove(pluginId);
0147 
0148     m_settings->cleanupPlugin(pluginId);
0149 }
0150 
0151 void PlasmoidRegistry::sanitizeSettings()
0152 {
0153     // remove all no longer available in the system (e.g. uninstalled)
0154     const QStringList knownPlugins = m_settings->knownPlugins();
0155     for (const QString &pluginId : knownPlugins) {
0156         if (!m_systrayApplets.contains(pluginId)) {
0157             m_settings->removeKnownPlugin(pluginId);
0158         }
0159     }
0160 
0161     const QStringList enabledPlugins = m_settings->enabledPlugins();
0162     for (const QString &pluginId : enabledPlugins) {
0163         if (!m_systrayApplets.contains(pluginId)) {
0164             m_settings->removeEnabledPlugin(pluginId);
0165         }
0166     }
0167 }