diff -Nru kubuntu-notification-helper-14.04ubuntu8/CMakeLists.txt kubuntu-notification-helper-14.04ubuntu9/CMakeLists.txt --- kubuntu-notification-helper-14.04ubuntu8/CMakeLists.txt 2014-02-20 09:03:48.000000000 +0000 +++ kubuntu-notification-helper-14.04ubuntu9/CMakeLists.txt 2014-04-01 11:35:39.000000000 +0000 @@ -18,6 +18,11 @@ add_definitions(${QT_DEFINITIONS} ${KDE4_DEFINITIONS} -DVERSION_STRING=\\"${VERSION_STRING}\\") add_definitions(-std=c++11) +if(START_TIMEOUT) + message(STATUS "timeout ${START_TIMEOUT}") + add_definitions(-DSTART_TIMEOUT=${START_TIMEOUT}) +endif() + add_subdirectory(data) add_subdirectory(src) diff -Nru kubuntu-notification-helper-14.04ubuntu8/debian/changelog kubuntu-notification-helper-14.04ubuntu9/debian/changelog --- kubuntu-notification-helper-14.04ubuntu8/debian/changelog 2014-03-17 12:32:10.000000000 +0000 +++ kubuntu-notification-helper-14.04ubuntu9/debian/changelog 2014-04-01 11:34:41.000000000 +0000 @@ -1,3 +1,16 @@ +kubuntu-notification-helper (14.04ubuntu9) trusty; urgency=medium + + * Port driverevent to new dbus API, needs some code copy for marshalling + as doing an automarshall to variant types somehow does not work + as expected. + + This repairs driver availability notification + * Instead of harcoding the init delay, allow definition through cmake, + debian/rules now defines the standard 3 minute delay while manual builds + will default to 1second. This removes the need to manually twiddle the + value when one wants to test changes. + + -- Harald Sitter Tue, 01 Apr 2014 13:28:16 +0200 + kubuntu-notification-helper (14.04ubuntu8) trusty; urgency=medium * Catch another source of PermissionError in whoopsie-upload-all, diff -Nru kubuntu-notification-helper-14.04ubuntu8/debian/rules kubuntu-notification-helper-14.04ubuntu9/debian/rules --- kubuntu-notification-helper-14.04ubuntu8/debian/rules 2014-02-20 09:03:48.000000000 +0000 +++ kubuntu-notification-helper-14.04ubuntu9/debian/rules 2014-04-01 11:22:53.000000000 +0000 @@ -6,4 +6,4 @@ dh $@ --parallel --dbg-package=kubuntu-notification-helper-dbg --with kde override_dh_auto_configure: - dh_auto_configure -- -DVERSION_STRING=$(version) + dh_auto_configure -- -DVERSION_STRING=$(version) -DVERSION_STRING="3*60*1000" diff -Nru kubuntu-notification-helper-14.04ubuntu8/src/daemon/CMakeLists.txt kubuntu-notification-helper-14.04ubuntu9/src/daemon/CMakeLists.txt --- kubuntu-notification-helper-14.04ubuntu8/src/daemon/CMakeLists.txt 2014-02-20 15:36:13.000000000 +0000 +++ kubuntu-notification-helper-14.04ubuntu9/src/daemon/CMakeLists.txt 2014-04-01 11:01:17.000000000 +0000 @@ -11,6 +11,7 @@ installevent/installgui.cpp l10nevent/l10nevent.cpp rebootevent/rebootevent.cpp + driverevent/Device.cpp driverevent/driverevent.cpp ) diff -Nru kubuntu-notification-helper-14.04ubuntu8/src/daemon/driverevent/Device.cpp kubuntu-notification-helper-14.04ubuntu9/src/daemon/driverevent/Device.cpp --- kubuntu-notification-helper-14.04ubuntu8/src/daemon/driverevent/Device.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kubuntu-notification-helper-14.04ubuntu9/src/daemon/driverevent/Device.cpp 2014-04-01 11:10:25.000000000 +0000 @@ -0,0 +1,159 @@ +/* + Copyright (C) 2014 Harald Sitter + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License or (at your option) version 3 or any later version + accepted by the membership of KDE e.V. (or its successor approved + by the membership of KDE e.V.), which shall act as a proxy + defined in Section 14 of version 3 of the license. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "Device.h" + +#include + +#warning code copy waaaaaaaaaaaaaaaaaaaaaaaah + +Driver::Driver() + : packageName() + , recommended(false) + , fromDistro(false) + , free(false) + , builtin(false) + , manualInstall(false) + // Set by manager; qapt dependent: + , fuzzyActive(false) + , package(nullptr) +{ +} + +bool Driver::operator<(const Driver &other) const +{ + return (packageName < other.packageName); +} + +QDebug operator<<(QDebug dbg, const Device &device) +{ + dbg.nospace() << "Dev("; + dbg.nospace() << "\n id: " << device.id; + dbg.nospace() << "\n modalias: " << device.modalias; + dbg.nospace() << "\n model: " << device.model; + dbg.nospace() << "\n vendor: " << device.vendor; + foreach (const Driver &driver, device.drivers) { + dbg.nospace() << "\n driver(" << driver.packageName; + dbg.nospace() << " recommended[" << driver.recommended << "]"; + dbg.nospace() << " free[" << driver.free << "]"; + dbg.nospace() << " fromDistro[" << driver.fromDistro << "]"; + dbg.nospace() << " builtin[" << driver.builtin << "]"; + dbg.nospace() << " manualInstall[" << driver.manualInstall << "]"; + dbg.nospace() << " fuzzyActive[" << driver.fuzzyActive << "]"; + dbg.nospace() << " package[" << driver.package << "]"; + dbg.nospace() << ")"; + } + dbg.nospace() << "\n)"; + return dbg.maybeSpace(); +} + +const QDBusArgument &operator>>(const QDBusArgument &argument, Driver &driver) +{ + argument.beginMap(); + while (!argument.atEnd()) { + QString key; + bool value; + argument.beginMapEntry(); + argument >> key >> value; + if (key == QLatin1String("recommended")) { + driver.recommended = value; + } else if (key == QLatin1String("free")) { + driver.free = value; + } else if (key == QLatin1String("from_distro")) { + driver.fromDistro = value; + } else if (key == QLatin1String("builtin")) { + driver.builtin = value; + } else if (key == QLatin1String("manual_install")) { + driver.manualInstall = value; + } + argument.endMapEntry(); + } + + argument.endMap(); + return argument; +} + +const QDBusArgument &operator>>(const QDBusArgument &argument, QList &driverList) +{ + argument.beginMap(); + while (!argument.atEnd()) { + Driver driver; + argument.beginMapEntry(); + argument >> driver.packageName >> driver; + argument.endMapEntry(); + driverList.append(driver); + } + argument.endMap(); + return argument; +} + +const QDBusArgument &operator>>(const QDBusArgument &argument, Device &device) +{ + argument.beginMap(); + + while (!argument.atEnd()) { + QString key; + QVariant value; + + argument.beginMapEntry(); + argument >> key >> value; + + if (key == QLatin1String("modalias")) { + device.modalias = value.toString(); + } else if (key == QLatin1String("vendor")) { + device.vendor = value.toString(); + } else if (key == QLatin1String("model")) { + device.model = value.toString(); + } else if (value.canConvert()) { + QDBusArgument arg = value.value(); + arg >> device.drivers; + } + + argument.endMapEntry(); + } + + argument.endMap(); + return argument; +} + +const QDBusArgument &operator>>(const QDBusArgument &argument, DeviceList &deviceList) +{ + qDebug() << Q_FUNC_INFO; + argument.beginMap(); + while (!argument.atEnd()) { + Device device; + argument.beginMapEntry(); + argument >> device.id >> device; + argument.endMapEntry(); + deviceList.append(device); + qDebug() << device; + } + argument.endMap(); + return argument; +} + +QDBusArgument &operator<<(QDBusArgument &argument, const DeviceList &deviceList) +{ + Q_UNUSED(deviceList); + qDebug() << Q_FUNC_INFO << "is noop"; + argument.beginMap(QVariant::String, QVariant::Map); + argument.endMap(); + return argument; +} diff -Nru kubuntu-notification-helper-14.04ubuntu8/src/daemon/driverevent/Device.h kubuntu-notification-helper-14.04ubuntu9/src/daemon/driverevent/Device.h --- kubuntu-notification-helper-14.04ubuntu8/src/daemon/driverevent/Device.h 1970-01-01 00:00:00.000000000 +0000 +++ kubuntu-notification-helper-14.04ubuntu9/src/daemon/driverevent/Device.h 2014-04-01 11:10:30.000000000 +0000 @@ -0,0 +1,106 @@ +/* + Copyright (C) 2014 Harald Sitter + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License or (at your option) version 3 or any later version + accepted by the membership of KDE e.V. (or its successor approved + by the membership of KDE e.V.), which shall act as a proxy + defined in Section 14 of version 3 of the license. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef DEVICE_H +#define DEVICE_H + +#include +#include + +namespace QApt { +class Package; +} + +struct Driver +{ + /** Constructor */ + Driver(); + + /** the distribution package providing this driver */ + QString packageName; + /** this is the recommended driver for the associated device */ + bool recommended; + /** this driver is an official distribution driver (otherwise 3rd party) */ + bool fromDistro; + /** this is a free driver */ + bool free; + /** this driver is built into the platform (e.g. official xorg drivers) */ + bool builtin; + /** driver was manually installed */ + bool manualInstall; + + /** most likely the active driver; dependent on fuzzy heuristics */ + bool fuzzyActive; + + /** QApt package pointer or nullptr if not initalized or found */ + QApt::Package *package; + + bool operator<(const Driver &other) const; +}; + +struct Device +{ + /** /dev system id of the device */ + QString id; + /** modalias */ + QString modalias; + /** model e.g. "GK104 [GeForce GTX 660 OEM]" */ + QString model; + /** vendor e.g. "NVIDIA Corporation" */ + QString vendor; + /** list of applicable drivers */ + QList drivers; +}; + +typedef QList DeviceList; +Q_DECLARE_METATYPE(DeviceList) + +// -------------------------------------------------------------------------- // +// --------------------------------- Debug ---------------------------------- // +// -------------------------------------------------------------------------- // + +/** + * QDebug operator for Device. This fung deep-debugs all members, without + * additional operators for the specific member types. + */ +QDebug operator<<(QDebug dbg, const Device &device); + +// -------------------------------------------------------------------------- // +// ---------------------------------- DBus ---------------------------------- // +// -------------------------------------------------------------------------- // + +// We are doing nested demarshalling as auto-marshalling into basic types +// such as QMap will not give us any advantage other than +// flattening out the marshalling, thus causing shitty to read functions; +// we'd still have to do string mapping and variant casting. + +/** demarshall driver */ +const QDBusArgument &operator>>(const QDBusArgument &argument, Driver &driver); +/** demarshall list of drivers */ +const QDBusArgument &operator>>(const QDBusArgument &argument, QList &driverList); +/** demarshall device */ +const QDBusArgument &operator>>(const QDBusArgument &argument, Device &device); +/** demarshall list of devices */ +const QDBusArgument &operator>>(const QDBusArgument &argument, DeviceList &deviceList); + +/** marshall list of devices. this function does nothing. */ +QDBusArgument &operator<<(QDBusArgument &argument, const DeviceList &deviceList); + +#endif // DEVICE_H diff -Nru kubuntu-notification-helper-14.04ubuntu8/src/daemon/driverevent/driverevent.cpp kubuntu-notification-helper-14.04ubuntu9/src/daemon/driverevent/driverevent.cpp --- kubuntu-notification-helper-14.04ubuntu8/src/daemon/driverevent/driverevent.cpp 2014-02-28 10:41:46.000000000 +0000 +++ kubuntu-notification-helper-14.04ubuntu9/src/daemon/driverevent/driverevent.cpp 2014-04-01 11:15:15.000000000 +0000 @@ -31,12 +31,13 @@ #include #include - DriverEvent::DriverEvent(QObject *parent, QString name) : Event(parent, name) , m_showNotification(false) , m_aptBackendInitialized(false) { + qDBusRegisterMetaType(); + m_aptBackend = new QApt::Backend(this); if (!m_aptBackend->init()) { kWarning() << m_aptBackend->initErrorMessage(); @@ -61,54 +62,55 @@ void DriverEvent::updateFinished() { if (!m_aptBackend->openXapianIndex()) { + kDebug() << "Xapian update could not be opened, probably broken."; return; } m_manager = new OrgKubuntuDriverManagerInterface("org.kubuntu.DriverManager", "/DriverManager", QDBusConnection::sessionBus()); - m_manager->getDriverDict(false); - connect(m_manager, SIGNAL(dataReady(QVariantMapMap)), SLOT(driverDictFinished(QVariantMapMap)), Qt::UniqueConnection); + QDBusPendingReply reply = m_manager->devices(); + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this); + connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), + this, SLOT(onDevicesReady(QDBusPendingCallWatcher*))); } - -void DriverEvent::driverDictFinished(QVariantMapMap data) +void DriverEvent::onDevicesReady(QDBusPendingCallWatcher *call) { - kDebug(); - if (data.isEmpty()) { + QDBusPendingReply reply = *call; + + if (reply.isError()) { + kDebug() << "got dbus error; abort"; return; } + DeviceList devices = reply.value(); + call->deleteLater(); // deep copy, delete caller + + kDebug() << "data " << devices; + KConfig driver_manager("kcmdrivermanagerrc"); KConfigGroup pciGroup( &driver_manager, "PCI" ); - Q_FOREACH(const QString &key,data.keys()) { - if (pciGroup.readEntry(key) != QLatin1String("true")) { - QDBusPendingReply driverForDeviceMap = m_manager->getDriverMapForDevice(key); - QDBusPendingCallWatcher *async = new QDBusPendingCallWatcher(driverForDeviceMap, this); - connect(async, SIGNAL(finished(QDBusPendingCallWatcher*)), SLOT(driverMapFinished(QDBusPendingCallWatcher*))); - } else { - kDebug() << key << "has already been processed by the KCM"; - } - } -} - -void DriverEvent::driverMapFinished(QDBusPendingCallWatcher *data) -{ - kDebug(); - if (!data->isError()) { - QDBusPendingReply mapReply = *data; - QVariantMapMap map = mapReply.value(); - - Q_FOREACH (const QString &key, map.keys()) { - if (map[key]["recommended"].toBool()) { - QApt::Package *pkg = m_aptBackend->package(key); - if (pkg) { - if (!pkg->isInstalled()) { - m_showNotification = true; - break; + foreach (Device device, devices) { + if (pciGroup.readEntry(device.id) != QLatin1String("true")) { + // Not seen before, check whether we have recommended drivers. + for (int i = 0; i < device.drivers.length(); ++i) { + // Supposedly Driver is not a pod due to ctor, so it can't + // be fully used by QList :'< + // Manually iter instead. + Driver driver = device.drivers.at(i); + if (driver.recommended) { + QApt::Package *package = m_aptBackend->package(driver.packageName); + if (package) { + if (!package->isInstalled()) { + m_showNotification = true; + break; + } } } } + } else { + kDebug() << device.id << "has already been processed by the KCM"; } } diff -Nru kubuntu-notification-helper-14.04ubuntu8/src/daemon/driverevent/driverevent.h kubuntu-notification-helper-14.04ubuntu9/src/daemon/driverevent/driverevent.h --- kubuntu-notification-helper-14.04ubuntu8/src/daemon/driverevent/driverevent.h 2014-02-23 16:39:13.000000000 +0000 +++ kubuntu-notification-helper-14.04ubuntu9/src/daemon/driverevent/driverevent.h 2014-04-01 11:35:59.000000000 +0000 @@ -49,8 +49,7 @@ bool m_aptBackendInitialized; private Q_SLOTS: - void driverDictFinished(QVariantMapMap); - void driverMapFinished(QDBusPendingCallWatcher*); + void onDevicesReady(QDBusPendingCallWatcher *call); void run(); void updateFinished(); diff -Nru kubuntu-notification-helper-14.04ubuntu8/src/daemon/driverevent/drivermanagerdbustypes.h kubuntu-notification-helper-14.04ubuntu9/src/daemon/driverevent/drivermanagerdbustypes.h --- kubuntu-notification-helper-14.04ubuntu8/src/daemon/driverevent/drivermanagerdbustypes.h 2014-02-20 09:03:48.000000000 +0000 +++ kubuntu-notification-helper-14.04ubuntu9/src/daemon/driverevent/drivermanagerdbustypes.h 2014-04-01 11:02:30.000000000 +0000 @@ -25,8 +25,7 @@ #include #include -typedef QMap QVariantMapMap; -Q_DECLARE_METATYPE(QVariantMapMap) +#include "Device.h" #endif // dbustypes_H diff -Nru kubuntu-notification-helper-14.04ubuntu8/src/daemon/driverevent/org.kubuntu.DriverManager.xml kubuntu-notification-helper-14.04ubuntu9/src/daemon/driverevent/org.kubuntu.DriverManager.xml --- kubuntu-notification-helper-14.04ubuntu8/src/daemon/driverevent/org.kubuntu.DriverManager.xml 2014-02-20 09:03:48.000000000 +0000 +++ kubuntu-notification-helper-14.04ubuntu9/src/daemon/driverevent/org.kubuntu.DriverManager.xml 2014-04-01 11:02:35.000000000 +0000 @@ -2,17 +2,9 @@ "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> - - - - - - - - - - + + - \ No newline at end of file + diff -Nru kubuntu-notification-helper-14.04ubuntu8/src/daemon/notificationhelpermodule.cpp kubuntu-notification-helper-14.04ubuntu9/src/daemon/notificationhelpermodule.cpp --- kubuntu-notification-helper-14.04ubuntu8/src/daemon/notificationhelpermodule.cpp 2014-02-28 10:41:46.000000000 +0000 +++ kubuntu-notification-helper-14.04ubuntu9/src/daemon/notificationhelpermodule.cpp 2014-04-01 11:35:20.000000000 +0000 @@ -50,6 +50,9 @@ ) K_EXPORT_PLUGIN(NotificationHelperModuleFactory("notificationhelper")) +#ifndef START_TIMEOUT +#define START_TIMEOUT 1000 +#endif NotificationHelperModule::NotificationHelperModule(QObject* parent, const QList&) : KDEDModule(parent) @@ -69,9 +72,7 @@ KLocalizedString(), "http://kubuntu.org", "https://bugs.launchpad.net/ubuntu"); - // Delay init by 3 minutes to speed up start of kded and prevent a notification - // wall on login. - QTimer::singleShot(1000, this, SLOT(init())); + QTimer::singleShot(START_TIMEOUT, this, SLOT(init())); } NotificationHelperModule::~NotificationHelperModule()