@@ -25,20 +25,6 @@
2525#include <QDBusConnectionInterface>
2626#include <QDBusReply>
2727
28−// On construction QDBusInterface synchronously introspects the service, which will block the GUI
29−// thread if the service is busy. QDBusAbstractInterface does not perform this introspection, so
30−// let's subclass that and avoid the blocking scenario.
31−class AsyncDBusInterface : public QDBusAbstractInterface
32−{
33−public:
34− AsyncDBusInterface(const QString &service, const QString &path,
35− const QString &interface, const QDBusConnection &connection,
36− QObject *parent = 0)
37− : QDBusAbstractInterface(service, path, interface.toLatin1().data(), connection, parent)
38− {}
39− ~AsyncDBusInterface() = default;
40−};
41−
4228AbstractDBusServiceMonitor::AbstractDBusServiceMonitor(const QString &service, const QString &path,
4329 const QString &interface, const Bus bus,
4430 QObject *parent)
@@ -46,19 +32,20 @@ AbstractDBusServiceMonitor::AbstractDBusServiceMonitor(const QString &service, c
4632 , m_service(service)
4733 , m_path(path)
4834 , m_interface(interface)
35+ , m_bus(bus)
4936 , m_watcher(new QDBusServiceWatcher(service,
5037 (bus == SystemBus) ? QDBusConnection::systemBus()
5138 : QDBusConnection::sessionBus()))
5239 , m_dbusInterface(nullptr)
5340{
54− connect(m_watcher, &QDBusServiceWatcher::serviceRegistered, this, &AbstractDBusServiceMonitor::createInterface);
55− connect(m_watcher, &QDBusServiceWatcher::serviceUnregistered, this, &AbstractDBusServiceMonitor::destroyInterface);
41+ connect(m_watcher, &QDBusServiceWatcher::serviceRegistered, this, &AbstractDBusServiceMonitor::onServiceRegistered);
42+ connect(m_watcher, &QDBusServiceWatcher::serviceUnregistered, this, &AbstractDBusServiceMonitor::onServiceUnregistered);
5643
5744 // Connect to the service if it's up already
5845 QDBusConnectionInterface* sessionBus = QDBusConnection::sessionBus().interface();
5946 QDBusReply<bool> reply = sessionBus->isServiceRegistered(m_service);
6047 if (reply.isValid() && reply.value()) {
61− createInterface(m_service);
48+ onServiceRegistered(m_service);
6249 }
6350}
6451
@@ -68,19 +55,31 @@ AbstractDBusServiceMonitor::~AbstractDBusServiceMonitor()
6855 delete m_dbusInterface;
6956}
7057
71−void AbstractDBusServiceMonitor::createInterface(const QString &)
58+void AbstractDBusServiceMonitor::onServiceRegistered(const QString &)
7259{
7360 if (m_dbusInterface != nullptr) {
7461 delete m_dbusInterface;
7562 m_dbusInterface = nullptr;
7663 }
7764
78− m_dbusInterface = new AsyncDBusInterface(m_service, m_path, m_interface,
79− QDBusConnection::sessionBus());
65+ m_dbusInterface = createInterface(m_service, m_path, m_interface,
66+ (m_bus == SystemBus) ? QDBusConnection::systemBus()
67+ : QDBusConnection::sessionBus());
8068 Q_EMIT serviceAvailableChanged(true);
8169}
8270
83−void AbstractDBusServiceMonitor::destroyInterface(const QString &)
71+/*
72+ * Default implementation creates a QDBusInterface. This performs blocking introspection of the
73+ * service at initialization, which may be undesirable if the service is slow/blocked.
74+ */
75+QDBusAbstractInterface*
76+AbstractDBusServiceMonitor::createInterface(const QString &service, const QString &path,
77+ const QString &interface, const QDBusConnection &connection)
78+{
79+ return new QDBusInterface(service, path, interface, connection);
80+}
81+
82+void AbstractDBusServiceMonitor::onServiceUnregistered(const QString &)
8483{
8584 if (m_dbusInterface != nullptr) {
8685 delete m_dbusInterface;