Magellan Linux

Contents of /trunk/kdelibs/patches/kdelibs-4.9.4-udisks2-backend.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1990 - (show annotations) (download)
Mon Dec 10 15:50:04 2012 UTC (11 years, 4 months ago) by niro
File size: 139746 byte(s)
-added udisks2 patches
1 diff --git a/solid/solid/CMakeLists.txt b/solid/solid/CMakeLists.txt
2 index 0aa7a43..b00e50a 100644
3 --- a/solid/solid/CMakeLists.txt
4 +++ b/solid/solid/CMakeLists.txt
5 @@ -1,6 +1,7 @@
6 set( EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR} )
7 add_subdirectory( ifaces )
8 include_directories( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} )
9 +include_directories( ${QT_QTDBUS_INCLUDE_DIR} )
10
11 if(WIN32)
12 include_directories( ${KDEWIN_INCLUDES} )
13 @@ -39,7 +40,6 @@ configure_file(config-processor.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-proce
14
15 file(MAKE_DIRECTORY
16 ${CMAKE_CURRENT_BINARY_DIR}/backends/fakehw
17 - ${CMAKE_CURRENT_BINARY_DIR}/backends/hal
18 ${CMAKE_CURRENT_BINARY_DIR}/backends/udev
19 ${CMAKE_CURRENT_BINARY_DIR}/backends/wmi
20 )
21 @@ -225,33 +225,6 @@ if(NOT WIN32 AND NOT APPLE)
22 endif( UDEV_FOUND )
23
24
25 - message(STATUS "Building Solid HAL backend." )
26 - set(solid_LIB_SRCS ${solid_LIB_SRCS}
27 - backends/hal/halacadapter.cpp
28 - backends/hal/halaudiointerface.cpp
29 - backends/hal/halbattery.cpp
30 - backends/hal/halblock.cpp
31 - backends/hal/halbutton.cpp
32 - backends/hal/halcamera.cpp
33 - backends/hal/halcdrom.cpp
34 - backends/hal/haldeviceinterface.cpp
35 - backends/hal/haldvbinterface.cpp
36 - backends/hal/halfstabhandling.cpp
37 - backends/hal/halgenericinterface.cpp
38 - backends/hal/haldevice.cpp
39 - backends/hal/halmanager.cpp
40 - backends/hal/halnetworkinterface.cpp
41 - backends/hal/halserialinterface.cpp
42 - backends/hal/halopticaldisc.cpp
43 - backends/hal/halportablemediaplayer.cpp
44 - backends/hal/halprocessor.cpp
45 - backends/hal/halstorageaccess.cpp
46 - backends/hal/halstorage.cpp
47 - backends/hal/halvideo.cpp
48 - backends/hal/halvolume.cpp
49 - backends/hal/halsmartcardreader.cpp
50 - )
51 -
52 message(STATUS "Building Solid UPower backend." )
53 set(solid_LIB_SRCS ${solid_LIB_SRCS}
54 backends/upower/upowermanager.cpp
55 @@ -264,19 +237,39 @@ if(NOT WIN32 AND NOT APPLE)
56
57 # FIXME: this should work on more Unix systems
58 if (CMAKE_SYSTEM_NAME MATCHES Linux)
59 - message(STATUS "Building Solid UDisks backend." )
60 - set(solid_LIB_SRCS ${solid_LIB_SRCS}
61 - backends/udisks/udisksmanager.cpp
62 - backends/udisks/udisksdevice.cpp
63 - backends/udisks/udisksblock.cpp
64 - backends/udisks/udisksstoragevolume.cpp
65 - backends/udisks/udisksdeviceinterface.cpp
66 - backends/udisks/udisksopticaldisc.cpp
67 - backends/udisks/udisksopticaldrive.cpp
68 - backends/udisks/udisksstoragedrive.cpp
69 - backends/udisks/udisksstorageaccess.cpp
70 - backends/udisks/udisksgenericinterface.cpp
71 - )
72 +
73 + if ( WITH_SOLID_UDISKS2 )
74 + message(STATUS "Building Solid UDisks2 backend." )
75 + add_definitions(-DWITH_SOLID_UDISKS2)
76 + set(solid_LIB_SRCS ${solid_LIB_SRCS}
77 + backends/udisks2/udisksmanager.cpp
78 + backends/udisks2/udisksdevice.cpp
79 + backends/udisks2/udisksdevicebackend.cpp
80 + backends/udisks2/udisksblock.cpp
81 + backends/udisks2/udisksstoragevolume.cpp
82 + backends/udisks2/udisksdeviceinterface.cpp
83 + backends/udisks2/udisksopticaldisc.cpp
84 + backends/udisks2/udisksopticaldrive.cpp
85 + backends/udisks2/udisksstoragedrive.cpp
86 + backends/udisks2/udisksstorageaccess.cpp
87 + backends/udisks2/udisksgenericinterface.cpp
88 + backends/udisks2/dbus/manager.cpp
89 + )
90 + else ( WITH_SOLID_UDISKS2 )
91 + message(STATUS "Building Solid UDisks backend." )
92 + set(solid_LIB_SRCS ${solid_LIB_SRCS}
93 + backends/udisks/udisksmanager.cpp
94 + backends/udisks/udisksdevice.cpp
95 + backends/udisks/udisksblock.cpp
96 + backends/udisks/udisksstoragevolume.cpp
97 + backends/udisks/udisksdeviceinterface.cpp
98 + backends/udisks/udisksopticaldisc.cpp
99 + backends/udisks/udisksopticaldrive.cpp
100 + backends/udisks/udisksstoragedrive.cpp
101 + backends/udisks/udisksstorageaccess.cpp
102 + backends/udisks/udisksgenericinterface.cpp
103 + )
104 + endif ( WITH_SOLID_UDISKS2 )
105 endif (CMAKE_SYSTEM_NAME MATCHES Linux)
106
107 message(STATUS "Building Solid fstab backend." )
108 diff --git a/solid/solid/backends/udisks2/dbus/manager.cpp b/solid/solid/backends/udisks2/dbus/manager.cpp
109 new file mode 100644
110 index 0000000..7ea4aa8
111 --- /dev/null
112 +++ b/solid/solid/backends/udisks2/dbus/manager.cpp
113 @@ -0,0 +1,26 @@
114 +/*
115 + * This file was generated by qdbusxml2cpp version 0.7
116 + * Command line was: qdbusxml2cpp -p manager manager.xml
117 + *
118 + * qdbusxml2cpp is Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
119 + *
120 + * This is an auto-generated file.
121 + * This file may have been hand-edited. Look for HAND-EDIT comments
122 + * before re-generating it.
123 + */
124 +
125 +#include "manager.h"
126 +
127 +/*
128 + * Implementation of interface class OrgFreedesktopDBusObjectManagerInterface
129 + */
130 +
131 +OrgFreedesktopDBusObjectManagerInterface::OrgFreedesktopDBusObjectManagerInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent)
132 + : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent)
133 +{
134 +}
135 +
136 +OrgFreedesktopDBusObjectManagerInterface::~OrgFreedesktopDBusObjectManagerInterface()
137 +{
138 +}
139 +
140 diff --git a/solid/solid/backends/udisks2/dbus/manager.h b/solid/solid/backends/udisks2/dbus/manager.h
141 new file mode 100644
142 index 0000000..11f0be8
143 --- /dev/null
144 +++ b/solid/solid/backends/udisks2/dbus/manager.h
145 @@ -0,0 +1,59 @@
146 +/*
147 + * This file was generated by qdbusxml2cpp version 0.7
148 + * Command line was: qdbusxml2cpp -p manager manager.xml
149 + *
150 + * qdbusxml2cpp is Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
151 + *
152 + * This is an auto-generated file.
153 + * Do not edit! All changes made to it will be lost.
154 + */
155 +
156 +#ifndef MANAGER_H_1329493525
157 +#define MANAGER_H_1329493525
158 +
159 +#include <QtCore/QObject>
160 +#include <QtCore/QByteArray>
161 +#include <QtCore/QList>
162 +#include <QtCore/QMap>
163 +#include <QtCore/QString>
164 +#include <QtCore/QStringList>
165 +#include <QtCore/QVariant>
166 +#include <QtDBus/QtDBus>
167 +
168 +#include "../udisks2.h"
169 +
170 +/*
171 + * Proxy class for interface org.freedesktop.DBus.ObjectManager
172 + */
173 +class OrgFreedesktopDBusObjectManagerInterface: public QDBusAbstractInterface
174 +{
175 + Q_OBJECT
176 +public:
177 + static inline const char *staticInterfaceName()
178 + { return "org.freedesktop.DBus.ObjectManager"; }
179 +
180 +public:
181 + OrgFreedesktopDBusObjectManagerInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0);
182 +
183 + ~OrgFreedesktopDBusObjectManagerInterface();
184 +
185 +public Q_SLOTS: // METHODS
186 + inline QDBusPendingReply<DBUSManagerStruct> GetManagedObjects()
187 + {
188 + QList<QVariant> argumentList;
189 + return asyncCallWithArgumentList(QLatin1String("GetManagedObjects"), argumentList);
190 + }
191 +
192 +Q_SIGNALS: // SIGNALS
193 + void InterfacesAdded(const QDBusObjectPath &object_path, const QVariantMapMap &interfaces_and_properties);
194 + void InterfacesRemoved(const QDBusObjectPath &object_path, const QStringList &interfaces);
195 +};
196 +
197 +namespace org {
198 + namespace freedesktop {
199 + namespace DBus {
200 + typedef ::OrgFreedesktopDBusObjectManagerInterface ObjectManager;
201 + }
202 + }
203 +}
204 +#endif
205 diff --git a/solid/solid/backends/udisks2/dbus/manager.xml b/solid/solid/backends/udisks2/dbus/manager.xml
206 new file mode 100644
207 index 0000000..8f25cb6
208 --- /dev/null
209 +++ b/solid/solid/backends/udisks2/dbus/manager.xml
210 @@ -0,0 +1,21 @@
211 +<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
212 + "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
213 +<node>
214 + <interface name="org.freedesktop.DBus.ObjectManager">
215 + <method name="GetManagedObjects">
216 + <arg type="a{oa{sa{sv}}}" name="object_paths_interfaces_and_properties" direction="out">
217 + <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="DBUSManagerStruct"/>
218 + </arg>
219 + </method>
220 + <signal name="InterfacesAdded">
221 + <arg type="o" name="object_path"/>
222 + <arg type="a{sa{sv}}" name="interfaces_and_properties">
223 + <annotation name="com.trolltech.QtDBus.QtTypeName.In1" value="QVariantMapMap"/>
224 + </arg>
225 + </signal>
226 + <signal name="InterfacesRemoved">
227 + <arg type="o" name="object_path"/>
228 + <arg type="as" name="interfaces"/>
229 + </signal>
230 + </interface>
231 +</node>
232 diff --git a/solid/solid/backends/udisks2/udisks2.h b/solid/solid/backends/udisks2/udisks2.h
233 new file mode 100644
234 index 0000000..8dda86a
235 --- /dev/null
236 +++ b/solid/solid/backends/udisks2/udisks2.h
237 @@ -0,0 +1,78 @@
238 +/*
239 + Copyright 2012 Lukáš Tinkl <ltinkl@redhat.com>
240 +
241 + This library is free software; you can redistribute it and/or
242 + modify it under the terms of the GNU Lesser General Public
243 + License as published by the Free Software Foundation; either
244 + version 2.1 of the License, or (at your option) version 3, or any
245 + later version accepted by the membership of KDE e.V. (or its
246 + successor approved by the membership of KDE e.V.), which shall
247 + act as a proxy defined in Section 6 of version 3 of the license.
248 +
249 + This library is distributed in the hope that it will be useful,
250 + but WITHOUT ANY WARRANTY; without even the implied warranty of
251 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
252 + Lesser General Public License for more details.
253 +
254 + You should have received a copy of the GNU Lesser General Public
255 + License along with this library. If not, see <http://www.gnu.org/licenses/>.
256 +*/
257 +
258 +#ifndef SOLID_BACKENDS_UDISKS2_H
259 +#define SOLID_BACKENDS_UDISKS2_H
260 +
261 +#include <QMetaType>
262 +#include <QtDBus>
263 +#include <QVariant>
264 +#include <QMap>
265 +#include <QList>
266 +
267 +typedef QList<QByteArray> QByteArrayList;
268 +Q_DECLARE_METATYPE(QByteArrayList)
269 +
270 +typedef QMap<QString,QVariantMap> QVariantMapMap;
271 +Q_DECLARE_METATYPE(QVariantMapMap)
272 +
273 +typedef QMap<QDBusObjectPath, QVariantMapMap> DBUSManagerStruct;
274 +Q_DECLARE_METATYPE(DBUSManagerStruct)
275 +
276 +/* UDisks2 */
277 +#define UD2_DBUS_SERVICE "org.freedesktop.UDisks2"
278 +#define UD2_DBUS_PATH "/org/freedesktop/UDisks2"
279 +#define UD2_UDI_DISKS_PREFIX "/org/freedesktop/UDisks2"
280 +#define UD2_DBUS_PATH_MANAGER "/org/freedesktop/UDisks2/Manager"
281 +#define UD2_DBUS_PATH_DRIVES "/org/freedesktop/UDisks2/drives/"
282 +#define UD2_DBUS_PATH_JOBS "/org/freedesktop/UDisks2/jobs/"
283 +#define DBUS_INTERFACE_PROPS "org.freedesktop.DBus.Properties"
284 +#define DBUS_INTERFACE_INTROSPECT "org.freedesktop.DBus.Introspectable"
285 +#define DBUS_INTERFACE_MANAGER "org.freedesktop.DBus.ObjectManager"
286 +#define UD2_DBUS_INTERFACE_BLOCK "org.freedesktop.UDisks2.Block"
287 +#define UD2_DBUS_INTERFACE_DRIVE "org.freedesktop.UDisks2.Drive"
288 +#define UD2_DBUS_INTERFACE_PARTITION "org.freedesktop.UDisks2.Partition"
289 +#define UD2_DBUS_INTERFACE_PARTITIONTABLE "org.freedesktop.UDisks2.PartitionTable"
290 +#define UD2_DBUS_INTERFACE_FILESYSTEM "org.freedesktop.UDisks2.Filesystem"
291 +#define UD2_DBUS_INTERFACE_ENCRYPTED "org.freedesktop.UDisks2.Encrypted"
292 +#define UD2_DBUS_INTERFACE_SWAP "org.freedesktop.UDisks2.Swapspace"
293 +#define UD2_DBUS_INTERFACE_LOOP "org.freedesktop.UDisks2.Loop"
294 +
295 +/* errors */
296 +#define UD2_ERROR_UNAUTHORIZED "org.freedesktop.PolicyKit.Error.NotAuthorized"
297 +#define UD2_ERROR_BUSY "org.freedesktop.UDisks2.Error.DeviceBusy"
298 +#define UD2_ERROR_FAILED "org.freedesktop.UDisks2.Error.Failed"
299 +#define UD2_ERROR_CANCELED "org.freedesktop.UDisks2.Error.Cancelled"
300 +#define UD2_ERROR_INVALID_OPTION "org.freedesktop.UDisks2.Error.OptionNotPermitted"
301 +#define UD2_ERROR_MISSING_DRIVER "org.freedesktop.UDisks2.Error.NotSupported"
302 +
303 +#define UD2_ERROR_ALREADY_MOUNTED "org.freedesktop.UDisks2.Error.AlreadyMounted"
304 +#define UD2_ERROR_NOT_MOUNTED "org.freedesktop.UDisks2.Error.NotMounted"
305 +#define UD2_ERROR_MOUNTED_BY_OTHER_USER "org.freedesktop.UDisks2.Error.MountedByOtherUser"
306 +#define UD2_ERROR_ALREADY_UNMOUNTING "org.freedesktop.UDisks2.Error.AlreadyUnmounting"
307 +#define UD2_ERROR_TIMED_OUT "org.freedesktop.UDisks2.Error.Timedout"
308 +#define UD2_ERROR_WOULD_WAKEUP "org.freedesktop.UDisks2.Error.WouldWakeup"
309 +#define UD2_ERROR_ALREADY_CANCELLED "org.freedesktop.UDisks2.Error.AlreadyCancelled"
310 +
311 +#define UD2_ERROR_NOT_AUTHORIZED "org.freedesktop.UDisks2.Error.NotAuthorized"
312 +#define UD2_ERROR_NOT_AUTHORIZED_CAN_OBTAIN "org.freedesktop.UDisks2.Error.NotAuthorizedCanObtain"
313 +#define UD2_ERROR_NOT_AUTHORIZED_DISMISSED "org.freedesktop.UDisks2.Error.NotAuthorizedDismissed"
314 +
315 +#endif // SOLID_BACKENDS_UDISKS2_H
316 diff --git a/solid/solid/backends/udisks2/udisksblock.cpp b/solid/solid/backends/udisks2/udisksblock.cpp
317 new file mode 100644
318 index 0000000..f3cd1e8
319 --- /dev/null
320 +++ b/solid/solid/backends/udisks2/udisksblock.cpp
321 @@ -0,0 +1,88 @@
322 +/*
323 + Copyright 2012 Lukáš Tinkl <ltinkl@redhat.com>
324 +
325 + This library is free software; you can redistribute it and/or
326 + modify it under the terms of the GNU Lesser General Public
327 + License as published by the Free Software Foundation; either
328 + version 2.1 of the License, or (at your option) version 3, or any
329 + later version accepted by the membership of KDE e.V. (or its
330 + successor approved by the membership of KDE e.V.), which shall
331 + act as a proxy defined in Section 6 of version 3 of the license.
332 +
333 + This library is distributed in the hope that it will be useful,
334 + but WITHOUT ANY WARRANTY; without even the implied warranty of
335 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
336 + Lesser General Public License for more details.
337 +
338 + You should have received a copy of the GNU Lesser General Public
339 + License along with this library. If not, see <http://www.gnu.org/licenses/>.
340 +*/
341 +
342 +#include <linux/kdev_t.h>
343 +
344 +#include <QFile>
345 +#include <QtDBus/QDBusConnection>
346 +#include <QtDBus/QDBusPendingReply>
347 +#include <QtXml/QDomDocument>
348 +
349 +#include "udisksblock.h"
350 +
351 +using namespace Solid::Backends::UDisks2;
352 +
353 +Block::Block(Device *dev)
354 + : DeviceInterface(dev)
355 +{
356 + m_devNum = m_device->prop("DeviceNumber").toULongLong();
357 + m_devFile = QFile::decodeName(m_device->prop("Device").toByteArray());
358 +
359 + // we have a drive (non-block device for udisks), so let's find the corresponding (real) block device
360 + if (m_devNum == 0 || m_devFile.isEmpty()) {
361 + const QString path = "/org/freedesktop/UDisks2/block_devices";
362 + QDBusMessage call = QDBusMessage::createMethodCall(UD2_DBUS_SERVICE, path,
363 + DBUS_INTERFACE_INTROSPECT, "Introspect");
364 + QDBusPendingReply<QString> reply = QDBusConnection::systemBus().asyncCall(call);
365 + reply.waitForFinished();
366 +
367 + if (reply.isValid()) {
368 + QDomDocument dom;
369 + dom.setContent(reply.value());
370 + QDomNodeList nodeList = dom.documentElement().elementsByTagName("node");
371 + for (int i = 0; i < nodeList.count(); i++) {
372 + QDomElement nodeElem = nodeList.item(i).toElement();
373 + if (!nodeElem.isNull() && nodeElem.hasAttribute("name")) {
374 + const QString udi = path + "/" + nodeElem.attribute("name");
375 +
376 + Device device(udi);
377 + if (device.drivePath() == dev->udi()) {
378 + m_devNum = device.prop("DeviceNumber").toULongLong();
379 + m_devFile = QFile::decodeName(device.prop("Device").toByteArray());
380 + break;
381 + }
382 + }
383 + }
384 + }
385 + else
386 + qWarning() << "Failed enumerating UDisks2 objects:" << reply.error().name() << "\n" << reply.error().message();
387 + }
388 +
389 + //qDebug() << "devnum:" << m_devNum << "dev file:" << m_devFile;
390 +}
391 +
392 +Block::~Block()
393 +{
394 +}
395 +
396 +QString Block::device() const
397 +{
398 + return m_devFile;
399 +}
400 +
401 +int Block::deviceMinor() const
402 +{
403 + return MINOR(m_devNum);
404 +}
405 +
406 +int Block::deviceMajor() const
407 +{
408 + return MAJOR(m_devNum);
409 +}
410 diff --git a/solid/solid/backends/udisks2/udisksblock.h b/solid/solid/backends/udisks2/udisksblock.h
411 new file mode 100644
412 index 0000000..19cb70a
413 --- /dev/null
414 +++ b/solid/solid/backends/udisks2/udisksblock.h
415 @@ -0,0 +1,56 @@
416 +/*
417 + Copyright 2012 Lukáš Tinkl <ltinkl@redhat.com>
418 +
419 + This library is free software; you can redistribute it and/or
420 + modify it under the terms of the GNU Lesser General Public
421 + License as published by the Free Software Foundation; either
422 + version 2.1 of the License, or (at your option) version 3, or any
423 + later version accepted by the membership of KDE e.V. (or its
424 + successor approved by the membership of KDE e.V.), which shall
425 + act as a proxy defined in Section 6 of version 3 of the license.
426 +
427 + This library is distributed in the hope that it will be useful,
428 + but WITHOUT ANY WARRANTY; without even the implied warranty of
429 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
430 + Lesser General Public License for more details.
431 +
432 + You should have received a copy of the GNU Lesser General Public
433 + License along with this library. If not, see <http://www.gnu.org/licenses/>.
434 +*/
435 +
436 +#ifndef UDISKS2BLOCK_H
437 +#define UDISKS2BLOCK_H
438 +
439 +#include <solid/ifaces/block.h>
440 +#include "udisksdeviceinterface.h"
441 +
442 +namespace Solid
443 +{
444 +namespace Backends
445 +{
446 +namespace UDisks2
447 +{
448 +
449 +class Block: public DeviceInterface, virtual public Solid::Ifaces::Block
450 +{
451 +
452 + Q_OBJECT
453 + Q_INTERFACES(Solid::Ifaces::Block)
454 +
455 +public:
456 + Block(Device *dev);
457 + virtual ~Block();
458 +
459 + virtual QString device() const;
460 + virtual int deviceMinor() const;
461 + virtual int deviceMajor() const;
462 +private:
463 + dev_t m_devNum;
464 + QString m_devFile;
465 +};
466 +
467 +}
468 +}
469 +}
470 +
471 +#endif // UDISKS2BLOCK_H
472 diff --git a/solid/solid/backends/udisks2/udisksdevice.cpp b/solid/solid/backends/udisks2/udisksdevice.cpp
473 new file mode 100644
474 index 0000000..b888360
475 --- /dev/null
476 +++ b/solid/solid/backends/udisks2/udisksdevice.cpp
477 @@ -0,0 +1,834 @@
478 +/*
479 + Copyright 2010 Michael Zanetti <mzanetti@kde.org>
480 + Copyright 2010-2012 Lukáš Tinkl <ltinkl@redhat.com>
481 +
482 + This library is free software; you can redistribute it and/or
483 + modify it under the terms of the GNU Lesser General Public
484 + License as published by the Free Software Foundation; either
485 + version 2.1 of the License, or (at your option) version 3, or any
486 + later version accepted by the membership of KDE e.V. (or its
487 + successor approved by the membership of KDE e.V.), which shall
488 + act as a proxy defined in Section 6 of version 3 of the license.
489 +
490 + This library is distributed in the hope that it will be useful,
491 + but WITHOUT ANY WARRANTY; without even the implied warranty of
492 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
493 + Lesser General Public License for more details.
494 +
495 + You should have received a copy of the GNU Lesser General Public
496 + License along with this library. If not, see <http://www.gnu.org/licenses/>.
497 +*/
498 +
499 +#include "udisksdevice.h"
500 +#include "udisksdevicebackend.h"
501 +#include "udisksblock.h"
502 +#include "udisksdeviceinterface.h"
503 +#include "udisksstoragevolume.h"
504 +#include "udisksopticaldisc.h"
505 +#include "udisksopticaldrive.h"
506 +#include "udisksstorageaccess.h"
507 +#include "udisksgenericinterface.h"
508 +
509 +#include <solid/genericinterface.h>
510 +#include <solid/deviceinterface.h>
511 +#include <solid/device.h>
512 +
513 +#include <QtCore/QDebug>
514 +
515 +#include <QtDBus/QDBusMessage>
516 +#include <QtDBus/QDBusMetaType>
517 +#include <QtDBus/QDBusPendingReply>
518 +#include <QtDBus/QDBusArgument>
519 +
520 +#include <QtXml/QDomDocument>
521 +
522 +using namespace Solid::Backends::UDisks2;
523 +
524 +// Adapted from KLocale as Solid needs to be Qt-only
525 +static QString formatByteSize(double size)
526 +{
527 + // Per IEC 60027-2
528 +
529 + // Binary prefixes
530 + //Tebi-byte TiB 2^40 1,099,511,627,776 bytes
531 + //Gibi-byte GiB 2^30 1,073,741,824 bytes
532 + //Mebi-byte MiB 2^20 1,048,576 bytes
533 + //Kibi-byte KiB 2^10 1,024 bytes
534 +
535 + QString s;
536 + // Gibi-byte
537 + if ( size >= 1073741824.0 )
538 + {
539 + size /= 1073741824.0;
540 + if ( size > 1024 ) // Tebi-byte
541 + s = QCoreApplication::translate("", "%1 TiB").arg(QLocale().toString(size / 1024.0, 'f', 1));
542 + else
543 + s = QCoreApplication::translate("", "%1 GiB").arg(QLocale().toString(size, 'f', 1));
544 + }
545 + // Mebi-byte
546 + else if ( size >= 1048576.0 )
547 + {
548 + size /= 1048576.0;
549 + s = QCoreApplication::translate("", "%1 MiB").arg(QLocale().toString(size, 'f', 1));
550 + }
551 + // Kibi-byte
552 + else if ( size >= 1024.0 )
553 + {
554 + size /= 1024.0;
555 + s = QCoreApplication::translate("", "%1 KiB").arg(QLocale().toString(size, 'f', 1));
556 + }
557 + // Just byte
558 + else if ( size > 0 )
559 + {
560 + s = QCoreApplication::translate("", "%1 B").arg(QLocale().toString(size, 'f', 1));
561 + }
562 + // Nothing
563 + else
564 + {
565 + s = QCoreApplication::translate("", "0 B");
566 + }
567 + return s;
568 +}
569 +
570 +Device::Device(const QString &udi)
571 + : Solid::Ifaces::Device()
572 + , m_backend(DeviceBackend::backendForUDI(udi))
573 +{
574 + if (m_backend) {
575 + connect(m_backend, SIGNAL(changed()), this, SIGNAL(changed()));
576 + connect(m_backend, SIGNAL(propertyChanged(QMap<QString,int>)), this, SIGNAL(propertyChanged(QMap<QString,int>)));
577 + } else {
578 + qDebug() << "Created invalid Device for udi" << udi;
579 + }
580 +}
581 +
582 +Device::~Device()
583 +{
584 +
585 +}
586 +
587 +QObject* Device::createDeviceInterface(const Solid::DeviceInterface::Type& type)
588 +{
589 + if (!queryDeviceInterface(type)) {
590 + return 0;
591 + }
592 +
593 + DeviceInterface *iface = 0;
594 + switch (type)
595 + {
596 + case Solid::DeviceInterface::GenericInterface:
597 + iface = new GenericInterface(this);
598 + break;
599 + case Solid::DeviceInterface::Block:
600 + iface = new Block(this);
601 + break;
602 + case Solid::DeviceInterface::StorageAccess:
603 + iface = new StorageAccess(this);
604 + break;
605 + case Solid::DeviceInterface::StorageDrive:
606 + iface = new StorageDrive(this);
607 + break;
608 + case Solid::DeviceInterface::OpticalDrive:
609 + iface = new OpticalDrive(this);
610 + break;
611 + case Solid::DeviceInterface::StorageVolume:
612 + iface = new StorageVolume(this);
613 + break;
614 + case Solid::DeviceInterface::OpticalDisc:
615 + iface = new OpticalDisc(this);
616 + break;
617 + default:
618 + break;
619 + }
620 + return iface;
621 +}
622 +
623 +bool Device::queryDeviceInterface(const Solid::DeviceInterface::Type& type) const
624 +{
625 + switch (type) {
626 + case Solid::DeviceInterface::GenericInterface:
627 + return true;
628 + case Solid::DeviceInterface::Block:
629 + return isBlock() || isDrive();
630 + case Solid::DeviceInterface::StorageVolume:
631 + return isStorageVolume();
632 + case Solid::DeviceInterface::StorageAccess:
633 + return isStorageAccess();
634 + case Solid::DeviceInterface::StorageDrive:
635 + return isDrive();
636 + case Solid::DeviceInterface::OpticalDrive:
637 + return isOpticalDrive();
638 + case Solid::DeviceInterface::OpticalDisc:
639 + return isOpticalDisc();
640 + default:
641 + return false;
642 + }
643 +}
644 +
645 +QStringList Device::emblems() const
646 +{
647 + QStringList res;
648 +
649 + if (queryDeviceInterface(Solid::DeviceInterface::StorageAccess))
650 + {
651 + const UDisks2::StorageAccess accessIface(const_cast<Device *>(this));
652 + if (accessIface.isAccessible())
653 + {
654 + if (isEncryptedContainer())
655 + res << "emblem-encrypted-unlocked";
656 + else
657 + res << "emblem-mounted";
658 + }
659 + else
660 + {
661 + if (isEncryptedContainer())
662 + res << "emblem-encrypted-locked";
663 + else
664 + res << "emblem-unmounted";
665 + }
666 + }
667 +
668 + return res;
669 +}
670 +
671 +QString Device::description() const
672 +{
673 + const QString hintName = property("HintName").toString(); // non-cached
674 + if (!hintName.isEmpty())
675 + return hintName;
676 +
677 + if (isLoop())
678 + return QObject::tr("Loop Device");
679 + else if (isSwap())
680 + return QObject::tr("Swap Space");
681 + else if (queryDeviceInterface(Solid::DeviceInterface::StorageDrive))
682 + return storageDescription();
683 + else if (queryDeviceInterface(Solid::DeviceInterface::StorageVolume))
684 + return volumeDescription();
685 + else
686 + return product();
687 +}
688 +
689 +QString Device::storageDescription() const
690 +{
691 + QString description;
692 + const UDisks2::StorageDrive storageDrive(const_cast<Device*>(this));
693 + Solid::StorageDrive::DriveType drive_type = storageDrive.driveType();
694 + const bool drive_is_hotpluggable = storageDrive.isHotpluggable();
695 +
696 + if (drive_type == Solid::StorageDrive::CdromDrive)
697 + {
698 + const UDisks2::OpticalDrive opticalDrive(const_cast<Device*>(this));
699 + Solid::OpticalDrive::MediumTypes mediumTypes = opticalDrive.supportedMedia();
700 + QString first;
701 + QString second;
702 +
703 + first = QCoreApplication::translate("", "CD-ROM", "First item of %1%2 Drive sentence");
704 + if (mediumTypes & Solid::OpticalDrive::Cdr)
705 + first = QCoreApplication::translate("", "CD-R", "First item of %1%2 Drive sentence");
706 + if (mediumTypes & Solid::OpticalDrive::Cdrw)
707 + first = QCoreApplication::translate("", "CD-RW", "First item of %1%2 Drive sentence");
708 +
709 + if (mediumTypes & Solid::OpticalDrive::Dvd)
710 + second = QCoreApplication::translate("", "/DVD-ROM", "Second item of %1%2 Drive sentence");
711 + if (mediumTypes & Solid::OpticalDrive::Dvdplusr)
712 + second = QCoreApplication::translate("", "/DVD+R", "Second item of %1%2 Drive sentence");
713 + if (mediumTypes & Solid::OpticalDrive::Dvdplusrw)
714 + second = QCoreApplication::translate("", "/DVD+RW", "Second item of %1%2 Drive sentence");
715 + if (mediumTypes & Solid::OpticalDrive::Dvdr)
716 + second = QCoreApplication::translate("", "/DVD-R", "Second item of %1%2 Drive sentence");
717 + if (mediumTypes & Solid::OpticalDrive::Dvdrw)
718 + second = QCoreApplication::translate("", "/DVD-RW", "Second item of %1%2 Drive sentence");
719 + if (mediumTypes & Solid::OpticalDrive::Dvdram)
720 + second = QCoreApplication::translate("", "/DVD-RAM", "Second item of %1%2 Drive sentence");
721 + if ((mediumTypes & Solid::OpticalDrive::Dvdr) && (mediumTypes & Solid::OpticalDrive::Dvdplusr))
722 + {
723 + if(mediumTypes & Solid::OpticalDrive::Dvdplusdl)
724 + second = QObject::trUtf8("/DVD±R DL", "Second item of %1%2 Drive sentence");
725 + else
726 + second = QObject::trUtf8("/DVD±R", "Second item of %1%2 Drive sentence");
727 + }
728 + if ((mediumTypes & Solid::OpticalDrive::Dvdrw) && (mediumTypes & Solid::OpticalDrive::Dvdplusrw))
729 + {
730 + if((mediumTypes & Solid::OpticalDrive::Dvdplusdl) || (mediumTypes & Solid::OpticalDrive::Dvdplusdlrw))
731 + second = QObject::trUtf8("/DVD±RW DL", "Second item of %1%2 Drive sentence");
732 + else
733 + second = QObject::trUtf8("/DVD±RW", "Second item of %1%2 Drive sentence");
734 + }
735 + if (mediumTypes & Solid::OpticalDrive::Bd)
736 + second = QCoreApplication::translate("", "/BD-ROM", "Second item of %1%2 Drive sentence");
737 + if (mediumTypes & Solid::OpticalDrive::Bdr)
738 + second = QCoreApplication::translate("", "/BD-R", "Second item of %1%2 Drive sentence");
739 + if (mediumTypes & Solid::OpticalDrive::Bdre)
740 + second = QCoreApplication::translate("", "/BD-RE", "Second item of %1%2 Drive sentence");
741 + if (mediumTypes & Solid::OpticalDrive::HdDvd)
742 + second = QCoreApplication::translate("", "/HD DVD-ROM", "Second item of %1%2 Drive sentence");
743 + if (mediumTypes & Solid::OpticalDrive::HdDvdr)
744 + second = QCoreApplication::translate("", "/HD DVD-R", "Second item of %1%2 Drive sentence");
745 + if (mediumTypes & Solid::OpticalDrive::HdDvdrw)
746 + second = QCoreApplication::translate("", "/HD DVD-RW", "Second item of %1%2 Drive sentence");
747 +
748 + if (drive_is_hotpluggable)
749 + description = QCoreApplication::translate("", "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);
750 + else
751 + description = QCoreApplication::translate("", "%1%2 Drive", "%1 is CD-ROM/CD-R/etc; %2 is '/DVD-ROM'/'/DVD-R'/etc (with leading slash)").arg(first).arg(second);
752 +
753 + return description;
754 + }
755 +
756 + if (drive_type == Solid::StorageDrive::Floppy)
757 + {
758 + if (drive_is_hotpluggable)
759 + description = QCoreApplication::translate("", "External Floppy Drive");
760 + else
761 + description = QCoreApplication::translate("", "Floppy Drive");
762 +
763 + return description;
764 + }
765 +
766 + const bool drive_is_removable = storageDrive.isRemovable();
767 +
768 + if (drive_type == Solid::StorageDrive::HardDisk && !drive_is_removable)
769 + {
770 + QString size_str = formatByteSize(storageDrive.size());
771 + if (!size_str.isEmpty())
772 + {
773 + if (drive_is_hotpluggable)
774 + description = QCoreApplication::translate("", "%1 External Hard Drive", "%1 is the size").arg(size_str);
775 + else
776 + description = QCoreApplication::translate("", "%1 Hard Drive", "%1 is the size").arg(size_str);
777 + } else {
778 + if (drive_is_hotpluggable)
779 + description = QCoreApplication::translate("", "External Hard Drive");
780 + else
781 + description = QCoreApplication::translate("", "Hard Drive");
782 + }
783 +
784 + return description;
785 + }
786 +
787 + QString vendormodel_str;
788 + QString model = product();
789 + QString vendor_str = vendor();
790 +
791 + if (vendor_str.isEmpty())
792 + {
793 + if (!model.isEmpty())
794 + vendormodel_str = model;
795 + }
796 + else
797 + {
798 + if (model.isEmpty())
799 + vendormodel_str = vendor_str;
800 + else
801 + {
802 + if (model.startsWith(vendor_str))
803 + {
804 + // e.g. vendor is "Nokia" and model is "Nokia N950" we do not want "Nokia Nokia N950" as description
805 + vendormodel_str = model;
806 + }
807 + else
808 + {
809 + vendormodel_str = QCoreApplication::translate("", "%1 %2", "%1 is the vendor, %2 is the model of the device").arg(vendor_str).arg(model);
810 + }
811 + }
812 + }
813 +
814 + if (vendormodel_str.isEmpty())
815 + description = QCoreApplication::translate("", "Drive");
816 + else
817 + description = vendormodel_str;
818 +
819 + return description;
820 +}
821 +
822 +QString Device::volumeDescription() const
823 +{
824 + QString description;
825 + const UDisks2::StorageVolume storageVolume(const_cast<Device*>(this));
826 + QString volume_label = prop("IdLabel").toString();
827 + if (volume_label.isEmpty())
828 + volume_label = prop("Name").toString();
829 + if (!volume_label.isEmpty())
830 + return volume_label;
831 +
832 + UDisks2::Device storageDevice(drivePath());
833 + const UDisks2::StorageDrive storageDrive(&storageDevice);
834 + Solid::StorageDrive::DriveType drive_type = storageDrive.driveType();
835 +
836 + // Handle media in optical drives
837 + if (drive_type == Solid::StorageDrive::CdromDrive)
838 + {
839 + const UDisks2::OpticalDisc disc(const_cast<Device*>(this));
840 + switch (disc.discType())
841 + {
842 + case Solid::OpticalDisc::UnknownDiscType:
843 + case Solid::OpticalDisc::CdRom:
844 + description = QCoreApplication::translate("", "CD-ROM");
845 + break;
846 +
847 + case Solid::OpticalDisc::CdRecordable:
848 + if (disc.isBlank())
849 + description = QCoreApplication::translate("", "Blank CD-R");
850 + else
851 + description = QCoreApplication::translate("", "CD-R");
852 + break;
853 +
854 + case Solid::OpticalDisc::CdRewritable:
855 + if (disc.isBlank())
856 + description = QCoreApplication::translate("", "Blank CD-RW");
857 + else
858 + description = QCoreApplication::translate("", "CD-RW");
859 + break;
860 +
861 + case Solid::OpticalDisc::DvdRom:
862 + description = QCoreApplication::translate("", "DVD-ROM");
863 + break;
864 +
865 + case Solid::OpticalDisc::DvdRam:
866 + if (disc.isBlank())
867 + description = QCoreApplication::translate("", "Blank DVD-RAM");
868 + else
869 + description = QCoreApplication::translate("", "DVD-RAM");
870 + break;
871 +
872 + case Solid::OpticalDisc::DvdRecordable:
873 + if (disc.isBlank())
874 + description = QCoreApplication::translate("", "Blank DVD-R");
875 + else
876 + description = QCoreApplication::translate("", "DVD-R");
877 + break;
878 +
879 + case Solid::OpticalDisc::DvdPlusRecordableDuallayer:
880 + if (disc.isBlank())
881 + description = QCoreApplication::translate("", "Blank DVD+R Dual-Layer");
882 + else
883 + description = QCoreApplication::translate("", "DVD+R Dual-Layer");
884 + break;
885 +
886 + case Solid::OpticalDisc::DvdRewritable:
887 + if (disc.isBlank())
888 + description = QCoreApplication::translate("", "Blank DVD-RW");
889 + else
890 + description = QCoreApplication::translate("", "DVD-RW");
891 + break;
892 +
893 + case Solid::OpticalDisc::DvdPlusRecordable:
894 + if (disc.isBlank())
895 + description = QCoreApplication::translate("", "Blank DVD+R");
896 + else
897 + description = QCoreApplication::translate("", "DVD+R");
898 + break;
899 +
900 + case Solid::OpticalDisc::DvdPlusRewritable:
901 + if (disc.isBlank())
902 + description = QCoreApplication::translate("", "Blank DVD+RW");
903 + else
904 + description = QCoreApplication::translate("", "DVD+RW");
905 + break;
906 +
907 + case Solid::OpticalDisc::DvdPlusRewritableDuallayer:
908 + if (disc.isBlank())
909 + description = QCoreApplication::translate("", "Blank DVD+RW Dual-Layer");
910 + else
911 + description = QCoreApplication::translate("", "DVD+RW Dual-Layer");
912 + break;
913 +
914 + case Solid::OpticalDisc::BluRayRom:
915 + description = QCoreApplication::translate("", "BD-ROM");
916 + break;
917 +
918 + case Solid::OpticalDisc::BluRayRecordable:
919 + if (disc.isBlank())
920 + description = QCoreApplication::translate("", "Blank BD-R");
921 + else
922 + description = QCoreApplication::translate("", "BD-R");
923 + break;
924 +
925 + case Solid::OpticalDisc::BluRayRewritable:
926 + if (disc.isBlank())
927 + description = QCoreApplication::translate("", "Blank BD-RE");
928 + else
929 + description = QCoreApplication::translate("", "BD-RE");
930 + break;
931 +
932 + case Solid::OpticalDisc::HdDvdRom:
933 + description = QCoreApplication::translate("", "HD DVD-ROM");
934 + break;
935 +
936 + case Solid::OpticalDisc::HdDvdRecordable:
937 + if (disc.isBlank())
938 + description = QCoreApplication::translate("", "Blank HD DVD-R");
939 + else
940 + description = QCoreApplication::translate("", "HD DVD-R");
941 + break;
942 +
943 + case Solid::OpticalDisc::HdDvdRewritable:
944 + if (disc.isBlank())
945 + description = QCoreApplication::translate("", "Blank HD DVD-RW");
946 + else
947 + description = QCoreApplication::translate("", "HD DVD-RW");
948 + break;
949 + }
950 +
951 + // Special case for pure audio disc
952 + if (disc.availableContent() == Solid::OpticalDisc::Audio)
953 + description = QCoreApplication::translate("", "Audio CD");
954 +
955 + return description;
956 + }
957 +
958 + const bool drive_is_removable = storageDrive.isRemovable();
959 + const bool drive_is_hotpluggable = storageDrive.isHotpluggable();
960 +
961 + QString size_str = formatByteSize(storageVolume.size());
962 + if (isEncryptedContainer())
963 + {
964 + if (!size_str.isEmpty())
965 + description = QCoreApplication::translate("", "%1 Encrypted Drive", "%1 is the size").arg(size_str);
966 + else
967 + description = QCoreApplication::translate("", "Encrypted Drive");
968 + }
969 + else if (drive_type == Solid::StorageDrive::HardDisk && !drive_is_removable)
970 + {
971 + if (!size_str.isEmpty())
972 + {
973 + if (drive_is_hotpluggable)
974 + description = QCoreApplication::translate("", "%1 External Hard Drive", "%1 is the size").arg(size_str);
975 + else
976 + description = QCoreApplication::translate("", "%1 Hard Drive", "%1 is the size").arg(size_str);
977 + }
978 + else
979 + {
980 + if (drive_is_hotpluggable)
981 + description = QCoreApplication::translate("", "External Hard Drive");
982 + else
983 + description = QCoreApplication::translate("", "Hard Drive");
984 + }
985 + }
986 + else
987 + {
988 + if (drive_is_removable)
989 + description = QCoreApplication::translate("", "%1 Removable Media", "%1 is the size").arg(size_str);
990 + else
991 + description = QCoreApplication::translate("", "%1 Media", "%1 is the size").arg(size_str);
992 + }
993 +
994 + return description;
995 +}
996 +
997 +QString Device::icon() const
998 +{
999 + QString iconName = property( "HintIconName" ).toString(); // non-cached
1000 +
1001 + if ( !iconName.isEmpty() )
1002 + {
1003 + return iconName;
1004 + }
1005 + else if (isLoop() || isSwap())
1006 + {
1007 + return "drive-harddisk";
1008 + }
1009 + else if (isDrive()) {
1010 + const bool isRemovable = prop("Removable").toBool();
1011 + const QString conn = prop("ConnectionBus").toString();
1012 +
1013 + if (isOpticalDrive())
1014 + return "drive-optical";
1015 + else if (isRemovable && !prop("Optical").toBool()) {
1016 + if (conn == "usb")
1017 + return "drive-removable-media-usb";
1018 + else
1019 + return "drive-removable-media";
1020 + }
1021 + }
1022 + else if (isBlock()) {
1023 + const QString drv = drivePath();
1024 + if (drv.isEmpty() || drv == "/")
1025 + return "drive-harddisk"; // stuff like loop devices or swap which don't have the Drive prop set
1026 +
1027 + Device drive(drv);
1028 +
1029 + // handle media
1030 + const QString media = drive.prop("Media").toString();
1031 +
1032 + if ( !media.isEmpty() )
1033 + {
1034 + if ( drive.prop("Optical").toBool() ) // optical stuff
1035 + {
1036 + bool isWritable = drive.prop("OpticalBlank").toBool();
1037 +
1038 + const UDisks2::OpticalDisc disc(const_cast<Device*>(this));
1039 + Solid::OpticalDisc::ContentTypes availContent = disc.availableContent();
1040 +
1041 + if (availContent & Solid::OpticalDisc::VideoDvd) // Video DVD
1042 + return "media-optical-dvd-video";
1043 + else if ((availContent & Solid::OpticalDisc::VideoCd) || (availContent & Solid::OpticalDisc::SuperVideoCd)) // Video CD
1044 + return "media-optical-video";
1045 + else if ((availContent & Solid::OpticalDisc::Data) && (availContent & Solid::OpticalDisc::Audio)) // Mixed CD
1046 + return "media-optical-mixed-cd";
1047 + else if (availContent & Solid::OpticalDisc::Audio) // Audio CD
1048 + return "media-optical-audio";
1049 + else if (availContent & Solid::OpticalDisc::Data) // Data CD
1050 + return "media-optical-data";
1051 + else if ( isWritable )
1052 + return "media-optical-recordable";
1053 + else
1054 + {
1055 + if ( media.startsWith( "optical_dvd" ) || media.startsWith( "optical_hddvd" ) ) // DVD
1056 + return "media-optical-dvd";
1057 + else if ( media.startsWith( "optical_bd" ) ) // BluRay
1058 + return "media-optical-blu-ray";
1059 + }
1060 +
1061 + // fallback for every other optical disc
1062 + return "media-optical";
1063 + }
1064 +
1065 + if ( media == "flash_ms" ) // Flash & Co.
1066 + return "media-flash-memory-stick";
1067 + else if ( media == "flash_sd" || media == "flash_sdhc" || media == "flash_sdxc" || media == "flash_mmc" )
1068 + return "media-flash-sd-mmc";
1069 + else if ( media == "flash_sm" )
1070 + return "media-flash-smart-media";
1071 + else if ( media == "thumb" )
1072 + return "drive-removable-media-usb-pendrive";
1073 + else if ( media.startsWith( "flash" ) )
1074 + return "media-flash";
1075 + else if ( media == "floppy" ) // the good ol' floppy
1076 + return "media-floppy";
1077 + }
1078 +
1079 + if (drive.prop("ConnectionBus").toString() == "sdio") // hack for SD cards connected thru sdio bus
1080 + return "media-flash-sd-mmc";
1081 +
1082 + return drive.icon();
1083 + }
1084 +
1085 + return "drive-harddisk"; // general fallback
1086 +}
1087 +
1088 +QString Device::product() const
1089 +{
1090 + if (!isDrive()) {
1091 + Device drive(drivePath());
1092 + return drive.prop("Model").toString();
1093 + }
1094 +
1095 + return prop("Model").toString();
1096 +}
1097 +
1098 +QString Device::vendor() const
1099 +{
1100 + if (!isDrive()) {
1101 + Device drive(drivePath());
1102 + return drive.prop("Vendor").toString();
1103 + }
1104 +
1105 + return prop("Vendor").toString();
1106 +}
1107 +
1108 +QString Device::udi() const
1109 +{
1110 + if (m_backend) {
1111 + return m_backend->udi;
1112 + }
1113 +
1114 + return QString();
1115 +}
1116 +
1117 +QString Device::parentUdi() const
1118 +{
1119 + QString parent;
1120 +
1121 + if (propertyExists("Drive")) // block
1122 + parent = prop("Drive").value<QDBusObjectPath>().path();
1123 + else if (propertyExists("Table")) // partition
1124 + parent = prop("Table").value<QDBusObjectPath>().path();
1125 + else if (parent.isEmpty() || parent=="/") {
1126 + parent = UD2_UDI_DISKS_PREFIX;
1127 + }
1128 + return parent;
1129 +}
1130 +
1131 +QVariant Device::prop(const QString &key) const
1132 +{
1133 + if (m_backend) {
1134 + return m_backend->prop(key);
1135 + }
1136 +
1137 + return QVariant();
1138 +}
1139 +
1140 +bool Device::propertyExists(const QString &key) const
1141 +{
1142 + if (m_backend) {
1143 + return m_backend->propertyExists(key);
1144 + }
1145 +
1146 + return false;
1147 +}
1148 +
1149 +QVariantMap Device::allProperties() const
1150 +{
1151 + if (m_backend) {
1152 + return m_backend->allProperties();
1153 + }
1154 +
1155 + return QVariantMap();
1156 +}
1157 +
1158 +bool Device::hasInterface(const QString &name) const
1159 +{
1160 + if (m_backend) {
1161 + return m_backend->interfaces().contains(name);
1162 + }
1163 +
1164 + return false;
1165 +}
1166 +
1167 +QStringList Device::interfaces() const
1168 +{
1169 + if (m_backend) {
1170 + return m_backend->interfaces();
1171 + }
1172 +
1173 + return QStringList();
1174 +}
1175 +
1176 +QString Device::errorToString(const QString & error) const
1177 +{
1178 + if (error == UD2_ERROR_UNAUTHORIZED || error == UD2_ERROR_NOT_AUTHORIZED)
1179 + return QCoreApplication::translate("", "You are not authorized to perform this operation");
1180 + else if (error == UD2_ERROR_BUSY)
1181 + return QCoreApplication::translate("", "The device is currently busy");
1182 + else if (error == UD2_ERROR_FAILED)
1183 + return QCoreApplication::translate("", "The requested operation has failed");
1184 + else if (error == UD2_ERROR_CANCELED)
1185 + return QCoreApplication::translate("", "The requested operation has been canceled");
1186 + else if (error == UD2_ERROR_INVALID_OPTION)
1187 + return QCoreApplication::translate("", "An invalid or malformed option has been given");
1188 + else if (error == UD2_ERROR_MISSING_DRIVER)
1189 + return QCoreApplication::translate("", "The kernel driver for this filesystem type is not available");
1190 + else if (error == UD2_ERROR_ALREADY_MOUNTED)
1191 + return QCoreApplication::translate("", "The device is already mounted");
1192 + else if (error == UD2_ERROR_NOT_MOUNTED)
1193 + return QCoreApplication::translate("", "The device is not mounted");
1194 + else if (error == UD2_ERROR_MOUNTED_BY_OTHER_USER)
1195 + return QCoreApplication::translate("", "The device is mounted by another user");
1196 + else if (error == UD2_ERROR_ALREADY_UNMOUNTING)
1197 + return QCoreApplication::translate("", "The device is already unmounting");
1198 + else if (error == UD2_ERROR_TIMED_OUT)
1199 + return QCoreApplication::translate("", "The operation timed out");
1200 + else if (error == UD2_ERROR_WOULD_WAKEUP)
1201 + return QCoreApplication::translate("", "The operation would wake up a disk that is in a deep-sleep state");
1202 + else if (error == UD2_ERROR_ALREADY_CANCELLED)
1203 + return QCoreApplication::translate("", "The operation has already been canceled");
1204 + else
1205 + return QCoreApplication::translate("", "An unspecified error has occurred");
1206 +}
1207 +
1208 +Solid::ErrorType Device::errorToSolidError(const QString & error) const
1209 +{
1210 + if (error == UD2_ERROR_BUSY)
1211 + return Solid::DeviceBusy;
1212 + else if (error == UD2_ERROR_FAILED)
1213 + return Solid::OperationFailed;
1214 + else if (error == UD2_ERROR_CANCELED)
1215 + return Solid::UserCanceled;
1216 + else if (error == UD2_ERROR_INVALID_OPTION)
1217 + return Solid::InvalidOption;
1218 + else if (error == UD2_ERROR_MISSING_DRIVER)
1219 + return Solid::MissingDriver;
1220 + else
1221 + return Solid::UnauthorizedOperation;
1222 +}
1223 +
1224 +bool Device::isBlock() const
1225 +{
1226 + return hasInterface(UD2_DBUS_INTERFACE_BLOCK);
1227 +}
1228 +
1229 +bool Device::isPartition() const
1230 +{
1231 + return hasInterface(UD2_DBUS_INTERFACE_PARTITION);
1232 +}
1233 +
1234 +bool Device::isPartitionTable() const
1235 +{
1236 + return hasInterface(UD2_DBUS_INTERFACE_PARTITIONTABLE);
1237 +}
1238 +
1239 +bool Device::isStorageVolume() const
1240 +{
1241 + return isPartition() || isPartitionTable() || isStorageAccess() || isOpticalDisc();
1242 +}
1243 +
1244 +bool Device::isStorageAccess() const
1245 +{
1246 + return hasInterface(UD2_DBUS_INTERFACE_FILESYSTEM) || isEncryptedContainer();
1247 +}
1248 +
1249 +bool Device::isDrive() const
1250 +{
1251 + return hasInterface(UD2_DBUS_INTERFACE_DRIVE);
1252 +}
1253 +
1254 +bool Device::isOpticalDrive() const
1255 +{
1256 + return isDrive() && !prop("MediaCompatibility").toStringList().filter("optical_").isEmpty();
1257 +}
1258 +
1259 +bool Device::isOpticalDisc() const
1260 +{
1261 + const QString drv = drivePath();
1262 + if (drv.isEmpty() || drv == "/")
1263 + return false;
1264 +
1265 + Device drive(drv);
1266 + return drive.prop("Optical").toBool();
1267 +}
1268 +
1269 +bool Device::mightBeOpticalDisc() const
1270 +{
1271 + const QString drv = drivePath();
1272 + if (drv.isEmpty() || drv == "/")
1273 + return false;
1274 +
1275 + Device drive(drv);
1276 + return drive.isOpticalDrive();
1277 +}
1278 +
1279 +bool Device::isMounted() const
1280 +{
1281 + return propertyExists("MountPoints") && !qdbus_cast<QByteArrayList>(prop("MountPoints")).isEmpty();
1282 +}
1283 +
1284 +bool Device::isEncryptedContainer() const
1285 +{
1286 + return hasInterface(UD2_DBUS_INTERFACE_ENCRYPTED);
1287 +}
1288 +
1289 +bool Device::isEncryptedCleartext() const
1290 +{
1291 + const QString holderDevice = prop("CryptoBackingDevice").toString();
1292 + if (holderDevice.isEmpty() || holderDevice == "/")
1293 + return false;
1294 + else
1295 + return true;
1296 +}
1297 +
1298 +bool Device::isSwap() const
1299 +{
1300 + return hasInterface(UD2_DBUS_INTERFACE_SWAP);
1301 +}
1302 +
1303 +bool Device::isLoop() const
1304 +{
1305 + return hasInterface(UD2_DBUS_INTERFACE_LOOP);
1306 +}
1307 +
1308 +QString Device::drivePath() const
1309 +{
1310 + return prop("Drive").value<QDBusObjectPath>().path();
1311 +}
1312 diff --git a/solid/solid/backends/udisks2/udisksdevice.h b/solid/solid/backends/udisks2/udisksdevice.h
1313 new file mode 100644
1314 index 0000000..90bb042
1315 --- /dev/null
1316 +++ b/solid/solid/backends/udisks2/udisksdevice.h
1317 @@ -0,0 +1,103 @@
1318 +/*
1319 + Copyright 2010 Michael Zanetti <mzanetti@kde.org>
1320 + Copyright 2010-2012 Lukáš Tinkl <ltinkl@redhat.com>
1321 +
1322 + This library is free software; you can redistribute it and/or
1323 + modify it under the terms of the GNU Lesser General Public
1324 + License as published by the Free Software Foundation; either
1325 + version 2.1 of the License, or (at your option) version 3, or any
1326 + later version accepted by the membership of KDE e.V. (or its
1327 + successor approved by the membership of KDE e.V.), which shall
1328 + act as a proxy defined in Section 6 of version 3 of the license.
1329 +
1330 + This library is distributed in the hope that it will be useful,
1331 + but WITHOUT ANY WARRANTY; without even the implied warranty of
1332 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1333 + Lesser General Public License for more details.
1334 +
1335 + You should have received a copy of the GNU Lesser General Public
1336 + License along with this library. If not, see <http://www.gnu.org/licenses/>.
1337 +*/
1338 +
1339 +#ifndef UDISKS2DEVICE_H
1340 +#define UDISKS2DEVICE_H
1341 +
1342 +#include "udisks2.h"
1343 +
1344 +#include <ifaces/device.h>
1345 +#include <solid/deviceinterface.h>
1346 +#include <solid/solidnamespace.h>
1347 +
1348 +#include <QtDBus/QDBusInterface>
1349 +#include <QtDBus/QDBusObjectPath>
1350 +#include <QtCore/QStringList>
1351 +
1352 +namespace Solid
1353 +{
1354 +namespace Backends
1355 +{
1356 +namespace UDisks2
1357 +{
1358 +
1359 +class DeviceBackend;
1360 +
1361 +class Device: public Solid::Ifaces::Device
1362 +{
1363 + Q_OBJECT
1364 +public:
1365 + Device(const QString &udi);
1366 + virtual ~Device();
1367 +
1368 + virtual QObject* createDeviceInterface(const Solid::DeviceInterface::Type& type);
1369 + virtual bool queryDeviceInterface(const Solid::DeviceInterface::Type& type) const;
1370 + virtual QString description() const;
1371 + virtual QStringList emblems() const;
1372 + virtual QString icon() const;
1373 + virtual QString product() const;
1374 + virtual QString vendor() const;
1375 + virtual QString udi() const;
1376 + virtual QString parentUdi() const;
1377 +
1378 + QVariant prop(const QString &key) const;
1379 + bool propertyExists(const QString &key) const;
1380 + QVariantMap allProperties() const;
1381 +
1382 + bool hasInterface(const QString & name) const;
1383 + QStringList interfaces() const;
1384 +
1385 + QString errorToString(const QString & error) const;
1386 + Solid::ErrorType errorToSolidError(const QString & error) const;
1387 +
1388 + bool isBlock() const;
1389 + bool isPartition() const;
1390 + bool isPartitionTable() const;
1391 + bool isStorageVolume() const;
1392 + bool isStorageAccess() const;
1393 + bool isDrive() const;
1394 + bool isOpticalDrive() const;
1395 + bool isOpticalDisc() const;
1396 + bool mightBeOpticalDisc() const;
1397 + bool isMounted() const;
1398 + bool isEncryptedContainer() const;
1399 + bool isEncryptedCleartext() const;
1400 + bool isSwap() const;
1401 + bool isLoop() const;
1402 +
1403 + QString drivePath() const;
1404 +
1405 +Q_SIGNALS:
1406 + void changed();
1407 + void propertyChanged(const QMap<QString,int> &changes);
1408 +
1409 +private:
1410 + QString storageDescription() const;
1411 + QString volumeDescription() const;
1412 +
1413 + DeviceBackend *m_backend;
1414 +};
1415 +
1416 +}
1417 +}
1418 +}
1419 +
1420 +#endif // UDISKS2DEVICE_H
1421 diff --git a/solid/solid/backends/udisks2/udisksdevicebackend.cpp b/solid/solid/backends/udisks2/udisksdevicebackend.cpp
1422 new file mode 100644
1423 index 0000000..ffa98db
1424 --- /dev/null
1425 +++ b/solid/solid/backends/udisks2/udisksdevicebackend.cpp
1426 @@ -0,0 +1,205 @@
1427 +/*
1428 + Copyright 2010 Michael Zanetti <mzanetti@kde.org>
1429 + Copyright 2010-2012 Lukáš Tinkl <ltinkl@redhat.com>
1430 + Copyright 2012 Dan Vrátil <dvratil@redhat.com>
1431 +
1432 + This library is free software; you can redistribute it and/or
1433 + modify it under the terms of the GNU Lesser General Public
1434 + License as published by the Free Software Foundation; either
1435 + version 2.1 of the License, or (at your option) version 3, or any
1436 + later version accepted by the membership of KDE e.V. (or its
1437 + successor approved by the membership of KDE e.V.), which shall
1438 + act as a proxy defined in Section 6 of version 3 of the license.
1439 +
1440 + This library is distributed in the hope that it will be useful,
1441 + but WITHOUT ANY WARRANTY; without even the implied warranty of
1442 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1443 + Lesser General Public License for more details.
1444 +
1445 + You should have received a copy of the GNU Lesser General Public
1446 + License along with this library. If not, see <http://www.gnu.org/licenses/>.
1447 +*/
1448 +
1449 +#include "udisksdevicebackend.h"
1450 +
1451 +#include <QtDBus/QDBusConnection>
1452 +#include <QtDBus/QDBusInterface>
1453 +#include <QtXml/QDomDocument>
1454 +
1455 +#include "solid/deviceinterface.h"
1456 +#include "solid/genericinterface.h"
1457 +
1458 +using namespace Solid::Backends::UDisks2;
1459 +
1460 +/* Static cache for DeviceBackends for all UDIs */
1461 +QMap<QString /* UDI */, DeviceBackend*> DeviceBackend::s_backends;
1462 +
1463 +DeviceBackend* DeviceBackend::backendForUDI(const QString& udi)
1464 +{
1465 + DeviceBackend *backend = 0;
1466 + if (udi.isEmpty()) {
1467 + return backend;
1468 + }
1469 +
1470 + if (s_backends.contains(udi)) {
1471 + backend = s_backends.value(udi);
1472 + } else {
1473 + backend = new DeviceBackend(udi);
1474 + s_backends.insert(udi, backend);
1475 + }
1476 +
1477 + return backend;
1478 +}
1479 +
1480 +DeviceBackend::DeviceBackend(const QString& udi)
1481 + : udi(udi)
1482 +{
1483 + qDebug() << "Creating backend for device" << udi;
1484 + m_device = new QDBusInterface(UD2_DBUS_SERVICE, udi,
1485 + QString(), // no interface, we aggregate them
1486 + QDBusConnection::systemBus(), this);
1487 +
1488 + if (m_device->isValid()) {
1489 + QDBusConnection::systemBus().connect(UD2_DBUS_SERVICE, udi, DBUS_INTERFACE_PROPS, "PropertiesChanged", this,
1490 + SLOT(slotPropertiesChanged(QString,QVariantMap,QStringList)));
1491 + QDBusConnection::systemBus().connect(UD2_DBUS_SERVICE, UD2_DBUS_PATH, DBUS_INTERFACE_MANAGER, "InterfacesAdded",
1492 + this, SLOT(slotInterfacesAdded(QDBusObjectPath,QVariantMapMap)));
1493 + QDBusConnection::systemBus().connect(UD2_DBUS_SERVICE, UD2_DBUS_PATH, DBUS_INTERFACE_MANAGER, "InterfacesRemoved",
1494 + this, SLOT(slotInterfacesRemoved(QDBusObjectPath,QStringList)));
1495 +
1496 + initInterfaces();
1497 + }
1498 +}
1499 +
1500 +DeviceBackend::~DeviceBackend()
1501 +{
1502 +}
1503 +
1504 +void DeviceBackend::initInterfaces()
1505 +{
1506 + m_interfaces.clear();
1507 + const QString xmlData = introspect();
1508 + QDomDocument dom;
1509 + dom.setContent(xmlData);
1510 + QDomNodeList ifaceNodeList = dom.elementsByTagName("interface");
1511 + for (int i = 0; i < ifaceNodeList.count(); i++) {
1512 + QDomElement ifaceElem = ifaceNodeList.item(i).toElement();
1513 + if (!ifaceElem.isNull())
1514 + m_interfaces.append(ifaceElem.attribute("name"));
1515 + }
1516 +}
1517 +
1518 +QStringList DeviceBackend::interfaces() const
1519 +{
1520 + return m_interfaces;
1521 +}
1522 +
1523 +
1524 +QString DeviceBackend::introspect() const
1525 +{
1526 + QDBusMessage call = QDBusMessage::createMethodCall(UD2_DBUS_SERVICE, udi,
1527 + DBUS_INTERFACE_INTROSPECT, "Introspect");
1528 + QDBusPendingReply<QString> reply = QDBusConnection::systemBus().call(call);
1529 +
1530 + if (reply.isValid())
1531 + return reply.value();
1532 + else {
1533 + return QString();
1534 + }
1535 +}
1536 +
1537 +QVariant DeviceBackend::prop(const QString& key)
1538 +{
1539 + checkCache(key);
1540 + return m_propertyCache.value(key);
1541 +}
1542 +
1543 +bool DeviceBackend::propertyExists(const QString& key)
1544 +{
1545 + checkCache(key);
1546 + return m_propertyCache.contains(key);
1547 +}
1548 +
1549 +
1550 +QVariantMap DeviceBackend::allProperties() const
1551 +{
1552 + QDBusMessage call = QDBusMessage::createMethodCall(UD2_DBUS_SERVICE, udi, DBUS_INTERFACE_PROPS, "GetAll");
1553 +
1554 + Q_FOREACH (const QString & iface, m_interfaces) {
1555 + if (iface.startsWith("org.freedesktop.DBus")) {
1556 + continue;
1557 + }
1558 +
1559 + call.setArguments(QVariantList() << iface);
1560 + QDBusPendingReply<QVariantMap> reply = QDBusConnection::systemBus().call(call);
1561 +
1562 + if (reply.isValid()) {
1563 + m_propertyCache.unite(reply.value());
1564 + } else {
1565 + qWarning() << "Error getting props:" << reply.error().name() << reply.error().message();
1566 + }
1567 + //qDebug() << "After iface" << iface << ", cache now contains" << m_cache.size() << "items";
1568 + }
1569 +
1570 + return m_propertyCache;
1571 +}
1572 +
1573 +void DeviceBackend::checkCache(const QString& key) const
1574 +{
1575 + if (m_propertyCache.isEmpty()) { // recreate the cache
1576 + allProperties();
1577 + }
1578 +
1579 + if (m_propertyCache.contains(key)) {
1580 + return;
1581 + }
1582 +
1583 + QVariant reply = m_device->property(key.toUtf8());
1584 +
1585 + if (reply.isValid()) {
1586 + m_propertyCache.insert(key, reply);
1587 + } else {
1588 + qWarning() << "got invalid reply for cache:" << key;
1589 + }
1590 +}
1591 +
1592 +void DeviceBackend::slotPropertiesChanged(const QString& ifaceName, const QVariantMap& changedProps, const QStringList& invalidatedProps)
1593 +{
1594 + qDebug() << udi << "'s interface" << ifaceName << "changed props:";
1595 +
1596 + QMap<QString, int> changeMap;
1597 +
1598 + Q_FOREACH(const QString & key, invalidatedProps) {
1599 + m_propertyCache.remove(key);
1600 + changeMap.insert(key, Solid::GenericInterface::PropertyRemoved);
1601 + qDebug() << "\t invalidated:" << key;
1602 + }
1603 +
1604 + QMapIterator<QString, QVariant> i(changedProps);
1605 + while (i.hasNext()) {
1606 + i.next();
1607 + const QString key = i.key();
1608 + m_propertyCache.insert(key, i.value()); // replace the value
1609 + changeMap.insert(key, Solid::GenericInterface::PropertyModified);
1610 + qDebug() << "\t modified:" << key << ":" << m_propertyCache.value(key);
1611 + }
1612 +
1613 + Q_EMIT propertyChanged(changeMap);
1614 + Q_EMIT changed();
1615 +}
1616 +
1617 +void DeviceBackend::slotInterfacesAdded(const QDBusObjectPath& object_path, const QVariantMapMap& interfaces_and_properties)
1618 +{
1619 + if (object_path.path() == udi) {
1620 + m_interfaces.append(interfaces_and_properties.keys());
1621 + }
1622 +}
1623 +
1624 +void DeviceBackend::slotInterfacesRemoved(const QDBusObjectPath& object_path, const QStringList& interfaces)
1625 +{
1626 + if (object_path.path() == udi) {
1627 + Q_FOREACH(const QString & iface, interfaces) {
1628 + m_interfaces.removeAll(iface);
1629 + }
1630 + }
1631 +}
1632 diff --git a/solid/solid/backends/udisks2/udisksdevicebackend.h b/solid/solid/backends/udisks2/udisksdevicebackend.h
1633 new file mode 100644
1634 index 0000000..4953ad5
1635 --- /dev/null
1636 +++ b/solid/solid/backends/udisks2/udisksdevicebackend.h
1637 @@ -0,0 +1,83 @@
1638 +/*
1639 + Copyright 2010 Michael Zanetti <mzanetti@kde.org>
1640 + Copyright 2010-2012 Lukáš Tinkl <ltinkl@redhat.com>
1641 + Copyright 2012 Dan Vrátil <dvratil@redhat.com>
1642 +
1643 + This library is free software; you can redistribute it and/or
1644 + modify it under the terms of the GNU Lesser General Public
1645 + License as published by the Free Software Foundation; either
1646 + version 2.1 of the License, or (at your option) version 3, or any
1647 + later version accepted by the membership of KDE e.V. (or its
1648 + successor approved by the membership of KDE e.V.), which shall
1649 + act as a proxy defined in Section 6 of version 3 of the license.
1650 +
1651 + This library is distributed in the hope that it will be useful,
1652 + but WITHOUT ANY WARRANTY; without even the implied warranty of
1653 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1654 + Lesser General Public License for more details.
1655 +
1656 + You should have received a copy of the GNU Lesser General Public
1657 + License along with this library. If not, see <http://www.gnu.org/licenses/>.
1658 +*/
1659 +
1660 +#ifndef UDISKSDEVICEBACKEND_H
1661 +#define UDISKSDEVICEBACKEND_H
1662 +
1663 +#include <QObject>
1664 +#include <QtDBus/QDBusConnection>
1665 +#include <QtDBus/QDBusObjectPath>
1666 +#include <QtDBus/QDBusInterface>
1667 +#include <QStringList>
1668 +
1669 +#include "udisks2.h"
1670 +
1671 +namespace Solid {
1672 +namespace Backends {
1673 +namespace UDisks2 {
1674 +
1675 +class DeviceBackend: public QObject {
1676 +
1677 + Q_OBJECT
1678 +
1679 + public:
1680 + static DeviceBackend* backendForUDI(const QString &udi);
1681 +
1682 + DeviceBackend(const QString &udi);
1683 + ~DeviceBackend();
1684 +
1685 + void initInterfaces();
1686 + QString introspect() const;
1687 +
1688 + QVariant prop(const QString &key);
1689 + bool propertyExists(const QString &key);
1690 + QVariantMap allProperties() const;
1691 + void checkCache(const QString &key) const;
1692 +
1693 + QStringList interfaces() const;
1694 +
1695 + QString udi;
1696 +
1697 + Q_SIGNALS:
1698 + void propertyChanged(const QMap<QString, int> &changeMap);
1699 + void changed();
1700 +
1701 + private Q_SLOTS:
1702 + void slotInterfacesAdded(const QDBusObjectPath &object_path, const QVariantMapMap &interfaces_and_properties);
1703 + void slotInterfacesRemoved(const QDBusObjectPath &object_path, const QStringList &interfaces);
1704 + void slotPropertiesChanged(const QString &ifaceName, const QVariantMap &changedProps, const QStringList &invalidatedProps);
1705 +
1706 + private:
1707 + QDBusInterface *m_device;
1708 +
1709 + mutable QVariantMap m_propertyCache;
1710 + QStringList m_interfaces;
1711 +
1712 + static QMap<QString, DeviceBackend*> s_backends;
1713 +
1714 +};
1715 +
1716 +} /* namespace UDisks2 */
1717 +} /* namespace Backends */
1718 +} /* namespace Solid */
1719 +
1720 +#endif /* UDISKSDEVICEBACKEND_H */
1721 \ No newline at end of file
1722 diff --git a/solid/solid/backends/udisks2/udisksdeviceinterface.cpp b/solid/solid/backends/udisks2/udisksdeviceinterface.cpp
1723 new file mode 100644
1724 index 0000000..9fa60e5
1725 --- /dev/null
1726 +++ b/solid/solid/backends/udisks2/udisksdeviceinterface.cpp
1727 @@ -0,0 +1,33 @@
1728 +/*
1729 + Copyright 2010 Michael Zanetti <mzanetti@kde.org>
1730 +
1731 + This library is free software; you can redistribute it and/or
1732 + modify it under the terms of the GNU Lesser General Public
1733 + License as published by the Free Software Foundation; either
1734 + version 2.1 of the License, or (at your option) version 3, or any
1735 + later version accepted by the membership of KDE e.V. (or its
1736 + successor approved by the membership of KDE e.V.), which shall
1737 + act as a proxy defined in Section 6 of version 3 of the license.
1738 +
1739 + This library is distributed in the hope that it will be useful,
1740 + but WITHOUT ANY WARRANTY; without even the implied warranty of
1741 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1742 + Lesser General Public License for more details.
1743 +
1744 + You should have received a copy of the GNU Lesser General Public
1745 + License along with this library. If not, see <http://www.gnu.org/licenses/>.
1746 +*/
1747 +
1748 +#include "udisksdeviceinterface.h"
1749 +
1750 +using namespace Solid::Backends::UDisks2;
1751 +
1752 +DeviceInterface::DeviceInterface(Device *device)
1753 + : QObject(device), m_device(device)
1754 +{
1755 +
1756 +}
1757 +
1758 +DeviceInterface::~DeviceInterface()
1759 +{
1760 +}
1761 diff --git a/solid/solid/backends/udisks2/udisksdeviceinterface.h b/solid/solid/backends/udisks2/udisksdeviceinterface.h
1762 new file mode 100644
1763 index 0000000..43a1b6f
1764 --- /dev/null
1765 +++ b/solid/solid/backends/udisks2/udisksdeviceinterface.h
1766 @@ -0,0 +1,148 @@
1767 +/*
1768 + Copyright 2010 Michael Zanetti <mzanetti@kde.org>
1769 +
1770 + This library is free software; you can redistribute it and/or
1771 + modify it under the terms of the GNU Lesser General Public
1772 + License as published by the Free Software Foundation; either
1773 + version 2.1 of the License, or (at your option) version 3, or any
1774 + later version accepted by the membership of KDE e.V. (or its
1775 + successor approved by the membership of KDE e.V.), which shall
1776 + act as a proxy defined in Section 6 of version 3 of the license.
1777 +
1778 + This library is distributed in the hope that it will be useful,
1779 + but WITHOUT ANY WARRANTY; without even the implied warranty of
1780 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1781 + Lesser General Public License for more details.
1782 +
1783 + You should have received a copy of the GNU Lesser General Public
1784 + License along with this library. If not, see <http://www.gnu.org/licenses/>.
1785 +*/
1786 +
1787 +#ifndef UDISKS2DEVICEINTERFACE_H
1788 +#define UDISKS2DEVICEINTERFACE_H
1789 +
1790 +#include <ifaces/deviceinterface.h>
1791 +#include "udisksdevice.h"
1792 +
1793 +#include <QtCore/QObject>
1794 +#include <QtCore/QStringList>
1795 +
1796 +namespace Solid
1797 +{
1798 +namespace Backends
1799 +{
1800 +namespace UDisks2
1801 +{
1802 +
1803 +class DeviceInterface : public QObject, virtual public Solid::Ifaces::DeviceInterface
1804 +{
1805 + Q_OBJECT
1806 + Q_INTERFACES(Solid::Ifaces::DeviceInterface)
1807 +public:
1808 + DeviceInterface(Device *device);
1809 + virtual ~DeviceInterface();
1810 +
1811 +protected:
1812 + Device *m_device;
1813 +
1814 +public:
1815 + inline static QStringList toStringList(Solid::DeviceInterface::Type type)
1816 + {
1817 + QStringList list;
1818 +
1819 + switch(type)
1820 + {
1821 + case Solid::DeviceInterface::GenericInterface:
1822 + list << "generic";
1823 + break;
1824 + case Solid::DeviceInterface::Processor:
1825 + // Doesn't exist with UDisks
1826 + break;
1827 + case Solid::DeviceInterface::Block:
1828 + list << "block";
1829 + break;
1830 + case Solid::DeviceInterface::StorageAccess:
1831 + list << "volume";
1832 + break;
1833 + case Solid::DeviceInterface::StorageDrive:
1834 + list << "storage";
1835 + break;
1836 + case Solid::DeviceInterface::OpticalDrive:
1837 + list << "storage.cdrom";
1838 + break;
1839 + case Solid::DeviceInterface::StorageVolume:
1840 + list << "volume";
1841 + break;
1842 + case Solid::DeviceInterface::OpticalDisc:
1843 + list << "volume.disc";
1844 + break;
1845 + case Solid::DeviceInterface::Camera:
1846 + // Doesn't exist with UDisks
1847 + break;
1848 + case Solid::DeviceInterface::PortableMediaPlayer:
1849 + // Doesn't exist with UDisks
1850 + break;
1851 + case Solid::DeviceInterface::NetworkInterface:
1852 + // Doesn't exist with UDisks
1853 + break;
1854 + case Solid::DeviceInterface::AcAdapter:
1855 + // Doesn't exist with UDisks
1856 + break;
1857 + case Solid::DeviceInterface::Battery:
1858 + // Doesn't exist with UDisks
1859 + break;
1860 + case Solid::DeviceInterface::Button:
1861 + // Doesn't exist with UDisks
1862 + break;
1863 + case Solid::DeviceInterface::AudioInterface:
1864 + // Doesn't exist with UDisks
1865 + break;
1866 + case Solid::DeviceInterface::DvbInterface:
1867 + // Doesn't exist with UDisks
1868 + break;
1869 + case Solid::DeviceInterface::Video:
1870 + // Doesn't exist with UDisks
1871 + break;
1872 + case Solid::DeviceInterface::SerialInterface:
1873 + // Doesn't exist with UDisks
1874 + break;
1875 + case Solid::DeviceInterface::InternetGateway:
1876 + break;
1877 + case Solid::DeviceInterface::SmartCardReader:
1878 + // Doesn't exist with UDisks
1879 + case Solid::DeviceInterface::NetworkShare:
1880 + // Doesn't exist with UDisks
1881 + break;
1882 + case Solid::DeviceInterface::Unknown:
1883 + break;
1884 + case Solid::DeviceInterface::Last:
1885 + break;
1886 + }
1887 +
1888 + return list;
1889 + }
1890 +
1891 + inline static Solid::DeviceInterface::Type fromString(const QString &capability)
1892 + {
1893 + if (capability == "generic")
1894 + return Solid::DeviceInterface::GenericInterface;
1895 + else if (capability == "block")
1896 + return Solid::DeviceInterface::Block;
1897 + else if (capability == "storage")
1898 + return Solid::DeviceInterface::StorageDrive;
1899 + else if (capability == "storage.cdrom")
1900 + return Solid::DeviceInterface::OpticalDrive;
1901 + else if (capability == "volume")
1902 + return Solid::DeviceInterface::StorageVolume;
1903 + else if (capability == "volume.disc")
1904 + return Solid::DeviceInterface::OpticalDisc;
1905 + else
1906 + return Solid::DeviceInterface::Unknown;
1907 + }
1908 +};
1909 +
1910 +}
1911 +}
1912 +}
1913 +
1914 +#endif // UDISKS2DEVICEINTERFACE_H
1915 diff --git a/solid/solid/backends/udisks2/udisksgenericinterface.cpp b/solid/solid/backends/udisks2/udisksgenericinterface.cpp
1916 new file mode 100644
1917 index 0000000..2d8cea2
1918 --- /dev/null
1919 +++ b/solid/solid/backends/udisks2/udisksgenericinterface.cpp
1920 @@ -0,0 +1,53 @@
1921 +/*
1922 + Copyright 2009 Pino Toscano <pino@kde.org>
1923 + Copyright 2012 Lukáš Tinkl <ltinkl@redhat.com>
1924 +
1925 + This library is free software; you can redistribute it and/or
1926 + modify it under the terms of the GNU Lesser General Public
1927 + License as published by the Free Software Foundation; either
1928 + version 2.1 of the License, or (at your option) version 3, or any
1929 + later version accepted by the membership of KDE e.V. (or its
1930 + successor approved by the membership of KDE e.V.), which shall
1931 + act as a proxy defined in Section 6 of version 3 of the license.
1932 +
1933 + This library is distributed in the hope that it will be useful,
1934 + but WITHOUT ANY WARRANTY; without even the implied warranty of
1935 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1936 + Lesser General Public License for more details.
1937 +
1938 + You should have received a copy of the GNU Lesser General Public
1939 + License along with this library. If not, see <http://www.gnu.org/licenses/>.
1940 +*/
1941 +
1942 +#include "udisksgenericinterface.h"
1943 +
1944 +#include "udisksdevice.h"
1945 +
1946 +using namespace Solid::Backends::UDisks2;
1947 +
1948 +GenericInterface::GenericInterface(Device *device)
1949 + : DeviceInterface(device)
1950 +{
1951 + connect(device, SIGNAL(propertyChanged(QMap<QString,int>)),
1952 + this, SIGNAL(propertyChanged(QMap<QString,int>)));
1953 +}
1954 +
1955 +GenericInterface::~GenericInterface()
1956 +{
1957 +}
1958 +
1959 +QVariant GenericInterface::property(const QString &key) const
1960 +{
1961 + return m_device->prop(key);
1962 +}
1963 +
1964 +QVariantMap GenericInterface::allProperties() const
1965 +{
1966 + return m_device->allProperties();
1967 +}
1968 +
1969 +bool GenericInterface::propertyExists(const QString &key) const
1970 +{
1971 + return m_device->propertyExists(key);
1972 +}
1973 +
1974 diff --git a/solid/solid/backends/udisks2/udisksgenericinterface.h b/solid/solid/backends/udisks2/udisksgenericinterface.h
1975 new file mode 100644
1976 index 0000000..d225f32
1977 --- /dev/null
1978 +++ b/solid/solid/backends/udisks2/udisksgenericinterface.h
1979 @@ -0,0 +1,57 @@
1980 +/*
1981 + Copyright 2009 Pino Toscano <pino@kde.org>
1982 +
1983 + This library is free software; you can redistribute it and/or
1984 + modify it under the terms of the GNU Lesser General Public
1985 + License as published by the Free Software Foundation; either
1986 + version 2.1 of the License, or (at your option) version 3, or any
1987 + later version accepted by the membership of KDE e.V. (or its
1988 + successor approved by the membership of KDE e.V.), which shall
1989 + act as a proxy defined in Section 6 of version 3 of the license.
1990 +
1991 + This library is distributed in the hope that it will be useful,
1992 + but WITHOUT ANY WARRANTY; without even the implied warranty of
1993 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1994 + Lesser General Public License for more details.
1995 +
1996 + You should have received a copy of the GNU Lesser General Public
1997 + License along with this library. If not, see <http://www.gnu.org/licenses/>.
1998 +*/
1999 +
2000 +#ifndef SOLID_BACKENDS_UDISKS2_GENERICINTERFACE_H
2001 +#define SOLID_BACKENDS_UDISKS2_GENERICINTERFACE_H
2002 +
2003 +#include <solid/ifaces/genericinterface.h>
2004 +#include <solid/genericinterface.h>
2005 +#include "udisksdeviceinterface.h"
2006 +
2007 +namespace Solid
2008 +{
2009 +namespace Backends
2010 +{
2011 +namespace UDisks2
2012 +{
2013 +class Device;
2014 +
2015 +class GenericInterface : public DeviceInterface, virtual public Solid::Ifaces::GenericInterface
2016 +{
2017 + Q_OBJECT
2018 + Q_INTERFACES(Solid::Ifaces::GenericInterface)
2019 +
2020 +public:
2021 + GenericInterface(Device *device);
2022 + virtual ~GenericInterface();
2023 +
2024 + virtual QVariant property(const QString &key) const;
2025 + virtual QVariantMap allProperties() const;
2026 + virtual bool propertyExists(const QString &key) const;
2027 +
2028 +Q_SIGNALS:
2029 + void propertyChanged(const QMap<QString, int> &changes);
2030 + void conditionRaised(const QString &condition, const QString &reason);
2031 +};
2032 +}
2033 +}
2034 +}
2035 +
2036 +#endif // SOLID_BACKENDS_UDISKS2_GENERICINTERFACE_H
2037 diff --git a/solid/solid/backends/udisks2/udisksmanager.cpp b/solid/solid/backends/udisks2/udisksmanager.cpp
2038 new file mode 100644
2039 index 0000000..69e053f
2040 --- /dev/null
2041 +++ b/solid/solid/backends/udisks2/udisksmanager.cpp
2042 @@ -0,0 +1,238 @@
2043 +/*
2044 + Copyright 2012 Lukáš Tinkl <ltinkl@redhat.com>
2045 +
2046 + This library is free software; you can redistribute it and/or
2047 + modify it under the terms of the GNU Lesser General Public
2048 + License as published by the Free Software Foundation; either
2049 + version 2.1 of the License, or (at your option) version 3, or any
2050 + later version accepted by the membership of KDE e.V. (or its
2051 + successor approved by the membership of KDE e.V.), which shall
2052 + act as a proxy defined in Section 6 of version 3 of the license.
2053 +
2054 + This library is distributed in the hope that it will be useful,
2055 + but WITHOUT ANY WARRANTY; without even the implied warranty of
2056 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2057 + Lesser General Public License for more details.
2058 +
2059 + You should have received a copy of the GNU Lesser General Public
2060 + License along with this library. If not, see <http://www.gnu.org/licenses/>.
2061 +*/
2062 +
2063 +#include "udisksmanager.h"
2064 +
2065 +#include <QtCore/QCoreApplication>
2066 +#include <QtCore/QDebug>
2067 +#include <QtDBus>
2068 +#include <QtXml/QDomDocument>
2069 +
2070 +#include "../shared/rootdevice.h"
2071 +
2072 +using namespace Solid::Backends::UDisks2;
2073 +using namespace Solid::Backends::Shared;
2074 +
2075 +Manager::Manager(QObject *parent)
2076 + : Solid::Ifaces::DeviceManager(parent),
2077 + m_manager(UD2_DBUS_SERVICE,
2078 + UD2_DBUS_PATH,
2079 + QDBusConnection::systemBus())
2080 +{
2081 + m_supportedInterfaces
2082 + << Solid::DeviceInterface::GenericInterface
2083 + << Solid::DeviceInterface::Block
2084 + << Solid::DeviceInterface::StorageAccess
2085 + << Solid::DeviceInterface::StorageDrive
2086 + << Solid::DeviceInterface::OpticalDrive
2087 + << Solid::DeviceInterface::OpticalDisc
2088 + << Solid::DeviceInterface::StorageVolume;
2089 +
2090 + qDBusRegisterMetaType<QList<QDBusObjectPath> >();
2091 + qDBusRegisterMetaType<QVariantMap>();
2092 + qDBusRegisterMetaType<QVariantMapMap>();
2093 + qDBusRegisterMetaType<QByteArrayList>();
2094 + qDBusRegisterMetaType<DBUSManagerStruct>();
2095 +
2096 + bool serviceFound = m_manager.isValid();
2097 + if (!serviceFound) {
2098 + // find out whether it will be activated automatically
2099 + QDBusMessage message = QDBusMessage::createMethodCall("org.freedesktop.DBus",
2100 + "/org/freedesktop/DBus",
2101 + "org.freedesktop.DBus",
2102 + "ListActivatableNames");
2103 +
2104 + QDBusReply<QStringList> reply = QDBusConnection::systemBus().call(message);
2105 + if (reply.isValid() && reply.value().contains(UD2_DBUS_SERVICE)) {
2106 + QDBusConnection::systemBus().interface()->startService(UD2_DBUS_SERVICE);
2107 + serviceFound = true;
2108 + }
2109 + }
2110 +
2111 + if (serviceFound) {
2112 + connect(&m_manager, SIGNAL(InterfacesAdded(QDBusObjectPath, QVariantMapMap)),
2113 + this, SLOT(slotInterfacesAdded(QDBusObjectPath,QVariantMapMap)));
2114 + connect(&m_manager, SIGNAL(InterfacesRemoved(QDBusObjectPath,QStringList)),
2115 + this, SLOT(slotInterfacesRemoved(QDBusObjectPath,QStringList)));
2116 + }
2117 +}
2118 +
2119 +Manager::~Manager()
2120 +{
2121 + QDBusConnection::systemBus().disconnectFromBus("Solid::UDisks2");
2122 +}
2123 +
2124 +QObject* Manager::createDevice(const QString& udi)
2125 +{
2126 + if (udi==udiPrefix()) {
2127 + RootDevice *root = new RootDevice(udi);
2128 +
2129 + root->setProduct(QCoreApplication::translate("", "Storage"));
2130 + root->setDescription(QCoreApplication::translate("", "Storage devices"));
2131 + root->setIcon("server-database"); // Obviously wasn't meant for that, but maps nicely in oxygen icon set :-p
2132 +
2133 + return root;
2134 + } else if (deviceCache().contains(udi)) {
2135 + return new Device(udi);
2136 + } else {
2137 + return 0;
2138 + }
2139 +}
2140 +
2141 +QStringList Manager::devicesFromQuery(const QString& parentUdi, Solid::DeviceInterface::Type type)
2142 +{
2143 + QStringList result;
2144 +
2145 + if (!parentUdi.isEmpty())
2146 + {
2147 + Q_FOREACH (const QString &udi, deviceCache())
2148 + {
2149 + Device device(udi);
2150 + if (device.queryDeviceInterface(type) && device.parentUdi() == parentUdi)
2151 + result << udi;
2152 + }
2153 +
2154 + return result;
2155 + }
2156 + else if (type != Solid::DeviceInterface::Unknown)
2157 + {
2158 + Q_FOREACH (const QString &udi, deviceCache())
2159 + {
2160 + Device device(udi);
2161 + if (device.queryDeviceInterface(type))
2162 + result << udi;
2163 + }
2164 +
2165 + return result;
2166 + }
2167 +
2168 + return deviceCache();
2169 +}
2170 +
2171 +QStringList Manager::allDevices()
2172 +{
2173 + m_deviceCache.clear();
2174 +
2175 + introspect("/org/freedesktop/UDisks2/block_devices", true /*checkOptical*/);
2176 + introspect("/org/freedesktop/UDisks2/drives");
2177 +
2178 + return m_deviceCache;
2179 +}
2180 +
2181 +void Manager::introspect(const QString & path, bool checkOptical)
2182 +{
2183 + QDBusMessage call = QDBusMessage::createMethodCall(UD2_DBUS_SERVICE, path,
2184 + DBUS_INTERFACE_INTROSPECT, "Introspect");
2185 + QDBusPendingReply<QString> reply = QDBusConnection::systemBus().call(call);
2186 +
2187 + if (reply.isValid()) {
2188 + QDomDocument dom;
2189 + dom.setContent(reply.value());
2190 + QDomNodeList nodeList = dom.documentElement().elementsByTagName("node");
2191 + for (int i = 0; i < nodeList.count(); i++) {
2192 + QDomElement nodeElem = nodeList.item(i).toElement();
2193 + if (!nodeElem.isNull() && nodeElem.hasAttribute("name")) {
2194 + const QString udi = path + "/" + nodeElem.attribute("name");
2195 +
2196 + if (checkOptical) {
2197 + Device device(udi);
2198 + if (device.mightBeOpticalDisc()) {
2199 + QDBusConnection::systemBus().connect(UD2_DBUS_SERVICE, udi, DBUS_INTERFACE_PROPS, "PropertiesChanged", this,
2200 + SLOT(slotMediaChanged(QDBusMessage)));
2201 + if (!device.isOpticalDisc()) // skip empty CD disc
2202 + continue;
2203 + }
2204 + }
2205 +
2206 + m_deviceCache.append(udi);
2207 + }
2208 + }
2209 + }
2210 + else
2211 + qWarning() << "Failed enumerating UDisks2 objects:" << reply.error().name() << "\n" << reply.error().message();
2212 +}
2213 +
2214 +QSet< Solid::DeviceInterface::Type > Manager::supportedInterfaces() const
2215 +{
2216 + return m_supportedInterfaces;
2217 +}
2218 +
2219 +QString Manager::udiPrefix() const
2220 +{
2221 + return UD2_UDI_DISKS_PREFIX;
2222 +}
2223 +
2224 +void Manager::slotInterfacesAdded(const QDBusObjectPath &object_path, const QVariantMapMap &interfaces_and_properties)
2225 +{
2226 + const QString udi = object_path.path();
2227 +
2228 + qDebug() << udi << "has new interfaces:" << interfaces_and_properties.keys();
2229 +
2230 + // new device, we don't know it yet
2231 + if (!m_deviceCache.contains(udi)) {
2232 + m_deviceCache.append(udi);
2233 + Q_EMIT deviceAdded(udi);
2234 + }
2235 +}
2236 +
2237 +void Manager::slotInterfacesRemoved(const QDBusObjectPath &object_path, const QStringList &interfaces)
2238 +{
2239 + const QString udi = object_path.path();
2240 +
2241 + qDebug() << udi << "lost interfaces:" << interfaces;
2242 +
2243 + Device device(udi);
2244 +
2245 + if (!udi.isEmpty() && (interfaces.isEmpty() || device.interfaces().isEmpty() || device.interfaces().contains(UD2_DBUS_INTERFACE_FILESYSTEM))) {
2246 + Q_EMIT deviceRemoved(udi);
2247 + m_deviceCache.removeAll(udi);
2248 + }
2249 +}
2250 +
2251 +void Manager::slotMediaChanged(const QDBusMessage & msg)
2252 +{
2253 + const QVariantMap properties = qdbus_cast<QVariantMap>(msg.arguments().at(1));
2254 +
2255 + if (!properties.contains("Size")) // react only on Size changes
2256 + return;
2257 +
2258 + const QString udi = msg.path();
2259 + qulonglong size = properties.value("Size").toULongLong();
2260 + qDebug() << "MEDIA CHANGED in" << udi << "; size is:" << size;
2261 +
2262 + if (!m_deviceCache.contains(udi) && size > 0) { // we don't know the optdisc, got inserted
2263 + m_deviceCache.append(udi);
2264 + Q_EMIT deviceAdded(udi);
2265 + }
2266 +
2267 + if (m_deviceCache.contains(udi) && size == 0) { // we know the optdisc, got removed
2268 + Q_EMIT deviceRemoved(udi);
2269 + m_deviceCache.removeAll(udi);
2270 + }
2271 +}
2272 +
2273 +const QStringList & Manager::deviceCache()
2274 +{
2275 + if (m_deviceCache.isEmpty())
2276 + allDevices();
2277 +
2278 + return m_deviceCache;
2279 +}
2280 +
2281 diff --git a/solid/solid/backends/udisks2/udisksmanager.h b/solid/solid/backends/udisks2/udisksmanager.h
2282 new file mode 100644
2283 index 0000000..fb929ce
2284 --- /dev/null
2285 +++ b/solid/solid/backends/udisks2/udisksmanager.h
2286 @@ -0,0 +1,70 @@
2287 +/*
2288 + Copyright 2010 Michael Zanetti <mzanetti@kde.org>
2289 + Copyright 2010-2012 Lukáš Tinkl <ltinkl@redhat.com>
2290 +
2291 + This library is free software; you can redistribute it and/or
2292 + modify it under the terms of the GNU Lesser General Public
2293 + License as published by the Free Software Foundation; either
2294 + version 2.1 of the License, or (at your option) version 3, or any
2295 + later version accepted by the membership of KDE e.V. (or its
2296 + successor approved by the membership of KDE e.V.), which shall
2297 + act as a proxy defined in Section 6 of version 3 of the license.
2298 +
2299 + This library is distributed in the hope that it will be useful,
2300 + but WITHOUT ANY WARRANTY; without even the implied warranty of
2301 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2302 + Lesser General Public License for more details.
2303 +
2304 + You should have received a copy of the GNU Lesser General Public
2305 + License along with this library. If not, see <http://www.gnu.org/licenses/>.
2306 +*/
2307 +
2308 +#ifndef UDISKS2MANAGER_H
2309 +#define UDISKS2MANAGER_H
2310 +
2311 +#include "udisks2.h"
2312 +#include "udisksdevice.h"
2313 +#include "dbus/manager.h"
2314 +
2315 +#include "solid/ifaces/devicemanager.h"
2316 +
2317 +#include <QtDBus/QDBusInterface>
2318 +#include <QtCore/QSet>
2319 +
2320 +namespace Solid
2321 +{
2322 +namespace Backends
2323 +{
2324 +namespace UDisks2
2325 +{
2326 +
2327 +class Manager: public Solid::Ifaces::DeviceManager
2328 +{
2329 + Q_OBJECT
2330 +
2331 +public:
2332 + Manager(QObject *parent);
2333 + virtual QObject* createDevice(const QString& udi);
2334 + virtual QStringList devicesFromQuery(const QString& parentUdi, Solid::DeviceInterface::Type type);
2335 + virtual QStringList allDevices();
2336 + virtual QSet< Solid::DeviceInterface::Type > supportedInterfaces() const;
2337 + virtual QString udiPrefix() const;
2338 + virtual ~Manager();
2339 +
2340 +private Q_SLOTS:
2341 + void slotInterfacesAdded(const QDBusObjectPath &object_path, const QVariantMapMap &interfaces_and_properties);
2342 + void slotInterfacesRemoved(const QDBusObjectPath &object_path, const QStringList &interfaces);
2343 + void slotMediaChanged(const QDBusMessage &msg);
2344 +
2345 +private:
2346 + const QStringList &deviceCache();
2347 + void introspect(const QString & path, bool checkOptical = false);
2348 + QSet<Solid::DeviceInterface::Type> m_supportedInterfaces;
2349 + org::freedesktop::DBus::ObjectManager m_manager;
2350 + QStringList m_deviceCache;
2351 +};
2352 +
2353 +}
2354 +}
2355 +}
2356 +#endif // UDISKS2MANAGER_H
2357 diff --git a/solid/solid/backends/udisks2/udisksopticaldisc.cpp b/solid/solid/backends/udisks2/udisksopticaldisc.cpp
2358 new file mode 100644
2359 index 0000000..dc5256d
2360 --- /dev/null
2361 +++ b/solid/solid/backends/udisks2/udisksopticaldisc.cpp
2362 @@ -0,0 +1,297 @@
2363 +/*
2364 + Copyright 2010 Michael Zanetti <mzanetti@kde.org>
2365 + Copyright 2010 - 2012 Lukáš Tinkl <ltinkl@redhat.com>
2366 +
2367 + This library is free software; you can redistribute it and/or
2368 + modify it under the terms of the GNU Lesser General Public
2369 + License as published by the Free Software Foundation; either
2370 + version 2.1 of the License, or (at your option) version 3, or any
2371 + later version accepted by the membership of KDE e.V. (or its
2372 + successor approved by the membership of KDE e.V.), which shall
2373 + act as a proxy defined in Section 6 of version 3 of the license.
2374 +
2375 + This library is distributed in the hope that it will be useful,
2376 + but WITHOUT ANY WARRANTY; without even the implied warranty of
2377 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2378 + Lesser General Public License for more details.
2379 +
2380 + You should have received a copy of the GNU Lesser General Public
2381 + License along with this library. If not, see <http://www.gnu.org/licenses/>.
2382 +*/
2383 +
2384 +#include <sys/types.h>
2385 +#include <unistd.h>
2386 +#include <sys/stat.h>
2387 +#include <fcntl.h>
2388 +
2389 +#include <QtCore/QFile>
2390 +#include <QtCore/QMap>
2391 +#include <QtCore/QMutexLocker>
2392 +#include <QtDBus/QDBusConnection>
2393 +
2394 +#include "../shared/udevqt.h"
2395 +
2396 +#include "udisks2.h"
2397 +#include "udisksopticaldisc.h"
2398 +#include "soliddefs_p.h"
2399 +
2400 +typedef QMap<QByteArray, Solid::OpticalDisc::ContentTypes> ContentTypesCache;
2401 +SOLID_GLOBAL_STATIC(ContentTypesCache, cache)
2402 +SOLID_GLOBAL_STATIC(QMutex, cacheLock)
2403 +
2404 +// inspired by http://cgit.freedesktop.org/hal/tree/hald/linux/probing/probe-volume.c
2405 +static Solid::OpticalDisc::ContentType advancedDiscDetect(const QByteArray & device_file)
2406 +{
2407 + /* the discs block size */
2408 + unsigned short bs;
2409 + /* the path table size */
2410 + unsigned short ts;
2411 + /* the path table location (in blocks) */
2412 + unsigned int tl;
2413 + /* length of the directory name in current path table entry */
2414 + unsigned char len_di = 0;
2415 + /* the number of the parent directory's path table entry */
2416 + unsigned int parent = 0;
2417 + /* filename for the current path table entry */
2418 + char dirname[256];
2419 + /* our position into the path table */
2420 + int pos = 0;
2421 + /* the path table record we're on */
2422 + int curr_record = 1;
2423 +
2424 + Solid::OpticalDisc::ContentType result = Solid::OpticalDisc::NoContent;
2425 +
2426 + int fd = open(device_file.constData(), O_RDONLY);
2427 +
2428 + /* read the block size */
2429 + lseek (fd, 0x8080, SEEK_CUR);
2430 + if (read (fd, &bs, 2) != 2)
2431 + {
2432 + qDebug("Advanced probing on %s failed while reading block size", qPrintable(device_file));
2433 + goto out;
2434 + }
2435 +
2436 + /* read in size of path table */
2437 + lseek (fd, 2, SEEK_CUR);
2438 + if (read (fd, &ts, 2) != 2)
2439 + {
2440 + qDebug("Advanced probing on %s failed while reading path table size", qPrintable(device_file));
2441 + goto out;
2442 + }
2443 +
2444 + /* read in which block path table is in */
2445 + lseek (fd, 6, SEEK_CUR);
2446 + if (read (fd, &tl, 4) != 4)
2447 + {
2448 + qDebug("Advanced probing on %s failed while reading path table block", qPrintable(device_file));
2449 + goto out;
2450 + }
2451 +
2452 + /* seek to the path table */
2453 + lseek (fd, bs * tl, SEEK_SET);
2454 +
2455 + /* loop through the path table entries */
2456 + while (pos < ts)
2457 + {
2458 + /* get the length of the filename of the current entry */
2459 + if (read (fd, &len_di, 1) != 1)
2460 + {
2461 + qDebug("Advanced probing on %s failed, cannot read more entries", qPrintable(device_file));
2462 + break;
2463 + }
2464 +
2465 + /* get the record number of this entry's parent
2466 + i'm pretty sure that the 1st entry is always the top directory */
2467 + lseek (fd, 5, SEEK_CUR);
2468 + if (read (fd, &parent, 2) != 2)
2469 + {
2470 + qDebug("Advanced probing on %s failed, couldn't read parent entry", qPrintable(device_file));
2471 + break;
2472 + }
2473 +
2474 + /* read the name */
2475 + if (read (fd, dirname, len_di) != len_di)
2476 + {
2477 + qDebug("Advanced probing on %s failed, couldn't read the entry name", qPrintable(device_file));
2478 + break;
2479 + }
2480 + dirname[len_di] = 0;
2481 +
2482 + /* if we found a folder that has the root as a parent, and the directory name matches
2483 + one of the special directories then set the properties accordingly */
2484 + if (parent == 1)
2485 + {
2486 + if (!strcasecmp (dirname, "VIDEO_TS"))
2487 + {
2488 + qDebug("Disc in %s is a Video DVD", qPrintable(device_file));
2489 + result = Solid::OpticalDisc::VideoDvd;
2490 + break;
2491 + }
2492 + else if (!strcasecmp (dirname, "BDMV"))
2493 + {
2494 + qDebug("Disc in %s is a Blu-ray video disc", qPrintable(device_file));
2495 + result = Solid::OpticalDisc::VideoBluRay;
2496 + break;
2497 + }
2498 + else if (!strcasecmp (dirname, "VCD"))
2499 + {
2500 + qDebug("Disc in %s is a Video CD", qPrintable(device_file));
2501 + result = Solid::OpticalDisc::VideoCd;
2502 + break;
2503 + }
2504 + else if (!strcasecmp (dirname, "SVCD"))
2505 + {
2506 + qDebug("Disc in %s is a Super Video CD", qPrintable(device_file));
2507 + result = Solid::OpticalDisc::SuperVideoCd;
2508 + break;
2509 + }
2510 + }
2511 +
2512 + /* all path table entries are padded to be even,
2513 + so if this is an odd-length table, seek a byte to fix it */
2514 + if (len_di%2 == 1)
2515 + {
2516 + lseek (fd, 1, SEEK_CUR);
2517 + pos++;
2518 + }
2519 +
2520 + /* update our position */
2521 + pos += 8 + len_di;
2522 + curr_record++;
2523 + }
2524 +
2525 + close(fd);
2526 + return result;
2527 +
2528 +out:
2529 + /* go back to the start of the file */
2530 + lseek (fd, 0, SEEK_SET);
2531 + close(fd);
2532 + return result;
2533 +}
2534 +
2535 +using namespace Solid::Backends::UDisks2;
2536 +
2537 +OpticalDisc::OpticalDisc(Device *dev)
2538 + : StorageVolume(dev), m_needsReprobe(true), m_cachedContent(Solid::OpticalDisc::NoContent)
2539 +{
2540 + UdevQt::Client client(this);
2541 + m_udevDevice = client.deviceByDeviceFile(device());
2542 + //qDebug() << "udev device:" << m_udevDevice.name() << "valid:" << m_udevDevice.isValid();
2543 + /*qDebug() << "\tProperties:" << */ m_udevDevice.deviceProperties(); // initialize the properties DB so that it doesn't crash further down, #298416
2544 +
2545 + m_drive = new Device(m_device->prop("Drive").value<QDBusObjectPath>().path());
2546 + QDBusConnection::systemBus().connect(UD2_DBUS_SERVICE, m_drive->udi(), DBUS_INTERFACE_PROPS, "PropertiesChanged", this,
2547 + SLOT(slotDrivePropertiesChanged(QString,QVariantMap,QStringList)));
2548 +}
2549 +
2550 +OpticalDisc::~OpticalDisc()
2551 +{
2552 + delete m_drive;
2553 +}
2554 +
2555 +qulonglong OpticalDisc::capacity() const
2556 +{
2557 + return m_device->prop("Size").toULongLong();
2558 +}
2559 +
2560 +bool OpticalDisc::isRewritable() const
2561 +{
2562 + // the hard way, udisks has no notion of a disc "rewritability"
2563 + const QString mediaType = media();
2564 + return mediaType == "optical_cd_rw" || mediaType == "optical_dvd_rw" || mediaType == "optical_dvd_ram" ||
2565 + mediaType == "optical_dvd_plus_rw" || mediaType == "optical_dvd_plus_rw_dl" ||
2566 + mediaType == "optical_bd_re" || mediaType == "optical_hddvd_rw";
2567 +}
2568 +
2569 +bool OpticalDisc::isBlank() const
2570 +{
2571 + return m_drive->prop("OpticalBlank").toBool();
2572 +}
2573 +
2574 +bool OpticalDisc::isAppendable() const
2575 +{
2576 + //qDebug() << "appendable prop" << m_udevDevice.deviceProperty("ID_CDROM_MEDIA_STATE");
2577 + return m_udevDevice.deviceProperty("ID_CDROM_MEDIA_STATE").toString() == QLatin1String("appendable");
2578 +}
2579 +
2580 +Solid::OpticalDisc::DiscType OpticalDisc::discType() const
2581 +{
2582 + QMap<Solid::OpticalDisc::DiscType, QString> map;
2583 + map[Solid::OpticalDisc::CdRom] = "optical_cd";
2584 + map[Solid::OpticalDisc::CdRecordable] = "optical_cd_r";
2585 + map[Solid::OpticalDisc::CdRewritable] = "optical_cd_rw";
2586 + map[Solid::OpticalDisc::DvdRom] = "optical_dvd";
2587 + map[Solid::OpticalDisc::DvdRecordable] = "optical_dvd_r";
2588 + map[Solid::OpticalDisc::DvdRewritable] ="optical_dvd_rw";
2589 + map[Solid::OpticalDisc::DvdRam] ="optical_dvd_ram";
2590 + map[Solid::OpticalDisc::DvdPlusRecordable] ="optical_dvd_plus_r";
2591 + map[Solid::OpticalDisc::DvdPlusRewritable] ="optical_dvd_plus_rw";
2592 + map[Solid::OpticalDisc::DvdPlusRecordableDuallayer] ="optical_dvd_plus_r_dl";
2593 + map[Solid::OpticalDisc::DvdPlusRewritableDuallayer] ="optical_dvd_plus_rw_dl";
2594 + map[Solid::OpticalDisc::BluRayRom] ="optical_bd";
2595 + map[Solid::OpticalDisc::BluRayRecordable] ="optical_bd_r";
2596 + map[Solid::OpticalDisc::BluRayRewritable] ="optical_bd_re";
2597 + map[Solid::OpticalDisc::HdDvdRom] ="optical_hddvd";
2598 + map[Solid::OpticalDisc::HdDvdRecordable] ="optical_hddvd_r";
2599 + map[Solid::OpticalDisc::HdDvdRewritable] ="optical_hddvd_rw";
2600 + // TODO add these to Solid
2601 + //map[Solid::OpticalDisc::MagnetoOptical] ="optical_mo";
2602 + //map[Solid::OpticalDisc::MountRainer] ="optical_mrw";
2603 + //map[Solid::OpticalDisc::MountRainerWritable] ="optical_mrw_w";
2604 +
2605 + return map.key(media(), Solid::OpticalDisc::UnknownDiscType); // FIXME optimize, lookup by value, not key
2606 +}
2607 +
2608 +Solid::OpticalDisc::ContentTypes OpticalDisc::availableContent() const
2609 +{
2610 + if (isBlank()) {
2611 + m_needsReprobe = false;
2612 + return Solid::OpticalDisc::NoContent;
2613 + }
2614 +
2615 + if (m_needsReprobe) {
2616 + QMutexLocker lock(cacheLock);
2617 +
2618 + const QByteArray deviceFile = m_device->prop("Device").toByteArray();
2619 +
2620 + if (cache->contains(deviceFile)) {
2621 + m_cachedContent = cache->value(deviceFile);
2622 + m_needsReprobe = false;
2623 + return m_cachedContent;
2624 + }
2625 +
2626 + m_cachedContent = Solid::OpticalDisc::NoContent;
2627 + const bool hasData = m_drive->prop("OpticalNumDataTracks").toUInt() > 0;
2628 + const bool hasAudio = m_drive->prop("OpticalNumAudioTracks").toUInt() > 0;
2629 +
2630 + if ( hasData ) {
2631 + m_cachedContent |= Solid::OpticalDisc::Data;
2632 + m_cachedContent |= advancedDiscDetect(deviceFile);
2633 + }
2634 + if ( hasAudio )
2635 + m_cachedContent |= Solid::OpticalDisc::Audio;
2636 +
2637 + m_needsReprobe = false;
2638 + cache->insert(deviceFile, m_cachedContent);
2639 + }
2640 +
2641 + return m_cachedContent;
2642 +}
2643 +
2644 +void OpticalDisc::slotDrivePropertiesChanged(const QString &ifaceName, const QVariantMap &changedProps, const QStringList &invalidatedProps)
2645 +{
2646 + Q_UNUSED(ifaceName);
2647 +
2648 + if (changedProps.keys().contains("Media") || invalidatedProps.contains("Media")) {
2649 + QMutexLocker lock(cacheLock);
2650 + m_needsReprobe = true;
2651 + m_cachedContent = Solid::OpticalDisc::NoContent;
2652 + cache->remove(m_device->prop("Device").toByteArray());
2653 + }
2654 +}
2655 +
2656 +QString OpticalDisc::media() const
2657 +{
2658 + return m_drive->prop("Media").toString();
2659 +}
2660 diff --git a/solid/solid/backends/udisks2/udisksopticaldisc.h b/solid/solid/backends/udisks2/udisksopticaldisc.h
2661 new file mode 100644
2662 index 0000000..0cdcc66
2663 --- /dev/null
2664 +++ b/solid/solid/backends/udisks2/udisksopticaldisc.h
2665 @@ -0,0 +1,69 @@
2666 +/*
2667 + Copyright 2010 Michael Zanetti <mzanetti@kde.org>
2668 + Copyright 2010 - 2012 Lukáš Tinkl <ltinkl@redhat.com>
2669 +
2670 + This library is free software; you can redistribute it and/or
2671 + modify it under the terms of the GNU Lesser General Public
2672 + License as published by the Free Software Foundation; either
2673 + version 2.1 of the License, or (at your option) version 3, or any
2674 + later version accepted by the membership of KDE e.V. (or its
2675 + successor approved by the membership of KDE e.V.), which shall
2676 + act as a proxy defined in Section 6 of version 3 of the license.
2677 +
2678 + This library is distributed in the hope that it will be useful,
2679 + but WITHOUT ANY WARRANTY; without even the implied warranty of
2680 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2681 + Lesser General Public License for more details.
2682 +
2683 + You should have received a copy of the GNU Lesser General Public
2684 + License along with this library. If not, see <http://www.gnu.org/licenses/>.
2685 +*/
2686 +
2687 +#ifndef UDISKS2OPTICALDISC_H
2688 +#define UDISKS2OPTICALDISC_H
2689 +
2690 +#include <solid/ifaces/opticaldisc.h>
2691 +
2692 +#include "../shared/udevqt.h"
2693 +
2694 +#include "udisksstoragevolume.h"
2695 +#include "udisksdevice.h"
2696 +
2697 +namespace Solid
2698 +{
2699 +namespace Backends
2700 +{
2701 +namespace UDisks2
2702 +{
2703 +
2704 +class OpticalDisc: public StorageVolume, virtual public Solid::Ifaces::OpticalDisc
2705 +{
2706 + Q_OBJECT
2707 + Q_INTERFACES(Solid::Ifaces::OpticalDisc)
2708 +
2709 +public:
2710 + OpticalDisc(Device *dev);
2711 + virtual ~OpticalDisc();
2712 +
2713 + virtual qulonglong capacity() const;
2714 + virtual bool isRewritable() const;
2715 + virtual bool isBlank() const;
2716 + virtual bool isAppendable() const;
2717 + virtual Solid::OpticalDisc::DiscType discType() const;
2718 + virtual Solid::OpticalDisc::ContentTypes availableContent() const;
2719 +
2720 +private Q_SLOTS:
2721 + void slotDrivePropertiesChanged(const QString & ifaceName, const QVariantMap & changedProps, const QStringList & invalidatedProps);
2722 +
2723 +private:
2724 + QString media() const;
2725 + mutable bool m_needsReprobe;
2726 + mutable Solid::OpticalDisc::ContentTypes m_cachedContent;
2727 + Device * m_drive;
2728 + UdevQt::Device m_udevDevice;
2729 +};
2730 +
2731 +}
2732 +}
2733 +}
2734 +#endif // UDISKS2OPTICALDISC_H
2735 diff --git a/solid/solid/backends/udisks2/udisksopticaldrive.cpp b/solid/solid/backends/udisks2/udisksopticaldrive.cpp
2736 new file mode 100644
2737 index 0000000..74a901e
2738 --- /dev/null
2739 +++ b/solid/solid/backends/udisks2/udisksopticaldrive.cpp
2740 @@ -0,0 +1,226 @@
2741 +/*
2742 + Copyright 2010 Michael Zanetti <mzanetti@kde.org>
2743 + Copyright 2010-2012 Lukáš Tinkl <ltinkl@redhat.com>
2744 +
2745 + This library is free software; you can redistribute it and/or
2746 + modify it under the terms of the GNU Lesser General Public
2747 + License as published by the Free Software Foundation; either
2748 + version 2.1 of the License, or (at your option) version 3, or any
2749 + later version accepted by the membership of KDE e.V. (or its
2750 + successor approved by the membership of KDE e.V.), which shall
2751 + act as a proxy defined in Section 6 of version 3 of the license.
2752 +
2753 + This library is distributed in the hope that it will be useful,
2754 + but WITHOUT ANY WARRANTY; without even the implied warranty of
2755 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2756 + Lesser General Public License for more details.
2757 +
2758 + You should have received a copy of the GNU Lesser General Public
2759 + License along with this library. If not, see <http://www.gnu.org/licenses/>.
2760 +*/
2761 +
2762 +#include <sys/types.h>
2763 +#include <sys/stat.h>
2764 +#include <fcntl.h>
2765 +#include <string.h>
2766 +#include <errno.h>
2767 +#include <unistd.h>
2768 +#include <stdlib.h>
2769 +
2770 +#include <QtCore/QFile>
2771 +#include <QtCore/QDebug>
2772 +
2773 +#include "udisksopticaldrive.h"
2774 +#include "udisks2.h"
2775 +#include "udisksdevice.h"
2776 +#include "dbus/manager.h"
2777 +
2778 +using namespace Solid::Backends::UDisks2;
2779 +
2780 +OpticalDrive::OpticalDrive(Device *device)
2781 + : StorageDrive(device)
2782 + , m_ejectInProgress(false)
2783 + , m_readSpeed(0)
2784 + , m_writeSpeed(0)
2785 + , m_speedsInit(false)
2786 +{
2787 + m_device->registerAction("eject", this,
2788 + SLOT(slotEjectRequested()),
2789 + SLOT(slotEjectDone(int, const QString&)));
2790 +
2791 + connect(m_device, SIGNAL(changed()), this, SLOT(slotChanged()));
2792 +}
2793 +
2794 +OpticalDrive::~OpticalDrive()
2795 +{
2796 +}
2797 +
2798 +bool OpticalDrive::eject()
2799 +{
2800 + if (m_ejectInProgress)
2801 + return false;
2802 + m_ejectInProgress = true;
2803 + m_device->broadcastActionRequested("eject");
2804 +
2805 + const QString path = m_device->udi();
2806 + QDBusConnection c = QDBusConnection::systemBus();
2807 +
2808 + // if the device is mounted, unmount first
2809 + QString blockPath;
2810 + org::freedesktop::DBus::ObjectManager manager(UD2_DBUS_SERVICE, UD2_DBUS_PATH, c);
2811 + QDBusPendingReply<DBUSManagerStruct> reply = manager.GetManagedObjects();
2812 + reply.waitForFinished();
2813 + if (!reply.isError()) { // enum devices
2814 + Q_FOREACH(const QDBusObjectPath &objPath, reply.value().keys()) {
2815 + const QString udi = objPath.path();
2816 +
2817 + //qDebug() << "Inspecting" << udi;
2818 +
2819 + if (udi == UD2_DBUS_PATH_MANAGER || udi == UD2_UDI_DISKS_PREFIX || udi.startsWith(UD2_DBUS_PATH_JOBS))
2820 + continue;
2821 +
2822 + Device device(udi);
2823 + if (device.drivePath() == path && device.isMounted()) {
2824 + //qDebug() << "Got mounted block device:" << udi;
2825 + blockPath = udi;
2826 + break;
2827 + }
2828 + }
2829 + }
2830 + else // show error
2831 + {
2832 + qWarning() << "Failed enumerating UDisks2 objects:" << reply.error().name() << "\n" << reply.error().message();
2833 + }
2834 +
2835 + if (!blockPath.isEmpty()) {
2836 + //qDebug() << "Calling unmount on" << blockPath;
2837 + QDBusMessage msg = QDBusMessage::createMethodCall(UD2_DBUS_SERVICE, blockPath, UD2_DBUS_INTERFACE_FILESYSTEM, "Unmount");
2838 + msg << QVariantMap(); // options, unused now
2839 + c.call(msg, QDBus::BlockWithGui);
2840 + }
2841 +
2842 + QDBusMessage msg = QDBusMessage::createMethodCall(UD2_DBUS_SERVICE, path, UD2_DBUS_INTERFACE_DRIVE, "Eject");
2843 + msg << QVariantMap();
2844 + return c.callWithCallback(msg, this, SLOT(slotDBusReply(const QDBusMessage &)), SLOT(slotDBusError(const QDBusError &)));
2845 +}
2846 +
2847 +void OpticalDrive::slotDBusReply(const QDBusMessage &/*reply*/)
2848 +{
2849 + m_ejectInProgress = false;
2850 + m_device->broadcastActionDone("eject");
2851 +}
2852 +
2853 +void OpticalDrive::slotDBusError(const QDBusError &error)
2854 +{
2855 + m_ejectInProgress = false;
2856 + m_device->broadcastActionDone("eject", m_device->errorToSolidError(error.name()),
2857 + m_device->errorToString(error.name()) + ": " +error.message());
2858 +}
2859 +
2860 +void OpticalDrive::slotEjectRequested()
2861 +{
2862 + m_ejectInProgress = true;
2863 + Q_EMIT ejectRequested(m_device->udi());
2864 +}
2865 +
2866 +void OpticalDrive::slotEjectDone(int error, const QString &errorString)
2867 +{
2868 + m_ejectInProgress = false;
2869 + Q_EMIT ejectDone(static_cast<Solid::ErrorType>(error), errorString, m_device->udi());
2870 +}
2871 +
2872 +void OpticalDrive::initReadWriteSpeeds() const
2873 +{
2874 +#if 0
2875 + int read_speed, write_speed;
2876 + char *write_speeds = 0;
2877 + QByteArray device_file = QFile::encodeName(m_device->property("Device").toString());
2878 +
2879 + //qDebug("Doing open (\"%s\", O_RDONLY | O_NONBLOCK)", device_file.constData());
2880 + int fd = open(device_file, O_RDONLY | O_NONBLOCK);
2881 + if (fd < 0) {
2882 + qWarning("Cannot open %s: %s", device_file.constData(), strerror (errno));
2883 + return;
2884 + }
2885 +
2886 + if (get_read_write_speed(fd, &read_speed, &write_speed, &write_speeds) >= 0) {
2887 + m_readSpeed = read_speed;
2888 + m_writeSpeed = write_speed;
2889 +
2890 + QStringList list = QString::fromLatin1(write_speeds).split(',', QString::SkipEmptyParts);
2891 + Q_FOREACH (const QString & speed, list)
2892 + m_writeSpeeds.append(speed.toInt());
2893 +
2894 + free(write_speeds);
2895 +
2896 + m_speedsInit = true;
2897 + }
2898 +
2899 + close(fd);
2900 +#endif
2901 +}
2902 +
2903 +QList<int> OpticalDrive::writeSpeeds() const
2904 +{
2905 + if (!m_speedsInit)
2906 + initReadWriteSpeeds();
2907 + //qDebug() << "solid write speeds:" << m_writeSpeeds;
2908 + return m_writeSpeeds;
2909 +}
2910 +
2911 +int OpticalDrive::writeSpeed() const
2912 +{
2913 + if (!m_speedsInit)
2914 + initReadWriteSpeeds();
2915 + return m_writeSpeed;
2916 +}
2917 +
2918 +int OpticalDrive::readSpeed() const
2919 +{
2920 + if (!m_speedsInit)
2921 + initReadWriteSpeeds();
2922 + return m_readSpeed;
2923 +}
2924 +
2925 +Solid::OpticalDrive::MediumTypes OpticalDrive::supportedMedia() const
2926 +{
2927 + const QStringList mediaTypes = m_device->prop("MediaCompatibility").toStringList();
2928 + Solid::OpticalDrive::MediumTypes supported;
2929 +
2930 + QMap<Solid::OpticalDrive::MediumType, QString> map;
2931 + map[Solid::OpticalDrive::Cdr] = "optical_cd_r";
2932 + map[Solid::OpticalDrive::Cdrw] = "optical_cd_rw";
2933 + map[Solid::OpticalDrive::Dvd] = "optical_dvd";
2934 + map[Solid::OpticalDrive::Dvdr] = "optical_dvd_r";
2935 + map[Solid::OpticalDrive::Dvdrw] ="optical_dvd_rw";
2936 + map[Solid::OpticalDrive::Dvdram] ="optical_dvd_ram";
2937 + map[Solid::OpticalDrive::Dvdplusr] ="optical_dvd_plus_r";
2938 + map[Solid::OpticalDrive::Dvdplusrw] ="optical_dvd_plus_rw";
2939 + map[Solid::OpticalDrive::Dvdplusdl] ="optical_dvd_plus_r_dl";
2940 + map[Solid::OpticalDrive::Dvdplusdlrw] ="optical_dvd_plus_rw_dl";
2941 + map[Solid::OpticalDrive::Bd] ="optical_bd";
2942 + map[Solid::OpticalDrive::Bdr] ="optical_bd_r";
2943 + map[Solid::OpticalDrive::Bdre] ="optical_bd_re";
2944 + map[Solid::OpticalDrive::HdDvd] ="optical_hddvd";
2945 + map[Solid::OpticalDrive::HdDvdr] ="optical_hddvd_r";
2946 + map[Solid::OpticalDrive::HdDvdrw] ="optical_hddvd_rw";
2947 + // TODO add these to Solid
2948 + //map[Solid::OpticalDrive::Mo] ="optical_mo";
2949 + //map[Solid::OpticalDrive::Mr] ="optical_mrw";
2950 + //map[Solid::OpticalDrive::Mrw] ="optical_mrw_w";
2951 +
2952 + Q_FOREACH ( const Solid::OpticalDrive::MediumType & type, map.keys() )
2953 + {
2954 + if ( mediaTypes.contains( map[type] ) )
2955 + {
2956 + supported |= type;
2957 + }
2958 + }
2959 +
2960 + return supported;
2961 +}
2962 +
2963 +void OpticalDrive::slotChanged()
2964 +{
2965 + m_speedsInit = false; // reset the read/write speeds, changes eg. with an inserted media
2966 +}
2967 diff --git a/solid/solid/backends/udisks2/udisksopticaldrive.h b/solid/solid/backends/udisks2/udisksopticaldrive.h
2968 new file mode 100644
2969 index 0000000..4c98ef5
2970 --- /dev/null
2971 +++ b/solid/solid/backends/udisks2/udisksopticaldrive.h
2972 @@ -0,0 +1,81 @@
2973 +/*
2974 + Copyright 2010 Michael Zanetti <mzanetti@kde.org>
2975 + Copyright 2010-2012 Lukáš Tinkl <ltinkl@redhat.com>
2976 +
2977 + This library is free software; you can redistribute it and/or
2978 + modify it under the terms of the GNU Lesser General Public
2979 + License as published by the Free Software Foundation; either
2980 + version 2.1 of the License, or (at your option) version 3, or any
2981 + later version accepted by the membership of KDE e.V. (or its
2982 + successor approved by the membership of KDE e.V.), which shall
2983 + act as a proxy defined in Section 6 of version 3 of the license.
2984 +
2985 + This library is distributed in the hope that it will be useful,
2986 + but WITHOUT ANY WARRANTY; without even the implied warranty of
2987 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2988 + Lesser General Public License for more details.
2989 +
2990 + You should have received a copy of the GNU Lesser General Public
2991 + License along with this library. If not, see <http://www.gnu.org/licenses/>.
2992 +*/
2993 +
2994 +#ifndef UDISKS2OPTICALDRIVE_H
2995 +#define UDISKS2OPTICALDRIVE_H
2996 +
2997 +#include <solid/ifaces/opticaldrive.h>
2998 +#include "udisksstoragedrive.h"
2999 +
3000 +namespace Solid
3001 +{
3002 +namespace Backends
3003 +{
3004 +namespace UDisks2
3005 +{
3006 +
3007 +class OpticalDrive: public StorageDrive, virtual public Solid::Ifaces::OpticalDrive
3008 +{
3009 + Q_OBJECT
3010 + Q_INTERFACES(Solid::Ifaces::OpticalDrive)
3011 +
3012 +public:
3013 + OpticalDrive(Device *device);
3014 + virtual ~OpticalDrive();
3015 +
3016 +Q_SIGNALS:
3017 + void ejectPressed(const QString &udi);
3018 + void ejectDone(Solid::ErrorType error, QVariant errorData, const QString &udi);
3019 + void ejectRequested(const QString &udi);
3020 +
3021 +public:
3022 + virtual bool eject();
3023 + virtual QList<int> writeSpeeds() const;
3024 + virtual int writeSpeed() const;
3025 + virtual int readSpeed() const;
3026 + virtual Solid::OpticalDrive::MediumTypes supportedMedia() const;
3027 +
3028 +private Q_SLOTS:
3029 + void slotDBusReply(const QDBusMessage &reply);
3030 + void slotDBusError(const QDBusError &error);
3031 +
3032 + void slotEjectRequested();
3033 + void slotEjectDone(int error, const QString &errorString);
3034 +
3035 + void slotChanged();
3036 +
3037 +private:
3038 + void initReadWriteSpeeds() const;
3039 +
3040 + bool m_ejectInProgress;
3041 +
3042 + // read/write speeds
3043 + mutable int m_readSpeed;
3044 + mutable int m_writeSpeed;
3045 + mutable QList<int> m_writeSpeeds;
3046 + mutable bool m_speedsInit;
3047 +};
3048 +
3049 +}
3050 +}
3051 +}
3052 +
3053 +#endif // UDISKS2OPTICALDRIVE_H
3054 diff --git a/solid/solid/backends/udisks2/udisksstorageaccess.cpp b/solid/solid/backends/udisks2/udisksstorageaccess.cpp
3055 new file mode 100644
3056 index 0000000..6958459
3057 --- /dev/null
3058 +++ b/solid/solid/backends/udisks2/udisksstorageaccess.cpp
3059 @@ -0,0 +1,390 @@
3060 +/*
3061 + Copyright 2009 Pino Toscano <pino@kde.org>
3062 + Copyright 2009-2012 Lukáš Tinkl <ltinkl@redhat.com>
3063 +
3064 + This library is free software; you can redistribute it and/or
3065 + modify it under the terms of the GNU Lesser General Public
3066 + License as published by the Free Software Foundation; either
3067 + version 2.1 of the License, or (at your option) version 3, or any
3068 + later version accepted by the membership of KDE e.V. (or its
3069 + successor approved by the membership of KDE e.V.), which shall
3070 + act as a proxy defined in Section 6 of version 3 of the license.
3071 +
3072 + This library is distributed in the hope that it will be useful,
3073 + but WITHOUT ANY WARRANTY; without even the implied warranty of
3074 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3075 + Lesser General Public License for more details.
3076 +
3077 + You should have received a copy of the GNU Lesser General Public
3078 + License along with this library. If not, see <http://www.gnu.org/licenses/>.
3079 +*/
3080 +
3081 +#include "udisksstorageaccess.h"
3082 +#include "udisks2.h"
3083 +
3084 +#include <QtDBus/QtDBus>
3085 +#include <QtGui/QApplication>
3086 +#include <QtGui/QWidget>
3087 +#include <QtXml/QDomDocument>
3088 +
3089 +using namespace Solid::Backends::UDisks2;
3090 +
3091 +StorageAccess::StorageAccess(Device *device)
3092 + : DeviceInterface(device), m_setupInProgress(false), m_teardownInProgress(false), m_passphraseRequested(false)
3093 +{
3094 + connect(device, SIGNAL(changed()), this, SLOT(checkAccessibility()));
3095 + updateCache();
3096 +
3097 + // Delay connecting to DBus signals to avoid the related time penalty
3098 + // in hot paths such as predicate matching
3099 + QTimer::singleShot(0, this, SLOT(connectDBusSignals()));
3100 +}
3101 +
3102 +StorageAccess::~StorageAccess()
3103 +{
3104 +}
3105 +
3106 +void StorageAccess::connectDBusSignals()
3107 +{
3108 + m_device->registerAction("setup", this,
3109 + SLOT(slotSetupRequested()),
3110 + SLOT(slotSetupDone(int, const QString&)));
3111 +
3112 + m_device->registerAction("teardown", this,
3113 + SLOT(slotTeardownRequested()),
3114 + SLOT(slotTeardownDone(int, const QString&)));
3115 +}
3116 +
3117 +bool StorageAccess::isLuksDevice() const
3118 +{
3119 + return m_device->isEncryptedContainer(); // encrypted device
3120 +}
3121 +
3122 +bool StorageAccess::isAccessible() const
3123 +{
3124 + if (isLuksDevice()) { // check if the cleartext slave is mounted
3125 + const QString path = clearTextPath();
3126 + //qDebug() << Q_FUNC_INFO << "CLEARTEXT device path: " << path;
3127 + if (path.isEmpty() || path == "/")
3128 + return false;
3129 + Device holderDevice(path);
3130 + return holderDevice.isMounted();
3131 + }
3132 +
3133 + return m_device->isMounted();
3134 +}
3135 +
3136 +QString StorageAccess::filePath() const
3137 +{
3138 + QByteArrayList mntPoints;
3139 +
3140 + if (isLuksDevice()) { // encrypted (and unlocked) device
3141 + const QString path = clearTextPath();
3142 + if (path.isEmpty() || path == "/")
3143 + return QString();
3144 + Device holderDevice(path);
3145 + mntPoints = qdbus_cast<QByteArrayList>(holderDevice.prop("MountPoints"));
3146 + if (!mntPoints.isEmpty())
3147 + return QFile::decodeName(mntPoints.first()); // FIXME Solid doesn't support multiple mount points
3148 + else
3149 + return QString();
3150 + }
3151 +
3152 + mntPoints = qdbus_cast<QByteArrayList>(m_device->prop("MountPoints"));
3153 +
3154 + if (!mntPoints.isEmpty())
3155 + return QFile::decodeName(mntPoints.first()); // FIXME Solid doesn't support multiple mount points
3156 + else
3157 + return QString();
3158 +}
3159 +
3160 +bool StorageAccess::isIgnored() const
3161 +{
3162 + return m_device->prop("HintIgnore").toBool();
3163 +}
3164 +
3165 +bool StorageAccess::setup()
3166 +{
3167 + if ( m_teardownInProgress || m_setupInProgress )
3168 + return false;
3169 + m_setupInProgress = true;
3170 + m_device->broadcastActionRequested("setup");
3171 +
3172 + if (m_device->isEncryptedContainer() && clearTextPath().isEmpty())
3173 + return requestPassphrase();
3174 + else
3175 + return mount();
3176 +}
3177 +
3178 +bool StorageAccess::teardown()
3179 +{
3180 + if ( m_teardownInProgress || m_setupInProgress )
3181 + return false;
3182 + m_teardownInProgress = true;
3183 + m_device->broadcastActionRequested("teardown");
3184 +
3185 + return unmount();
3186 +}
3187 +
3188 +void StorageAccess::updateCache()
3189 +{
3190 + m_isAccessible = isAccessible();
3191 +}
3192 +
3193 +void StorageAccess::checkAccessibility()
3194 +{
3195 + const bool old_isAccessible = m_isAccessible;
3196 + updateCache();
3197 +
3198 + if (old_isAccessible != m_isAccessible) {
3199 + Q_EMIT accessibilityChanged(m_isAccessible, m_device->udi());
3200 + }
3201 +}
3202 +
3203 +void StorageAccess::slotDBusReply( const QDBusMessage & /*reply*/ )
3204 +{
3205 + const QString ctPath = clearTextPath();
3206 + if (m_setupInProgress)
3207 + {
3208 + if (isLuksDevice() && !isAccessible()) { // unlocked device, now mount it
3209 + mount();
3210 + }
3211 + else // Don't broadcast setupDone unless the setup is really done. (Fix kde#271156)
3212 + {
3213 + m_setupInProgress = false;
3214 + m_device->broadcastActionDone("setup");
3215 +
3216 + checkAccessibility();
3217 + }
3218 + }
3219 + else if (m_teardownInProgress) // FIXME
3220 + {
3221 + if (isLuksDevice() && !ctPath.isEmpty() && ctPath != "/") // unlocked device, lock it
3222 + {
3223 + callCryptoTeardown();
3224 + }
3225 + else if (!ctPath.isEmpty() && ctPath != "/") {
3226 + callCryptoTeardown(true); // Lock crypted parent
3227 + }
3228 + else
3229 + {
3230 + // try to "eject" (aka safely remove) from the (parent) drive, e.g. SD card from a reader
3231 + QString drivePath = m_device->drivePath();
3232 + if (!drivePath.isEmpty() || drivePath != "/")
3233 + {
3234 + Device drive(drivePath);
3235 + if (drive.prop("Ejectable").toBool() &&
3236 + drive.prop("MediaAvailable").toBool() &&
3237 + !m_device->isOpticalDisc()) // optical drives have their Eject method
3238 + {
3239 + QDBusConnection c = QDBusConnection::systemBus();
3240 + QDBusMessage msg = QDBusMessage::createMethodCall(UD2_DBUS_SERVICE, drivePath, UD2_DBUS_INTERFACE_DRIVE, "Eject");
3241 + msg << QVariantMap(); // options, unused now
3242 + c.call(msg, QDBus::NoBlock);
3243 + }
3244 + }
3245 +
3246 + m_teardownInProgress = false;
3247 + m_device->broadcastActionDone("teardown");
3248 +
3249 + checkAccessibility();
3250 + }
3251 + }
3252 +}
3253 +
3254 +void StorageAccess::slotDBusError( const QDBusError & error )
3255 +{
3256 + //qDebug() << Q_FUNC_INFO << "DBUS ERROR:" << error.name() << error.message();
3257 +
3258 + if (m_setupInProgress)
3259 + {
3260 + m_setupInProgress = false;
3261 + m_device->broadcastActionDone("setup", m_device->errorToSolidError(error.name()),
3262 + m_device->errorToString(error.name()) + ": " +error.message());
3263 +
3264 + checkAccessibility();
3265 + }
3266 + else if (m_teardownInProgress)
3267 + {
3268 + m_teardownInProgress = false;
3269 + m_device->broadcastActionDone("teardown", m_device->errorToSolidError(error.name()),
3270 + m_device->errorToString(error.name()) + ": " + error.message());
3271 + checkAccessibility();
3272 + }
3273 +}
3274 +
3275 +void StorageAccess::slotSetupRequested()
3276 +{
3277 + m_setupInProgress = true;
3278 + //qDebug() << "SETUP REQUESTED:" << m_device->udi();
3279 + Q_EMIT setupRequested(m_device->udi());
3280 +}
3281 +
3282 +void StorageAccess::slotSetupDone(int error, const QString &errorString)
3283 +{
3284 + m_setupInProgress = false;
3285 + //qDebug() << "SETUP DONE:" << m_device->udi();
3286 + Q_EMIT setupDone(static_cast<Solid::ErrorType>(error), errorString, m_device->udi());
3287 +
3288 + checkAccessibility();
3289 +}
3290 +
3291 +void StorageAccess::slotTeardownRequested()
3292 +{
3293 + m_teardownInProgress = true;
3294 + Q_EMIT teardownRequested(m_device->udi());
3295 +}
3296 +
3297 +void StorageAccess::slotTeardownDone(int error, const QString &errorString)
3298 +{
3299 + m_teardownInProgress = false;
3300 + Q_EMIT teardownDone(static_cast<Solid::ErrorType>(error), errorString, m_device->udi());
3301 +
3302 + checkAccessibility();
3303 +}
3304 +
3305 +bool StorageAccess::mount()
3306 +{
3307 + QString path = m_device->udi();
3308 + const QString ctPath = clearTextPath();
3309 +
3310 + if (isLuksDevice() && !ctPath.isEmpty()) { // mount options for the cleartext volume
3311 + path = ctPath;
3312 + }
3313 +
3314 + QDBusConnection c = QDBusConnection::systemBus();
3315 + QDBusMessage msg = QDBusMessage::createMethodCall(UD2_DBUS_SERVICE, path, UD2_DBUS_INTERFACE_FILESYSTEM, "Mount");
3316 + QVariantMap options;
3317 +
3318 + if (m_device->prop("IdType").toString() == "vfat")
3319 + options.insert("options", "flush");
3320 +
3321 + msg << options;
3322 +
3323 + return c.callWithCallback(msg, this,
3324 + SLOT(slotDBusReply(const QDBusMessage &)),
3325 + SLOT(slotDBusError(const QDBusError &)));
3326 +}
3327 +
3328 +bool StorageAccess::unmount()
3329 +{
3330 + QString path = m_device->udi();
3331 + const QString ctPath = clearTextPath();
3332 +
3333 + if (isLuksDevice() && !ctPath.isEmpty()) { // unmount options for the cleartext volume
3334 + path = ctPath;
3335 + }
3336 +
3337 + QDBusConnection c = QDBusConnection::systemBus();
3338 + QDBusMessage msg = QDBusMessage::createMethodCall(UD2_DBUS_SERVICE, path, UD2_DBUS_INTERFACE_FILESYSTEM, "Unmount");
3339 +
3340 + msg << QVariantMap(); // options, unused now
3341 +
3342 + return c.callWithCallback(msg, this,
3343 + SLOT(slotDBusReply(const QDBusMessage &)),
3344 + SLOT(slotDBusError(const QDBusError &)),
3345 + s_unmountTimeout);
3346 +}
3347 +
3348 +QString StorageAccess::generateReturnObjectPath()
3349 +{
3350 + static int number = 1;
3351 +
3352 + return "/org/kde/solid/UDisks2StorageAccess_"+QString::number(number++);
3353 +}
3354 +
3355 +QString StorageAccess::clearTextPath() const
3356 +{
3357 + const QString prefix = "/org/freedesktop/UDisks2/block_devices";
3358 + QDBusMessage call = QDBusMessage::createMethodCall(UD2_DBUS_SERVICE, prefix,
3359 + DBUS_INTERFACE_INTROSPECT, "Introspect");
3360 + QDBusPendingReply<QString> reply = QDBusConnection::systemBus().asyncCall(call);
3361 + reply.waitForFinished();
3362 +
3363 + if (reply.isValid()) {
3364 + QDomDocument dom;
3365 + dom.setContent(reply.value());
3366 + QDomNodeList nodeList = dom.documentElement().elementsByTagName("node");
3367 + for (int i = 0; i < nodeList.count(); i++) {
3368 + QDomElement nodeElem = nodeList.item(i).toElement();
3369 + if (!nodeElem.isNull() && nodeElem.hasAttribute("name")) {
3370 + const QString udi = prefix + "/" + nodeElem.attribute("name");
3371 + Device holderDevice(udi);
3372 +
3373 + if (m_device->udi() == holderDevice.prop("CryptoBackingDevice").value<QDBusObjectPath>().path()) {
3374 + //qDebug() << Q_FUNC_INFO << "CLEARTEXT device path: " << udi;
3375 + return udi;
3376 + }
3377 + }
3378 + }
3379 + }
3380 +
3381 + return QString();
3382 +}
3383 +
3384 +bool StorageAccess::requestPassphrase()
3385 +{
3386 + QString udi = m_device->udi();
3387 + QString returnService = QDBusConnection::sessionBus().baseService();
3388 + m_lastReturnObject = generateReturnObjectPath();
3389 +
3390 + QDBusConnection::sessionBus().registerObject(m_lastReturnObject, this, QDBusConnection::ExportScriptableSlots);
3391 +
3392 + QWidget *activeWindow = QApplication::activeWindow();
3393 + uint wId = 0;
3394 + if (activeWindow!=0)
3395 + wId = (uint)activeWindow->winId();
3396 +
3397 + QString appId = QCoreApplication::applicationName();
3398 +
3399 + QDBusInterface soliduiserver("org.kde.kded", "/modules/soliduiserver", "org.kde.SolidUiServer");
3400 + QDBusReply<void> reply = soliduiserver.call("showPassphraseDialog", udi, returnService,
3401 + m_lastReturnObject, wId, appId);
3402 + m_passphraseRequested = reply.isValid();
3403 + if (!m_passphraseRequested)
3404 + qWarning() << "Failed to call the SolidUiServer, D-Bus said:" << reply.error();
3405 +
3406 + return m_passphraseRequested;
3407 +}
3408 +
3409 +void StorageAccess::passphraseReply(const QString & passphrase)
3410 +{
3411 + if (m_passphraseRequested)
3412 + {
3413 + QDBusConnection::sessionBus().unregisterObject(m_lastReturnObject);
3414 + m_passphraseRequested = false;
3415 + if (!passphrase.isEmpty())
3416 + callCryptoSetup(passphrase);
3417 + else
3418 + {
3419 + m_setupInProgress = false;
3420 + m_device->broadcastActionDone("setup");
3421 + }
3422 + }
3423 +}
3424 +
3425 +void StorageAccess::callCryptoSetup(const QString & passphrase)
3426 +{
3427 + QDBusConnection c = QDBusConnection::systemBus();
3428 + QDBusMessage msg = QDBusMessage::createMethodCall(UD2_DBUS_SERVICE, m_device->udi(), UD2_DBUS_INTERFACE_ENCRYPTED, "Unlock");
3429 +
3430 + msg << passphrase;
3431 + msg << QVariantMap(); // options, unused now
3432 +
3433 + c.callWithCallback(msg, this,
3434 + SLOT(slotDBusReply(const QDBusMessage &)),
3435 + SLOT(slotDBusError(const QDBusError &)));
3436 +}
3437 +
3438 +bool StorageAccess::callCryptoTeardown(bool actOnParent)
3439 +{
3440 + QDBusConnection c = QDBusConnection::systemBus();
3441 + QDBusMessage msg = QDBusMessage::createMethodCall(UD2_DBUS_SERVICE,
3442 + actOnParent ? (m_device->prop("CryptoBackingDevice").value<QDBusObjectPath>().path()) : m_device->udi(),
3443 + UD2_DBUS_INTERFACE_ENCRYPTED, "Lock");
3444 + msg << QVariantMap(); // options, unused now
3445 +
3446 + return c.callWithCallback(msg, this,
3447 + SLOT(slotDBusReply(const QDBusMessage &)),
3448 + SLOT(slotDBusError(const QDBusError &)));
3449 +}
3450 diff --git a/solid/solid/backends/udisks2/udisksstorageaccess.h b/solid/solid/backends/udisks2/udisksstorageaccess.h
3451 new file mode 100644
3452 index 0000000..ec91f89
3453 --- /dev/null
3454 +++ b/solid/solid/backends/udisks2/udisksstorageaccess.h
3455 @@ -0,0 +1,104 @@
3456 +/*
3457 + Copyright 2009 Pino Toscano <pino@kde.org>
3458 + Copyright 2009-2012 Lukáš Tinkl <ltinkl@redhat.com>
3459 +
3460 + This library is free software; you can redistribute it and/or
3461 + modify it under the terms of the GNU Lesser General Public
3462 + License as published by the Free Software Foundation; either
3463 + version 2.1 of the License, or (at your option) version 3, or any
3464 + later version accepted by the membership of KDE e.V. (or its
3465 + successor approved by the membership of KDE e.V.), which shall
3466 + act as a proxy defined in Section 6 of version 3 of the license.
3467 +
3468 + This library is distributed in the hope that it will be useful,
3469 + but WITHOUT ANY WARRANTY; without even the implied warranty of
3470 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3471 + Lesser General Public License for more details.
3472 +
3473 + You should have received a copy of the GNU Lesser General Public
3474 + License along with this library. If not, see <http://www.gnu.org/licenses/>.
3475 +*/
3476 +
3477 +#ifndef UDISKS2STORAGEACCESS_H
3478 +#define UDISKS2STORAGEACCESS_H
3479 +
3480 +#include <solid/ifaces/storageaccess.h>
3481 +#include "udisksdeviceinterface.h"
3482 +
3483 +#include <QtDBus/QDBusMessage>
3484 +#include <QtDBus/QDBusError>
3485 +
3486 +namespace Solid
3487 +{
3488 +namespace Backends
3489 +{
3490 +namespace UDisks2
3491 +{
3492 +class StorageAccess : public DeviceInterface, virtual public Solid::Ifaces::StorageAccess
3493 +{
3494 + Q_OBJECT
3495 + Q_INTERFACES(Solid::Ifaces::StorageAccess)
3496 +
3497 +public:
3498 + StorageAccess(Device *device);
3499 + virtual ~StorageAccess();
3500 +
3501 + virtual bool isAccessible() const;
3502 + virtual QString filePath() const;
3503 + virtual bool isIgnored() const;
3504 + virtual bool setup();
3505 + virtual bool teardown();
3506 +
3507 +Q_SIGNALS:
3508 + void accessibilityChanged(bool accessible, const QString &udi);
3509 + void setupDone(Solid::ErrorType error, QVariant errorData, const QString &udi);
3510 + void teardownDone(Solid::ErrorType error, QVariant errorData, const QString &udi);
3511 + void setupRequested(const QString &udi);
3512 + void teardownRequested(const QString &udi);
3513 +
3514 +public Q_SLOTS:
3515 + Q_SCRIPTABLE Q_NOREPLY void passphraseReply(const QString & passphrase);
3516 +
3517 +private Q_SLOTS:
3518 + void slotDBusReply(const QDBusMessage & reply);
3519 + void slotDBusError(const QDBusError & error);
3520 +
3521 + void connectDBusSignals();
3522 +
3523 + void slotSetupRequested();
3524 + void slotSetupDone(int error, const QString &errorString);
3525 + void slotTeardownRequested();
3526 + void slotTeardownDone(int error, const QString &errorString);
3527 +
3528 + void checkAccessibility();
3529 +
3530 +private:
3531 + /// @return true if this device is luks and unlocked
3532 + bool isLuksDevice() const;
3533 +
3534 + void updateCache();
3535 +
3536 + bool mount();
3537 + bool unmount();
3538 +
3539 + bool requestPassphrase();
3540 + void callCryptoSetup( const QString & passphrase );
3541 + bool callCryptoTeardown( bool actOnParent=false );
3542 +
3543 + QString generateReturnObjectPath();
3544 + QString clearTextPath() const;
3545 +
3546 +private:
3547 + bool m_isAccessible;
3548 + bool m_setupInProgress;
3549 + bool m_teardownInProgress;
3550 + bool m_passphraseRequested;
3551 + QString m_lastReturnObject;
3552 +
3553 + static const int s_unmountTimeout = 0x7fffffff;
3554 +};
3555 +}
3556 +}
3557 +}
3558 +
3559 +#endif // UDISKS2STORAGEACCESS_H
3560 diff --git a/solid/solid/backends/udisks2/udisksstoragedrive.cpp b/solid/solid/backends/udisks2/udisksstoragedrive.cpp
3561 new file mode 100644
3562 index 0000000..e382154
3563 --- /dev/null
3564 +++ b/solid/solid/backends/udisks2/udisksstoragedrive.cpp
3565 @@ -0,0 +1,147 @@
3566 +/*
3567 + Copyright 2010 Michael Zanetti <mzanetti@kde.org>
3568 + Copyright 2010-2012 Lukáš Tinkl <ltinkl@redhat.com>
3569 +
3570 + This library is free software; you can redistribute it and/or
3571 + modify it under the terms of the GNU Lesser General Public
3572 + License as published by the Free Software Foundation; either
3573 + version 2.1 of the License, or (at your option) version 3, or any
3574 + later version accepted by the membership of KDE e.V. (or its
3575 + successor approved by the membership of KDE e.V.), which shall
3576 + act as a proxy defined in Section 6 of version 3 of the license.
3577 +
3578 + This library is distributed in the hope that it will be useful,
3579 + but WITHOUT ANY WARRANTY; without even the implied warranty of
3580 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3581 + Lesser General Public License for more details.
3582 +
3583 + You should have received a copy of the GNU Lesser General Public
3584 + License along with this library. If not, see <http://www.gnu.org/licenses/>.
3585 +*/
3586 +
3587 +#include "udisksstoragedrive.h"
3588 +
3589 +#include "../shared/udevqt.h"
3590 +
3591 +#include <QtCore/QDebug>
3592 +#include <QtCore/QFile>
3593 +
3594 +using namespace Solid::Backends::UDisks2;
3595 +
3596 +StorageDrive::StorageDrive(Device *dev)
3597 + : Block(dev)
3598 +{
3599 + UdevQt::Client client(this);
3600 + m_udevDevice = client.deviceByDeviceFile(device());
3601 + m_udevDevice.deviceProperties();
3602 +}
3603 +
3604 +StorageDrive::~StorageDrive()
3605 +{
3606 +}
3607 +
3608 +qulonglong StorageDrive::size() const
3609 +{
3610 + return m_device->prop("Size").toULongLong();
3611 +}
3612 +
3613 +bool StorageDrive::isHotpluggable() const
3614 +{
3615 + const Solid::StorageDrive::Bus _bus = bus();
3616 + return _bus == Solid::StorageDrive::Usb || _bus == Solid::StorageDrive::Ieee1394;
3617 +}
3618 +
3619 +bool StorageDrive::isRemovable() const
3620 +{
3621 + return m_device->prop("MediaRemovable").toBool() || m_device->prop("Removable").toBool();
3622 +}
3623 +
3624 +Solid::StorageDrive::DriveType StorageDrive::driveType() const
3625 +{
3626 + const QStringList mediaTypes = m_device->prop("MediaCompatibility").toStringList();
3627 +
3628 + if ( m_device->isOpticalDrive() ) // optical disks
3629 + {
3630 + return Solid::StorageDrive::CdromDrive;
3631 + }
3632 + else if ( mediaTypes.contains( "floppy" ) )
3633 + {
3634 + return Solid::StorageDrive::Floppy;
3635 + }
3636 +#if 0 // TODO add to Solid
3637 + else if ( mediaTypes.contains( "floppy_jaz" ) )
3638 + {
3639 + return Solid::StorageDrive::Jaz;
3640 + }
3641 + else if ( mediaTypes.contains( "floppy_zip" ) )
3642 + {
3643 + return Solid::StorageDrive::Zip;
3644 + }
3645 + else if ( mediaTypes.contains( "flash" ) )
3646 + {
3647 + return Solid::StorageDrive::Flash;
3648 + }
3649 +#endif
3650 + else if ( mediaTypes.contains( "flash_cf" ) )
3651 + {
3652 + return Solid::StorageDrive::CompactFlash;
3653 + }
3654 + else if ( mediaTypes.contains( "flash_ms" ) )
3655 + {
3656 + return Solid::StorageDrive::MemoryStick;
3657 + }
3658 + else if ( mediaTypes.contains( "flash_sm" ) )
3659 + {
3660 + return Solid::StorageDrive::SmartMedia;
3661 + }
3662 + else if ( mediaTypes.contains( "flash_sd" ) || mediaTypes.contains( "flash_sdhc" )
3663 + || mediaTypes.contains( "flash_mmc" ) || mediaTypes.contains("flash_sdxc") )
3664 + {
3665 + return Solid::StorageDrive::SdMmc;
3666 + }
3667 + // FIXME: udisks2 doesn't know about xD cards
3668 + else
3669 + {
3670 + return Solid::StorageDrive::HardDisk;
3671 + }
3672 +}
3673 +
3674 +Solid::StorageDrive::Bus StorageDrive::bus() const
3675 +{
3676 + const QString bus = m_device->prop("ConnectionBus").toString();
3677 + const QString udevBus = m_udevDevice.deviceProperty("ID_BUS").toString();
3678 +
3679 + //qDebug() << "bus:" << bus << "udev bus:" << udevBus;
3680 +
3681 + if (udevBus == "ata")
3682 + {
3683 + if (m_udevDevice.deviceProperty("ID_ATA_SATA").toInt() == 1) // serial ATA
3684 + return Solid::StorageDrive::Sata;
3685 + else // parallel (classical) ATA
3686 + return Solid::StorageDrive::Ide;
3687 + }
3688 + else if (bus == "usb")
3689 + {
3690 + return Solid::StorageDrive::Usb;
3691 + }
3692 + else if (bus == "ieee1394")
3693 + {
3694 + return Solid::StorageDrive::Ieee1394;
3695 + }
3696 + else if (udevBus == "scsi")
3697 + {
3698 + return Solid::StorageDrive::Scsi;
3699 + }
3700 +#if 0 // TODO add these to Solid
3701 + else if ( bus == "sdio" )
3702 + {
3703 + return Solid::StorageDrive::SDIO;
3704 + }
3705 + else if ( bus == "virtual" )
3706 + {
3707 + return Solid::StorageDrive::Virtual;
3708 + }
3709 +#endif
3710 + else
3711 + return Solid::StorageDrive::Platform;
3712 +}
3713 diff --git a/solid/solid/backends/udisks2/udisksstoragedrive.h b/solid/solid/backends/udisks2/udisksstoragedrive.h
3714 new file mode 100644
3715 index 0000000..d8c1046
3716 --- /dev/null
3717 +++ b/solid/solid/backends/udisks2/udisksstoragedrive.h
3718 @@ -0,0 +1,61 @@
3719 +/*
3720 + Copyright 2010 Michael Zanetti <mzanetti@kde.org>
3721 + Copyright 2010-2012 Lukáš Tinkl <ltinkl@redhat.com>
3722 +
3723 + This library is free software; you can redistribute it and/or
3724 + modify it under the terms of the GNU Lesser General Public
3725 + License as published by the Free Software Foundation; either
3726 + version 2.1 of the License, or (at your option) version 3, or any
3727 + later version accepted by the membership of KDE e.V. (or its
3728 + successor approved by the membership of KDE e.V.), which shall
3729 + act as a proxy defined in Section 6 of version 3 of the license.
3730 +
3731 + This library is distributed in the hope that it will be useful,
3732 + but WITHOUT ANY WARRANTY; without even the implied warranty of
3733 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3734 + Lesser General Public License for more details.
3735 +
3736 + You should have received a copy of the GNU Lesser General Public
3737 + License along with this library. If not, see <http://www.gnu.org/licenses/>.
3738 +*/
3739 +
3740 +#ifndef UDISKS2STORAGEDRIVE_H
3741 +#define UDISKS2STORAGEDRIVE_H
3742 +
3743 +#include <ifaces/storagedrive.h>
3744 +
3745 +#include "../shared/udevqt.h"
3746 +
3747 +#include "udisksblock.h"
3748 +
3749 +namespace Solid
3750 +{
3751 +namespace Backends
3752 +{
3753 +namespace UDisks2
3754 +{
3755 +
3756 +class StorageDrive: public Block, virtual public Solid::Ifaces::StorageDrive
3757 +{
3758 + Q_OBJECT
3759 + Q_INTERFACES(Solid::Ifaces::StorageDrive)
3760 +
3761 +public:
3762 + StorageDrive(Device *dev);
3763 + virtual ~StorageDrive();
3764 +
3765 + virtual qulonglong size() const;
3766 + virtual bool isHotpluggable() const;
3767 + virtual bool isRemovable() const;
3768 + virtual Solid::StorageDrive::DriveType driveType() const;
3769 + virtual Solid::StorageDrive::Bus bus() const;
3770 +
3771 +private:
3772 + UdevQt::Device m_udevDevice;
3773 +};
3774 +
3775 +}
3776 +}
3777 +}
3778 +
3779 +#endif // UDISK2SSTORAGEDRIVE_H
3780 diff --git a/solid/solid/backends/udisks2/udisksstoragevolume.cpp b/solid/solid/backends/udisks2/udisksstoragevolume.cpp
3781 new file mode 100644
3782 index 0000000..a7d8fad
3783 --- /dev/null
3784 +++ b/solid/solid/backends/udisks2/udisksstoragevolume.cpp
3785 @@ -0,0 +1,105 @@
3786 +/*
3787 + Copyright 2010 Michael Zanetti <mzanetti@kde.org>
3788 + Copyright 2010-2012 Lukáš Tinkl <ltinkl@redhat.com>
3789 +
3790 + This library is free software; you can redistribute it and/or
3791 + modify it under the terms of the GNU Lesser General Public
3792 + License as published by the Free Software Foundation; either
3793 + version 2.1 of the License, or (at your option) version 3, or any
3794 + later version accepted by the membership of KDE e.V. (or its
3795 + successor approved by the membership of KDE e.V.), which shall
3796 + act as a proxy defined in Section 6 of version 3 of the license.
3797 +
3798 + This library is distributed in the hope that it will be useful,
3799 + but WITHOUT ANY WARRANTY; without even the implied warranty of
3800 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3801 + Lesser General Public License for more details.
3802 +
3803 + You should have received a copy of the GNU Lesser General Public
3804 + License along with this library. If not, see <http://www.gnu.org/licenses/>.
3805 +*/
3806 +
3807 +#include "udisksstoragevolume.h"
3808 +#include "udisks2.h"
3809 +
3810 +using namespace Solid::Backends::UDisks2;
3811 +
3812 +StorageVolume::StorageVolume(Device *device)
3813 + : Block(device)
3814 +{
3815 +}
3816 +
3817 +StorageVolume::~StorageVolume()
3818 +{
3819 +}
3820 +
3821 +QString StorageVolume::encryptedContainerUdi() const
3822 +{
3823 + const QString path = m_device->prop("CryptoBackingDevice").value<QDBusObjectPath>().path();
3824 + if ( path.isEmpty() || path == "/")
3825 + return QString();
3826 + else
3827 + return path;
3828 +}
3829 +
3830 +qulonglong StorageVolume::size() const
3831 +{
3832 + return m_device->prop("Size").toULongLong();
3833 +}
3834 +
3835 +QString StorageVolume::uuid() const
3836 +{
3837 + return m_device->prop("IdUUID").toString();
3838 +}
3839 +
3840 +QString StorageVolume::label() const
3841 +{
3842 + QString label = m_device->prop("HintName").toString();
3843 + if (label.isEmpty())
3844 + label = m_device->prop("IdLabel").toString();
3845 + if (label.isEmpty())
3846 + label = m_device->prop("Name").toString();
3847 + return label;
3848 +}
3849 +
3850 +QString StorageVolume::fsType() const
3851 +{
3852 + return m_device->prop("IdType").toString();
3853 +}
3854 +
3855 +Solid::StorageVolume::UsageType StorageVolume::usage() const
3856 +{
3857 + const QString usage = m_device->prop("IdUsage").toString();
3858 +
3859 + if (m_device->hasInterface(UD2_DBUS_INTERFACE_FILESYSTEM))
3860 + {
3861 + return Solid::StorageVolume::FileSystem;
3862 + }
3863 + else if (m_device->isPartitionTable())
3864 + {
3865 + return Solid::StorageVolume::PartitionTable;
3866 + }
3867 + else if (usage == "raid")
3868 + {
3869 + return Solid::StorageVolume::Raid;
3870 + }
3871 + else if (m_device->isEncryptedContainer())
3872 + {
3873 + return Solid::StorageVolume::Encrypted;
3874 + }
3875 + else if (usage == "unused" || usage.isEmpty())
3876 + {
3877 + return Solid::StorageVolume::Unused;
3878 + }
3879 + else
3880 + {
3881 + return Solid::StorageVolume::Other;
3882 + }
3883 +}
3884 +
3885 +bool StorageVolume::isIgnored() const
3886 +{
3887 + const Solid::StorageVolume::UsageType usg = usage();
3888 + return m_device->prop("HintIgnore").toBool() || m_device->isSwap() ||
3889 + ((usg == Solid::StorageVolume::Unused || usg == Solid::StorageVolume::Other || usg == Solid::StorageVolume::PartitionTable) && !m_device->isOpticalDisc());
3890 +}
3891 diff --git a/solid/solid/backends/udisks2/udisksstoragevolume.h b/solid/solid/backends/udisks2/udisksstoragevolume.h
3892 new file mode 100644
3893 index 0000000..2ca04d2
3894 --- /dev/null
3895 +++ b/solid/solid/backends/udisks2/udisksstoragevolume.h
3896 @@ -0,0 +1,57 @@
3897 +/*
3898 + Copyright 2010 Michael Zanetti <mzanetti@kde.org>
3899 +
3900 + This library is free software; you can redistribute it and/or
3901 + modify it under the terms of the GNU Lesser General Public
3902 + License as published by the Free Software Foundation; either
3903 + version 2.1 of the License, or (at your option) version 3, or any
3904 + later version accepted by the membership of KDE e.V. (or its
3905 + successor approved by the membership of KDE e.V.), which shall
3906 + act as a proxy defined in Section 6 of version 3 of the license.
3907 +
3908 + This library is distributed in the hope that it will be useful,
3909 + but WITHOUT ANY WARRANTY; without even the implied warranty of
3910 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3911 + Lesser General Public License for more details.
3912 +
3913 + You should have received a copy of the GNU Lesser General Public
3914 + License along with this library. If not, see <http://www.gnu.org/licenses/>.
3915 +*/
3916 +
3917 +#ifndef UDISKS2STORAGEVOLUME_H
3918 +#define UDISKS2STORAGEVOLUME_H
3919 +
3920 +#include <ifaces/storagevolume.h>
3921 +#include "udisksblock.h"
3922 +
3923 +
3924 +namespace Solid
3925 +{
3926 +namespace Backends
3927 +{
3928 +namespace UDisks2
3929 +{
3930 +
3931 +class StorageVolume: public Block, virtual public Solid::Ifaces::StorageVolume
3932 +{
3933 + Q_OBJECT
3934 + Q_INTERFACES(Solid::Ifaces::StorageVolume)
3935 +
3936 +public:
3937 + StorageVolume(Device *device);
3938 + virtual ~StorageVolume();
3939 +
3940 + virtual QString encryptedContainerUdi() const;
3941 + virtual qulonglong size() const;
3942 + virtual QString uuid() const;
3943 + virtual QString label() const;
3944 + virtual QString fsType() const;
3945 + virtual Solid::StorageVolume::UsageType usage() const;
3946 + virtual bool isIgnored() const;
3947 +};
3948 +
3949 +}
3950 +}
3951 +}
3952 +
3953 +#endif // UDISKS2STORAGEVOLUME_H
3954 diff --git a/solid/solid/managerbase.cpp b/solid/solid/managerbase.cpp
3955 index fb5a67c..c7005ff 100644
3956 --- a/solid/solid/managerbase.cpp
3957 +++ b/solid/solid/managerbase.cpp
3958 @@ -30,8 +30,11 @@
3959 #if defined (Q_OS_MAC)
3960 #include "backends/iokit/iokitmanager.h"
3961 #elif defined (Q_OS_UNIX)
3962 -#include "backends/hal/halmanager.h"
3963 +#if defined (WITH_SOLID_UDISKS2)
3964 +#include "backends/udisks2/udisksmanager.h"
3965 +#else
3966 #include "backends/udisks/udisksmanager.h"
3967 +#endif
3968 #include "backends/upower/upowermanager.h"
3969
3970 #if defined (HUPNP_FOUND)
3971 @@ -71,22 +74,17 @@ void Solid::ManagerBasePrivate::loadBackends()
3972 # elif defined(Q_WS_WIN) && defined(HAVE_WBEM) && !defined(_WIN32_WCE)
3973 m_backends << new Solid::Backends::Wmi::WmiManager(0);
3974
3975 -# elif defined(Q_OS_UNIX) && !defined(Q_OS_LINUX)
3976 - m_backends << new Solid::Backends::Hal::HalManager(0);
3977 -
3978 # elif defined(Q_OS_LINUX)
3979 - bool solidHalLegacyEnabled
3980 - = QString::fromLocal8Bit(qgetenv("SOLID_HAL_LEGACY")).toInt()==1;
3981 - if (solidHalLegacyEnabled) {
3982 - m_backends << new Solid::Backends::Hal::HalManager(0);
3983 - } else {
3984 # if defined(UDEV_FOUND)
3985 m_backends << new Solid::Backends::UDev::UDevManager(0);
3986 # endif
3987 +# if defined(WITH_SOLID_UDISKS2)
3988 + m_backends << new Solid::Backends::UDisks2::Manager(0)
3989 +# else
3990 m_backends << new Solid::Backends::UDisks::UDisksManager(0)
3991 +# endif
3992 << new Solid::Backends::UPower::UPowerManager(0)
3993 << new Solid::Backends::Fstab::FstabManager(0);
3994 - }
3995 # endif
3996
3997 # if defined (HUPNP_FOUND)
3998 @@ -99,5 +97,3 @@ QList<QObject*> Solid::ManagerBasePrivate::managerBackends() const
3999 {
4000 return m_backends;
4001 }
4002 -
4003 -
4004 diff --git a/solid/tests/CMakeLists.txt b/solid/tests/CMakeLists.txt
4005 index ef507d1..9212741 100644
4006 --- a/solid/tests/CMakeLists.txt
4007 +++ b/solid/tests/CMakeLists.txt
4008 @@ -16,20 +16,6 @@ target_link_libraries(fakehardwaretest solid_static ${QT_QTCORE_LIBRARY} ${QT_QT
4009 add_definitions(-DTEST_DATA="\\"${CMAKE_CURRENT_SOURCE_DIR}/../solid/backends/fakehw/fakecomputer.xml\\"")
4010
4011
4012 -########### halbasictest ###############
4013 -
4014 -if(NOT WIN32 AND NOT APPLE)
4015 -set(halbasictest_SRCS halbasictest.cpp )
4016 -
4017 -kde4_add_executable(halbasictest ${halbasictest_SRCS})
4018 -
4019 -if(WIN32)
4020 - set_target_properties(halbasictest PROPERTIES COMPILE_FLAGS -DSOLID_EXPORT=)
4021 -endif(WIN32)
4022 -
4023 -target_link_libraries(halbasictest solid_static ${KDEWIN_LIBRARIES} ${QT_QTCORE_LIBRARY} ${QT_QTDBUS_LIBRARY} ${QT_QTXML_LIBRARY} ${QT_QTTEST_LIBRARY} )
4024 -endif(NOT WIN32 AND NOT APPLE)
4025 -
4026 ########### solidhwtest ###############
4027
4028 set(solidhwtest_SRCS