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(QStringLiteral("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(QStringLiteral("eject"));
51
52 const QString path = m_device->udi();
53 QDBusConnection c = QDBusConnection::connectToBus(QDBusConnection::SystemBus, QStringLiteral("Solid::Udisks2::OpticalDrive::") + path);
54
55 // if the device is mounted, unmount first
56 QString blockPath;
57 org::freedesktop::DBus::ObjectManager manager(QStringLiteral(UD2_DBUS_SERVICE), QStringLiteral(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 == QLatin1String(UD2_DBUS_PATH_MANAGER) //
68 || udi == QLatin1String(UD2_UDI_DISKS_PREFIX) //
69 || udi.startsWith(QStringLiteral(UD2_DBUS_PATH_JOBS))) {
70 continue;
71 }
72
73 Device device(udi);
74 if (device.drivePath() == path && device.isMounted()) {
75 // qDebug() << "Got mounted block device:" << udi;
76 blockPath = udi;
77 break;
78 }
79 }
80 } else { // show error
81 qCWarning(UDISKS2) << "Failed enumerating UDisks2 objects:" << reply.error().name() << "\n" << reply.error().message();
82 }
83
84 if (!blockPath.isEmpty()) {
85 // qDebug() << "Calling unmount on" << blockPath;
86 QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral(UD2_DBUS_SERVICE),
87 blockPath,
88 QStringLiteral(UD2_DBUS_INTERFACE_FILESYSTEM),
89 QStringLiteral("Unmount"));
90 msg << QVariantMap(); // options, unused now
92 }
93
94 QDBusMessage msg =
95 QDBusMessage::createMethodCall(QStringLiteral(UD2_DBUS_SERVICE), path, QStringLiteral(UD2_DBUS_INTERFACE_DRIVE), QStringLiteral("Eject"));
96 msg << QVariantMap();
97 return c.callWithCallback(msg, this, SLOT(slotDBusReply(QDBusMessage)), SLOT(slotDBusError(QDBusError)));
98}
99
100void OpticalDrive::slotDBusReply(const QDBusMessage & /*reply*/)
101{
102 m_ejectInProgress = false;
103 m_device->broadcastActionDone(QStringLiteral("eject"));
104}
105
106void OpticalDrive::slotDBusError(const QDBusError &error)
107{
108 m_ejectInProgress = false;
109 m_device->broadcastActionDone(QStringLiteral("eject"), //
110 m_device->errorToSolidError(error.name()),
111 m_device->errorToString(error.name()) + QStringLiteral(": ") + error.message());
112}
113
114void OpticalDrive::slotEjectRequested()
115{
116 m_ejectInProgress = true;
117 Q_EMIT ejectRequested(m_device->udi());
118}
119
120void OpticalDrive::slotEjectDone(int error, const QString &errorString)
121{
122 m_ejectInProgress = false;
123 Q_EMIT ejectDone(static_cast<Solid::ErrorType>(error), errorString, m_device->udi());
124}
125
126void OpticalDrive::initReadWriteSpeeds() const
127{
128#if 0
129 int read_speed, write_speed;
130 char *write_speeds = 0;
131 QByteArray device_file = QFile::encodeName(m_device->property("Device").toString());
132
133 //qDebug("Doing open (\"%s\", O_RDONLY | O_NONBLOCK)", device_file.constData());
134 int fd = open(device_file, O_RDONLY | O_NONBLOCK);
135 if (fd < 0) {
136 qWarning("Cannot open %s: %s", device_file.constData(), strerror(errno));
137 return;
138 }
139
140 if (get_read_write_speed(fd, &read_speed, &write_speed, &write_speeds) >= 0) {
141 m_readSpeed = read_speed;
142 m_writeSpeed = write_speed;
143
145 Q_FOREACH (const QString &speed, list) {
146 m_writeSpeeds.append(speed.toInt());
147 }
148
149 free(write_speeds);
150
151 m_speedsInit = true;
152 }
153
154 close(fd);
155#endif
156}
157
158QList<int> OpticalDrive::writeSpeeds() const
159{
160 if (!m_speedsInit) {
161 initReadWriteSpeeds();
162 }
163 // qDebug() << "solid write speeds:" << m_writeSpeeds;
164 return m_writeSpeeds;
165}
166
167int OpticalDrive::writeSpeed() const
168{
169 if (!m_speedsInit) {
170 initReadWriteSpeeds();
171 }
172 return m_writeSpeed;
173}
174
175int OpticalDrive::readSpeed() const
176{
177 if (!m_speedsInit) {
178 initReadWriteSpeeds();
179 }
180 return m_readSpeed;
181}
182
183Solid::OpticalDrive::MediumTypes OpticalDrive::supportedMedia() const
184{
185 const QStringList mediaTypes = m_device->prop(QStringLiteral("MediaCompatibility")).toStringList();
187
189 {QStringLiteral("optical_cd_r"), Solid::OpticalDrive::Cdr},
190 {QStringLiteral("optical_cd_rw"), Solid::OpticalDrive::Cdrw},
191 {QStringLiteral("optical_dvd"), Solid::OpticalDrive::Dvd},
192 {QStringLiteral("optical_dvd_r"), Solid::OpticalDrive::Dvdr},
193 {QStringLiteral("optical_dvd_rw"), Solid::OpticalDrive::Dvdrw},
194 {QStringLiteral("optical_dvd_ram"), Solid::OpticalDrive::Dvdram},
195 {QStringLiteral("optical_dvd_plus_r"), Solid::OpticalDrive::Dvdplusr},
196 {QStringLiteral("optical_dvd_plus_rw"), Solid::OpticalDrive::Dvdplusrw},
197 {QStringLiteral("optical_dvd_plus_r_dl"), Solid::OpticalDrive::Dvdplusdl},
198 {QStringLiteral("optical_dvd_plus_rw_dl"), Solid::OpticalDrive::Dvdplusdlrw},
199 {QStringLiteral("optical_bd"), Solid::OpticalDrive::Bd},
200 {QStringLiteral("optical_bd_r"), Solid::OpticalDrive::Bdr},
201 {QStringLiteral("optical_bd_re"), Solid::OpticalDrive::Bdre},
202 {QStringLiteral("optical_hddvd"), Solid::OpticalDrive::HdDvd},
203 {QStringLiteral("optical_hddvd_r"), Solid::OpticalDrive::HdDvdr},
204 {QStringLiteral("optical_hddvd_rw"), Solid::OpticalDrive::HdDvdrw},
205 };
206
207 // TODO add these to Solid
208 // map[Solid::OpticalDrive::Mo] ="optical_mo";
209 // map[Solid::OpticalDrive::Mr] ="optical_mrw";
210 // map[Solid::OpticalDrive::Mrw] ="optical_mrw_w";
211
212 for (const QString &media : mediaTypes) {
213 supported |= map.value(media, Solid::OpticalDrive::UnknownMediumType);
214 }
215
216 return supported;
217}
218
219void OpticalDrive::slotChanged()
220{
221 m_speedsInit = false; // reset the read/write speeds, changes eg. with an inserted media
222}
223
224#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 Fri Dec 6 2024 12:07:11 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.