1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
/*
SPDX-FileCopyrightText: 2019 Kai Uwe Broulik <kde@privat.broulik.de>
SPDX-License-Identifier: GPL-3.0-or-later
*/
#include "pluginmanager.h"
#include <QJsonObject>
#include "abstractbrowserplugin.h"
#include "connection.h"
PluginManager::PluginManager()
: QObject(nullptr)
{
connect(Connection::self(), &Connection::dataReceived, this, &PluginManager::onDataReceived);
}
PluginManager::~PluginManager() = default;
PluginManager &PluginManager::self()
{
static PluginManager s_self;
return s_self;
}
AbstractBrowserPlugin *PluginManager::pluginForSubsystem(const QString &subsystem) const
{
return m_plugins.value(subsystem);
}
void PluginManager::addPlugin(AbstractBrowserPlugin *plugin)
{
m_plugins.insert(plugin->m_subsystem, plugin);
}
bool PluginManager::loadPlugin(AbstractBrowserPlugin *plugin)
{
return setPluginLoaded(plugin, true);
}
bool PluginManager::unloadPlugin(AbstractBrowserPlugin *plugin)
{
return setPluginLoaded(plugin, false);
}
bool PluginManager::setPluginLoaded(AbstractBrowserPlugin *plugin, bool loaded)
{
if (!plugin) {
return false;
}
if (plugin->isLoaded() == loaded) {
return true;
}
bool ok = false;
if (loaded && !plugin->isLoaded()) {
ok = plugin->onLoad();
} else if (!loaded && plugin->isLoaded()) {
ok = plugin->onUnload();
}
if (!ok) {
qDebug() << "plugin" << plugin->subsystem() << "refused to" << (loaded ? "load" : "unload");
return false;
}
plugin->setLoaded(loaded);
if (loaded) {
Q_EMIT pluginLoaded(plugin);
} else {
Q_EMIT pluginUnloaded(plugin);
}
return true;
}
void PluginManager::settingsChanged(AbstractBrowserPlugin *plugin, const QJsonObject &settings)
{
plugin->onSettingsChanged(settings);
}
QStringList PluginManager::knownPluginSubsystems() const
{
return m_plugins.keys();
}
QStringList PluginManager::loadedPluginSubsystems() const
{
QStringList plugins;
for (auto it = m_plugins.constBegin(), end = m_plugins.constEnd(); it != end; ++it) {
if (it.value()->isLoaded()) {
plugins << it.key();
}
}
return plugins;
}
void PluginManager::onDataReceived(const QJsonObject &json)
{
const QString subsystem = json.value(QStringLiteral("subsystem")).toString();
AbstractBrowserPlugin *plugin = m_plugins.value(subsystem);
if (!plugin) {
return;
}
if (!plugin->isLoaded()) {
return;
}
const QString event = json.value(QStringLiteral("event")).toString();
if (event.isEmpty()) {
return;
}
const QJsonValue requestSerialVariant = json.value(QStringLiteral("serial"));
if (!requestSerialVariant.isUndefined()) {
const int requestSerial = requestSerialVariant.toInt();
const auto reply = plugin->handleData(requestSerial, event, json);
if (!reply.isEmpty()) {
plugin->sendReply(requestSerial, reply);
}
} else {
// design question, should we have a JSON of subsystem, event, payload, or have all data at the root level?
plugin->handleData(event, json);
}
}
#include "moc_pluginmanager.cpp"
|