File indexing completed on 2024-05-19 05:39:09

0001 /*
0002     SPDX-FileCopyrightText: 2017 Valerio Pilo <vpilo@coldshock.net>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-only
0005 */
0006 
0007 #include <QCommandLineParser>
0008 #include <QDebug>
0009 
0010 #include <QDBusConnection>
0011 #include <QDBusConnectionInterface>
0012 #include <QDBusServiceWatcher>
0013 
0014 #include <unistd.h>
0015 
0016 #include "debug_p.h"
0017 #include "waiter.h"
0018 
0019 constexpr static const char dbusServiceName[] = "org.freedesktop.Notifications";
0020 
0021 Waiter::Waiter(int argc, char **argv)
0022     : QCoreApplication(argc, argv)
0023     , mService(dbusServiceName)
0024 {
0025     setApplicationName(QStringLiteral("plasma_waitforname"));
0026     setApplicationVersion(QStringLiteral("1.0"));
0027 
0028     QCommandLineParser parser;
0029     parser.setApplicationDescription(
0030         QStringLiteral("Waits for D-Bus registration of the Notifications service.\n"
0031                        "Prevents notifications from being processed before the desktop is ready."));
0032     parser.addHelpOption();
0033     parser.addVersionOption();
0034     parser.addPositionalArgument(QStringLiteral("service"),
0035                                  QStringLiteral("Optionally listen for a service different than '%1'").arg(mService),
0036                                  QStringLiteral("[service]"));
0037     parser.process(*this);
0038 
0039     const QStringList args = parser.positionalArguments();
0040     if (!args.isEmpty()) {
0041         mService = args.at(0);
0042     }
0043 }
0044 
0045 bool Waiter::waitForService()
0046 {
0047     QDBusConnection sessionBus = QDBusConnection::sessionBus();
0048 
0049     if (sessionBus.interface()->isServiceRegistered(mService)) {
0050         qCDebug(LOG_PLASMA) << "WaitForName: Service" << mService << "is already registered";
0051         return false;
0052     }
0053 
0054     qCDebug(LOG_PLASMA) << "WaitForName: Waiting for appearance of service" << mService << "for" << dbusTimeoutSec << "seconds";
0055 
0056     QDBusServiceWatcher *watcher = new QDBusServiceWatcher(this);
0057     watcher->setConnection(sessionBus);
0058     watcher->setWatchMode(QDBusServiceWatcher::WatchForRegistration);
0059     watcher->addWatchedService(mService);
0060     connect(watcher, &QDBusServiceWatcher::serviceRegistered, this, &Waiter::registered);
0061 
0062     mTimeoutTimer.setSingleShot(true);
0063     mTimeoutTimer.setInterval(dbusTimeoutSec * 1000);
0064     connect(&mTimeoutTimer, &QTimer::timeout, this, &Waiter::timeout);
0065     mTimeoutTimer.start();
0066 
0067     return true;
0068 }
0069 
0070 void Waiter::registered()
0071 {
0072     qCDebug(LOG_PLASMA) << "WaitForName: Service was registered after" << (dbusTimeoutSec - (mTimeoutTimer.remainingTime() / 1000)) << "seconds";
0073     mTimeoutTimer.stop();
0074     exit(0);
0075 }
0076 
0077 void Waiter::timeout()
0078 {
0079     qCInfo(LOG_PLASMA) << "WaitForName: Service was not registered within timeout";
0080     exit(1);
0081 }