Solid

udisksopticaldrive.cpp
1/*
2 SPDX-FileCopyrightText: 2010 Michael Zanetti <mzanetti@kde.org>
3 SPDX-FileCopyrightText: 2010-2012 Lukáš Tinkl <ltinkl@redhat.com>
4
5 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
6*/
7
8#include "udisksopticaldrive.h"
9
10#include <errno.h>
11#include <fcntl.h>
12#include <stdlib.h>
13#include <string.h>
14#include <sys/stat.h>
15#include <sys/types.h>
16#include <unistd.h>
17
18#include <QDebug>
19#include <QFile>
20
21#include "dbus/manager.h"
22#include "udisks2.h"
23#include "udisks_debug.h"
24#include "udisksdevice.h"
25
26using namespace Solid::Backends::UDisks2;
27
28OpticalDrive::OpticalDrive(Device *device)
29 : StorageDrive(device)
30 , m_ejectInProgress(false)
31 , m_readSpeed(0)
32 , m_writeSpeed(0)
33 , m_speedsInit(false)
34{
35 m_device->registerAction("eject", this, SLOT(slotEjectRequested()), SLOT(slotEjectDone(int, QString)));
36
37 connect(m_device, SIGNAL(changed()), this, SLOT(slotChanged()));
38}
39
40OpticalDrive::~OpticalDrive()
41{
42}
43
44bool OpticalDrive::eject()
45{
46 if (m_ejectInProgress) {
47 return false;
48 }
49 m_ejectInProgress = true;
50 m_device->broadcastActionRequested("eject");
51
52 const QString path = m_device->udi();
53 QDBusConnection c = QDBusConnection::connectToBus(QDBusConnection::SystemBus, "Solid::Udisks2::OpticalDrive::" + path);
54
55 // if the device is mounted, unmount first
56 QString blockPath;
57 org::freedesktop::DBus::ObjectManager manager(UD2_DBUS_SERVICE, UD2_DBUS_PATH, c);
58 QDBusPendingReply<DBUSManagerStruct> reply = manager.GetManagedObjects();
59 reply.waitForFinished();
60 if (!reply.isError()) { // enum devices
61 const auto objPathMap = reply.value();
62 for (auto it = objPathMap.cbegin(); it != objPathMap.cend(); ++it) {
63 const QString udi = it.key().path();
64
65 // qDebug() << "Inspecting" << udi;
66
67 if (udi == UD2_DBUS_PATH_MANAGER || udi == UD2_UDI_DISKS_PREFIX || udi.startsWith(UD2_DBUS_PATH_JOBS)) {
68 continue;
69 }
70
71 Device device(udi);
72 if (device.drivePath() == path && device.isMounted()) {
73 // qDebug() << "Got mounted block device:" << udi;
74 blockPath = udi;
75 break;
76 }
77 }
78 } else { // show error
79 qCWarning(UDISKS2) << "Failed enumerating UDisks2 objects:" << reply.error().name() << "\n" << reply.error().message();
80 }
81
82 if (!blockPath.isEmpty()) {
83 // qDebug() << "Calling unmount on" << blockPath;
84 QDBusMessage msg = QDBusMessage::createMethodCall(UD2_DBUS_SERVICE, blockPath, UD2_DBUS_INTERFACE_FILESYSTEM, "Unmount");
85 msg << QVariantMap(); // options, unused now
87 }
88
89 QDBusMessage msg = QDBusMessage::createMethodCall(UD2_DBUS_SERVICE, path, UD2_DBUS_INTERFACE_DRIVE, "Eject");
90 msg << QVariantMap();
91 return c.callWithCallback(msg, this, SLOT(slotDBusReply(QDBusMessage)), SLOT(slotDBusError(QDBusError)));
92}
93
94void OpticalDrive::slotDBusReply(const QDBusMessage & /*reply*/)
95{
96 m_ejectInProgress = false;
97 m_device->broadcastActionDone("eject");
98}
99
100void OpticalDrive::slotDBusError(const QDBusError &error)
101{
102 m_ejectInProgress = false;
103 m_device->broadcastActionDone("eject", //
104 m_device->errorToSolidError(error.name()),
105 m_device->errorToString(error.name()) + ": " + error.message());
106}
107
108void OpticalDrive::slotEjectRequested()
109{
110 m_ejectInProgress = true;
111 Q_EMIT ejectRequested(m_device->udi());
112}
113
114void OpticalDrive::slotEjectDone(int error, const QString &errorString)
115{
116 m_ejectInProgress = false;
117 Q_EMIT ejectDone(static_cast<Solid::ErrorType>(error), errorString, m_device->udi());
118}
119
120void OpticalDrive::initReadWriteSpeeds() const
121{
122#if 0
123 int read_speed, write_speed;
124 char *write_speeds = 0;
125 QByteArray device_file = QFile::encodeName(m_device->property("Device").toString());
126
127 //qDebug("Doing open (\"%s\", O_RDONLY | O_NONBLOCK)", device_file.constData());
128 int fd = open(device_file, O_RDONLY | O_NONBLOCK);
129 if (fd < 0) {
130 qWarning("Cannot open %s: %s", device_file.constData(), strerror(errno));
131 return;
132 }
133
134 if (get_read_write_speed(fd, &read_speed, &write_speed, &write_speeds) >= 0) {
135 m_readSpeed = read_speed;
136 m_writeSpeed = write_speed;
137
139 Q_FOREACH (const QString &speed, list) {
140 m_writeSpeeds.append(speed.toInt());
141 }
142
143 free(write_speeds);
144
145 m_speedsInit = true;
146 }
147
148 close(fd);
149#endif
150}
151
152QList<int> OpticalDrive::writeSpeeds() const
153{
154 if (!m_speedsInit) {
155 initReadWriteSpeeds();
156 }
157 // qDebug() << "solid write speeds:" << m_writeSpeeds;
158 return m_writeSpeeds;
159}
160
161int OpticalDrive::writeSpeed() const
162{
163 if (!m_speedsInit) {
164 initReadWriteSpeeds();
165 }
166 return m_writeSpeed;
167}
168
169int OpticalDrive::readSpeed() const
170{
171 if (!m_speedsInit) {
172 initReadWriteSpeeds();
173 }
174 return m_readSpeed;
175}
176
177Solid::OpticalDrive::MediumTypes OpticalDrive::supportedMedia() const
178{
179 const QStringList mediaTypes = m_device->prop("MediaCompatibility").toStringList();
181
183 {QStringLiteral("optical_cd_r"), Solid::OpticalDrive::Cdr},
184 {QStringLiteral("optical_cd_rw"), Solid::OpticalDrive::Cdrw},
185 {QStringLiteral("optical_dvd"), Solid::OpticalDrive::Dvd},
186 {QStringLiteral("optical_dvd_r"), Solid::OpticalDrive::Dvdr},
187 {QStringLiteral("optical_dvd_rw"), Solid::OpticalDrive::Dvdrw},
188 {QStringLiteral("optical_dvd_ram"), Solid::OpticalDrive::Dvdram},
189 {QStringLiteral("optical_dvd_plus_r"), Solid::OpticalDrive::Dvdplusr},
190 {QStringLiteral("optical_dvd_plus_rw"), Solid::OpticalDrive::Dvdplusrw},
191 {QStringLiteral("optical_dvd_plus_r_dl"), Solid::OpticalDrive::Dvdplusdl},
192 {QStringLiteral("optical_dvd_plus_rw_dl"), Solid::OpticalDrive::Dvdplusdlrw},
193 {QStringLiteral("optical_bd"), Solid::OpticalDrive::Bd},
194 {QStringLiteral("optical_bd_r"), Solid::OpticalDrive::Bdr},
195 {QStringLiteral("optical_bd_re"), Solid::OpticalDrive::Bdre},
196 {QStringLiteral("optical_hddvd"), Solid::OpticalDrive::HdDvd},
197 {QStringLiteral("optical_hddvd_r"), Solid::OpticalDrive::HdDvdr},
198 {QStringLiteral("optical_hddvd_rw"), Solid::OpticalDrive::HdDvdrw},
199 };
200
201 // TODO add these to Solid
202 // map[Solid::OpticalDrive::Mo] ="optical_mo";
203 // map[Solid::OpticalDrive::Mr] ="optical_mrw";
204 // map[Solid::OpticalDrive::Mrw] ="optical_mrw_w";
205
206 for (const QString &media : mediaTypes) {
207 supported |= map.value(media, Solid::OpticalDrive::UnknownMediumType);
208 }
209
210 return supported;
211}
212
213void OpticalDrive::slotChanged()
214{
215 m_speedsInit = false; // reset the read/write speeds, changes eg. with an inserted media
216}
217
218#include "moc_udisksopticaldrive.cpp"
void broadcastActionRequested(const QString &actionName) const
Allows to broadcast that an action just got requested on a device to all the corresponding devices in...
void broadcastActionDone(const QString &actionName, int error=Solid::NoError, const QString &errorString=QString()) const
Allows to broadcast that an action just completed in a device to all the corresponding devices in oth...
QString path(const QString &relativePath)
void error(QWidget *parent, const QString &text, const QString &title, const KGuiItem &buttonOk, Options options=Notify)
KIOCORE_EXPORT QStringList list(const QString &fileClass)
const QList< QKeySequence > & close()
const QList< QKeySequence > & open()
const char * constData() const const
QDBusMessage call(const QDBusMessage &message, QDBus::CallMode mode, int timeout) const const
bool callWithCallback(const QDBusMessage &message, QObject *receiver, const char *returnMethod, const char *errorMethod, int timeout) const const
QDBusConnection connectToBus(BusType type, const QString &name)
QString message() const const
QString name() const const
QDBusMessage createMethodCall(const QString &service, const QString &path, const QString &interface, const QString &method)
QDBusError error() const const
bool isError() const const
typename Select< 0 >::Type value() const const
QByteArray encodeName(const QString &fileName)
void append(QList< T > &&value)
Q_EMITQ_EMIT
QVariant property(const char *name) const const
QString fromLatin1(QByteArrayView str)
bool isEmpty() const const
QStringList split(QChar sep, Qt::SplitBehavior behavior, Qt::CaseSensitivity cs) const const
bool startsWith(QChar c, Qt::CaseSensitivity cs) const const
int toInt(bool *ok, int base) const const
SkipEmptyParts
QFuture< void > map(Iterator begin, Iterator end, MapFunctor &&function)
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
QString toString() const const
QStringList toStringList() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:17:12 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.