diff --git a/0003-Cache-UDisks2-Device-DBus-connections.patch b/0003-Cache-UDisks2-Device-DBus-connections.patch new file mode 100644 index 0000000..504f016 --- /dev/null +++ b/0003-Cache-UDisks2-Device-DBus-connections.patch @@ -0,0 +1,744 @@ +From be5ca0c8406d82af0cfb8f8a250410399873b76d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Dan=20Vr=C3=A1til?= +Date: Mon, 3 Dec 2012 15:42:32 +0100 +Subject: [PATCH 03/26] Cache UDisks2 Device DBus connections + +Cache the QDBusInterface connection for each UDI so that +it's not recreated every time Solid::Device is constructed. +This greatly reduces the number of DBus calls and makes +the UDisks2 backend much faster. +--- + solid/solid/CMakeLists.txt | 1 + + solid/solid/backends/udisks2/udisksdevice.cpp | 212 +++++------------- + solid/solid/backends/udisks2/udisksdevice.h | 19 +- + .../solid/backends/udisks2/udisksdevicebackend.cpp | 239 +++++++++++++++++++++ + solid/solid/backends/udisks2/udisksdevicebackend.h | 84 ++++++++ + solid/solid/backends/udisks2/udisksmanager.cpp | 16 +- + .../solid/backends/udisks2/udisksopticaldrive.cpp | 6 +- + 7 files changed, 405 insertions(+), 172 deletions(-) + create mode 100644 solid/solid/backends/udisks2/udisksdevicebackend.cpp + create mode 100644 solid/solid/backends/udisks2/udisksdevicebackend.h + +diff --git a/solid/solid/CMakeLists.txt b/solid/solid/CMakeLists.txt +index 5cd1484..b7dcc97 100644 +--- a/solid/solid/CMakeLists.txt ++++ b/solid/solid/CMakeLists.txt +@@ -272,6 +272,7 @@ if(NOT WIN32 AND NOT APPLE) + set(solid_LIB_SRCS ${solid_LIB_SRCS} + backends/udisks2/udisksmanager.cpp + backends/udisks2/udisksdevice.cpp ++ backends/udisks2/udisksdevicebackend.cpp + backends/udisks2/udisksblock.cpp + backends/udisks2/udisksstoragevolume.cpp + backends/udisks2/udisksdeviceinterface.cpp +diff --git a/solid/solid/backends/udisks2/udisksdevice.cpp b/solid/solid/backends/udisks2/udisksdevice.cpp +index 3508d57..2a4313a 100644 +--- a/solid/solid/backends/udisks2/udisksdevice.cpp ++++ b/solid/solid/backends/udisks2/udisksdevice.cpp +@@ -20,6 +20,7 @@ + */ + + #include "udisksdevice.h" ++#include "udisksdevicebackend.h" + #include "udisksblock.h" + #include "udisksdeviceinterface.h" + #include "udisksstoragevolume.h" +@@ -91,29 +92,72 @@ static QString formatByteSize(double size) + + Device::Device(const QString &udi) + : Solid::Ifaces::Device() +- , m_udi(udi) +- , m_connection(QDBusConnection::connectToBus(QDBusConnection::SystemBus, "Solid::Udisks2::Device::" + udi)) ++ , m_backend(DeviceBackend::backendForUDI(udi)) + { +- m_device = new QDBusInterface(UD2_DBUS_SERVICE, m_udi, +- QString(), // no interface, we aggregate them +- m_connection); ++ if (m_backend) { ++ connect(m_backend, SIGNAL(changed()), this, SIGNAL(changed())); ++ connect(m_backend, SIGNAL(propertyChanged(QMap)), this, SIGNAL(propertyChanged(QMap))); ++ } else { ++ qDebug() << "Created invalid Device for udi" << udi; ++ } ++} ++ ++Device::~Device() ++{ ++} ++ ++QString Device::udi() const ++{ ++ if (m_backend) { ++ return m_backend->udi(); ++ } ++ ++ return QString(); ++} + +- if (m_device->isValid()) { +- m_connection.connect(UD2_DBUS_SERVICE, m_udi, DBUS_INTERFACE_PROPS, "PropertiesChanged", this, +- SLOT(slotPropertiesChanged(QString,QVariantMap,QStringList))); ++QVariant Device::prop(const QString &key) const ++{ ++ if (m_backend) { ++ return m_backend->prop(key); ++ } + +- m_connection.connect(UD2_DBUS_SERVICE, UD2_DBUS_PATH, DBUS_INTERFACE_MANAGER, "InterfacesAdded", +- this, SLOT(slotInterfacesAdded(QDBusObjectPath,QVariantMapMap))); +- m_connection.connect(UD2_DBUS_SERVICE, UD2_DBUS_PATH, DBUS_INTERFACE_MANAGER, "InterfacesRemoved", +- this, SLOT(slotInterfacesRemoved(QDBusObjectPath,QStringList))); ++ return QVariant(); ++} + +- initInterfaces(); ++bool Device::propertyExists(const QString &key) const ++{ ++ if (m_backend) { ++ return m_backend->propertyExists(key); + } ++ ++ return false; + } + +-Device::~Device() ++QVariantMap Device::allProperties() const + { +- delete m_device; ++ if (m_backend) { ++ return m_backend->allProperties(); ++ } ++ ++ return QVariantMap(); ++} ++ ++bool Device::hasInterface(const QString &name) const ++{ ++ if (m_backend) { ++ return m_backend->interfaces().contains(name); ++ } ++ ++ return false; ++} ++ ++QStringList Device::interfaces() const ++{ ++ if (m_backend) { ++ return m_backend->interfaces(); ++ } ++ ++ return QStringList(); + } + + QObject* Device::createDeviceInterface(const Solid::DeviceInterface::Type& type) +@@ -637,11 +681,6 @@ QString Device::vendor() const + return prop("Vendor").toString(); + } + +-QString Device::udi() const +-{ +- return m_udi; +-} +- + QString Device::parentUdi() const + { + QString parent; +@@ -656,139 +695,6 @@ QString Device::parentUdi() const + return parent; + } + +-void Device::checkCache(const QString &key) const +-{ +- if (m_cache.isEmpty()) // recreate the cache +- allProperties(); +- +- if (m_cache.contains(key)) +- return; +- +- QVariant reply = m_device->property(key.toUtf8()); +- +- if (reply.isValid()) { +- m_cache.insert(key, reply); +- } else { +- //qDebug() << "got invalid reply for cache:" << key; +- } +-} +- +-QString Device::introspect() const +-{ +- QDBusMessage call = QDBusMessage::createMethodCall(UD2_DBUS_SERVICE, m_udi, +- DBUS_INTERFACE_INTROSPECT, "Introspect"); +- QDBusPendingReply reply = m_connection.asyncCall(call); +- reply.waitForFinished(); +- +- if (reply.isValid()) +- return reply.value(); +- else { +- return QString(); +- } +-} +- +-QVariant Device::prop(const QString &key) const +-{ +- checkCache(key); +- return m_cache.value(key); +-} +- +-bool Device::propertyExists(const QString &key) const +-{ +- checkCache(key); +- return m_cache.contains(key); +-} +- +-QVariantMap Device::allProperties() const +-{ +- QDBusMessage call = QDBusMessage::createMethodCall(UD2_DBUS_SERVICE, m_udi, DBUS_INTERFACE_PROPS, "GetAll"); +- +- Q_FOREACH (const QString & iface, m_interfaces) { +- if (iface.startsWith("org.freedesktop.DBus")) +- continue; +- call.setArguments(QVariantList() << iface); +- QDBusPendingReply reply = m_connection.asyncCall(call); +- reply.waitForFinished(); +- +- if (reply.isValid()) +- m_cache.unite(reply.value()); +- else +- qWarning() << "Error getting props:" << reply.error().name() << reply.error().message(); +- //qDebug() << "After iface" << iface << ", cache now contains" << m_cache.size() << "items"; +- } +- +- return m_cache; +-} +- +-bool Device::hasInterface(const QString &name) const +-{ +- return m_interfaces.contains(name); +-} +- +-QStringList Device::interfaces() const +-{ +- return m_interfaces; +-} +- +-void Device::initInterfaces() +-{ +- m_interfaces.clear(); +- const QString xmlData = introspect(); +- QDomDocument dom; +- dom.setContent(xmlData); +- QDomNodeList ifaceNodeList = dom.elementsByTagName("interface"); +- for (int i = 0; i < ifaceNodeList.count(); i++) { +- QDomElement ifaceElem = ifaceNodeList.item(i).toElement(); +- if (!ifaceElem.isNull()) +- m_interfaces.append(ifaceElem.attribute("name")); +- } +- //qDebug() << "Device" << m_udi << "has interfaces:" << m_interfaces; +-} +- +-void Device::slotPropertiesChanged(const QString &ifaceName, const QVariantMap &changedProps, const QStringList &invalidatedProps) +-{ +- //Q_UNUSED(ifaceName); +- +- qDebug() << m_udi << "'s interface" << ifaceName << "changed props:"; +- +- QMap changeMap; +- +- Q_FOREACH(const QString & key, invalidatedProps) { +- m_cache.remove(key); +- changeMap.insert(key, Solid::GenericInterface::PropertyRemoved); +- qDebug() << "\t invalidated:" << key; +- } +- +- QMapIterator i(changedProps); +- while (i.hasNext()) { +- i.next(); +- const QString key = i.key(); +- m_cache.insert(key, i.value()); // replace the value +- changeMap.insert(key, Solid::GenericInterface::PropertyModified); +- qDebug() << "\t modified:" << key << ":" << m_cache.value(key); +- } +- +- Q_EMIT propertyChanged(changeMap); +- Q_EMIT changed(); +-} +- +-void Device::slotInterfacesAdded(const QDBusObjectPath &object_path, const QVariantMapMap &interfaces_and_properties) +-{ +- if (object_path.path() == m_udi) { +- m_interfaces.append(interfaces_and_properties.keys()); +- } +-} +- +-void Device::slotInterfacesRemoved(const QDBusObjectPath &object_path, const QStringList &interfaces) +-{ +- if (object_path.path() == m_udi) { +- Q_FOREACH(const QString & iface, interfaces) { +- m_interfaces.removeAll(iface); +- } +- } +-} +- +- + QString Device::errorToString(const QString & error) const + { + if (error == UD2_ERROR_UNAUTHORIZED || error == UD2_ERROR_NOT_AUTHORIZED) +diff --git a/solid/solid/backends/udisks2/udisksdevice.h b/solid/solid/backends/udisks2/udisksdevice.h +index ee6bc1b..6038178 100644 +--- a/solid/solid/backends/udisks2/udisksdevice.h ++++ b/solid/solid/backends/udisks2/udisksdevice.h +@@ -39,6 +39,8 @@ namespace Backends + namespace UDisks2 + { + ++class DeviceBackend; ++ + class Device: public Solid::Ifaces::Device + { + Q_OBJECT +@@ -87,25 +89,12 @@ Q_SIGNALS: + void changed(); + void propertyChanged(const QMap &changes); + +-private Q_SLOTS: +- void slotPropertiesChanged(const QString & ifaceName, const QVariantMap & changedProps, const QStringList & invalidatedProps); +- void slotInterfacesAdded(const QDBusObjectPath &object_path, const QVariantMapMap &interfaces_and_properties); +- void slotInterfacesRemoved(const QDBusObjectPath &object_path, const QStringList &interfaces); ++protected: ++ QPointer m_backend; + + private: + QString storageDescription() const; + QString volumeDescription() const; +- mutable QDBusInterface *m_device; +- QString m_udi; +- mutable QVariantMap m_cache; +- +- void initInterfaces(); +- QStringList m_interfaces; +- +- void checkCache(const QString &key) const; +- QString introspect() const; +- +- QDBusConnection m_connection; + }; + + } +diff --git a/solid/solid/backends/udisks2/udisksdevicebackend.cpp b/solid/solid/backends/udisks2/udisksdevicebackend.cpp +new file mode 100644 +index 0000000..74d202c +--- /dev/null ++++ b/solid/solid/backends/udisks2/udisksdevicebackend.cpp +@@ -0,0 +1,239 @@ ++/* ++ Copyright 2010 Michael Zanetti ++ Copyright 2010-2012 Lukáš Tinkl ++ Copyright 2012 Dan Vrátil ++ ++ This library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 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 6 of version 3 of the license. ++ ++ This library 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 ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with this library. If not, see . ++*/ ++ ++#include "udisksdevicebackend.h" ++ ++#include ++#include ++#include ++ ++#include "solid/deviceinterface.h" ++#include "solid/genericinterface.h" ++ ++using namespace Solid::Backends::UDisks2; ++ ++/* Static cache for DeviceBackends for all UDIs */ ++QMap DeviceBackend::s_backends; ++ ++DeviceBackend* DeviceBackend::backendForUDI(const QString& udi) ++{ ++ DeviceBackend *backend = 0; ++ if (udi.isEmpty()) { ++ return backend; ++ } ++ ++ if (s_backends.contains(udi)) { ++ backend = s_backends.value(udi); ++ } else { ++ backend = new DeviceBackend(udi); ++ s_backends.insert(udi, backend); ++ } ++ ++ return backend; ++} ++ ++void DeviceBackend::destroyBackend(const QString& udi) ++{ ++ if (s_backends.contains(udi)) { ++ DeviceBackend *backend = s_backends.value(udi); ++ s_backends.remove(udi); ++ delete backend; ++ } ++} ++ ++DeviceBackend::DeviceBackend(const QString& udi) ++ : m_udi(udi) ++{ ++ qDebug() << "Creating backend for device" << m_udi; ++ m_device = new QDBusInterface(UD2_DBUS_SERVICE, m_udi, ++ QString(), // no interface, we aggregate them ++ QDBusConnection::systemBus(), this); ++ ++ if (m_device->isValid()) { ++ QDBusConnection::systemBus().connect(UD2_DBUS_SERVICE, m_udi, DBUS_INTERFACE_PROPS, "PropertiesChanged", this, ++ SLOT(slotPropertiesChanged(QString,QVariantMap,QStringList))); ++ QDBusConnection::systemBus().connect(UD2_DBUS_SERVICE, UD2_DBUS_PATH, DBUS_INTERFACE_MANAGER, "InterfacesAdded", ++ this, SLOT(slotInterfacesAdded(QDBusObjectPath,QVariantMapMap))); ++ QDBusConnection::systemBus().connect(UD2_DBUS_SERVICE, UD2_DBUS_PATH, DBUS_INTERFACE_MANAGER, "InterfacesRemoved", ++ this, SLOT(slotInterfacesRemoved(QDBusObjectPath,QStringList))); ++ ++ initInterfaces(); ++ } ++} ++ ++DeviceBackend::~DeviceBackend() ++{ ++ qDebug() << "Destroying backend for device" << m_udi; ++} ++ ++void DeviceBackend::initInterfaces() ++{ ++ m_interfaces.clear(); ++ ++ const QString xmlData = introspect(); ++ if (xmlData.isEmpty()) { ++ qDebug() << m_udi << "has no interfaces!"; ++ return; ++ } ++ ++ QDomDocument dom; ++ dom.setContent(xmlData); ++ ++ QDomNodeList ifaceNodeList = dom.elementsByTagName("interface"); ++ for (int i = 0; i < ifaceNodeList.count(); i++) { ++ QDomElement ifaceElem = ifaceNodeList.item(i).toElement(); ++ /* Accept only org.freedesktop.UDisks2.* interfaces so that when the device is unplugged, ++ * m_interfaces goes empty and we can easily verify that the device is gone. */ ++ if (!ifaceElem.isNull() && ifaceElem.attribute("name").startsWith(UD2_DBUS_SERVICE)) { ++ m_interfaces.append(ifaceElem.attribute("name")); ++ } ++ } ++ ++ qDebug() << m_udi << "has interfaces:" << m_interfaces; ++} ++ ++QStringList DeviceBackend::interfaces() const ++{ ++ return m_interfaces; ++} ++ ++const QString& DeviceBackend::udi() const ++{ ++ return m_udi; ++} ++ ++QVariant DeviceBackend::prop(const QString& key) const ++{ ++ checkCache(key); ++ return m_propertyCache.value(key); ++} ++ ++bool DeviceBackend::propertyExists(const QString& key) const ++{ ++ checkCache(key); ++ /* checkCache() will put an invalid QVariant in cache when the property ++ * does not exist, so check for validity, not for an actual presence. */ ++ return m_propertyCache.value(key).isValid(); ++} ++ ++QVariantMap DeviceBackend::allProperties() const ++{ ++ QDBusMessage call = QDBusMessage::createMethodCall(UD2_DBUS_SERVICE, m_udi, DBUS_INTERFACE_PROPS, "GetAll"); ++ ++ Q_FOREACH (const QString & iface, m_interfaces) { ++ call.setArguments(QVariantList() << iface); ++ QDBusPendingReply reply = QDBusConnection::systemBus().call(call); ++ ++ if (reply.isValid()) { ++ m_propertyCache.unite(reply.value()); ++ } else { ++ qWarning() << "Error getting props:" << reply.error().name() << reply.error().message(); ++ } ++ //qDebug() << "After iface" << iface << ", cache now contains" << m_cache.size() << "items"; ++ } ++ ++ return m_propertyCache; ++} ++ ++QString DeviceBackend::introspect() const ++{ ++ QDBusMessage call = QDBusMessage::createMethodCall(UD2_DBUS_SERVICE, m_udi, ++ DBUS_INTERFACE_INTROSPECT, "Introspect"); ++ QDBusPendingReply reply = QDBusConnection::systemBus().call(call); ++ ++ if (reply.isValid()) ++ return reply.value(); ++ else { ++ return QString(); ++ } ++} ++ ++void DeviceBackend::checkCache(const QString& key) const ++{ ++ if (m_propertyCache.isEmpty()) { // recreate the cache ++ allProperties(); ++ } ++ ++ if (m_propertyCache.contains(key)) { ++ return; ++ } ++ ++ QVariant reply = m_device->property(key.toUtf8()); ++ m_propertyCache.insert(key, reply); ++ ++ if (!reply.isValid()) { ++ /* Store the item in the cache anyway so next time we don't have to ++ * do the DBus call to find out it does not exist but just check whether ++ * prop(key).isValid() */ ++ qDebug() << m_udi << ": property" << key << "does not exist"; ++ } ++} ++ ++void DeviceBackend::slotPropertiesChanged(const QString& ifaceName, const QVariantMap& changedProps, const QStringList& invalidatedProps) ++{ ++ qDebug() << m_udi << "'s interface" << ifaceName << "changed props:"; ++ ++ QMap changeMap; ++ ++ Q_FOREACH(const QString & key, invalidatedProps) { ++ m_propertyCache.remove(key); ++ changeMap.insert(key, Solid::GenericInterface::PropertyRemoved); ++ qDebug() << "\t invalidated:" << key; ++ } ++ ++ QMapIterator i(changedProps); ++ while (i.hasNext()) { ++ i.next(); ++ const QString key = i.key(); ++ m_propertyCache.insert(key, i.value()); // replace the value ++ changeMap.insert(key, Solid::GenericInterface::PropertyModified); ++ qDebug() << "\t modified:" << key << ":" << m_propertyCache.value(key); ++ } ++ ++ Q_EMIT propertyChanged(changeMap); ++ Q_EMIT changed(); ++} ++ ++void DeviceBackend::slotInterfacesAdded(const QDBusObjectPath& object_path, const QVariantMapMap& interfaces_and_properties) ++{ ++ if (object_path.path() != m_udi) { ++ return; ++ } ++ ++ Q_FOREACH(const QString & iface, interfaces_and_properties.keys()) { ++ /* Don't store generic DBus interfaces */ ++ if (iface.startsWith(UD2_DBUS_SERVICE)) { ++ m_interfaces.append(interfaces_and_properties.keys()); ++ } ++ } ++} ++ ++void DeviceBackend::slotInterfacesRemoved(const QDBusObjectPath& object_path, const QStringList& interfaces) ++{ ++ if (object_path.path() == m_udi) { ++ return; ++ } ++ ++ Q_FOREACH(const QString & iface, interfaces) { ++ m_interfaces.removeAll(iface); ++ } ++} +diff --git a/solid/solid/backends/udisks2/udisksdevicebackend.h b/solid/solid/backends/udisks2/udisksdevicebackend.h +new file mode 100644 +index 0000000..829fa41 +--- /dev/null ++++ b/solid/solid/backends/udisks2/udisksdevicebackend.h +@@ -0,0 +1,84 @@ ++/* ++ Copyright 2010 Michael Zanetti ++ Copyright 2010-2012 Lukáš Tinkl ++ Copyright 2012 Dan Vrátil ++ ++ This library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 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 6 of version 3 of the license. ++ ++ This library 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 ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with this library. If not, see . ++*/ ++ ++#ifndef UDISKSDEVICEBACKEND_H ++#define UDISKSDEVICEBACKEND_H ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include "udisks2.h" ++ ++namespace Solid { ++namespace Backends { ++namespace UDisks2 { ++ ++class DeviceBackend: public QObject { ++ ++ Q_OBJECT ++ ++ public: ++ static DeviceBackend* backendForUDI(const QString &udi); ++ static void destroyBackend(const QString &udi); ++ ++ DeviceBackend(const QString &udi); ++ ~DeviceBackend(); ++ ++ QVariant prop(const QString &key) const; ++ bool propertyExists(const QString &key) const; ++ QVariantMap allProperties() const; ++ ++ QStringList interfaces() const; ++ const QString & udi() const; ++ ++ Q_SIGNALS: ++ void propertyChanged(const QMap &changeMap); ++ void changed(); ++ ++ private Q_SLOTS: ++ void slotInterfacesAdded(const QDBusObjectPath &object_path, const QVariantMapMap &interfaces_and_properties); ++ void slotInterfacesRemoved(const QDBusObjectPath &object_path, const QStringList &interfaces); ++ void slotPropertiesChanged(const QString &ifaceName, const QVariantMap &changedProps, const QStringList &invalidatedProps); ++ ++ private: ++ void initInterfaces(); ++ QString introspect() const; ++ void checkCache(const QString &key) const; ++ ++ QDBusInterface *m_device; ++ ++ mutable QVariantMap m_propertyCache; ++ QStringList m_interfaces; ++ QString m_udi; ++ ++ static QMap s_backends; ++ ++}; ++ ++} /* namespace UDisks2 */ ++} /* namespace Backends */ ++} /* namespace Solid */ ++ ++#endif /* UDISKSDEVICEBACKEND_H */ +\ No newline at end of file +diff --git a/solid/solid/backends/udisks2/udisksmanager.cpp b/solid/solid/backends/udisks2/udisksmanager.cpp +index e781abb..1cc150c 100644 +--- a/solid/solid/backends/udisks2/udisksmanager.cpp ++++ b/solid/solid/backends/udisks2/udisksmanager.cpp +@@ -19,6 +19,7 @@ + */ + + #include "udisksmanager.h" ++#include "udisksdevicebackend.h" + + #include + #include +@@ -77,6 +78,10 @@ Manager::Manager(QObject *parent) + + Manager::~Manager() + { ++ while (!m_deviceCache.isEmpty()) { ++ QString udi = m_deviceCache.takeFirst(); ++ DeviceBackend::destroyBackend(udi); ++ } + } + + QObject* Manager::createDevice(const QString& udi) +@@ -128,7 +133,11 @@ QStringList Manager::devicesFromQuery(const QString& parentUdi, Solid::DeviceInt + + QStringList Manager::allDevices() + { +- m_deviceCache.clear(); ++ /* Clear the cache, destroy all backends */ ++ while (!m_deviceCache.isEmpty()) { ++ QString udi= m_deviceCache.takeFirst(); ++ DeviceBackend::destroyBackend(udi); ++ } + + introspect("/org/freedesktop/UDisks2/block_devices", true /*checkOptical*/); + introspect("/org/freedesktop/UDisks2/drives"); +@@ -140,8 +149,7 @@ void Manager::introspect(const QString & path, bool checkOptical) + { + QDBusMessage call = QDBusMessage::createMethodCall(UD2_DBUS_SERVICE, path, + DBUS_INTERFACE_INTROSPECT, "Introspect"); +- QDBusPendingReply reply = QDBusConnection::systemBus().asyncCall(call); +- reply.waitForFinished(); ++ QDBusPendingReply reply = QDBusConnection::systemBus().call(call); + + if (reply.isValid()) { + QDomDocument dom; +@@ -204,6 +212,7 @@ void Manager::slotInterfacesRemoved(const QDBusObjectPath &object_path, const QS + if (!udi.isEmpty() && (interfaces.isEmpty() || device.interfaces().isEmpty() || device.interfaces().contains(UD2_DBUS_INTERFACE_FILESYSTEM))) { + Q_EMIT deviceRemoved(udi); + m_deviceCache.removeAll(udi); ++ DeviceBackend::destroyBackend(udi); + } + } + +@@ -226,6 +235,7 @@ void Manager::slotMediaChanged(const QDBusMessage & msg) + if (m_deviceCache.contains(udi) && size == 0) { // we know the optdisc, got removed + Q_EMIT deviceRemoved(udi); + m_deviceCache.removeAll(udi); ++ DeviceBackend::destroyBackend(udi); + } + } + +diff --git a/solid/solid/backends/udisks2/udisksopticaldrive.cpp b/solid/solid/backends/udisks2/udisksopticaldrive.cpp +index 8ad3df0..4df18b1 100644 +--- a/solid/solid/backends/udisks2/udisksopticaldrive.cpp ++++ b/solid/solid/backends/udisks2/udisksopticaldrive.cpp +@@ -38,7 +38,11 @@ + using namespace Solid::Backends::UDisks2; + + OpticalDrive::OpticalDrive(Device *device) +- : StorageDrive(device), m_ejectInProgress(false), m_readSpeed(0), m_writeSpeed(0), m_speedsInit(false) ++ : StorageDrive(device) ++ , m_ejectInProgress(false) ++ , m_readSpeed(0) ++ , m_writeSpeed(0) ++ , m_speedsInit(false) + { + m_device->registerAction("eject", this, + SLOT(slotEjectRequested()), +-- +1.8.0.2 + diff --git a/0006-Use-QDBusConnection-systemBus-instead-of-custom-conn.patch b/0006-Use-QDBusConnection-systemBus-instead-of-custom-conn.patch new file mode 100644 index 0000000..acb6d2b --- /dev/null +++ b/0006-Use-QDBusConnection-systemBus-instead-of-custom-conn.patch @@ -0,0 +1,101 @@ +From 098fe7e322ad6d0c2af1a9ec0dd3131a0e69aaf8 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Dan=20Vr=C3=A1til?= +Date: Mon, 3 Dec 2012 16:40:37 +0100 +Subject: [PATCH 06/26] Use QDBusConnection::systemBus() instead of custom + connection + +Leftover from previous patch for Solid's UDisks2 backend. +--- + solid/solid/backends/udisks2/udisksblock.cpp | 5 ++--- + solid/solid/backends/udisks2/udisksblock.h | 1 - + solid/solid/backends/udisks2/udisksmanager.cpp | 9 ++++----- + solid/solid/backends/udisks2/udisksmanager.h | 1 - + 4 files changed, 6 insertions(+), 10 deletions(-) + +diff --git a/solid/solid/backends/udisks2/udisksblock.cpp b/solid/solid/backends/udisks2/udisksblock.cpp +index 027ea03..f3cd1e8 100644 +--- a/solid/solid/backends/udisks2/udisksblock.cpp ++++ b/solid/solid/backends/udisks2/udisksblock.cpp +@@ -30,8 +30,7 @@ + using namespace Solid::Backends::UDisks2; + + Block::Block(Device *dev) +- : DeviceInterface(dev), +- m_connection(QDBusConnection::connectToBus(QDBusConnection::SystemBus, "Solid::Udisks2::Block::" + dev->udi())) ++ : DeviceInterface(dev) + { + m_devNum = m_device->prop("DeviceNumber").toULongLong(); + m_devFile = QFile::decodeName(m_device->prop("Device").toByteArray()); +@@ -41,7 +40,7 @@ Block::Block(Device *dev) + const QString path = "/org/freedesktop/UDisks2/block_devices"; + QDBusMessage call = QDBusMessage::createMethodCall(UD2_DBUS_SERVICE, path, + DBUS_INTERFACE_INTROSPECT, "Introspect"); +- QDBusPendingReply reply = m_connection.asyncCall(call); ++ QDBusPendingReply reply = QDBusConnection::systemBus().asyncCall(call); + reply.waitForFinished(); + + if (reply.isValid()) { +diff --git a/solid/solid/backends/udisks2/udisksblock.h b/solid/solid/backends/udisks2/udisksblock.h +index 65ef2b8..19cb70a 100644 +--- a/solid/solid/backends/udisks2/udisksblock.h ++++ b/solid/solid/backends/udisks2/udisksblock.h +@@ -45,7 +45,6 @@ public: + virtual int deviceMinor() const; + virtual int deviceMajor() const; + private: +- QDBusConnection m_connection; + dev_t m_devNum; + QString m_devFile; + }; +diff --git a/solid/solid/backends/udisks2/udisksmanager.cpp b/solid/solid/backends/udisks2/udisksmanager.cpp +index 1cc150c..35b0d23 100644 +--- a/solid/solid/backends/udisks2/udisksmanager.cpp ++++ b/solid/solid/backends/udisks2/udisksmanager.cpp +@@ -33,10 +33,9 @@ using namespace Solid::Backends::Shared; + + Manager::Manager(QObject *parent) + : Solid::Ifaces::DeviceManager(parent), +- m_connection(QDBusConnection::connectToBus(QDBusConnection::SystemBus, "Solid::Udisks2")), + m_manager(UD2_DBUS_SERVICE, + UD2_DBUS_PATH, +- m_connection) ++ QDBusConnection::systemBus()) + { + m_supportedInterfaces + << Solid::DeviceInterface::GenericInterface +@@ -61,9 +60,9 @@ Manager::Manager(QObject *parent) + "org.freedesktop.DBus", + "ListActivatableNames"); + +- QDBusReply reply = m_connection.call(message); ++ QDBusReply reply = QDBusConnection::systemBus().call(message); + if (reply.isValid() && reply.value().contains(UD2_DBUS_SERVICE)) { +- m_connection.interface()->startService(UD2_DBUS_SERVICE); ++ QDBusConnection::systemBus().interface()->startService(UD2_DBUS_SERVICE); + serviceFound = true; + } + } +@@ -163,7 +162,7 @@ void Manager::introspect(const QString & path, bool checkOptical) + if (checkOptical) { + Device device(udi); + if (device.mightBeOpticalDisc()) { +- m_connection.connect(UD2_DBUS_SERVICE, udi, DBUS_INTERFACE_PROPS, "PropertiesChanged", this, ++ QDBusConnection::systemBus().connect(UD2_DBUS_SERVICE, udi, DBUS_INTERFACE_PROPS, "PropertiesChanged", this, + SLOT(slotMediaChanged(QDBusMessage))); + if (!device.isOpticalDisc()) // skip empty CD disc + continue; +diff --git a/solid/solid/backends/udisks2/udisksmanager.h b/solid/solid/backends/udisks2/udisksmanager.h +index bf74703..fb929ce 100644 +--- a/solid/solid/backends/udisks2/udisksmanager.h ++++ b/solid/solid/backends/udisks2/udisksmanager.h +@@ -60,7 +60,6 @@ private: + const QStringList &deviceCache(); + void introspect(const QString & path, bool checkOptical = false); + QSet m_supportedInterfaces; +- QDBusConnection m_connection; + org::freedesktop::DBus::ObjectManager m_manager; + QStringList m_deviceCache; + }; +-- +1.8.0.2 + diff --git a/0007-Ignore-UDisks2-jobs.patch b/0007-Ignore-UDisks2-jobs.patch new file mode 100644 index 0000000..3976ec9 --- /dev/null +++ b/0007-Ignore-UDisks2-jobs.patch @@ -0,0 +1,41 @@ +From f883796dff6956c51d2b2494a600a935bd910a5a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Dan=20Vr=C3=A1til?= +Date: Mon, 3 Dec 2012 16:57:05 +0100 +Subject: [PATCH 07/26] Ignore UDisks2 jobs + +Jobs don't represent any devices, so we can just ignore them. +--- + solid/solid/backends/udisks2/udisksmanager.cpp | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/solid/solid/backends/udisks2/udisksmanager.cpp b/solid/solid/backends/udisks2/udisksmanager.cpp +index 35b0d23..ecb9add 100644 +--- a/solid/solid/backends/udisks2/udisksmanager.cpp ++++ b/solid/solid/backends/udisks2/udisksmanager.cpp +@@ -191,6 +191,11 @@ void Manager::slotInterfacesAdded(const QDBusObjectPath &object_path, const QVar + { + const QString udi = object_path.path(); + ++ /* Ignore jobs */ ++ if (udi.startsWith(UD2_DBUS_PATH_JOBS)) { ++ return; ++ } ++ + qDebug() << udi << "has new interfaces:" << interfaces_and_properties.keys(); + + // new device, we don't know it yet +@@ -204,6 +209,11 @@ void Manager::slotInterfacesRemoved(const QDBusObjectPath &object_path, const QS + { + const QString udi = object_path.path(); + ++ /* Ignore jobs */ ++ if (udi.startsWith(UD2_DBUS_PATH_JOBS)) { ++ return; ++ } ++ + qDebug() << udi << "lost interfaces:" << interfaces; + + Device device(udi); +-- +1.8.0.2 + diff --git a/kdelibs-solid_qt_no_debug_output.patch b/kdelibs-solid_qt_no_debug_output.patch new file mode 100644 index 0000000..f39c0ba --- /dev/null +++ b/kdelibs-solid_qt_no_debug_output.patch @@ -0,0 +1,12 @@ +diff -up kdelibs-4.9.4/solid/solid/CMakeLists.txt.no_solid_spam kdelibs-4.9.4/solid/solid/CMakeLists.txt +--- kdelibs-4.9.4/solid/solid/CMakeLists.txt.no_solid_spam 2012-12-12 11:54:59.644811835 -0600 ++++ kdelibs-4.9.4/solid/solid/CMakeLists.txt 2012-12-12 12:03:11.093451554 -0600 +@@ -240,7 +240,7 @@ if(NOT WIN32 AND NOT APPLE) + + if ( WITH_SOLID_UDISKS2 ) + message(STATUS "Building Solid UDisks2 backend." ) +- add_definitions(-DWITH_SOLID_UDISKS2) ++ add_definitions(-DWITH_SOLID_UDISKS2 -DQT_NO_DEBUG_OUTPUT) + set(solid_LIB_SRCS ${solid_LIB_SRCS} + backends/udisks2/udisksmanager.cpp + backends/udisks2/udisksdevice.cpp diff --git a/kdelibs-udisks2-kfileplacesdevicecache.patch b/kdelibs-udisks2-kfileplacesdevicecache.patch deleted file mode 100644 index 5e45d6f..0000000 --- a/kdelibs-udisks2-kfileplacesdevicecache.patch +++ /dev/null @@ -1,406 +0,0 @@ -diff --git a/kfile/CMakeLists.txt b/kfile/CMakeLists.txt -index ceae140..c7c4d3d 100644 ---- a/kfile/CMakeLists.txt -+++ b/kfile/CMakeLists.txt -@@ -20,6 +20,7 @@ set(kfile_LIB_SRCS - kfilefiltercombo.cpp - kfiletreeview.cpp - kfilewidget.cpp -+ kfileplacesdevicecache.cpp - kfileplacesitem.cpp - kfileplacesmodel.cpp - kfileplacessharedbookmarks.cpp -@@ -63,6 +64,7 @@ install( FILES - kdirselectdialog.h - kdirsortfilterproxymodel.h - kfilefiltercombo.h -+ kfileplacesdevicecache.h - kfileplacesmodel.h - kfileplacesview.h - kfilepreviewgenerator.h -diff --git a/kfile/kfileplacesdevicecache.cpp b/kfile/kfileplacesdevicecache.cpp -new file mode 100644 -index 0000000..40f7242 ---- /dev/null -+++ b/kfile/kfileplacesdevicecache.cpp -@@ -0,0 +1,174 @@ -+/* -+ Copyright (C) 2012 Dan Vrátil -+ -+ This library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Library General Public -+ License version 2 as published by the Free Software Foundation. -+ -+ This library 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 -+ Library General Public License for more details. -+ -+ You should have received a copy of the GNU Library General Public License -+ along with this library; see the file COPYING.LIB. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+#include "kfileplacesdevicecache.h" -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+KFilePlacesDeviceCache* KFilePlacesDeviceCache::s_instance = 0; -+ -+class KFilePlacesDeviceCache::Private -+{ -+ public: -+ Private(KFilePlacesDeviceCache *parent): -+ queryRunning(false), -+ q(parent) -+ { } -+ -+ ~Private() -+ { } -+ -+ /* This method runs asynchronously in thread */ -+ QSet listSolidDevicesAsync() -+ { -+ QSet udis; -+ -+ kDebug() << "Querying Solid devices..."; -+ const QList& deviceList = Solid::Device::listFromQuery(solidPredicate); -+ kDebug() << "Retrieved" << deviceList.count() << "devices"; -+ -+ Q_FOREACH (const Solid::Device& device, deviceList) { -+ if (solidPredicate.matches(device)) { -+ udis << device.udi(); -+ } -+ } -+ -+ return udis; -+ } -+ -+ void _k_slotDeviceAdded(const QString &udi) -+ { -+ devicesCache << udi; -+ -+ Q_EMIT q->deviceAdded(udi); -+ } -+ -+ void _k_slotDeviceRemoved(const QString &udi) -+ { -+ if (!devicesCache.contains(udi)) { -+ return; -+ } -+ -+ devicesCache.remove(udi); -+ -+ Q_EMIT q->deviceRemoved(udi); -+ } -+ -+ void _k_listSolidDevicesFinished() -+ { -+ Q_FOREACH (const QString& device, futureWatcher->result()) { -+ _k_slotDeviceAdded(device); -+ } -+ -+ delete futureWatcher; -+ futureWatcher = 0; -+ -+ queryRunning = false; -+ } -+ -+ Solid::Predicate solidPredicate; -+ -+ QFutureWatcher< QSet >* futureWatcher; -+ -+ /* Static */ -+ QSet devicesCache; -+ bool queryRunning; -+ -+ KFilePlacesDeviceCache *q; -+}; -+ -+KFilePlacesDeviceCache::KFilePlacesDeviceCache(): -+ QObject(), -+ d(new Private(this)) -+{ -+ Solid::DeviceNotifier* notifier = Solid::DeviceNotifier::instance(); -+ connect(notifier, SIGNAL(deviceAdded(QString)), this, SLOT(_k_slotDeviceAdded(QString))); -+ connect(notifier, SIGNAL(deviceRemoved(QString)), this, SLOT(_k_slotDeviceRemoved(QString))); -+ -+ QString predicate("[[[[ StorageVolume.ignored == false AND [ StorageVolume.usage == 'FileSystem' OR StorageVolume.usage == 'Encrypted' ]]" -+ " OR " -+ "[ IS StorageAccess AND StorageDrive.driveType == 'Floppy' ]]" -+ " OR " -+ "OpticalDisc.availableContent & 'Audio' ]" -+ " OR " -+ "StorageAccess.ignored == false ]"); -+ -+ if (KProtocolInfo::isKnownProtocol("mtp")) { -+ predicate.prepend("["); -+ predicate.append(" OR PortableMediaPlayer.supportedProtocols == 'mtp']"); -+ } -+ -+ d->solidPredicate = Solid::Predicate::fromString(predicate); -+} -+ -+KFilePlacesDeviceCache* KFilePlacesDeviceCache::self() -+{ -+ static QMutex mutex; -+ -+ mutex.lock(); -+ if (s_instance == 0) { -+ s_instance = new KFilePlacesDeviceCache(); -+ } -+ mutex.unlock(); -+ -+ return s_instance; -+} -+ -+KFilePlacesDeviceCache::~KFilePlacesDeviceCache() -+{ -+ Solid::DeviceNotifier* notifier = Solid::DeviceNotifier::instance(); -+ disconnect(notifier, SIGNAL(deviceAdded(QString))); -+ disconnect(notifier, SIGNAL(deviceRemoved(QString))); -+ -+ delete d; -+} -+ -+const Solid::Predicate& KFilePlacesDeviceCache::predicate() const -+{ -+ return d->solidPredicate; -+} -+ -+const QSet& KFilePlacesDeviceCache::devices() const -+{ -+ kDebug(); -+ if (d->devicesCache.isEmpty() && !d->queryRunning) { -+ d->queryRunning = true; -+ d->futureWatcher = new QFutureWatcher< QSet >; -+ connect(d->futureWatcher, SIGNAL(finished()), this, SLOT(_k_listSolidDevicesFinished())); -+ -+ QFuture< QSet > future = QtConcurrent::run(d, &Private::listSolidDevicesAsync); -+ d->futureWatcher->setFuture(future); -+ } -+ -+ return d->devicesCache; -+} -+ -+ -+ -+#include "kfileplacesdevicecache.moc" -diff --git a/kfile/kfileplacesdevicecache.h b/kfile/kfileplacesdevicecache.h -new file mode 100644 -index 0000000..7293d03 ---- /dev/null -+++ b/kfile/kfileplacesdevicecache.h -@@ -0,0 +1,96 @@ -+/* -+ Copyright (C) 2012 Dan Vrátil -+ -+ This library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Library General Public -+ License version 2 as published by the Free Software Foundation. -+ -+ This library 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 -+ Library General Public License for more details. -+ -+ You should have received a copy of the GNU Library General Public License -+ along with this library; see the file COPYING.LIB. If not, write to -+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. -+*/ -+ -+#ifndef KFILEPLACESDEVICECACHE_H -+#define KFILEPLACESDEVICECACHE_H -+ -+#include -+ -+#include -+#include -+ -+#include -+ -+/** -+ * @short Asynchronous cache for Solid devices -+ * -+ * Purpose of this cache is to load Solid devices asynchronously, because -+ * udisks2 backend can take quite a lot of time to enumerate devices, and -+ * since Solid does not have async API, the UI thread is blocked for too long. -+ * -+ * When libsolid2 with asynchronous API is available, this class can go away. -+ * -+ * The cache keeps itself up-to-date and notifies listeners when a -+ * new devices is added or removed. -+ */ -+class KFILE_EXPORT KFilePlacesDeviceCache : public QObject -+{ -+ Q_OBJECT -+ -+public: -+ /** -+ * Returns a global instance of the cache -+ */ -+ static KFilePlacesDeviceCache* self(); -+ -+ /** -+ * Returns list of Solid devices. -+ * -+ * This method always returns immediatelly. When there are no -+ * devices in the cache, it returns an empty list and will asynchronously -+ * query Solid for devices and will notify listeners by emitting -+ * deviceAdded() signal for each devices loaded. -+ */ -+ const QSet& devices() const; -+ -+ /** -+ * Returns Solid::Predicate used to obtain devices from Solid -+ */ -+ const Solid::Predicate& predicate() const; -+ -+Q_SIGNALS: -+ /** -+ * Emitted whenever a new device is discovered. -+ * -+ * @param udi UDI (Universal Device ID) of the newly discovered device -+ */ -+ void deviceAdded(const QString& udi); -+ -+ /** -+ * Emitted whenever a device is removed from system -+ * -+ * @param udi UDI (Universal Device ID) of the removed device -+ */ -+ void deviceRemoved(const QString& udi); -+ -+private: -+ Q_PRIVATE_SLOT(d, void _k_listSolidDevicesFinished()) -+ Q_PRIVATE_SLOT(d, void _k_slotDeviceAdded(const QString&)) -+ Q_PRIVATE_SLOT(d, void _k_slotDeviceRemoved(const QString&)) -+ -+ class Private; -+ Private * const d; -+ friend class Private; -+ -+ explicit KFilePlacesDeviceCache(); -+ virtual ~KFilePlacesDeviceCache(); -+ -+ static KFilePlacesDeviceCache* s_instance; -+}; -+ -+#endif // KFILEPLACESDEVICECACHE_H -diff --git a/kfile/kfileplacesmodel.cpp b/kfile/kfileplacesmodel.cpp -index 0192926..e0b01c6 100644 ---- a/kfile/kfileplacesmodel.cpp -+++ b/kfile/kfileplacesmodel.cpp -@@ -20,6 +20,7 @@ - #include "kfileplacesmodel.h" - #include "kfileplacesitem_p.h" - #include "kfileplacessharedbookmarks_p.h" -+#include "kfileplacesdevicecache.h" - - #ifdef _WIN32_WCE - #include "Windows.h" -@@ -49,14 +50,12 @@ - #include - #include - --#include - #include - #include - #include - #include - #include - #include --#include - - class KFilePlacesModel::Private - { -@@ -74,7 +73,6 @@ public: - QSet availableDevices; - QMap setupInProgress; - -- Solid::Predicate predicate; - KBookmarkManager *bookmarkManager; - KFilePlacesSharedBookmarks * sharedBookmarks; - -@@ -149,30 +147,12 @@ KFilePlacesModel::KFilePlacesModel(QObject *parent) - // create after, so if we have own places, they are added afterwards, in case of equal priorities - d->sharedBookmarks = new KFilePlacesSharedBookmarks(d->bookmarkManager); - -- QString predicate("[[[[ StorageVolume.ignored == false AND [ StorageVolume.usage == 'FileSystem' OR StorageVolume.usage == 'Encrypted' ]]" -- " OR " -- "[ IS StorageAccess AND StorageDrive.driveType == 'Floppy' ]]" -- " OR " -- "OpticalDisc.availableContent & 'Audio' ]" -- " OR " -- "StorageAccess.ignored == false ]"); -- -- if (KProtocolInfo::isKnownProtocol("mtp")) { -- predicate.prepend("["); -- predicate.append(" OR PortableMediaPlayer.supportedProtocols == 'mtp']"); -- } -- -- d->predicate = Solid::Predicate::fromString(predicate); -- -- Q_ASSERT(d->predicate.isValid()); -- - connect(d->bookmarkManager, SIGNAL(changed(QString,QString)), - this, SLOT(_k_reloadBookmarks())); - connect(d->bookmarkManager, SIGNAL(bookmarksChanged(QString)), - this, SLOT(_k_reloadBookmarks())); - -- d->_k_reloadBookmarks(); -- QTimer::singleShot(0, this, SLOT(_k_initDeviceList())); -+ d->_k_initDeviceList(); - } - - KFilePlacesModel::~KFilePlacesModel() -@@ -313,30 +293,21 @@ QModelIndex KFilePlacesModel::closestItem(const KUrl &url) const - - void KFilePlacesModel::Private::_k_initDeviceList() - { -- Solid::DeviceNotifier *notifier = Solid::DeviceNotifier::instance(); -- -- connect(notifier, SIGNAL(deviceAdded(QString)), -+ KFilePlacesDeviceCache *cache = KFilePlacesDeviceCache::self(); -+ connect(cache, SIGNAL(deviceAdded(QString)), - q, SLOT(_k_deviceAdded(QString))); -- connect(notifier, SIGNAL(deviceRemoved(QString)), -+ connect(cache, SIGNAL(deviceRemoved(QString)), - q, SLOT(_k_deviceRemoved(QString))); - -- const QList &deviceList = Solid::Device::listFromQuery(predicate); -- -- foreach(const Solid::Device &device, deviceList) { -- availableDevices << device.udi(); -- } -+ availableDevices = cache->devices(); - - _k_reloadBookmarks(); - } - - void KFilePlacesModel::Private::_k_deviceAdded(const QString &udi) - { -- Solid::Device d(udi); -- -- if (predicate.matches(d)) { -- availableDevices << udi; -- _k_reloadBookmarks(); -- } -+ availableDevices << udi; -+ _k_reloadBookmarks(); - } - - void KFilePlacesModel::Private::_k_deviceRemoved(const QString &udi) diff --git a/kdelibs.spec b/kdelibs.spec index b707ecd..74fdb8b 100644 --- a/kdelibs.spec +++ b/kdelibs.spec @@ -22,7 +22,7 @@ Summary: KDE Libraries Version: 4.9.90 -Release: 1%{?dist} +Release: 2%{?dist} Name: kdelibs Epoch: 6 @@ -114,8 +114,10 @@ Patch41: 0002-Trigger-installation-of-missing-components-when-inst.patch # https://git.reviewboard.kde.org/r/102350/ Patch42: 0003-Implement-automatic-scanning-of-source-code-for-requ.patch -# cache to improve performance of apps using Solid with udisks2 (#868530) -Patch48: kdelibs-udisks2-kfileplacesdevicecache.patch +# limit solid qDebug spam +# http://bugzilla.redhat.com/882731 +# TODO: could make uptreamable and conditional only on Release-type builds +Patch49: kdelibs-solid_qt_no_debug_output.patch ## upstreamable # knewstuff2 variant of: @@ -142,6 +144,10 @@ Patch56: kdelibs-4.9.1-FindKipi-libkipi2.patch Patch59: kdelibs-4.9.3-kcm_ssl.patch ## upstream +# since 4.9.90, solid/udisk2 related fixes +Patch103: 0003-Cache-UDisks2-Device-DBus-connections.patch +Patch106: 0006-Use-QDBusConnection-systemBus-instead-of-custom-conn.patch +Patch107: 0007-Ignore-UDisks2-jobs.patch ## security fix # Not Upstreamed? why not ? -- Rex @@ -299,7 +305,7 @@ sed -i -e "s|@@VERSION_RELEASE@@|%{version}-%{release}|" kio/kio/kprotocolmanage %patch42 -p1 -b .libplasma-pk-0003 %if "%{?udisks}" == "udisks2" -%patch48 -p1 -b .kfileplacesdevicescache +%patch49 -p1 -b .solid_qt_no_debug_output %endif # upstreamable patches @@ -312,6 +318,9 @@ sed -i -e "s|@@VERSION_RELEASE@@|%{version}-%{release}|" kio/kio/kprotocolmanage %patch59 -p1 -b .filter # upstream patches +%patch103 -p1 -b .0003 +%patch106 -p1 -b .0006 +%patch107 -p1 -b .0007 # security fixes %patch200 -p1 -b .CVE-2009-2702 @@ -558,6 +567,10 @@ gtk-update-icon-cache %{_kde4_iconsdir}/hicolor &> /dev/null || : %changelog +* Wed Dec 12 2012 Rex Dieter - 6:4.9.90-2 +- sync with latest solid/udisks2 upstream bits +- Debug output in kdelibs-udisks2-backend.patch should be disabled (#882731) + * Mon Dec 03 2012 Rex Dieter 6:4.9.90-1 - 4.9.90 (4.10beta2)