File indexing completed on 2024-04-14 03:51:47

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 }
0031 
0032 void KDEDModule::setModuleName(const QString &name)
0033 {
0034     d->moduleName = name;
0035     QDBusObjectPath realPath(QLatin1String("/modules/") + d->moduleName);
0036 
0037     if (realPath.path().isEmpty()) {
0038         qCWarning(KDBUSADDONS_LOG) << "The kded module name" << name << "is invalid!";
0039         return;
0040     }
0041 
0042     QDBusConnection::RegisterOptions regOptions;
0043 
0044     if (this->metaObject()->indexOfClassInfo("D-Bus Interface") != -1) {
0045         // 1. There are kded modules that don't have a D-Bus interface.
0046         // 2. qt 4.4.3 crashes when trying to emit signals on class without
0047         //    Q_CLASSINFO("D-Bus Interface", "<your interface>") but
0048         //    ExportSignal set.
0049         // We try to solve that for now with just registering Properties and
0050         // Adaptors. But we should investigate where the sense is in registering
0051         // the module at all. Just for autoload? Is there a better solution?
0052         regOptions = QDBusConnection::ExportScriptableContents | QDBusConnection::ExportAdaptors;
0053     } else {
0054         // Full functional module. Register everything.
0055         regOptions = QDBusConnection::ExportScriptableSlots //
0056             | QDBusConnection::ExportScriptableProperties //
0057             | QDBusConnection::ExportAdaptors;
0058         qCDebug(KDBUSADDONS_LOG) << "Registration of kded module" << d->moduleName << "without D-Bus interface.";
0059     }
0060 
0061     if (!QDBusConnection::sessionBus().registerObject(realPath.path(), this, regOptions)) {
0062         // Happens for khotkeys but the module works. Need some time to investigate.
0063         qCDebug(KDBUSADDONS_LOG) << "registerObject() returned false for" << d->moduleName;
0064     } else {
0065         // qCDebug(KDBUSADDONS_LOG) << "registerObject() successful for" << d->moduleName;
0066         // Fix deadlock with Qt 5.6: this has to be delayed until the dbus thread is unlocked
0067         auto registeredSignal = [this, realPath]() {
0068             moduleRegistered(realPath);
0069         };
0070         QMetaObject::invokeMethod(this, registeredSignal, Qt::QueuedConnection);
0071     }
0072 }
0073 
0074 QString KDEDModule::moduleName() const
0075 {
0076     return d->moduleName;
0077 }
0078 
0079 static const char s_modules_path[] = "/modules/";
0080 
0081 QString KDEDModule::moduleForMessage(const QDBusMessage &message)
0082 {
0083     if (message.type() != QDBusMessage::MethodCallMessage) {
0084         return QString();
0085     }
0086 
0087     QString obj = message.path();
0088     if (!obj.startsWith(QLatin1String(s_modules_path))) {
0089         return QString();
0090     }
0091 
0092     // Remove the <s_modules_path> part
0093     obj = obj.mid(strlen(s_modules_path));
0094 
0095     // Remove the part after the modules name
0096     const int index = obj.indexOf(QLatin1Char('/'));
0097     if (index != -1) {
0098         obj = obj.left(index);
0099     }
0100 
0101     return obj;
0102 }
0103 
0104 #include "moc_kdedmodule.cpp"