b54aa3a731
- Resolves #835107 - Unable to eject optical media using "Device notifier"
3560 lines
120 KiB
Diff
3560 lines
120 KiB
Diff
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
|