File indexing completed on 2024-04-28 11:35:28

0001 /*
0002     This file is part of the KDE libraries
0003 
0004     SPDX-FileCopyrightText: 2001 Waldo Bastian <bastian@kde.org>
0005 
0006     SPDX-License-Identifier: LGPL-2.0-or-later
0007 */
0008 
0009 #include "kdedmodule.h"
0010 #include "kdbusaddons_debug.h"
0011 
0012 #include <QDBusConnection>
0013 #include <QDBusMessage>
0014 #include <QDBusObjectPath>
0015 
0016 class KDEDModulePrivate
0017 {
0018 public:
0019     QString moduleName;
0020 };
0021 
0022 KDEDModule::KDEDModule(QObject *parent)
0023     : QObject(parent)
0024     , d(new KDEDModulePrivate)
0025 {
0026 }
0027 
0028 KDEDModule::~KDEDModule()
0029 {
0030     Q_EMIT moduleDeleted(this);
0031 }
0032 
0033 void KDEDModule::setModuleName(const QString &name)
0034 {
0035     d->moduleName = name;
0036     QDBusObjectPath realPath(QLatin1String("/modules/") + d->moduleName);
0037 
0038     if (realPath.path().isEmpty()) {
0039         qCWarning(KDBUSADDONS_LOG) << "The kded module name" << name << "is invalid!";
0040         return;
0041     }
0042 
0043     QDBusConnection::RegisterOptions regOptions;
0044 
0045     if (this->metaObject()->indexOfClassInfo("D-Bus Interface") != -1) {
0046         // 1. There are kded modules that don't have a D-Bus interface.
0047         // 2. qt 4.4.3 crashes when trying to emit signals on class without
0048         //    Q_CLASSINFO("D-Bus Interface", "<your interface>") but
0049         //    ExportSignal set.
0050         // We try to solve that for now with just registering Properties and
0051         // Adaptors. But we should investigate where the sense is in registering
0052         // the module at all. Just for autoload? Is there a better solution?
0053         regOptions = QDBusConnection::ExportScriptableContents | QDBusConnection::ExportAdaptors;
0054     } else {
0055         // Full functional module. Register everything.
0056         regOptions = QDBusConnection::ExportScriptableSlots //
0057             | QDBusConnection::ExportScriptableProperties //
0058             | QDBusConnection::ExportAdaptors;
0059         qCDebug(KDBUSADDONS_LOG) << "Registration of kded module" << d->moduleName << "without D-Bus interface.";
0060     }
0061 
0062     if (!QDBusConnection::sessionBus().registerObject(realPath.path(), this, regOptions)) {
0063         // Happens for khotkeys but the module works. Need some time to investigate.
0064         qCDebug(KDBUSADDONS_LOG) << "registerObject() returned false for" << d->moduleName;
0065     } else {
0066         // qCDebug(KDBUSADDONS_LOG) << "registerObject() successful for" << d->moduleName;
0067         // Fix deadlock with Qt 5.6: this has to be delayed until the dbus thread is unlocked
0068         auto registeredSignal = [this, realPath]() {
0069             moduleRegistered(realPath);
0070         };
0071         QMetaObject::invokeMethod(this, registeredSignal, Qt::QueuedConnection);
0072     }
0073 }
0074 
0075 QString KDEDModule::moduleName() const
0076 {
0077     return d->moduleName;
0078 }
0079 
0080 static const char s_modules_path[] = "/modules/";
0081 
0082 QString KDEDModule::moduleForMessage(const QDBusMessage &message)
0083 {
0084     if (message.type() != QDBusMessage::MethodCallMessage) {
0085         return QString();
0086     }
0087 
0088     QString obj = message.path();
0089     if (!obj.startsWith(QLatin1String(s_modules_path))) {
0090         return QString();
0091     }
0092 
0093     // Remove the <s_modules_path> part
0094     obj = obj.mid(strlen(s_modules_path));
0095 
0096     // Remove the part after the modules name
0097     const int index = obj.indexOf(QLatin1Char('/'));
0098     if (index != -1) {
0099         obj = obj.left(index);
0100     }
0101 
0102     return obj;
0103 }
0104 
0105 #include "moc_kdedmodule.cpp"