File indexing completed on 2024-05-12 09:36:15
0001 /* 0002 * SPDX-FileCopyrightText: 2014 Daniel Vratil <dvratil@redhat.com> 0003 * 0004 * SPDX-License-Identifier: LGPL-2.1-or-later 0005 * 0006 */ 0007 0008 #include "backendloader.h" 0009 #include "abstractbackend.h" 0010 #include "backenddbuswrapper.h" 0011 #include "backendloaderadaptor.h" 0012 #include "backendmanager_p.h" 0013 #include "kscreen_backendLauncher_debug.h" 0014 0015 #include <QCoreApplication> 0016 #include <QDBusConnectionInterface> 0017 #include <QDir> 0018 #include <QPluginLoader> 0019 0020 #include <memory> 0021 0022 #include <QDBusConnection> 0023 #include <QDBusInterface> 0024 0025 void pluginDeleter(QPluginLoader *p) 0026 { 0027 if (p) { 0028 qCDebug(KSCREEN_BACKEND_LAUNCHER) << "Unloading" << p->fileName(); 0029 p->unload(); 0030 delete p; 0031 } 0032 } 0033 0034 BackendLoader::BackendLoader() 0035 : QObject() 0036 , QDBusContext() 0037 , mLoader(nullptr) 0038 , mBackend(nullptr) 0039 { 0040 } 0041 0042 BackendLoader::~BackendLoader() 0043 { 0044 delete mBackend; 0045 pluginDeleter(mLoader); 0046 qCDebug(KSCREEN_BACKEND_LAUNCHER) << "Backend loader destroyed"; 0047 } 0048 0049 bool BackendLoader::init() 0050 { 0051 QDBusConnection dbus = QDBusConnection::sessionBus(); 0052 new BackendLoaderAdaptor(this); 0053 if (!dbus.registerObject(QStringLiteral("/"), this, QDBusConnection::ExportAdaptors)) { 0054 qCWarning(KSCREEN_BACKEND_LAUNCHER) << "Failed to export backend to DBus: another launcher already running?"; 0055 qCWarning(KSCREEN_BACKEND_LAUNCHER) << dbus.lastError().message(); 0056 return false; 0057 } 0058 0059 return true; 0060 } 0061 0062 QString BackendLoader::backend() const 0063 { 0064 if (mBackend) { 0065 return mBackend->backend()->name(); 0066 } 0067 0068 return QString(); 0069 } 0070 0071 bool BackendLoader::requestBackend(const QString &backendName, const QVariantMap &arguments) 0072 { 0073 if (mBackend) { 0074 // If an backend is already loaded, but it's not the same as the one 0075 // requested, then it's an error 0076 if (!backendName.isEmpty() && mBackend->backend()->name() != backendName) { 0077 sendErrorReply(QDBusError::Failed, QStringLiteral("Another backend is already active")); 0078 return false; 0079 } else { 0080 // If caller requested the same one as already loaded, or did not 0081 // request a specific backend, hapilly reuse the existing one 0082 return true; 0083 } 0084 } 0085 0086 KScreen::AbstractBackend *backend = loadBackend(backendName, arguments); 0087 if (!backend) { 0088 return false; 0089 } 0090 0091 mBackend = new BackendDBusWrapper(backend); 0092 if (!mBackend->init()) { 0093 delete mBackend; 0094 mBackend = nullptr; 0095 pluginDeleter(mLoader); 0096 mLoader = nullptr; 0097 return false; 0098 } 0099 return true; 0100 } 0101 0102 KScreen::AbstractBackend *BackendLoader::loadBackend(const QString &name, const QVariantMap &arguments) 0103 { 0104 if (mLoader == nullptr) { 0105 std::unique_ptr<QPluginLoader, void (*)(QPluginLoader *)> loader(new QPluginLoader(), pluginDeleter); 0106 mLoader = loader.release(); 0107 } 0108 return KScreen::BackendManager::loadBackendPlugin(mLoader, name, arguments); 0109 } 0110 0111 void BackendLoader::quit() 0112 { 0113 qApp->quit(); 0114 } 0115 0116 #include "moc_backendloader.cpp"