Sophie

Sophie

distrib > Fedora > 16 > x86_64 > media > updates-src > by-pkgid > edf7cb5fc7ec1835dba1455c3bf2044d > files > 26

kdelibs-4.8.5-2.fc16.src.rpm

diff --git a/tier1/solid/src/solid/backends/udisks2/dbus/manager.cpp b/tier1/solid/src/solid/backends/udisks2/dbus/manager.cpp
new file mode 100644
index 0000000..7ea4aa8
--- /dev/null
+++ b/tier1/solid/src/solid/backends/udisks2/dbus/manager.cpp
@@ -0,0 +1,26 @@
+/*
+ * This file was generated by qdbusxml2cpp version 0.7
+ * Command line was: qdbusxml2cpp -p manager manager.xml
+ *
+ * qdbusxml2cpp is Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * This is an auto-generated file.
+ * This file may have been hand-edited. Look for HAND-EDIT comments
+ * before re-generating it.
+ */
+
+#include "manager.h"
+
+/*
+ * Implementation of interface class OrgFreedesktopDBusObjectManagerInterface
+ */
+
+OrgFreedesktopDBusObjectManagerInterface::OrgFreedesktopDBusObjectManagerInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent)
+    : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent)
+{
+}
+
+OrgFreedesktopDBusObjectManagerInterface::~OrgFreedesktopDBusObjectManagerInterface()
+{
+}
+
diff --git a/tier1/solid/src/solid/backends/udisks2/dbus/manager.h b/tier1/solid/src/solid/backends/udisks2/dbus/manager.h
new file mode 100644
index 0000000..11f0be8
--- /dev/null
+++ b/tier1/solid/src/solid/backends/udisks2/dbus/manager.h
@@ -0,0 +1,59 @@
+/*
+ * This file was generated by qdbusxml2cpp version 0.7
+ * Command line was: qdbusxml2cpp -p manager manager.xml
+ *
+ * qdbusxml2cpp is Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * This is an auto-generated file.
+ * Do not edit! All changes made to it will be lost.
+ */
+
+#ifndef MANAGER_H_1329493525
+#define MANAGER_H_1329493525
+
+#include <QtCore/QObject>
+#include <QtCore/QByteArray>
+#include <QtCore/QList>
+#include <QtCore/QMap>
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+#include <QtCore/QVariant>
+#include <QtDBus/QtDBus>
+
+#include "../udisks2.h"
+
+/*
+ * Proxy class for interface org.freedesktop.DBus.ObjectManager
+ */
+class OrgFreedesktopDBusObjectManagerInterface: public QDBusAbstractInterface
+{
+    Q_OBJECT
+public:
+    static inline const char *staticInterfaceName()
+    { return "org.freedesktop.DBus.ObjectManager"; }
+
+public:
+    OrgFreedesktopDBusObjectManagerInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0);
+
+    ~OrgFreedesktopDBusObjectManagerInterface();
+
+public Q_SLOTS: // METHODS
+    inline QDBusPendingReply<DBUSManagerStruct> GetManagedObjects()
+    {
+        QList<QVariant> argumentList;
+        return asyncCallWithArgumentList(QLatin1String("GetManagedObjects"), argumentList);
+    }
+
+Q_SIGNALS: // SIGNALS
+    void InterfacesAdded(const QDBusObjectPath &object_path, const QVariantMapMap &interfaces_and_properties);
+    void InterfacesRemoved(const QDBusObjectPath &object_path, const QStringList &interfaces);
+};
+
+namespace org {
+  namespace freedesktop {
+    namespace DBus {
+      typedef ::OrgFreedesktopDBusObjectManagerInterface ObjectManager;
+    }
+  }
+}
+#endif
diff --git a/tier1/solid/src/solid/backends/udisks2/dbus/manager.xml b/tier1/solid/src/solid/backends/udisks2/dbus/manager.xml
new file mode 100644
index 0000000..8f25cb6
--- /dev/null
+++ b/tier1/solid/src/solid/backends/udisks2/dbus/manager.xml
@@ -0,0 +1,21 @@
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
+                      "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+<node>
+  <interface name="org.freedesktop.DBus.ObjectManager">
+    <method name="GetManagedObjects">
+      <arg type="a{oa{sa{sv}}}" name="object_paths_interfaces_and_properties" direction="out">
+        <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="DBUSManagerStruct"/>
+      </arg>
+    </method>
+    <signal name="InterfacesAdded">
+      <arg type="o" name="object_path"/>
+      <arg type="a{sa{sv}}" name="interfaces_and_properties">
+        <annotation name="com.trolltech.QtDBus.QtTypeName.In1" value="QVariantMapMap"/>
+      </arg>
+    </signal>
+    <signal name="InterfacesRemoved">
+      <arg type="o" name="object_path"/>
+      <arg type="as" name="interfaces"/>
+    </signal>
+  </interface>
+</node>
diff --git a/tier1/solid/src/solid/backends/udisks2/udisks2.h b/tier1/solid/src/solid/backends/udisks2/udisks2.h
new file mode 100644
index 0000000..25a1dc0
--- /dev/null
+++ b/tier1/solid/src/solid/backends/udisks2/udisks2.h
@@ -0,0 +1,77 @@
+/*
+    Copyright 2012 Lukáš Tinkl <ltinkl@redhat.com>
+
+    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 <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef SOLID_BACKENDS_UDISKS2_H
+#define SOLID_BACKENDS_UDISKS2_H
+
+#include <QMetaType>
+#include <QtDBus>
+#include <QVariant>
+#include <QMap>
+#include <QList>
+
+typedef QList<QByteArray> QByteArrayList;
+Q_DECLARE_METATYPE(QByteArrayList)
+
+typedef QMap<QString,QVariantMap> QVariantMapMap;
+Q_DECLARE_METATYPE(QVariantMapMap)
+
+typedef QMap<QDBusObjectPath, QVariantMapMap> DBUSManagerStruct;
+Q_DECLARE_METATYPE(DBUSManagerStruct)
+
+/* UDisks2 */
+#define UD2_DBUS_SERVICE                 "org.freedesktop.UDisks2"
+#define UD2_DBUS_PATH                    "/org/freedesktop/UDisks2"
+#define UD2_UDI_DISKS_PREFIX             "/org/freedesktop/UDisks2"
+#define UD2_DBUS_PATH_MANAGER            "/org/freedesktop/UDisks2/Manager"
+#define UD2_DBUS_PATH_DRIVES             "/org/freedesktop/UDisks2/drives/"
+#define UD2_DBUS_PATH_JOBS               "/org/freedesktop/UDisks2/jobs/"
+#define DBUS_INTERFACE_PROPS             "org.freedesktop.DBus.Properties"
+#define DBUS_INTERFACE_INTROSPECT        "org.freedesktop.DBus.Introspectable"
+#define DBUS_INTERFACE_MANAGER           "org.freedesktop.DBus.ObjectManager"
+#define UD2_DBUS_INTERFACE_BLOCK         "org.freedesktop.UDisks2.Block"
+#define UD2_DBUS_INTERFACE_DRIVE         "org.freedesktop.UDisks2.Drive"
+#define UD2_DBUS_INTERFACE_PARTITION     "org.freedesktop.UDisks2.Partition"
+#define UD2_DBUS_INTERFACE_PARTITIONTABLE   "org.freedesktop.UDisks2.PartitionTable"
+#define UD2_DBUS_INTERFACE_FILESYSTEM    "org.freedesktop.UDisks2.Filesystem"
+#define UD2_DBUS_INTERFACE_ENCRYPTED     "org.freedesktop.UDisks2.Encrypted"
+#define UD2_DBUS_INTERFACE_SWAP          "org.freedesktop.UDisks2.Swapspace"
+
+/* errors */
+#define UD2_ERROR_UNAUTHORIZED            "org.freedesktop.PolicyKit.Error.NotAuthorized"
+#define UD2_ERROR_BUSY                    "org.freedesktop.UDisks2.Error.DeviceBusy"
+#define UD2_ERROR_FAILED                  "org.freedesktop.UDisks2.Error.Failed"
+#define UD2_ERROR_CANCELED                "org.freedesktop.UDisks2.Error.Cancelled"
+#define UD2_ERROR_INVALID_OPTION          "org.freedesktop.UDisks2.Error.OptionNotPermitted"
+#define UD2_ERROR_MISSING_DRIVER          "org.freedesktop.UDisks2.Error.NotSupported"
+
+#define UD2_ERROR_ALREADY_MOUNTED         "org.freedesktop.UDisks2.Error.AlreadyMounted"
+#define UD2_ERROR_NOT_MOUNTED             "org.freedesktop.UDisks2.Error.NotMounted"
+#define UD2_ERROR_MOUNTED_BY_OTHER_USER   "org.freedesktop.UDisks2.Error.MountedByOtherUser"
+#define UD2_ERROR_ALREADY_UNMOUNTING      "org.freedesktop.UDisks2.Error.AlreadyUnmounting"
+#define UD2_ERROR_TIMED_OUT               "org.freedesktop.UDisks2.Error.Timedout"
+#define UD2_ERROR_WOULD_WAKEUP            "org.freedesktop.UDisks2.Error.WouldWakeup"
+#define UD2_ERROR_ALREADY_CANCELLED       "org.freedesktop.UDisks2.Error.AlreadyCancelled"
+
+#define UD2_ERROR_NOT_AUTHORIZED          "org.freedesktop.UDisks2.Error.NotAuthorized"
+#define UD2_ERROR_NOT_AUTHORIZED_CAN_OBTAIN  "org.freedesktop.UDisks2.Error.NotAuthorizedCanObtain"
+#define UD2_ERROR_NOT_AUTHORIZED_DISMISSED   "org.freedesktop.UDisks2.Error.NotAuthorizedDismissed"
+
+#endif // SOLID_BACKENDS_UDISKS2_H
diff --git a/tier1/solid/src/solid/backends/udisks2/udisksblock.cpp b/tier1/solid/src/solid/backends/udisks2/udisksblock.cpp
new file mode 100644
index 0000000..474f3d6
--- /dev/null
+++ b/tier1/solid/src/solid/backends/udisks2/udisksblock.cpp
@@ -0,0 +1,84 @@
+/*
+    Copyright 2012 Lukáš Tinkl <ltinkl@redhat.com>
+
+    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 <http://www.gnu.org/licenses/>.
+*/
+
+#include <linux/kdev_t.h>
+
+#include <QFile>
+#include <QtDBus/QDBusConnection>
+#include <QtDBus/QDBusPendingReply>
+
+#include "udisksblock.h"
+#include "dbus/manager.h"
+
+using namespace Solid::Backends::UDisks2;
+
+Block::Block(Device *dev)
+    : DeviceInterface(dev)
+{
+    m_devNum = m_device->prop("DeviceNumber").toULongLong();
+    m_devFile = QFile::decodeName(m_device->prop("Device").toByteArray());
+
+    // we have a drive (non-block device for udisks), so let's find the corresponding (real) block device
+    if (m_devNum == 0 || m_devFile.isEmpty()) {
+        org::freedesktop::DBus::ObjectManager manager(UD2_DBUS_SERVICE, UD2_DBUS_PATH, QDBusConnection::systemBus());
+        QDBusPendingReply<DBUSManagerStruct> reply = manager.GetManagedObjects();
+        reply.waitForFinished();
+        if (!reply.isError()) {  // enum devices
+            Q_FOREACH(const QDBusObjectPath &path, reply.value().keys()) {
+                const QString udi = path.path();
+
+                if (udi == UD2_DBUS_PATH_MANAGER || udi == UD2_UDI_DISKS_PREFIX || udi.startsWith(UD2_DBUS_PATH_JOBS))
+                    continue;
+
+                Device device(udi);
+                if (device.drivePath() == dev->udi()) {
+                    m_devNum = device.prop("DeviceNumber").toULongLong();
+                    m_devFile = QFile::decodeName(device.prop("Device").toByteArray());
+                    break;
+                }
+            }
+        }
+        else  // show error
+        {
+            qWarning() << "Failed enumerating UDisks2 objects:" << reply.error().name() << "\n" << reply.error().message();
+        }
+    }
+
+    //qDebug() << "devnum:" << m_devNum << "dev file:" << m_devFile;
+}
+
+Block::~Block()
+{
+}
+
+QString Block::device() const
+{
+    return m_devFile;
+}
+
+int Block::deviceMinor() const
+{
+    return MINOR(m_devNum);
+}
+
+int Block::deviceMajor() const
+{
+    return MAJOR(m_devNum);
+}
diff --git a/tier1/solid/src/solid/backends/udisks2/udisksblock.h b/tier1/solid/src/solid/backends/udisks2/udisksblock.h
new file mode 100644
index 0000000..19cb70a
--- /dev/null
+++ b/tier1/solid/src/solid/backends/udisks2/udisksblock.h
@@ -0,0 +1,56 @@
+/*
+    Copyright 2012 Lukáš Tinkl <ltinkl@redhat.com>
+
+    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 <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef UDISKS2BLOCK_H
+#define UDISKS2BLOCK_H
+
+#include <solid/ifaces/block.h>
+#include "udisksdeviceinterface.h"
+
+namespace Solid
+{
+namespace Backends
+{
+namespace UDisks2
+{
+
+class Block: public DeviceInterface, virtual public Solid::Ifaces::Block
+{
+
+    Q_OBJECT
+    Q_INTERFACES(Solid::Ifaces::Block)
+
+public:
+    Block(Device *dev);
+    virtual ~Block();
+
+    virtual QString device() const;
+    virtual int deviceMinor() const;
+    virtual int deviceMajor() const;
+private:
+    dev_t m_devNum;
+    QString m_devFile;
+};
+
+}
+}
+}
+
+#endif // UDISKS2BLOCK_H
diff --git a/tier1/solid/src/solid/backends/udisks2/udisksdevice.cpp b/tier1/solid/src/solid/backends/udisks2/udisksdevice.cpp
new file mode 100644
index 0000000..fb74fa2
--- /dev/null
+++ b/tier1/solid/src/solid/backends/udisks2/udisksdevice.cpp
@@ -0,0 +1,910 @@
+/*
+    Copyright 2010 Michael Zanetti <mzanetti@kde.org>
+    Copyright 2010-2012 Lukáš Tinkl <ltinkl@redhat.com>
+
+    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 <http://www.gnu.org/licenses/>.
+*/
+
+#include "udisksdevice.h"
+#include "udisksblock.h"
+#include "udisksdeviceinterface.h"
+#include "udisksstoragevolume.h"
+#include "udisksopticaldisc.h"
+#include "udisksopticaldrive.h"
+#include "udisksstorageaccess.h"
+#include "udisksgenericinterface.h"
+
+#include <solid/genericinterface.h>
+#include <solid/deviceinterface.h>
+#include <solid/device.h>
+
+#include <QtCore/QDebug>
+
+#include <QtDBus/QDBusMessage>
+#include <QtDBus/QDBusMetaType>
+#include <QtDBus/QDBusPendingReply>
+#include <QtDBus/QDBusArgument>
+
+#include <QtXml/QDomDocument>
+
+using namespace Solid::Backends::UDisks2;
+
+// Adapted from KLocale as Solid needs to be Qt-only
+static QString formatByteSize(double size)
+{
+    // Per IEC 60027-2
+
+    // Binary prefixes
+    //Tebi-byte             TiB             2^40    1,099,511,627,776 bytes
+    //Gibi-byte             GiB             2^30    1,073,741,824 bytes
+    //Mebi-byte             MiB             2^20    1,048,576 bytes
+    //Kibi-byte             KiB             2^10    1,024 bytes
+
+    QString s;
+    // Gibi-byte
+    if ( size >= 1073741824.0 )
+    {
+        size /= 1073741824.0;
+        if ( size > 1024 ) // Tebi-byte
+            s = QObject::tr("%1 TiB").arg(QLocale().toString(size / 1024.0, 'f', 1));
+        else
+            s = QObject::tr("%1 GiB").arg(QLocale().toString(size, 'f', 1));
+    }
+    // Mebi-byte
+    else if ( size >= 1048576.0 )
+    {
+        size /= 1048576.0;
+        s = QObject::tr("%1 MiB").arg(QLocale().toString(size, 'f', 1));
+    }
+    // Kibi-byte
+    else if ( size >= 1024.0 )
+    {
+        size /= 1024.0;
+        s = QObject::tr("%1 KiB").arg(QLocale().toString(size, 'f', 1));
+    }
+    // Just byte
+    else if ( size > 0 )
+    {
+        s = QObject::tr("%1 B").arg(QLocale().toString(size, 'f', 1));
+    }
+    // Nothing
+    else
+    {
+        s = QObject::tr("0 B");
+    }
+    return s;
+}
+
+Device::Device(const QString &udi)
+    : Solid::Ifaces::Device()
+    , m_udi(udi)
+{
+    m_device = new QDBusInterface(UD2_DBUS_SERVICE, m_udi,
+                                  QString(), // no interface, we aggregate them
+                                  QDBusConnection::systemBus());
+
+    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();
+    }
+}
+
+Device::~Device()
+{
+    delete m_device;
+}
+
+QObject* Device::createDeviceInterface(const Solid::DeviceInterface::Type& type)
+{
+    if (!queryDeviceInterface(type)) {
+        return 0;
+    }
+
+    DeviceInterface *iface = 0;
+    switch (type)
+    {
+    case Solid::DeviceInterface::GenericInterface:
+        iface = new GenericInterface(this);
+        break;
+    case Solid::DeviceInterface::Block:
+        iface = new Block(this);
+        break;
+    case Solid::DeviceInterface::StorageAccess:
+        iface = new StorageAccess(this);
+        break;
+    case Solid::DeviceInterface::StorageDrive:
+        iface = new StorageDrive(this);
+        break;
+    case Solid::DeviceInterface::OpticalDrive:
+        iface = new OpticalDrive(this);
+        break;
+    case Solid::DeviceInterface::StorageVolume:
+        iface = new StorageVolume(this);
+        break;
+    case Solid::DeviceInterface::OpticalDisc:
+        iface = new OpticalDisc(this);
+        break;
+    default:
+        break;
+    }
+    return iface;
+}
+
+bool Device::queryDeviceInterface(const Solid::DeviceInterface::Type& type) const
+{
+    switch (type) {
+    case Solid::DeviceInterface::GenericInterface:
+        return true;
+    case Solid::DeviceInterface::Block:
+        return isBlock();
+    case Solid::DeviceInterface::StorageVolume:
+        return isStorageVolume();
+    case Solid::DeviceInterface::StorageAccess:
+        return isStorageAccess();
+    case Solid::DeviceInterface::StorageDrive:
+        return isDrive();
+    case Solid::DeviceInterface::OpticalDrive:
+        return isOpticalDrive();
+    case Solid::DeviceInterface::OpticalDisc:
+        return isOpticalDisc();
+    default:
+        return false;
+    }
+}
+
+QStringList Device::emblems() const
+{
+    QStringList res;
+
+    if (queryDeviceInterface(Solid::DeviceInterface::StorageAccess))
+    {
+        const UDisks2::StorageAccess accessIface(const_cast<Device *>(this));
+        if (accessIface.isAccessible())
+        {
+            if (isEncryptedContainer())
+                res << "emblem-encrypted-unlocked";
+            else
+                res << "emblem-mounted";
+        }
+        else
+        {
+            if (isEncryptedContainer())
+                res << "emblem-encrypted-locked";
+            else
+                res << "emblem-unmounted";
+        }
+    }
+
+    return res;
+}
+
+QString Device::description() const
+{
+    const QString hintName = prop("HintName").toString();
+    if (!hintName.isEmpty())
+        return hintName;
+
+    if (queryDeviceInterface(Solid::DeviceInterface::StorageDrive))
+        return storageDescription();
+    else if (queryDeviceInterface(Solid::DeviceInterface::StorageVolume))
+        return volumeDescription();
+    else
+        return product();
+}
+
+QString Device::storageDescription() const
+{
+    QString description;
+    const UDisks2::StorageDrive storageDrive(const_cast<Device*>(this));
+    Solid::StorageDrive::DriveType drive_type = storageDrive.driveType();
+    bool drive_is_hotpluggable = storageDrive.isHotpluggable();
+
+    if (drive_type == Solid::StorageDrive::CdromDrive)
+    {
+        const UDisks2::OpticalDrive opticalDrive(const_cast<Device*>(this));
+        Solid::OpticalDrive::MediumTypes mediumTypes = opticalDrive.supportedMedia();
+        QString first;
+        QString second;
+
+        first = QObject::tr("CD-ROM", "First item of %1%2 Drive sentence");
+        if (mediumTypes & Solid::OpticalDrive::Cdr)
+            first = QObject::tr("CD-R", "First item of %1%2 Drive sentence");
+        if (mediumTypes & Solid::OpticalDrive::Cdrw)
+            first = QObject::tr("CD-RW", "First item of %1%2 Drive sentence");
+
+        if (mediumTypes & Solid::OpticalDrive::Dvd)
+            second = QObject::tr("/DVD-ROM", "Second item of %1%2 Drive sentence");
+        if (mediumTypes & Solid::OpticalDrive::Dvdplusr)
+            second = QObject::tr("/DVD+R", "Second item of %1%2 Drive sentence");
+        if (mediumTypes & Solid::OpticalDrive::Dvdplusrw)
+            second = QObject::tr("/DVD+RW", "Second item of %1%2 Drive sentence");
+        if (mediumTypes & Solid::OpticalDrive::Dvdr)
+            second = QObject::tr("/DVD-R", "Second item of %1%2 Drive sentence");
+        if (mediumTypes & Solid::OpticalDrive::Dvdrw)
+            second = QObject::tr("/DVD-RW", "Second item of %1%2 Drive sentence");
+        if (mediumTypes & Solid::OpticalDrive::Dvdram)
+            second = QObject::tr("/DVD-RAM", "Second item of %1%2 Drive sentence");
+        if ((mediumTypes & Solid::OpticalDrive::Dvdr) && (mediumTypes & Solid::OpticalDrive::Dvdplusr))
+        {
+            if(mediumTypes & Solid::OpticalDrive::Dvdplusdl)
+                second = QObject::trUtf8("/DVD±R DL", "Second item of %1%2 Drive sentence");
+            else
+                second = QObject::trUtf8("/DVD±R", "Second item of %1%2 Drive sentence");
+        }
+        if ((mediumTypes & Solid::OpticalDrive::Dvdrw) && (mediumTypes & Solid::OpticalDrive::Dvdplusrw))
+        {
+            if((mediumTypes & Solid::OpticalDrive::Dvdplusdl) || (mediumTypes & Solid::OpticalDrive::Dvdplusdlrw))
+                second = QObject::trUtf8("/DVD±RW DL", "Second item of %1%2 Drive sentence");
+            else
+                second = QObject::trUtf8("/DVD±RW", "Second item of %1%2 Drive sentence");
+        }
+        if (mediumTypes & Solid::OpticalDrive::Bd)
+            second = QObject::tr("/BD-ROM", "Second item of %1%2 Drive sentence");
+        if (mediumTypes & Solid::OpticalDrive::Bdr)
+            second = QObject::tr("/BD-R", "Second item of %1%2 Drive sentence");
+        if (mediumTypes & Solid::OpticalDrive::Bdre)
+            second = QObject::tr("/BD-RE", "Second item of %1%2 Drive sentence");
+        if (mediumTypes & Solid::OpticalDrive::HdDvd)
+            second = QObject::tr("/HD DVD-ROM", "Second item of %1%2 Drive sentence");
+        if (mediumTypes & Solid::OpticalDrive::HdDvdr)
+            second = QObject::tr("/HD DVD-R", "Second item of %1%2 Drive sentence");
+        if (mediumTypes & Solid::OpticalDrive::HdDvdrw)
+            second = QObject::tr("/HD DVD-RW", "Second item of %1%2 Drive sentence");
+
+        if (drive_is_hotpluggable)
+            description = QObject::tr("External %1%2 Drive", "%1 is CD-ROM/CD-R/etc; %2 is '/DVD-ROM'/'/DVD-R'/etc (with leading slash)").arg(first).arg(second);
+        else
+            description = QObject::tr("%1%2 Drive", "%1 is CD-ROM/CD-R/etc; %2 is '/DVD-ROM'/'/DVD-R'/etc (with leading slash)").arg(first).arg(second);
+
+        return description;
+    }
+
+    if (drive_type == Solid::StorageDrive::Floppy)
+    {
+        if (drive_is_hotpluggable)
+            description = QObject::tr("External Floppy Drive");
+        else
+            description = QObject::tr("Floppy Drive");
+
+        return description;
+    }
+
+    bool drive_is_removable = storageDrive.isRemovable();
+
+    if (drive_type == Solid::StorageDrive::HardDisk && !drive_is_removable)
+    {
+        QString size_str = formatByteSize(storageDrive.size());
+        if (!size_str.isEmpty())
+        {
+            if (drive_is_hotpluggable)
+                description = QObject::tr("%1 External Hard Drive", "%1 is the size").arg(size_str);
+            else
+                description = QObject::tr("%1 Hard Drive", "%1 is the size").arg(size_str);
+        } else {
+            if (drive_is_hotpluggable)
+                description = QObject::tr("External Hard Drive");
+            else
+                description = QObject::tr("Hard Drive");
+        }
+
+        return description;
+    }
+
+    QString vendormodel_str;
+    QString model = product();
+    QString vendor_str = vendor();
+
+    if (vendor_str.isEmpty())
+    {
+        if (!model.isEmpty())
+            vendormodel_str = model;
+    }
+    else
+    {
+        if (model.isEmpty())
+            vendormodel_str = vendor_str;
+        else
+        {
+            if (model.startsWith(vendor_str))
+            {
+                // e.g. vendor is "Nokia" and model is "Nokia N950" we do not want "Nokia Nokia N950" as description
+                vendormodel_str = model;
+            }
+            else
+            {
+                vendormodel_str = QObject::tr("%1 %2", "%1 is the vendor, %2 is the model of the device").arg(vendor_str).arg(model);
+            }
+        }
+    }
+
+    if (vendormodel_str.isEmpty())
+        description = QObject::tr("Drive");
+    else
+        description = vendormodel_str;
+
+    return description;
+}
+
+QString Device::volumeDescription() const
+{
+    QString description;
+    const UDisks2::StorageVolume storageVolume(const_cast<Device*>(this));
+    QString volume_label = prop("IdLabel").toString();
+    if (volume_label.isEmpty())
+        volume_label = prop("Name").toString();
+    if (!volume_label.isEmpty())
+        return volume_label;
+
+    UDisks2::Device storageDevice(drivePath());
+    const UDisks2::StorageDrive storageDrive(&storageDevice);
+    Solid::StorageDrive::DriveType drive_type = storageDrive.driveType();
+
+    // Handle media in optical drives
+    if (drive_type == Solid::StorageDrive::CdromDrive)
+    {
+        const UDisks2::OpticalDisc disc(const_cast<Device*>(this));
+        switch (disc.discType())
+        {
+            case Solid::OpticalDisc::UnknownDiscType:
+            case Solid::OpticalDisc::CdRom:
+                description = QObject::tr("CD-ROM");
+                break;
+
+            case Solid::OpticalDisc::CdRecordable:
+                if (disc.isBlank())
+                    description = QObject::tr("Blank CD-R");
+                else
+                    description = QObject::tr("CD-R");
+                break;
+
+            case Solid::OpticalDisc::CdRewritable:
+                if (disc.isBlank())
+                    description = QObject::tr("Blank CD-RW");
+                else
+                    description = QObject::tr("CD-RW");
+                break;
+
+            case Solid::OpticalDisc::DvdRom:
+                description = QObject::tr("DVD-ROM");
+                break;
+
+            case Solid::OpticalDisc::DvdRam:
+                if (disc.isBlank())
+                    description = QObject::tr("Blank DVD-RAM");
+                else
+                    description = QObject::tr("DVD-RAM");
+                break;
+
+            case Solid::OpticalDisc::DvdRecordable:
+                if (disc.isBlank())
+                    description = QObject::tr("Blank DVD-R");
+                else
+                    description = QObject::tr("DVD-R");
+                break;
+
+            case Solid::OpticalDisc::DvdPlusRecordableDuallayer:
+                if (disc.isBlank())
+                    description = QObject::tr("Blank DVD+R Dual-Layer");
+                else
+                    description = QObject::tr("DVD+R Dual-Layer");
+                break;
+
+            case Solid::OpticalDisc::DvdRewritable:
+                if (disc.isBlank())
+                    description = QObject::tr("Blank DVD-RW");
+                else
+                    description = QObject::tr("DVD-RW");
+                break;
+
+            case Solid::OpticalDisc::DvdPlusRecordable:
+                if (disc.isBlank())
+                    description = QObject::tr("Blank DVD+R");
+                else
+                    description = QObject::tr("DVD+R");
+                break;
+
+            case Solid::OpticalDisc::DvdPlusRewritable:
+                if (disc.isBlank())
+                    description = QObject::tr("Blank DVD+RW");
+                else
+                    description = QObject::tr("DVD+RW");
+                break;
+
+            case Solid::OpticalDisc::DvdPlusRewritableDuallayer:
+                if (disc.isBlank())
+                    description = QObject::tr("Blank DVD+RW Dual-Layer");
+                else
+                    description = QObject::tr("DVD+RW Dual-Layer");
+                break;
+
+            case Solid::OpticalDisc::BluRayRom:
+                description = QObject::tr("BD-ROM");
+                break;
+
+            case Solid::OpticalDisc::BluRayRecordable:
+                if (disc.isBlank())
+                    description = QObject::tr("Blank BD-R");
+                else
+                    description = QObject::tr("BD-R");
+                break;
+
+            case Solid::OpticalDisc::BluRayRewritable:
+                if (disc.isBlank())
+                    description = QObject::tr("Blank BD-RE");
+                else
+                    description = QObject::tr("BD-RE");
+                break;
+
+            case Solid::OpticalDisc::HdDvdRom:
+                description = QObject::tr("HD DVD-ROM");
+                break;
+
+            case Solid::OpticalDisc::HdDvdRecordable:
+                if (disc.isBlank())
+                    description = QObject::tr("Blank HD DVD-R");
+                else
+                    description = QObject::tr("HD DVD-R");
+                break;
+
+            case Solid::OpticalDisc::HdDvdRewritable:
+                if (disc.isBlank())
+                    description = QObject::tr("Blank HD DVD-RW");
+                else
+                    description = QObject::tr("HD DVD-RW");
+                break;
+            }
+
+        // Special case for pure audio disc
+        if (disc.availableContent() == Solid::OpticalDisc::Audio)
+            description = QObject::tr("Audio CD");
+
+        return description;
+    }
+
+    const bool drive_is_removable = storageDrive.isRemovable();
+    const bool drive_is_hotpluggable = storageDrive.isHotpluggable();
+
+    QString size_str = formatByteSize(storageVolume.size());
+    if (isEncryptedContainer())
+    {
+        if (!size_str.isEmpty())
+            description = QObject::tr("%1 Encrypted Container", "%1 is the size").arg(size_str);
+        else
+            description = QObject::tr("Encrypted Container");
+    }
+    else if (drive_type == Solid::StorageDrive::HardDisk && !drive_is_removable)
+    {
+        if (!size_str.isEmpty())
+        {
+            if (drive_is_hotpluggable)
+                description = QObject::tr("%1 External Hard Drive", "%1 is the size").arg(size_str);
+            else
+                description = QObject::tr("%1 Hard Drive", "%1 is the size").arg(size_str);
+        }
+        else
+        {
+            if (drive_is_hotpluggable)
+                description = QObject::tr("External Hard Drive");
+            else
+                description = QObject::tr("Hard Drive");
+        }
+    }
+    else
+    {
+        if (drive_is_removable)
+            description = QObject::tr("%1 Removable Media", "%1 is the size").arg(size_str);
+        else
+            description = QObject::tr("%1 Media", "%1 is the size").arg(size_str);
+    }
+
+    return description;
+}
+
+QString Device::icon() const
+{
+    QString iconName = prop( "HintIconName" ).toString();
+
+    if ( !iconName.isEmpty() )
+    {
+        return iconName;
+    }
+    else if (isDrive()) {
+        const bool isRemovable = prop("Removable").toBool();
+        const QString conn = prop("ConnectionBus").toString();
+
+        if (isOpticalDrive())
+            return "drive-optical";
+        else if (isRemovable && !isOpticalDisc()) {
+            if (conn == "usb")
+                return "drive-removable-media-usb";
+            else
+                return "drive-removable-media";
+        }
+    }
+    else if (isBlock()) {
+        Device drive(drivePath());
+
+        // handle media
+        const QString media = drive.prop("Media").toString();
+
+        if ( !media.isEmpty() )
+        {
+            if ( isOpticalDisc() )    // optical stuff
+            {
+                bool isWritable = drive.prop("OpticalBlank").toBool();
+
+                const UDisks2::OpticalDisc disc(const_cast<Device*>(this));
+                Solid::OpticalDisc::ContentTypes availContent = disc.availableContent();
+
+                if (availContent & Solid::OpticalDisc::VideoDvd) // Video DVD
+                    return "media-optical-dvd-video";
+                else if ((availContent & Solid::OpticalDisc::VideoCd) || (availContent & Solid::OpticalDisc::SuperVideoCd)) // Video CD
+                    return "media-optical-video";
+                else if ((availContent & Solid::OpticalDisc::Data) && (availContent & Solid::OpticalDisc::Audio)) // Mixed CD
+                    return "media-optical-mixed-cd";
+                else if (availContent & Solid::OpticalDisc::Audio) // Audio CD
+                    return "media-optical-audio";
+                else if (availContent & Solid::OpticalDisc::Data) // Data CD
+                    return "media-optical-data";
+                else if ( isWritable )
+                    return "media-optical-recordable";
+                else
+                {
+                    if ( media.startsWith( "optical_dvd" ) || media.startsWith( "optical_hddvd" ) ) // DVD
+                        return "media-optical-dvd";
+                    else if ( media.startsWith( "optical_bd" ) ) // BluRay
+                        return "media-optical-blu-ray";
+                }
+
+                // fallback for every other optical disc
+                return "media-optical";
+            }
+
+            if ( media == "flash_ms" ) // Flash & Co.
+                return "media-flash-memory-stick";
+            else if ( media == "flash_sd" || media == "flash_sdhc" || media == "flash_sdxc" || media == "flash_mmc" )
+                return "media-flash-sd-mmc";
+            else if ( media == "flash_sm" )
+                return "media-flash-smart-media";
+            else if ( media == "thumb" )
+                return "drive-removable-media-usb-pendrive";
+            else if ( media.startsWith( "flash" ) )
+                return "media-flash";
+            else if ( media == "floppy" ) // the good ol' floppy
+                return "media-floppy";
+        }
+
+        if (drive.prop("ConnectionBus").toString() == "sdio")  // hack for SD cards connected thru sdio bus
+            return "media-flash-sd-mmc";
+
+        return drive.icon();
+    }
+
+    return "drive-harddisk";    // general fallback
+}
+
+QString Device::product() const
+{
+    QString product = prop("Model").toString();
+
+    if (!isDrive()) {
+        QString label = prop("IdLabel").toString();
+        if (!label.isEmpty()) {
+            product = label;
+        }
+    }
+
+    return product;
+}
+
+QString Device::vendor() const
+{
+    return prop("Vendor").toString();
+}
+
+QString Device::udi() const
+{
+    return m_udi;
+}
+
+QString Device::parentUdi() const
+{
+    QString parent;
+
+    if (isEncryptedContainer())
+        parent = prop("CryptoBackingDevice").value<QDBusObjectPath>().path();
+    else if (propertyExists("Drive"))  // block
+        parent = prop("Drive").value<QDBusObjectPath>().path();
+    else if (propertyExists("Table"))  // partition
+        parent = prop("Table").value<QDBusObjectPath>().path();
+    else if (parent.isEmpty() || parent=="/") {
+        parent = UD2_UDI_DISKS_PREFIX;
+    }
+    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;
+        //m_cache.insert(key, QVariant());
+    }
+}
+
+QString Device::introspect() const
+{
+    QDBusMessage call = QDBusMessage::createMethodCall(UD2_DBUS_SERVICE, m_udi,
+                                                       DBUS_INTERFACE_INTROSPECT, "Introspect");
+    QDBusPendingReply<QString> reply = QDBusConnection::systemBus().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
+{
+    Q_FOREACH (const QString & iface, m_interfaces) {
+        if (iface.startsWith("org.freedesktop.DBus"))
+            continue;
+        QDBusMessage call = QDBusMessage::createMethodCall(UD2_DBUS_SERVICE, m_udi, DBUS_INTERFACE_PROPS, "GetAll");
+        call << iface;
+        QDBusPendingReply<QVariantMap> reply = QDBusConnection::systemBus().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<QString, int> changeMap;
+
+    Q_FOREACH(const QString & key, invalidatedProps) {
+        m_cache.remove(key);
+        changeMap.insert(key, Solid::GenericInterface::PropertyRemoved);
+        qDebug() << "\t invalidated:" << key;
+    }
+
+    QMapIterator<QString, QVariant> 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)
+        return QObject::tr("You are not authorized to perform this operation");
+    else if (error == UD2_ERROR_BUSY)
+        return QObject::tr("The device is currently busy");
+    else if (error == UD2_ERROR_FAILED)
+        return QObject::tr("The requested operation has failed");
+    else if (error == UD2_ERROR_CANCELED)
+        return QObject::tr("The requested operation has been canceled");
+    else if (error == UD2_ERROR_INVALID_OPTION)
+        return QObject::tr("An invalid or malformed option has been given");
+    else if (error == UD2_ERROR_MISSING_DRIVER)
+        return QObject::tr("The kernel driver for this filesystem type is not available");
+    else if (error == UD2_ERROR_ALREADY_MOUNTED)
+        return QObject::tr("The device is already mounted");
+    else if (error == UD2_ERROR_NOT_MOUNTED)
+        return QObject::tr("The device is not mounted");
+    else if (error == UD2_ERROR_MOUNTED_BY_OTHER_USER)
+        return QObject::tr("The device is mounted by another user");
+    else if (error == UD2_ERROR_ALREADY_UNMOUNTING)
+        return QObject::tr("The device is already unmounting");
+    else if (error == UD2_ERROR_TIMED_OUT)
+        return QObject::tr("The operation timed out");
+    else if (error == UD2_ERROR_WOULD_WAKEUP)
+        return QObject::tr("The operation would wake up a disk that is in a deep-sleep state");
+    else if (error == UD2_ERROR_ALREADY_CANCELLED)
+        return QObject::tr("The operation has already been canceled");
+    else
+        return QObject::tr("An unspecified error has occurred");
+}
+
+Solid::ErrorType Device::errorToSolidError(const QString & error) const
+{
+    if (error == UD2_ERROR_BUSY)
+        return Solid::DeviceBusy;
+    else if (error == UD2_ERROR_FAILED)
+        return Solid::OperationFailed;
+    else if (error == UD2_ERROR_CANCELED)
+        return Solid::UserCanceled;
+    else if (error == UD2_ERROR_INVALID_OPTION)
+        return Solid::InvalidOption;
+    else if (error == UD2_ERROR_MISSING_DRIVER)
+        return Solid::MissingDriver;
+    else
+        return Solid::UnauthorizedOperation;
+}
+
+bool Device::isBlock() const
+{
+    return hasInterface(UD2_DBUS_INTERFACE_BLOCK);
+}
+
+bool Device::isPartition() const
+{
+    return hasInterface(UD2_DBUS_INTERFACE_PARTITION);
+}
+
+bool Device::isPartitionTable() const
+{
+    return hasInterface(UD2_DBUS_INTERFACE_PARTITIONTABLE);
+}
+
+bool Device::isStorageVolume() const
+{
+    return isPartition() || isPartitionTable() || isStorageAccess() || isOpticalDisc();
+}
+
+bool Device::isStorageAccess() const
+{
+    return hasInterface(UD2_DBUS_INTERFACE_FILESYSTEM) || isEncryptedContainer();
+}
+
+bool Device::isDrive() const
+{
+    return hasInterface(UD2_DBUS_INTERFACE_DRIVE);
+}
+
+bool Device::isOpticalDrive() const
+{
+    return isDrive() && !prop("MediaCompatibility").toStringList().filter("optical_").isEmpty();
+}
+
+bool Device::isOpticalDisc() const
+{
+    const QString drv = drivePath();
+    if (drv.isEmpty() || drv == "/")
+        return false;
+
+    Device drive(drv);
+    return drive.prop("Optical").toBool();
+}
+
+bool Device::mightBeOpticalDisc() const
+{
+    const QString drv = drivePath();
+    if (drv.isEmpty() || drv == "/")
+        return false;
+
+    Device drive(drv);
+    return drive.isOpticalDrive();
+}
+
+bool Device::isMounted() const
+{
+    return propertyExists("MountPoints") && !qdbus_cast<QByteArrayList>(prop("MountPoints")).isEmpty();
+}
+
+bool Device::isEncryptedContainer() const
+{
+    return hasInterface(UD2_DBUS_INTERFACE_ENCRYPTED);
+}
+
+bool Device::isEncryptedCleartext() const
+{
+    const QString holderDevice = prop("CryptoBackingDevice").toString();
+    if (holderDevice.isEmpty() || holderDevice == "/")
+        return false;
+    else
+        return true;
+}
+
+bool Device::isSwap() const
+{
+    return hasInterface(UD2_DBUS_INTERFACE_SWAP);
+}
+
+QString Device::drivePath() const
+{
+    return prop("Drive").value<QDBusObjectPath>().path();
+}
diff --git a/tier1/solid/src/solid/backends/udisks2/udisksdevice.h b/tier1/solid/src/solid/backends/udisks2/udisksdevice.h
new file mode 100644
index 0000000..cf8e2f5
--- /dev/null
+++ b/tier1/solid/src/solid/backends/udisks2/udisksdevice.h
@@ -0,0 +1,112 @@
+/*
+    Copyright 2010 Michael Zanetti <mzanetti@kde.org>
+    Copyright 2010-2012 Lukáš Tinkl <ltinkl@redhat.com>
+
+    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 <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef UDISKS2DEVICE_H
+#define UDISKS2DEVICE_H
+
+#include "udisks2.h"
+
+#include <ifaces/device.h>
+#include <solid/deviceinterface.h>
+#include <solid/solidnamespace.h>
+
+#include <QtDBus/QDBusInterface>
+#include <QtDBus/QDBusObjectPath>
+#include <QtCore/QStringList>
+
+namespace Solid
+{
+namespace Backends
+{
+namespace UDisks2
+{
+
+class Device: public Solid::Ifaces::Device
+{
+    Q_OBJECT
+public:
+    Device(const QString &udi);
+    virtual ~Device();
+
+    virtual QObject* createDeviceInterface(const Solid::DeviceInterface::Type& type);
+    virtual bool queryDeviceInterface(const Solid::DeviceInterface::Type& type) const;
+    virtual QString description() const;
+    virtual QStringList emblems() const;
+    virtual QString icon() const;
+    virtual QString product() const;
+    virtual QString vendor() const;
+    virtual QString udi() const;
+    virtual QString parentUdi() const;
+
+    QVariant prop(const QString &key) const;
+    bool propertyExists(const QString &key) const;
+    QVariantMap allProperties() const;
+
+    bool hasInterface(const QString & name) const;
+    QStringList interfaces() const;
+
+    QString errorToString(const QString & error) const;
+    Solid::ErrorType errorToSolidError(const QString & error) const;
+
+    bool isBlock() const;
+    bool isPartition() const;
+    bool isPartitionTable() const;
+    bool isStorageVolume() const;
+    bool isStorageAccess() const;
+    bool isDrive() const;
+    bool isOpticalDrive() const;
+    bool isOpticalDisc() const;
+    bool mightBeOpticalDisc() const;
+    bool isMounted() const;
+    bool isEncryptedContainer() const;
+    bool isEncryptedCleartext() const;
+    bool isSwap() const;
+
+    QString drivePath() const;
+
+Q_SIGNALS:
+    void changed();
+    void propertyChanged(const QMap<QString,int> &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);
+
+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;
+};
+
+}
+}
+}
+
+#endif // UDISKS2DEVICE_H
diff --git a/tier1/solid/src/solid/backends/udisks2/udisksdeviceinterface.cpp b/tier1/solid/src/solid/backends/udisks2/udisksdeviceinterface.cpp
new file mode 100644
index 0000000..9fa60e5
--- /dev/null
+++ b/tier1/solid/src/solid/backends/udisks2/udisksdeviceinterface.cpp
@@ -0,0 +1,33 @@
+/*
+    Copyright 2010 Michael Zanetti <mzanetti@kde.org>
+
+    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 <http://www.gnu.org/licenses/>.
+*/
+
+#include "udisksdeviceinterface.h"
+
+using namespace Solid::Backends::UDisks2;
+
+DeviceInterface::DeviceInterface(Device *device)
+    : QObject(device), m_device(device)
+{
+
+}
+
+DeviceInterface::~DeviceInterface()
+{
+}
diff --git a/tier1/solid/src/solid/backends/udisks2/udisksdeviceinterface.h b/tier1/solid/src/solid/backends/udisks2/udisksdeviceinterface.h
new file mode 100644
index 0000000..43a1b6f
--- /dev/null
+++ b/tier1/solid/src/solid/backends/udisks2/udisksdeviceinterface.h
@@ -0,0 +1,148 @@
+/*
+    Copyright 2010 Michael Zanetti <mzanetti@kde.org>
+
+    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 <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef UDISKS2DEVICEINTERFACE_H
+#define UDISKS2DEVICEINTERFACE_H
+
+#include <ifaces/deviceinterface.h>
+#include "udisksdevice.h"
+
+#include <QtCore/QObject>
+#include <QtCore/QStringList>
+
+namespace Solid
+{
+namespace Backends
+{
+namespace UDisks2
+{
+
+class DeviceInterface : public QObject, virtual public Solid::Ifaces::DeviceInterface
+{
+    Q_OBJECT
+    Q_INTERFACES(Solid::Ifaces::DeviceInterface)
+public:
+    DeviceInterface(Device *device);
+    virtual ~DeviceInterface();
+
+protected:
+    Device *m_device;
+
+public:
+    inline static QStringList toStringList(Solid::DeviceInterface::Type type)
+    {
+        QStringList list;
+
+        switch(type)
+        {
+        case Solid::DeviceInterface::GenericInterface:
+            list << "generic";
+            break;
+        case Solid::DeviceInterface::Processor:
+            // Doesn't exist with UDisks
+            break;
+        case Solid::DeviceInterface::Block:
+            list << "block";
+            break;
+        case Solid::DeviceInterface::StorageAccess:
+            list << "volume";
+            break;
+        case Solid::DeviceInterface::StorageDrive:
+            list << "storage";
+            break;
+        case Solid::DeviceInterface::OpticalDrive:
+            list << "storage.cdrom";
+            break;
+        case Solid::DeviceInterface::StorageVolume:
+            list << "volume";
+            break;
+        case Solid::DeviceInterface::OpticalDisc:
+            list << "volume.disc";
+            break;
+        case Solid::DeviceInterface::Camera:
+            // Doesn't exist with UDisks
+            break;
+        case Solid::DeviceInterface::PortableMediaPlayer:
+            // Doesn't exist with UDisks
+            break;
+        case Solid::DeviceInterface::NetworkInterface:
+            // Doesn't exist with UDisks
+            break;
+        case Solid::DeviceInterface::AcAdapter:
+            // Doesn't exist with UDisks
+            break;
+        case Solid::DeviceInterface::Battery:
+            // Doesn't exist with UDisks
+            break;
+        case Solid::DeviceInterface::Button:
+            // Doesn't exist with UDisks
+            break;
+        case Solid::DeviceInterface::AudioInterface:
+            // Doesn't exist with UDisks
+            break;
+        case Solid::DeviceInterface::DvbInterface:
+            // Doesn't exist with UDisks
+            break;
+        case Solid::DeviceInterface::Video:
+            // Doesn't exist with UDisks
+            break;
+        case Solid::DeviceInterface::SerialInterface:
+            // Doesn't exist with UDisks
+            break;
+        case Solid::DeviceInterface::InternetGateway:
+            break;
+        case Solid::DeviceInterface::SmartCardReader:
+            // Doesn't exist with UDisks
+        case Solid::DeviceInterface::NetworkShare:
+            // Doesn't exist with UDisks
+            break;
+        case Solid::DeviceInterface::Unknown:
+            break;
+        case Solid::DeviceInterface::Last:
+            break;
+        }
+
+        return list;
+    }
+
+    inline static Solid::DeviceInterface::Type fromString(const QString &capability)
+    {
+        if (capability == "generic")
+            return Solid::DeviceInterface::GenericInterface;
+        else if (capability == "block")
+            return Solid::DeviceInterface::Block;
+        else if (capability == "storage")
+            return Solid::DeviceInterface::StorageDrive;
+        else if (capability == "storage.cdrom")
+            return Solid::DeviceInterface::OpticalDrive;
+        else if (capability == "volume")
+            return Solid::DeviceInterface::StorageVolume;
+        else if (capability == "volume.disc")
+            return Solid::DeviceInterface::OpticalDisc;
+        else
+            return Solid::DeviceInterface::Unknown;
+    }
+};
+
+}
+}
+}
+
+#endif // UDISKS2DEVICEINTERFACE_H
diff --git a/tier1/solid/src/solid/backends/udisks2/udisksgenericinterface.cpp b/tier1/solid/src/solid/backends/udisks2/udisksgenericinterface.cpp
new file mode 100644
index 0000000..2d8cea2
--- /dev/null
+++ b/tier1/solid/src/solid/backends/udisks2/udisksgenericinterface.cpp
@@ -0,0 +1,53 @@
+/*
+    Copyright 2009 Pino Toscano <pino@kde.org>
+    Copyright 2012 Lukáš Tinkl <ltinkl@redhat.com>
+
+    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 <http://www.gnu.org/licenses/>.
+*/
+
+#include "udisksgenericinterface.h"
+
+#include "udisksdevice.h"
+
+using namespace Solid::Backends::UDisks2;
+
+GenericInterface::GenericInterface(Device *device)
+    : DeviceInterface(device)
+{
+    connect(device, SIGNAL(propertyChanged(QMap<QString,int>)),
+            this, SIGNAL(propertyChanged(QMap<QString,int>)));
+}
+
+GenericInterface::~GenericInterface()
+{
+}
+
+QVariant GenericInterface::property(const QString &key) const
+{
+    return m_device->prop(key);
+}
+
+QVariantMap GenericInterface::allProperties() const
+{
+    return m_device->allProperties();
+}
+
+bool GenericInterface::propertyExists(const QString &key) const
+{
+    return m_device->propertyExists(key);
+}
+
diff --git a/tier1/solid/src/solid/backends/udisks2/udisksgenericinterface.h b/tier1/solid/src/solid/backends/udisks2/udisksgenericinterface.h
new file mode 100644
index 0000000..d225f32
--- /dev/null
+++ b/tier1/solid/src/solid/backends/udisks2/udisksgenericinterface.h
@@ -0,0 +1,57 @@
+/*
+    Copyright 2009 Pino Toscano <pino@kde.org>
+
+    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 <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef SOLID_BACKENDS_UDISKS2_GENERICINTERFACE_H
+#define SOLID_BACKENDS_UDISKS2_GENERICINTERFACE_H
+
+#include <solid/ifaces/genericinterface.h>
+#include <solid/genericinterface.h>
+#include "udisksdeviceinterface.h"
+
+namespace Solid
+{
+namespace Backends
+{
+namespace UDisks2
+{
+class Device;
+
+class GenericInterface : public DeviceInterface, virtual public Solid::Ifaces::GenericInterface
+{
+    Q_OBJECT
+    Q_INTERFACES(Solid::Ifaces::GenericInterface)
+
+public:
+    GenericInterface(Device *device);
+    virtual ~GenericInterface();
+
+    virtual QVariant property(const QString &key) const;
+    virtual QVariantMap allProperties() const;
+    virtual bool propertyExists(const QString &key) const;
+
+Q_SIGNALS:
+    void propertyChanged(const QMap<QString, int> &changes);
+    void conditionRaised(const QString &condition, const QString &reason);
+};
+}
+}
+}
+
+#endif // SOLID_BACKENDS_UDISKS2_GENERICINTERFACE_H
diff --git a/tier1/solid/src/solid/backends/udisks2/udisksmanager.cpp b/tier1/solid/src/solid/backends/udisks2/udisksmanager.cpp
new file mode 100644
index 0000000..0a77c16
--- /dev/null
+++ b/tier1/solid/src/solid/backends/udisks2/udisksmanager.cpp
@@ -0,0 +1,227 @@
+/*
+    Copyright 2012 Lukáš Tinkl <ltinkl@redhat.com>
+
+    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 <http://www.gnu.org/licenses/>.
+*/
+
+#include "udisksmanager.h"
+
+#include <QtCore/QDebug>
+#include <QtDBus>
+
+#include "../shared/rootdevice.h"
+
+using namespace Solid::Backends::UDisks2;
+using namespace Solid::Backends::Shared;
+
+Manager::Manager(QObject *parent)
+    : Solid::Ifaces::DeviceManager(parent),
+      m_manager(UD2_DBUS_SERVICE,
+                UD2_DBUS_PATH,
+                QDBusConnection::systemBus())
+{
+    m_supportedInterfaces
+            << Solid::DeviceInterface::GenericInterface
+            << Solid::DeviceInterface::Block
+            << Solid::DeviceInterface::StorageAccess
+            << Solid::DeviceInterface::StorageDrive
+            << Solid::DeviceInterface::OpticalDrive
+            << Solid::DeviceInterface::OpticalDisc
+            << Solid::DeviceInterface::StorageVolume;
+
+    qDBusRegisterMetaType<QList<QDBusObjectPath> >();
+    qDBusRegisterMetaType<QVariantMap>();
+    qDBusRegisterMetaType<QVariantMapMap>();
+    qDBusRegisterMetaType<QByteArrayList>();
+    qDBusRegisterMetaType<DBUSManagerStruct>();
+
+    bool serviceFound = m_manager.isValid();
+    if (!serviceFound) {
+        // find out whether it will be activated automatically
+        QDBusMessage message = QDBusMessage::createMethodCall("org.freedesktop.DBus",
+                                                              "/org/freedesktop/DBus",
+                                                              "org.freedesktop.DBus",
+                                                              "ListActivatableNames");
+
+        QDBusReply<QStringList> reply = QDBusConnection::systemBus().call(message);
+        if (reply.isValid() && reply.value().contains(UD2_DBUS_SERVICE)) {
+            QDBusConnection::systemBus().interface()->startService(UD2_DBUS_SERVICE);
+            serviceFound = true;
+        }
+    }
+
+    if (serviceFound) {
+        connect(&m_manager, SIGNAL(InterfacesAdded(QDBusObjectPath, QVariantMapMap)),
+                this, SLOT(slotInterfacesAdded(QDBusObjectPath,QVariantMapMap)));
+        connect(&m_manager, SIGNAL(InterfacesRemoved(QDBusObjectPath,QStringList)),
+                this, SLOT(slotInterfacesRemoved(QDBusObjectPath,QStringList)));
+    }
+}
+
+Manager::~Manager()
+{
+}
+
+QObject* Manager::createDevice(const QString& udi)
+{
+    if (udi==udiPrefix()) {
+        RootDevice *root = new RootDevice(udi);
+
+        root->setProduct(tr("Storage"));
+        root->setDescription(tr("Storage devices"));
+        root->setIcon("server-database"); // Obviously wasn't meant for that, but maps nicely in oxygen icon set :-p
+
+        return root;
+    } else if (deviceCache().contains(udi)) {
+        return new Device(udi);
+    } else {
+        return 0;
+    }
+}
+
+QStringList Manager::devicesFromQuery(const QString& parentUdi, Solid::DeviceInterface::Type type)
+{
+    QStringList result;
+
+    if (!parentUdi.isEmpty())
+    {
+        Q_FOREACH (const QString &udi, deviceCache())
+        {
+            Device device(udi);
+            if (device.queryDeviceInterface(type) && device.parentUdi() == parentUdi)
+                result << udi;
+        }
+
+        return result;
+    }
+    else if (type != Solid::DeviceInterface::Unknown)
+    {
+        Q_FOREACH (const QString &udi, deviceCache())
+        {
+            Device device(udi);
+            if (device.queryDeviceInterface(type))
+                result << udi;
+        }
+
+        return result;
+    }
+
+    return deviceCache();
+}
+
+QStringList Manager::allDevices()
+{
+    m_deviceCache.clear();
+
+    QDBusPendingReply<DBUSManagerStruct> reply = m_manager.GetManagedObjects();
+    reply.waitForFinished();
+    if (!reply.isError()) {  // enum devices
+        m_deviceCache << udiPrefix();
+
+        Q_FOREACH(const QDBusObjectPath &path, reply.value().keys()) {
+            const QString udi = path.path();
+            //qDebug() << "Adding device" << udi;
+
+            if (udi == UD2_DBUS_PATH_MANAGER || udi == UD2_UDI_DISKS_PREFIX || udi.startsWith(UD2_DBUS_PATH_JOBS))
+                continue;
+
+            Device device(udi);
+            if (device.mightBeOpticalDisc()) {
+                QDBusConnection::systemBus().connect(UD2_DBUS_SERVICE, udi, DBUS_INTERFACE_PROPS, "PropertiesChanged", this,
+                                                     SLOT(slotMediaChanged(QDBusMessage)));
+                if (!device.isOpticalDisc())  // skip empty CD disc
+                    continue;
+            }
+
+            m_deviceCache.append(udi);
+        }
+    }
+    else  // show error
+    {
+        qWarning() << "Failed enumerating UDisks2 objects:" << reply.error().name() << "\n" << reply.error().message();
+    }
+
+    return m_deviceCache;
+}
+
+
+QSet< Solid::DeviceInterface::Type > Manager::supportedInterfaces() const
+{
+    return m_supportedInterfaces;
+}
+
+QString Manager::udiPrefix() const
+{
+    return UD2_UDI_DISKS_PREFIX;
+}
+
+void Manager::slotInterfacesAdded(const QDBusObjectPath &object_path, const QVariantMapMap &interfaces_and_properties)
+{
+    const QString udi = object_path.path();
+
+    qDebug() << udi << "has new interfaces:" << interfaces_and_properties.keys();
+
+    // new device, we don't know it yet
+    if (!m_deviceCache.contains(udi)) {
+        m_deviceCache.append(udi);
+        Q_EMIT deviceAdded(udi);
+    }
+}
+
+void Manager::slotInterfacesRemoved(const QDBusObjectPath &object_path, const QStringList &interfaces)
+{
+    const QString udi = object_path.path();
+
+    qDebug() << udi << "lost interfaces:" << interfaces;
+
+    Device device(udi);
+
+    if (!udi.isEmpty() && (interfaces.isEmpty() || device.interfaces().isEmpty() || device.interfaces().contains(UD2_DBUS_INTERFACE_FILESYSTEM))) {
+        Q_EMIT deviceRemoved(udi);
+        m_deviceCache.removeAll(udi);
+    }
+}
+
+void Manager::slotMediaChanged(const QDBusMessage & msg)
+{
+    const QVariantMap properties = qdbus_cast<QVariantMap>(msg.arguments().at(1));
+
+    if (!properties.contains("Size"))  // react only on Size changes
+        return;
+
+    const QString udi = msg.path();
+    qulonglong size = properties.value("Size").toULongLong();
+    qDebug() << "MEDIA CHANGED in" << udi << "; size is:" << size;
+
+    if (!m_deviceCache.contains(udi) && size > 0) { // we don't know the optdisc, got inserted
+        m_deviceCache.append(udi);
+        Q_EMIT deviceAdded(udi);
+    }
+
+    if (m_deviceCache.contains(udi) && size == 0) {  // we know the optdisc, got removed
+        Q_EMIT deviceRemoved(udi);
+        m_deviceCache.removeAll(udi);
+    }
+}
+
+const QStringList & Manager::deviceCache()
+{
+    if (m_deviceCache.isEmpty())
+        allDevices();
+
+    return m_deviceCache;
+}
diff --git a/tier1/solid/src/solid/backends/udisks2/udisksmanager.h b/tier1/solid/src/solid/backends/udisks2/udisksmanager.h
new file mode 100644
index 0000000..7cf0a72
--- /dev/null
+++ b/tier1/solid/src/solid/backends/udisks2/udisksmanager.h
@@ -0,0 +1,69 @@
+/*
+    Copyright 2010 Michael Zanetti <mzanetti@kde.org>
+    Copyright 2010-2012 Lukáš Tinkl <ltinkl@redhat.com>
+
+    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 <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef UDISKS2MANAGER_H
+#define UDISKS2MANAGER_H
+
+#include "udisks2.h"
+#include "udisksdevice.h"
+#include "dbus/manager.h"
+
+#include "solid/ifaces/devicemanager.h"
+
+#include <QtDBus/QDBusInterface>
+#include <QtCore/QSet>
+
+namespace Solid
+{
+namespace Backends
+{
+namespace UDisks2
+{
+
+class Manager: public Solid::Ifaces::DeviceManager
+{
+    Q_OBJECT
+
+public:
+    Manager(QObject *parent);
+    virtual QObject* createDevice(const QString& udi);
+    virtual QStringList devicesFromQuery(const QString& parentUdi, Solid::DeviceInterface::Type type);
+    virtual QStringList allDevices();
+    virtual QSet< Solid::DeviceInterface::Type > supportedInterfaces() const;
+    virtual QString udiPrefix() const;
+    virtual ~Manager();
+
+private Q_SLOTS:
+    void slotInterfacesAdded(const QDBusObjectPath &object_path, const QVariantMapMap &interfaces_and_properties);
+    void slotInterfacesRemoved(const QDBusObjectPath &object_path, const QStringList &interfaces);
+    void slotMediaChanged(const QDBusMessage &msg);
+
+private:
+    const QStringList &deviceCache();
+    QSet<Solid::DeviceInterface::Type> m_supportedInterfaces;
+    org::freedesktop::DBus::ObjectManager m_manager;
+    QStringList m_deviceCache;
+};
+
+}
+}
+}
+#endif // UDISKS2MANAGER_H
diff --git a/tier1/solid/src/solid/backends/udisks2/udisksopticaldisc.cpp b/tier1/solid/src/solid/backends/udisks2/udisksopticaldisc.cpp
new file mode 100644
index 0000000..478c930
--- /dev/null
+++ b/tier1/solid/src/solid/backends/udisks2/udisksopticaldisc.cpp
@@ -0,0 +1,277 @@
+/*
+    Copyright 2010 Michael Zanetti <mzanetti@kde.org>
+    Copyright 2010 - 2012 Lukáš Tinkl <ltinkl@redhat.com>
+
+    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 <http://www.gnu.org/licenses/>.
+*/
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <QtCore/QFile>
+#include <QtDBus/QDBusConnection>
+
+#include "../shared/udevqtclient.h"
+
+#include "udisks2.h"
+#include "udisksopticaldisc.h"
+
+// inspired by http://cgit.freedesktop.org/hal/tree/hald/linux/probing/probe-volume.c
+static Solid::OpticalDisc::ContentType advancedDiscDetect(const QByteArray & device_file)
+{
+    /* the discs block size */
+    unsigned short bs;
+    /* the path table size */
+    unsigned short ts;
+    /* the path table location (in blocks) */
+    unsigned int tl;
+    /* length of the directory name in current path table entry */
+    unsigned char len_di = 0;
+    /* the number of the parent directory's path table entry */
+    unsigned int parent = 0;
+    /* filename for the current path table entry */
+    char dirname[256];
+    /* our position into the path table */
+    int pos = 0;
+    /* the path table record we're on */
+    int curr_record = 1;
+
+    Solid::OpticalDisc::ContentType result = Solid::OpticalDisc::NoContent;
+
+    int fd = open(device_file.constData(), O_RDONLY);
+
+    /* read the block size */
+    lseek (fd, 0x8080, SEEK_CUR);
+    if (read (fd, &bs, 2) != 2)
+    {
+        qDebug("Advanced probing on %s failed while reading block size", qPrintable(device_file));
+        goto out;
+    }
+
+    /* read in size of path table */
+    lseek (fd, 2, SEEK_CUR);
+    if (read (fd, &ts, 2) != 2)
+    {
+        qDebug("Advanced probing on %s failed while reading path table size", qPrintable(device_file));
+        goto out;
+    }
+
+    /* read in which block path table is in */
+    lseek (fd, 6, SEEK_CUR);
+    if (read (fd, &tl, 4) != 4)
+    {
+        qDebug("Advanced probing on %s failed while reading path table block", qPrintable(device_file));
+        goto out;
+    }
+
+    /* seek to the path table */
+    lseek (fd, bs * tl, SEEK_SET);
+
+    /* loop through the path table entries */
+    while (pos < ts)
+    {
+        /* get the length of the filename of the current entry */
+        if (read (fd, &len_di, 1) != 1)
+        {
+            qDebug("Advanced probing on %s failed, cannot read more entries", qPrintable(device_file));
+            break;
+        }
+
+        /* get the record number of this entry's parent
+           i'm pretty sure that the 1st entry is always the top directory */
+        lseek (fd, 5, SEEK_CUR);
+        if (read (fd, &parent, 2) != 2)
+        {
+            qDebug("Advanced probing on %s failed, couldn't read parent entry", qPrintable(device_file));
+            break;
+        }
+
+        /* read the name */
+        if (read (fd, dirname, len_di) != len_di)
+        {
+            qDebug("Advanced probing on %s failed, couldn't read the entry name", qPrintable(device_file));
+            break;
+        }
+        dirname[len_di] = 0;
+
+        /* if we found a folder that has the root as a parent, and the directory name matches
+           one of the special directories then set the properties accordingly */
+        if (parent == 1)
+        {
+            if (!strcasecmp (dirname, "VIDEO_TS"))
+            {
+                qDebug("Disc in %s is a Video DVD", qPrintable(device_file));
+                result = Solid::OpticalDisc::VideoDvd;
+                break;
+            }
+            else if (!strcasecmp (dirname, "BDMV"))
+            {
+                qDebug("Disc in %s is a Blu-ray video disc", qPrintable(device_file));
+                result = Solid::OpticalDisc::VideoBluRay;
+                break;
+            }
+            else if (!strcasecmp (dirname, "VCD"))
+            {
+                qDebug("Disc in %s is a Video CD", qPrintable(device_file));
+                result = Solid::OpticalDisc::VideoCd;
+                break;
+            }
+            else if (!strcasecmp (dirname, "SVCD"))
+            {
+                qDebug("Disc in %s is a Super Video CD", qPrintable(device_file));
+                result = Solid::OpticalDisc::SuperVideoCd;
+                break;
+            }
+        }
+
+        /* all path table entries are padded to be even,
+           so if this is an odd-length table, seek a byte to fix it */
+        if (len_di%2 == 1)
+        {
+            lseek (fd, 1, SEEK_CUR);
+            pos++;
+        }
+
+        /* update our position */
+        pos += 8 + len_di;
+        curr_record++;
+    }
+
+    close(fd);
+    return result;
+
+out:
+    /* go back to the start of the file */
+    lseek (fd, 0, SEEK_SET);
+    close(fd);
+    return result;
+}
+
+using namespace Solid::Backends::UDisks2;
+
+OpticalDisc::OpticalDisc(Device *dev)
+    : StorageVolume(dev), m_needsReprobe(true), m_cachedContent(Solid::OpticalDisc::NoContent)
+{
+    UdevQt::Client client(this);
+    m_udevDevice = client.deviceByDeviceFile(device());
+    //qDebug() << "udev device:" << m_udevDevice.name() << "valid:" << m_udevDevice.isValid();
+    /*qDebug() << "\tProperties:" << */ m_udevDevice.deviceProperties(); // initialize the properties DB so that it doesn't crash further down, #298416
+
+    m_drive = new Device(m_device->prop("Drive").value<QDBusObjectPath>().path());
+    QDBusConnection::systemBus().connect(UD2_DBUS_SERVICE, m_drive->udi(), DBUS_INTERFACE_PROPS, "PropertiesChanged", this,
+                                         SLOT(slotDrivePropertiesChanged(QString,QVariantMap,QStringList)));
+}
+
+OpticalDisc::~OpticalDisc()
+{
+    delete m_drive;
+}
+
+qulonglong OpticalDisc::capacity() const
+{
+    return m_device->prop("Size").toULongLong();
+}
+
+bool OpticalDisc::isRewritable() const
+{
+    // the hard way, udisks has no notion of a disc "rewritability"
+    const QString mediaType = media();
+    return mediaType == "optical_cd_rw" || mediaType == "optical_dvd_rw" || mediaType == "optical_dvd_ram" ||
+            mediaType == "optical_dvd_plus_rw" || mediaType == "optical_dvd_plus_rw_dl" ||
+            mediaType == "optical_bd_re" || mediaType == "optical_hddvd_rw";
+}
+
+bool OpticalDisc::isBlank() const
+{
+    return m_drive->prop("OpticalBlank").toBool();
+}
+
+bool OpticalDisc::isAppendable() const
+{
+    //qDebug() << "appendable prop" << m_udevDevice.deviceProperty("ID_CDROM_MEDIA_STATE");
+    return m_udevDevice.deviceProperty("ID_CDROM_MEDIA_STATE").toString() == QLatin1String("appendable");
+}
+
+Solid::OpticalDisc::DiscType OpticalDisc::discType() const
+{
+    QMap<Solid::OpticalDisc::DiscType, QString> map;
+    map[Solid::OpticalDisc::CdRom] = "optical_cd";
+    map[Solid::OpticalDisc::CdRecordable] = "optical_cd_r";
+    map[Solid::OpticalDisc::CdRewritable] = "optical_cd_rw";
+    map[Solid::OpticalDisc::DvdRom] = "optical_dvd";
+    map[Solid::OpticalDisc::DvdRecordable] = "optical_dvd_r";
+    map[Solid::OpticalDisc::DvdRewritable] ="optical_dvd_rw";
+    map[Solid::OpticalDisc::DvdRam] ="optical_dvd_ram";
+    map[Solid::OpticalDisc::DvdPlusRecordable] ="optical_dvd_plus_r";
+    map[Solid::OpticalDisc::DvdPlusRewritable] ="optical_dvd_plus_rw";
+    map[Solid::OpticalDisc::DvdPlusRecordableDuallayer] ="optical_dvd_plus_r_dl";
+    map[Solid::OpticalDisc::DvdPlusRewritableDuallayer] ="optical_dvd_plus_rw_dl";
+    map[Solid::OpticalDisc::BluRayRom] ="optical_bd";
+    map[Solid::OpticalDisc::BluRayRecordable] ="optical_bd_r";
+    map[Solid::OpticalDisc::BluRayRewritable] ="optical_bd_re";
+    map[Solid::OpticalDisc::HdDvdRom] ="optical_hddvd";
+    map[Solid::OpticalDisc::HdDvdRecordable] ="optical_hddvd_r";
+    map[Solid::OpticalDisc::HdDvdRewritable] ="optical_hddvd_rw";
+    // TODO add these to Solid
+    //map[Solid::OpticalDisc::MagnetoOptical] ="optical_mo";
+    //map[Solid::OpticalDisc::MountRainer] ="optical_mrw";
+    //map[Solid::OpticalDisc::MountRainerWritable] ="optical_mrw_w";
+
+    return map.key(media(), Solid::OpticalDisc::UnknownDiscType);  // FIXME optimize, lookup by value, not key
+}
+
+Solid::OpticalDisc::ContentTypes OpticalDisc::availableContent() const
+{
+    if (isBlank()) {
+        m_needsReprobe = false;
+        return Solid::OpticalDisc::NoContent;
+    }
+
+    if (m_needsReprobe) {
+        m_cachedContent = Solid::OpticalDisc::NoContent;
+        const bool hasData = m_drive->prop("OpticalNumDataTracks").toUInt() > 0;
+        const bool hasAudio = m_drive->prop("OpticalNumAudioTracks").toUInt() > 0;
+
+        if ( hasData ) {
+            m_cachedContent |= Solid::OpticalDisc::Data;
+            m_cachedContent |= advancedDiscDetect(m_device->prop("Device").toByteArray());
+        }
+        if ( hasAudio )
+            m_cachedContent |= Solid::OpticalDisc::Audio;
+
+        m_needsReprobe = false;
+    }
+
+    return m_cachedContent;
+}
+
+void OpticalDisc::slotDrivePropertiesChanged(const QString &ifaceName, const QVariantMap &changedProps, const QStringList &invalidatedProps)
+{
+    Q_UNUSED(ifaceName);
+
+    if (changedProps.keys().contains("Media") || invalidatedProps.contains("Media")) {
+        m_needsReprobe = true;
+        m_cachedContent = Solid::OpticalDisc::NoContent;
+    }
+}
+
+QString OpticalDisc::media() const
+{
+    return m_drive->prop("Media").toString();
+}
diff --git a/tier1/solid/src/solid/backends/udisks2/udisksopticaldisc.h b/tier1/solid/src/solid/backends/udisks2/udisksopticaldisc.h
new file mode 100644
index 0000000..5b80995
--- /dev/null
+++ b/tier1/solid/src/solid/backends/udisks2/udisksopticaldisc.h
@@ -0,0 +1,69 @@
+/*
+    Copyright 2010 Michael Zanetti <mzanetti@kde.org>
+    Copyright 2010 - 2012 Lukáš Tinkl <ltinkl@redhat.com>
+
+    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 <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef UDISKS2OPTICALDISC_H
+#define UDISKS2OPTICALDISC_H
+
+#include <solid/ifaces/opticaldisc.h>
+
+#include "../shared/udevqtdevice.h"
+
+#include "udisksstoragevolume.h"
+#include "udisksdevice.h"
+
+namespace Solid
+{
+namespace Backends
+{
+namespace UDisks2
+{
+
+class OpticalDisc: public StorageVolume, virtual public Solid::Ifaces::OpticalDisc
+{
+    Q_OBJECT
+    Q_INTERFACES(Solid::Ifaces::OpticalDisc)
+
+public:
+    OpticalDisc(Device *dev);
+    virtual ~OpticalDisc();
+
+    virtual qulonglong capacity() const;
+    virtual bool isRewritable() const;
+    virtual bool isBlank() const;
+    virtual bool isAppendable() const;
+    virtual Solid::OpticalDisc::DiscType discType() const;
+    virtual Solid::OpticalDisc::ContentTypes availableContent() const;
+
+private Q_SLOTS:
+    void slotDrivePropertiesChanged(const QString & ifaceName, const QVariantMap & changedProps, const QStringList & invalidatedProps);
+
+private:
+    QString media() const;
+    mutable bool m_needsReprobe;
+    mutable Solid::OpticalDisc::ContentTypes m_cachedContent;
+    Device * m_drive;
+    UdevQt::Device m_udevDevice;
+};
+
+}
+}
+}
+#endif // UDISKS2OPTICALDISC_H
diff --git a/tier1/solid/src/solid/backends/udisks2/udisksopticaldrive.cpp b/tier1/solid/src/solid/backends/udisks2/udisksopticaldrive.cpp
new file mode 100644
index 0000000..f4351a7
--- /dev/null
+++ b/tier1/solid/src/solid/backends/udisks2/udisksopticaldrive.cpp
@@ -0,0 +1,222 @@
+/*
+    Copyright 2010 Michael Zanetti <mzanetti@kde.org>
+    Copyright 2010-2012 Lukáš Tinkl <ltinkl@redhat.com>
+
+    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 <http://www.gnu.org/licenses/>.
+*/
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#include <QtCore/QFile>
+#include <QtCore/QDebug>
+
+#include "udisksopticaldrive.h"
+#include "udisks2.h"
+#include "udisksdevice.h"
+#include "dbus/manager.h"
+
+using namespace Solid::Backends::UDisks2;
+
+OpticalDrive::OpticalDrive(Device *device)
+    : StorageDrive(device), m_ejectInProgress(false), m_readSpeed(0), m_writeSpeed(0), m_speedsInit(false)
+{
+    m_device->registerAction("eject", this,
+                             SLOT(slotEjectRequested()),
+                             SLOT(slotEjectDone(int, const QString&)));
+
+    connect(m_device, SIGNAL(changed()), this, SLOT(slotChanged()));
+}
+
+OpticalDrive::~OpticalDrive()
+{
+}
+
+bool OpticalDrive::eject()
+{
+    if (m_ejectInProgress)
+        return false;
+    m_ejectInProgress = true;
+    m_device->broadcastActionRequested("eject");
+
+    const QString path = m_device->udi();
+    QDBusConnection c = QDBusConnection::systemBus();
+
+    // if the device is mounted, unmount first
+    QString blockPath;
+    org::freedesktop::DBus::ObjectManager manager(UD2_DBUS_SERVICE, UD2_DBUS_PATH, c);
+    QDBusPendingReply<DBUSManagerStruct> reply = manager.GetManagedObjects();
+    reply.waitForFinished();
+    if (!reply.isError()) {  // enum devices
+        Q_FOREACH(const QDBusObjectPath &objPath, reply.value().keys()) {
+            const QString udi = objPath.path();
+
+            //qDebug() << "Inspecting" << udi;
+
+            if (udi == UD2_DBUS_PATH_MANAGER || udi == UD2_UDI_DISKS_PREFIX || udi.startsWith(UD2_DBUS_PATH_JOBS))
+                continue;
+
+            Device device(udi);
+            if (device.drivePath() == path && device.isMounted()) {
+                //qDebug() << "Got mounted block device:" << udi;
+                blockPath = udi;
+                break;
+            }
+        }
+    }
+    else  // show error
+    {
+        qWarning() << "Failed enumerating UDisks2 objects:" << reply.error().name() << "\n" << reply.error().message();
+    }
+
+    if (!blockPath.isEmpty()) {
+        //qDebug() << "Calling unmount on" << blockPath;
+        QDBusMessage msg = QDBusMessage::createMethodCall(UD2_DBUS_SERVICE, blockPath, UD2_DBUS_INTERFACE_FILESYSTEM, "Unmount");
+        msg << QVariantMap();   // options, unused now
+        c.call(msg, QDBus::BlockWithGui);
+    }
+
+    QDBusMessage msg = QDBusMessage::createMethodCall(UD2_DBUS_SERVICE, path, UD2_DBUS_INTERFACE_DRIVE, "Eject");
+    msg << QVariantMap();
+    return c.callWithCallback(msg, this, SLOT(slotDBusReply(const QDBusMessage &)), SLOT(slotDBusError(const QDBusError &)));
+}
+
+void OpticalDrive::slotDBusReply(const QDBusMessage &/*reply*/)
+{
+    m_ejectInProgress = false;
+    m_device->broadcastActionDone("eject");
+}
+
+void OpticalDrive::slotDBusError(const QDBusError &error)
+{
+    m_ejectInProgress = false;
+    m_device->broadcastActionDone("eject", m_device->errorToSolidError(error.name()),
+                                  m_device->errorToString(error.name()) + ": " +error.message());
+}
+
+void OpticalDrive::slotEjectRequested()
+{
+    m_ejectInProgress = true;
+    Q_EMIT ejectRequested(m_device->udi());
+}
+
+void OpticalDrive::slotEjectDone(int error, const QString &errorString)
+{
+    m_ejectInProgress = false;
+    Q_EMIT ejectDone(static_cast<Solid::ErrorType>(error), errorString, m_device->udi());
+}
+
+void OpticalDrive::initReadWriteSpeeds() const
+{
+#if 0
+    int read_speed, write_speed;
+    char *write_speeds = 0;
+    QByteArray device_file = QFile::encodeName(m_device->property("Device").toString());
+
+    //qDebug("Doing open (\"%s\", O_RDONLY | O_NONBLOCK)", device_file.constData());
+    int fd = open(device_file, O_RDONLY | O_NONBLOCK);
+    if (fd < 0) {
+        qWarning("Cannot open %s: %s", device_file.constData(), strerror (errno));
+        return;
+    }
+
+    if (get_read_write_speed(fd, &read_speed, &write_speed, &write_speeds) >= 0) {
+        m_readSpeed = read_speed;
+        m_writeSpeed = write_speed;
+
+        QStringList list = QString::fromLatin1(write_speeds).split(',', QString::SkipEmptyParts);
+        Q_FOREACH (const QString & speed, list)
+            m_writeSpeeds.append(speed.toInt());
+
+        free(write_speeds);
+
+        m_speedsInit = true;
+    }
+
+    close(fd);
+#endif
+}
+
+QList<int> OpticalDrive::writeSpeeds() const
+{
+    if (!m_speedsInit)
+        initReadWriteSpeeds();
+    //qDebug() << "solid write speeds:" << m_writeSpeeds;
+    return m_writeSpeeds;
+}
+
+int OpticalDrive::writeSpeed() const
+{
+    if (!m_speedsInit)
+        initReadWriteSpeeds();
+    return m_writeSpeed;
+}
+
+int OpticalDrive::readSpeed() const
+{
+    if (!m_speedsInit)
+        initReadWriteSpeeds();
+    return m_readSpeed;
+}
+
+Solid::OpticalDrive::MediumTypes OpticalDrive::supportedMedia() const
+{
+    const QStringList mediaTypes = m_device->prop("MediaCompatibility").toStringList();
+    Solid::OpticalDrive::MediumTypes supported;
+
+    QMap<Solid::OpticalDrive::MediumType, QString> map;
+    map[Solid::OpticalDrive::Cdr] = "optical_cd_r";
+    map[Solid::OpticalDrive::Cdrw] = "optical_cd_rw";
+    map[Solid::OpticalDrive::Dvd] = "optical_dvd";
+    map[Solid::OpticalDrive::Dvdr] = "optical_dvd_r";
+    map[Solid::OpticalDrive::Dvdrw] ="optical_dvd_rw";
+    map[Solid::OpticalDrive::Dvdram] ="optical_dvd_ram";
+    map[Solid::OpticalDrive::Dvdplusr] ="optical_dvd_plus_r";
+    map[Solid::OpticalDrive::Dvdplusrw] ="optical_dvd_plus_rw";
+    map[Solid::OpticalDrive::Dvdplusdl] ="optical_dvd_plus_r_dl";
+    map[Solid::OpticalDrive::Dvdplusdlrw] ="optical_dvd_plus_rw_dl";
+    map[Solid::OpticalDrive::Bd] ="optical_bd";
+    map[Solid::OpticalDrive::Bdr] ="optical_bd_r";
+    map[Solid::OpticalDrive::Bdre] ="optical_bd_re";
+    map[Solid::OpticalDrive::HdDvd] ="optical_hddvd";
+    map[Solid::OpticalDrive::HdDvdr] ="optical_hddvd_r";
+    map[Solid::OpticalDrive::HdDvdrw] ="optical_hddvd_rw";
+    // TODO add these to Solid
+    //map[Solid::OpticalDrive::Mo] ="optical_mo";
+    //map[Solid::OpticalDrive::Mr] ="optical_mrw";
+    //map[Solid::OpticalDrive::Mrw] ="optical_mrw_w";
+
+    Q_FOREACH ( const Solid::OpticalDrive::MediumType & type, map.keys() )
+    {
+        if ( mediaTypes.contains( map[type] ) )
+        {
+            supported |= type;
+        }
+    }
+
+    return supported;
+}
+
+void OpticalDrive::slotChanged()
+{
+    m_speedsInit = false; // reset the read/write speeds, changes eg. with an inserted media
+}
diff --git a/tier1/solid/src/solid/backends/udisks2/udisksopticaldrive.h b/tier1/solid/src/solid/backends/udisks2/udisksopticaldrive.h
new file mode 100644
index 0000000..4c98ef5
--- /dev/null
+++ b/tier1/solid/src/solid/backends/udisks2/udisksopticaldrive.h
@@ -0,0 +1,81 @@
+/*
+    Copyright 2010 Michael Zanetti <mzanetti@kde.org>
+    Copyright 2010-2012 Lukáš Tinkl <ltinkl@redhat.com>
+
+    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 <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef UDISKS2OPTICALDRIVE_H
+#define UDISKS2OPTICALDRIVE_H
+
+#include <solid/ifaces/opticaldrive.h>
+#include "udisksstoragedrive.h"
+
+namespace Solid
+{
+namespace Backends
+{
+namespace UDisks2
+{
+
+class OpticalDrive: public StorageDrive, virtual public Solid::Ifaces::OpticalDrive
+{
+    Q_OBJECT
+    Q_INTERFACES(Solid::Ifaces::OpticalDrive)
+
+public:
+    OpticalDrive(Device *device);
+    virtual ~OpticalDrive();
+
+Q_SIGNALS:
+    void ejectPressed(const QString &udi);
+    void ejectDone(Solid::ErrorType error, QVariant errorData, const QString &udi);
+    void ejectRequested(const QString &udi);
+
+public:
+    virtual bool eject();
+    virtual QList<int> writeSpeeds() const;
+    virtual int writeSpeed() const;
+    virtual int readSpeed() const;
+    virtual Solid::OpticalDrive::MediumTypes supportedMedia() const;
+
+private Q_SLOTS:
+    void slotDBusReply(const QDBusMessage &reply);
+    void slotDBusError(const QDBusError &error);
+
+    void slotEjectRequested();
+    void slotEjectDone(int error, const QString &errorString);
+
+    void slotChanged();
+
+private:
+    void initReadWriteSpeeds() const;
+
+    bool m_ejectInProgress;
+
+    // read/write speeds
+    mutable int m_readSpeed;
+    mutable int m_writeSpeed;
+    mutable QList<int> m_writeSpeeds;
+    mutable bool m_speedsInit;
+};
+
+}
+}
+}
+
+#endif // UDISKS2OPTICALDRIVE_H
diff --git a/tier1/solid/src/solid/backends/udisks2/udisksstorageaccess.cpp b/tier1/solid/src/solid/backends/udisks2/udisksstorageaccess.cpp
new file mode 100644
index 0000000..c2af2b0
--- /dev/null
+++ b/tier1/solid/src/solid/backends/udisks2/udisksstorageaccess.cpp
@@ -0,0 +1,360 @@
+/*
+    Copyright 2009 Pino Toscano <pino@kde.org>
+    Copyright 2009-2012 Lukáš Tinkl <ltinkl@redhat.com>
+
+    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 <http://www.gnu.org/licenses/>.
+*/
+
+#include "udisksstorageaccess.h"
+#include "udisks2.h"
+
+#include <QtCore/QProcess>
+#include <QtDBus/QtDBus>
+#include <QtGui/QApplication>
+#include <QtGui/QWidget>
+
+using namespace Solid::Backends::UDisks2;
+
+StorageAccess::StorageAccess(Device *device)
+    : DeviceInterface(device), m_setupInProgress(false), m_teardownInProgress(false), m_passphraseRequested(false)
+{
+    connect(device, SIGNAL(changed()), this, SLOT(checkAccessibility()));
+    updateCache();
+
+    // Delay connecting to DBus signals to avoid the related time penalty
+    // in hot paths such as predicate matching
+    QTimer::singleShot(0, this, SLOT(connectDBusSignals()));
+}
+
+StorageAccess::~StorageAccess()
+{
+}
+
+void StorageAccess::connectDBusSignals()
+{
+    m_device->registerAction("setup", this,
+                             SLOT(slotSetupRequested()),
+                             SLOT(slotSetupDone(int, const QString&)));
+
+    m_device->registerAction("teardown", this,
+                             SLOT(slotTeardownRequested()),
+                             SLOT(slotTeardownDone(int, const QString&)));
+}
+
+bool StorageAccess::isLuksDevice() const
+{
+    return m_device->isEncryptedContainer(); // encrypted device
+}
+
+bool StorageAccess::isAccessible() const
+{
+    if (isLuksDevice()) { // check if the cleartext slave is mounted
+        if (m_clearTextPath.isEmpty() || m_clearTextPath == "/")
+            return false;
+        Device holderDevice(m_clearTextPath);
+        return holderDevice.isMounted();
+    }
+
+    return m_device->isMounted();
+}
+
+QString StorageAccess::filePath() const
+{
+    if (!isAccessible())
+        return QString();
+
+    QByteArrayList mntPoints;
+
+    if (isLuksDevice()) {  // encrypted (and unlocked) device
+        if (m_clearTextPath.isEmpty() || m_clearTextPath == "/")
+            return QString();
+        Device holderDevice(m_clearTextPath);
+        mntPoints = qdbus_cast<QByteArrayList>(holderDevice.prop("MountPoints"));
+        if (!mntPoints.isEmpty())
+            return QFile::decodeName(mntPoints.first()); // FIXME Solid doesn't support multiple mount points
+        else
+            return QString();
+    }
+
+    mntPoints = qdbus_cast<QByteArrayList>(m_device->prop("MountPoints"));
+
+    if (!mntPoints.isEmpty())
+        return QFile::decodeName(mntPoints.first()); // FIXME Solid doesn't support multiple mount points
+    else
+        return QString();
+}
+
+bool StorageAccess::isIgnored() const
+{
+    return m_device->prop("HintIgnore").toBool(); // FIXME tune
+}
+
+bool StorageAccess::setup()
+{
+    if ( m_teardownInProgress || m_setupInProgress )
+        return false;
+    m_setupInProgress = true;
+    m_device->broadcastActionRequested("setup");
+
+    if (m_device->isEncryptedContainer())
+        return requestPassphrase();
+    else
+        return mount();
+}
+
+bool StorageAccess::teardown()
+{
+    if ( m_teardownInProgress || m_setupInProgress )
+        return false;
+    m_teardownInProgress = true;
+    m_device->broadcastActionRequested("teardown");
+
+    return unmount();
+}
+
+void StorageAccess::updateCache()
+{
+    m_isAccessible = isAccessible();
+}
+
+void StorageAccess::checkAccessibility()
+{
+    const bool old_isAccessible = m_isAccessible;
+    updateCache();
+
+    if (old_isAccessible != m_isAccessible) {
+        Q_EMIT accessibilityChanged(m_isAccessible, isLuksDevice() ? m_clearTextPath : m_device->udi());
+    }
+}
+
+void StorageAccess::slotDBusReply( const QDBusMessage & reply )
+{
+    if (m_setupInProgress)
+    {
+        if (isLuksDevice() && !isAccessible()) { // unlocked device, now mount it
+            if (reply.type() == QDBusMessage::ReplyMessage)  // we've got a response from Unlock
+                m_clearTextPath = reply.arguments().value(0).value<QDBusObjectPath>().path();
+            mount();
+        }
+        else // Don't broadcast setupDone unless the setup is really done. (Fix kde#271156)
+        {
+            m_setupInProgress = false;
+            m_device->broadcastActionDone("setup");
+
+            checkAccessibility();
+        }
+    }
+    else if (m_teardownInProgress)  // FIXME
+    {
+        if (isLuksDevice() && !m_clearTextPath.isEmpty() && m_clearTextPath != "/") // unlocked device, lock it
+        {
+            callCryptoTeardown();
+        }
+        else if (!m_clearTextPath.isEmpty() && m_clearTextPath != "/") {
+            callCryptoTeardown(true); // Lock crypted parent
+        }
+        else
+        {
+            // try to "eject" (aka safely remove) from the (parent) drive, e.g. SD card from a reader
+            QString drivePath = m_device->prop("Drive").value<QDBusObjectPath>().path();
+            if (!drivePath.isEmpty() || drivePath != "/")
+            {
+                Device drive(drivePath);
+                if (drive.prop("Ejectable").toBool() && !m_device->isOpticalDisc()) // optical drives have their Eject method
+                {
+                    QDBusConnection c = QDBusConnection::systemBus();
+                    QDBusMessage msg = QDBusMessage::createMethodCall(UD2_DBUS_SERVICE, drivePath, UD2_DBUS_INTERFACE_DRIVE, "Eject");
+                    msg << QVariantMap();   // options, unused now
+                    c.call(msg, QDBus::NoBlock);
+                }
+            }
+
+            m_teardownInProgress = false;
+            m_device->broadcastActionDone("teardown");
+
+            checkAccessibility();
+        }
+    }
+}
+
+void StorageAccess::slotDBusError( const QDBusError & error )
+{
+    if (m_setupInProgress)
+    {
+        m_setupInProgress = false;
+        m_device->broadcastActionDone("setup", m_device->errorToSolidError(error.name()),
+                                      m_device->errorToString(error.name()) + ": " +error.message());
+
+        checkAccessibility();
+    }
+    else if (m_teardownInProgress)
+    {
+        m_teardownInProgress = false;
+        m_clearTextPath.clear();
+        m_device->broadcastActionDone("teardown", m_device->errorToSolidError(error.name()),
+                                      m_device->errorToString(error.name()) + ": " + error.message());
+        checkAccessibility();
+    }
+}
+
+void StorageAccess::slotSetupRequested()
+{
+    m_setupInProgress = true;
+    //qDebug() << "SETUP REQUESTED:" << m_device->udi();
+    Q_EMIT setupRequested(m_device->udi());
+}
+
+void StorageAccess::slotSetupDone(int error, const QString &errorString)
+{
+    m_setupInProgress = false;
+    //qDebug() << "SETUP DONE:" << m_device->udi();
+    Q_EMIT setupDone(static_cast<Solid::ErrorType>(error), errorString, m_device->udi());
+
+    checkAccessibility();
+}
+
+void StorageAccess::slotTeardownRequested()
+{
+    m_teardownInProgress = true;
+    Q_EMIT teardownRequested(m_device->udi());
+}
+
+void StorageAccess::slotTeardownDone(int error, const QString &errorString)
+{
+    m_teardownInProgress = false;
+    m_clearTextPath.clear();
+    Q_EMIT teardownDone(static_cast<Solid::ErrorType>(error), errorString, m_device->udi());
+
+    checkAccessibility();
+}
+
+bool StorageAccess::mount()
+{
+    QString path = m_device->udi();
+
+    if (isLuksDevice()) { // mount options for the cleartext volume
+        path = m_clearTextPath;
+    }
+
+    QDBusConnection c = QDBusConnection::systemBus();
+    QDBusMessage msg = QDBusMessage::createMethodCall(UD2_DBUS_SERVICE, path, UD2_DBUS_INTERFACE_FILESYSTEM, "Mount");
+    QVariantMap options;
+
+    if (m_device->prop("IdType").toString() == "vfat")
+        options.insert("options", "flush");
+
+    msg << options;
+
+    return c.callWithCallback(msg, this,
+                              SLOT(slotDBusReply(const QDBusMessage &)),
+                              SLOT(slotDBusError(const QDBusError &)));
+}
+
+bool StorageAccess::unmount()
+{
+    QString path = m_device->udi();
+
+    if (isLuksDevice()) { // unmount options for the cleartext volume
+        path = m_clearTextPath;
+    }
+
+    QDBusConnection c = QDBusConnection::systemBus();
+    QDBusMessage msg = QDBusMessage::createMethodCall(UD2_DBUS_SERVICE, path, UD2_DBUS_INTERFACE_FILESYSTEM, "Unmount");
+
+    msg << QVariantMap();   // options, unused now
+
+    return c.callWithCallback(msg, this,
+                              SLOT(slotDBusReply(const QDBusMessage &)),
+                              SLOT(slotDBusError(const QDBusError &)),
+                              s_unmountTimeout);
+}
+
+QString StorageAccess::generateReturnObjectPath()
+{
+    static int number = 1;
+
+    return "/org/kde/solid/UDisks2StorageAccess_"+QString::number(number++);
+}
+
+bool StorageAccess::requestPassphrase()
+{
+    QString udi = m_device->udi();
+    QString returnService = QDBusConnection::sessionBus().baseService();
+    m_lastReturnObject = generateReturnObjectPath();
+
+    QDBusConnection::sessionBus().registerObject(m_lastReturnObject, this, QDBusConnection::ExportScriptableSlots);
+
+    QWidget *activeWindow = QApplication::activeWindow();
+    uint wId = 0;
+    if (activeWindow!=0)
+        wId = (uint)activeWindow->winId();
+
+    QString appId = QCoreApplication::applicationName();
+
+    QDBusInterface soliduiserver("org.kde.kded5", "/modules/soliduiserver", "org.kde.SolidUiServer");
+    QDBusReply<void> reply = soliduiserver.call("showPassphraseDialog", udi, returnService,
+                                                m_lastReturnObject, wId, appId);
+    m_passphraseRequested = reply.isValid();
+    if (!m_passphraseRequested)
+        qWarning() << "Failed to call the SolidUiServer, D-Bus said:" << reply.error();
+
+    return m_passphraseRequested;
+}
+
+void StorageAccess::passphraseReply(const QString & passphrase)
+{
+    if (m_passphraseRequested)
+    {
+        QDBusConnection::sessionBus().unregisterObject(m_lastReturnObject);
+        m_passphraseRequested = false;
+        if (!passphrase.isEmpty())
+            callCryptoSetup(passphrase);
+        else
+        {
+            m_setupInProgress = false;
+            m_device->broadcastActionDone("setup");
+        }
+    }
+}
+
+void StorageAccess::callCryptoSetup(const QString & passphrase)
+{
+    QDBusConnection c = QDBusConnection::systemBus();
+    QDBusMessage msg = QDBusMessage::createMethodCall(UD2_DBUS_SERVICE, m_device->udi(), UD2_DBUS_INTERFACE_ENCRYPTED, "Unlock");
+
+    msg << passphrase;
+    msg << QVariantMap();   // options, unused now
+
+    c.callWithCallback(msg, this,
+                       SLOT(slotDBusReply(const QDBusMessage &)),
+                       SLOT(slotDBusError(const QDBusError &)));
+}
+
+bool StorageAccess::callCryptoTeardown(bool actOnParent)
+{
+    QDBusConnection c = QDBusConnection::systemBus();
+    QDBusMessage msg = QDBusMessage::createMethodCall(UD2_DBUS_SERVICE,
+                                                      actOnParent ? (m_device->prop("CryptoBackingDevice").value<QDBusObjectPath>().path()) : m_device->udi(),
+                                                      UD2_DBUS_INTERFACE_ENCRYPTED, "Lock");
+    msg << QVariantMap();   // options, unused now
+
+    m_clearTextPath.clear();
+
+    return c.callWithCallback(msg, this,
+                              SLOT(slotDBusReply(const QDBusMessage &)),
+                              SLOT(slotDBusError(const QDBusError &)));
+}
diff --git a/tier1/solid/src/solid/backends/udisks2/udisksstorageaccess.h b/tier1/solid/src/solid/backends/udisks2/udisksstorageaccess.h
new file mode 100644
index 0000000..2901067
--- /dev/null
+++ b/tier1/solid/src/solid/backends/udisks2/udisksstorageaccess.h
@@ -0,0 +1,104 @@
+/*
+    Copyright 2009 Pino Toscano <pino@kde.org>
+    Copyright 2009-2012 Lukáš Tinkl <ltinkl@redhat.com>
+
+    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 <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef UDISKS2STORAGEACCESS_H
+#define UDISKS2STORAGEACCESS_H
+
+#include <solid/ifaces/storageaccess.h>
+#include "udisksdeviceinterface.h"
+
+#include <QtDBus/QDBusMessage>
+#include <QtDBus/QDBusError>
+
+namespace Solid
+{
+namespace Backends
+{
+namespace UDisks2
+{
+class StorageAccess : public DeviceInterface, virtual public Solid::Ifaces::StorageAccess
+{
+    Q_OBJECT
+    Q_INTERFACES(Solid::Ifaces::StorageAccess)
+
+public:
+    StorageAccess(Device *device);
+    virtual ~StorageAccess();
+
+    virtual bool isAccessible() const;
+    virtual QString filePath() const;
+    virtual bool isIgnored() const;
+    virtual bool setup();
+    virtual bool teardown();
+
+Q_SIGNALS:
+    void accessibilityChanged(bool accessible, const QString &udi);
+    void setupDone(Solid::ErrorType error, QVariant errorData, const QString &udi);
+    void teardownDone(Solid::ErrorType error, QVariant errorData, const QString &udi);
+    void setupRequested(const QString &udi);
+    void teardownRequested(const QString &udi);
+
+public Q_SLOTS:
+    Q_SCRIPTABLE Q_NOREPLY void passphraseReply(const QString & passphrase);
+
+private Q_SLOTS:
+    void slotDBusReply(const QDBusMessage & reply);
+    void slotDBusError(const QDBusError & error);
+
+    void connectDBusSignals();
+
+    void slotSetupRequested();
+    void slotSetupDone(int error, const QString &errorString);
+    void slotTeardownRequested();
+    void slotTeardownDone(int error, const QString &errorString);
+
+    void checkAccessibility();
+
+private:
+    /// @return true if this device is luks and unlocked
+    bool isLuksDevice() const;
+
+    void updateCache();
+
+    bool mount();
+    bool unmount();
+
+    bool requestPassphrase();
+    void callCryptoSetup( const QString & passphrase );
+    bool callCryptoTeardown( bool actOnParent=false );
+
+    QString generateReturnObjectPath();
+
+private:
+    bool m_isAccessible;
+    bool m_setupInProgress;
+    bool m_teardownInProgress;
+    bool m_passphraseRequested;
+    QString m_lastReturnObject;
+    QString m_clearTextPath;  // path to the unlocked cleartext device
+
+    static const int s_unmountTimeout = 0x7fffffff;
+};
+}
+}
+}
+
+#endif // UDISKS2STORAGEACCESS_H
diff --git a/tier1/solid/src/solid/backends/udisks2/udisksstoragedrive.cpp b/tier1/solid/src/solid/backends/udisks2/udisksstoragedrive.cpp
new file mode 100644
index 0000000..c79ac20
--- /dev/null
+++ b/tier1/solid/src/solid/backends/udisks2/udisksstoragedrive.cpp
@@ -0,0 +1,147 @@
+/*
+    Copyright 2010 Michael Zanetti <mzanetti@kde.org>
+    Copyright 2010-2012 Lukáš Tinkl <ltinkl@redhat.com>
+
+    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 <http://www.gnu.org/licenses/>.
+*/
+
+#include "udisksstoragedrive.h"
+
+#include "../shared/udevqtclient.h"
+
+#include <QtCore/QDebug>
+#include <QtCore/QFile>
+
+using namespace Solid::Backends::UDisks2;
+
+StorageDrive::StorageDrive(Device *dev)
+    : Block(dev)
+{
+    UdevQt::Client client(this);
+    m_udevDevice = client.deviceByDeviceFile(device());
+    m_udevDevice.deviceProperties();
+}
+
+StorageDrive::~StorageDrive()
+{
+}
+
+qulonglong StorageDrive::size() const
+{
+    return m_device->prop("Size").toULongLong();
+}
+
+bool StorageDrive::isHotpluggable() const
+{
+    const Solid::StorageDrive::Bus _bus = bus();
+    return _bus == Solid::StorageDrive::Usb || _bus == Solid::StorageDrive::Ieee1394;
+}
+
+bool StorageDrive::isRemovable() const
+{
+    return m_device->prop("MediaRemovable").toBool() || m_device->prop("Removable").toBool();
+}
+
+Solid::StorageDrive::DriveType StorageDrive::driveType() const
+{
+    const QStringList mediaTypes = m_device->prop("MediaCompatibility").toStringList();
+
+    if ( m_device->isOpticalDrive() ) // optical disks
+    {
+        return Solid::StorageDrive::CdromDrive;
+    }
+    else if ( mediaTypes.contains( "floppy" ) )
+    {
+        return Solid::StorageDrive::Floppy;
+    }
+#if 0 // TODO add to Solid
+    else if ( mediaTypes.contains( "floppy_jaz" ) )
+    {
+        return Solid::StorageDrive::Jaz;
+    }
+    else if ( mediaTypes.contains( "floppy_zip" ) )
+    {
+        return Solid::StorageDrive::Zip;
+    }
+    else if ( mediaTypes.contains( "flash" ) )
+    {
+        return Solid::StorageDrive::Flash;
+    }
+#endif
+    else if ( mediaTypes.contains( "flash_cf" ) )
+    {
+        return Solid::StorageDrive::CompactFlash;
+    }
+    else if ( mediaTypes.contains( "flash_ms" ) )
+    {
+        return Solid::StorageDrive::MemoryStick;
+    }
+    else if ( mediaTypes.contains( "flash_sm" ) )
+    {
+        return Solid::StorageDrive::SmartMedia;
+    }
+    else if ( mediaTypes.contains( "flash_sd" ) || mediaTypes.contains( "flash_sdhc" )
+              || mediaTypes.contains( "flash_mmc" ) || mediaTypes.contains("flash_sdxc") )
+    {
+        return Solid::StorageDrive::SdMmc;
+    }
+    // FIXME: udisks2 doesn't know about xD cards
+    else
+    {
+        return Solid::StorageDrive::HardDisk;
+    }
+}
+
+Solid::StorageDrive::Bus StorageDrive::bus() const
+{
+    const QString bus = m_device->prop("ConnectionBus").toString();
+    const QString udevBus = m_udevDevice.deviceProperty("ID_BUS").toString();
+
+    //qDebug() << "bus:" << bus << "udev bus:" << udevBus;
+
+    if (udevBus == "ata")
+    {
+        if (m_udevDevice.deviceProperty("ID_ATA_SATA").toInt() == 1) // serial ATA
+            return Solid::StorageDrive::Sata;
+        else  // parallel (classical) ATA
+            return Solid::StorageDrive::Ide;
+    }
+    else if (bus == "usb")
+    {
+        return Solid::StorageDrive::Usb;
+    }
+    else if (bus == "ieee1394")
+    {
+        return Solid::StorageDrive::Ieee1394;
+    }
+    else if (udevBus == "scsi")
+    {
+        return Solid::StorageDrive::Scsi;
+    }
+#if 0  // TODO add these to Solid
+    else if ( bus == "sdio" )
+    {
+        return Solid::StorageDrive::SDIO;
+    }
+    else if ( bus == "virtual" )
+    {
+        return Solid::StorageDrive::Virtual;
+    }
+#endif
+    else
+        return Solid::StorageDrive::Platform;
+}
diff --git a/tier1/solid/src/solid/backends/udisks2/udisksstoragedrive.h b/tier1/solid/src/solid/backends/udisks2/udisksstoragedrive.h
new file mode 100644
index 0000000..9c87a23
--- /dev/null
+++ b/tier1/solid/src/solid/backends/udisks2/udisksstoragedrive.h
@@ -0,0 +1,61 @@
+/*
+    Copyright 2010 Michael Zanetti <mzanetti@kde.org>
+    Copyright 2010-2012 Lukáš Tinkl <ltinkl@redhat.com>
+
+    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 <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef UDISKS2STORAGEDRIVE_H
+#define UDISKS2STORAGEDRIVE_H
+
+#include <ifaces/storagedrive.h>
+
+#include "../shared/udevqtdevice.h"
+
+#include "udisksblock.h"
+
+namespace Solid
+{
+namespace Backends
+{
+namespace UDisks2
+{
+
+class StorageDrive: public Block, virtual public Solid::Ifaces::StorageDrive
+{
+    Q_OBJECT
+    Q_INTERFACES(Solid::Ifaces::StorageDrive)
+
+public:
+    StorageDrive(Device *dev);
+    virtual ~StorageDrive();
+
+    virtual qulonglong size() const;
+    virtual bool isHotpluggable() const;
+    virtual bool isRemovable() const;
+    virtual Solid::StorageDrive::DriveType driveType() const;
+    virtual Solid::StorageDrive::Bus bus() const;
+
+private:
+    UdevQt::Device m_udevDevice;
+};
+
+}
+}
+}
+
+#endif // UDISK2SSTORAGEDRIVE_H
diff --git a/tier1/solid/src/solid/backends/udisks2/udisksstoragevolume.cpp b/tier1/solid/src/solid/backends/udisks2/udisksstoragevolume.cpp
new file mode 100644
index 0000000..a7d8fad
--- /dev/null
+++ b/tier1/solid/src/solid/backends/udisks2/udisksstoragevolume.cpp
@@ -0,0 +1,105 @@
+/*
+    Copyright 2010 Michael Zanetti <mzanetti@kde.org>
+    Copyright 2010-2012 Lukáš Tinkl <ltinkl@redhat.com>
+
+    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 <http://www.gnu.org/licenses/>.
+*/
+
+#include "udisksstoragevolume.h"
+#include "udisks2.h"
+
+using namespace Solid::Backends::UDisks2;
+
+StorageVolume::StorageVolume(Device *device)
+    : Block(device)
+{
+}
+
+StorageVolume::~StorageVolume()
+{
+}
+
+QString StorageVolume::encryptedContainerUdi() const
+{
+    const QString path = m_device->prop("CryptoBackingDevice").value<QDBusObjectPath>().path();
+    if ( path.isEmpty() || path == "/")
+        return QString();
+    else
+        return path;
+}
+
+qulonglong StorageVolume::size() const
+{
+    return m_device->prop("Size").toULongLong();
+}
+
+QString StorageVolume::uuid() const
+{
+    return m_device->prop("IdUUID").toString();
+}
+
+QString StorageVolume::label() const
+{
+    QString label = m_device->prop("HintName").toString();
+    if (label.isEmpty())
+        label = m_device->prop("IdLabel").toString();
+    if (label.isEmpty())
+        label = m_device->prop("Name").toString();
+    return label;
+}
+
+QString StorageVolume::fsType() const
+{
+    return m_device->prop("IdType").toString();
+}
+
+Solid::StorageVolume::UsageType StorageVolume::usage() const
+{
+    const QString usage = m_device->prop("IdUsage").toString();
+
+    if (m_device->hasInterface(UD2_DBUS_INTERFACE_FILESYSTEM))
+    {
+        return Solid::StorageVolume::FileSystem;
+    }
+    else if (m_device->isPartitionTable())
+    {
+        return Solid::StorageVolume::PartitionTable;
+    }
+    else if (usage == "raid")
+    {
+        return Solid::StorageVolume::Raid;
+    }
+    else if (m_device->isEncryptedContainer())
+    {
+        return Solid::StorageVolume::Encrypted;
+    }
+    else if (usage == "unused" || usage.isEmpty())
+    {
+        return Solid::StorageVolume::Unused;
+    }
+    else
+    {
+        return Solid::StorageVolume::Other;
+    }
+}
+
+bool StorageVolume::isIgnored() const
+{
+    const Solid::StorageVolume::UsageType usg = usage();
+    return m_device->prop("HintIgnore").toBool() || m_device->isSwap() ||
+            ((usg == Solid::StorageVolume::Unused || usg == Solid::StorageVolume::Other || usg == Solid::StorageVolume::PartitionTable) && !m_device->isOpticalDisc());
+}
diff --git a/tier1/solid/src/solid/backends/udisks2/udisksstoragevolume.h b/tier1/solid/src/solid/backends/udisks2/udisksstoragevolume.h
new file mode 100644
index 0000000..2ca04d2
--- /dev/null
+++ b/tier1/solid/src/solid/backends/udisks2/udisksstoragevolume.h
@@ -0,0 +1,57 @@
+/*
+    Copyright 2010 Michael Zanetti <mzanetti@kde.org>
+
+    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 <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef UDISKS2STORAGEVOLUME_H
+#define UDISKS2STORAGEVOLUME_H
+
+#include <ifaces/storagevolume.h>
+#include "udisksblock.h"
+
+
+namespace Solid
+{
+namespace Backends
+{
+namespace UDisks2
+{
+
+class StorageVolume: public Block, virtual public Solid::Ifaces::StorageVolume
+{
+    Q_OBJECT
+    Q_INTERFACES(Solid::Ifaces::StorageVolume)
+
+public:
+    StorageVolume(Device *device);
+    virtual ~StorageVolume();
+
+    virtual QString encryptedContainerUdi() const;
+    virtual qulonglong size() const;
+    virtual QString uuid() const;
+    virtual QString label() const;
+    virtual QString fsType() const;
+    virtual Solid::StorageVolume::UsageType usage() const;
+    virtual bool isIgnored() const;
+};
+
+}
+}
+}
+
+#endif // UDISKS2STORAGEVOLUME_H