Solid

udisksdevice.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 "udisksdevice.h"
9#include "udisks_debug.h"
10#include "udisksblock.h"
11#include "udisksdevicebackend.h"
12#include "udisksdeviceinterface.h"
13#include "udisksgenericinterface.h"
14#include "udisksopticaldisc.h"
15#include "udisksopticaldrive.h"
16#include "udisksstorageaccess.h"
17#include "udisksstoragevolume.h"
18
19#include <solid/device.h>
20#include <solid/genericinterface.h>
21
22#include <QLocale>
23#include <QMimeDatabase>
24
25using namespace Solid::Backends::UDisks2;
26
27// Adapted from KLocale as Solid needs to be Qt-only
28static QString formatByteSize(double size)
29{
30 // Per IEC 60027-2
31
32 // Binary prefixes
33 // Tebi-byte TiB 2^40 1,099,511,627,776 bytes
34 // Gibi-byte GiB 2^30 1,073,741,824 bytes
35 // Mebi-byte MiB 2^20 1,048,576 bytes
36 // Kibi-byte KiB 2^10 1,024 bytes
37
38 QString s;
39 // Gibi-byte
40 if (size >= 1073741824.0) {
41 size /= 1073741824.0;
42 if (size > 1024) { // Tebi-byte
43 s = QCoreApplication::translate("udisksdevice", "%1 TiB").arg(QLocale().toString(size / 1024.0, 'f', 1));
44 } else {
45 s = QCoreApplication::translate("udisksdevice", "%1 GiB").arg(QLocale().toString(size, 'f', 1));
46 }
47 }
48 // Mebi-byte
49 else if (size >= 1048576.0) {
50 size /= 1048576.0;
51 s = QCoreApplication::translate("udisksdevice", "%1 MiB").arg(QLocale().toString(size, 'f', 1));
52 }
53 // Kibi-byte
54 else if (size >= 1024.0) {
55 size /= 1024.0;
56 s = QCoreApplication::translate("udisksdevice", "%1 KiB").arg(QLocale().toString(size, 'f', 1));
57 }
58 // Just byte
59 else if (size > 0) {
60 s = QCoreApplication::translate("udisksdevice", "%1 B").arg(QLocale().toString(size, 'f', 1));
61 }
62 // Nothing
63 else {
64 s = QCoreApplication::translate("udisksdevice", "0 B");
65 }
66 return s;
67}
68
69static QString concatBlockDeviceDescription(const QString &name, qulonglong size, bool isExternal)
70{
71 QString description;
72 if (size > 0) {
73 const QString sizeStr = formatByteSize(size);
74 if (isExternal) {
75 description = QObject::tr("%1 External Drive (%2)", "%1 is the size, %2 is the block device name e.g. sda, sda1").arg(sizeStr, name);
76 } else {
77 description = QObject::tr("%1 Internal Drive (%2)", "%1 is the size, %2 is the block device name e.g. sda, sda1").arg(sizeStr, name);
78 }
79 } else {
80 if (isExternal) {
81 description = QObject::tr("External Drive (%1)", "%1 is the block device name e.g. sda, sda1").arg(name);
82 } else {
83 description = QObject::tr("Internal Drive (%1)", "%1 is the block device name e.g. sda, sda1").arg(name);
84 }
85 }
86
87 return description;
88}
89
90Device::Device(const QString &udi)
91 : Solid::Ifaces::Device()
92 , m_backend(DeviceBackend::backendForUDI(udi))
93{
94 if (m_backend) {
95 connect(m_backend, &DeviceBackend::changed, this, &Device::changed);
96 connect(m_backend, &DeviceBackend::propertyChanged, this, &Device::propertyChanged);
97 } else {
98 qCDebug(UDISKS2) << "Created invalid Device for udi" << udi;
99 }
100}
101
102Device::~Device()
103{
104}
105
106QString Device::udi() const
107{
108 if (m_backend) {
109 return m_backend->udi();
110 }
111
112 return QString();
113}
114
115QVariant Device::prop(const QString &key) const
116{
117 if (m_backend) {
118 return m_backend->prop(key);
119 }
120
121 return QVariant();
122}
123
124bool Device::propertyExists(const QString &key) const
125{
126 if (m_backend) {
127 return m_backend->propertyExists(key);
128 }
129
130 return false;
131}
132
133QVariantMap Device::allProperties() const
134{
135 if (m_backend) {
136 return m_backend->allProperties();
137 }
138
139 return QVariantMap();
140}
141
142bool Device::hasInterface(const QString &name) const
143{
144 if (m_backend) {
145 return m_backend->interfaces().contains(name);
146 }
147
148 return false;
149}
150
151QStringList Device::interfaces() const
152{
153 if (m_backend) {
154 return m_backend->interfaces();
155 }
156
157 return QStringList();
158}
159
160void Device::invalidateCache()
161{
162 if (m_backend) {
163 return m_backend->invalidateProperties();
164 }
165}
166
167QObject *Device::createDeviceInterface(const Solid::DeviceInterface::Type &type)
168{
169 if (!queryDeviceInterface(type)) {
170 return nullptr;
171 }
172
173 DeviceInterface *iface = nullptr;
174 switch (type) {
175 case Solid::DeviceInterface::GenericInterface:
176 iface = new GenericInterface(this);
177 break;
178 case Solid::DeviceInterface::Block:
179 iface = new Block(this);
180 break;
181 case Solid::DeviceInterface::StorageAccess:
182 iface = new StorageAccess(this);
183 break;
184 case Solid::DeviceInterface::StorageDrive:
185 iface = new StorageDrive(this);
186 break;
187 case Solid::DeviceInterface::OpticalDrive:
188 iface = new OpticalDrive(this);
189 break;
190 case Solid::DeviceInterface::StorageVolume:
191 iface = new StorageVolume(this);
192 break;
193 case Solid::DeviceInterface::OpticalDisc:
194 iface = new OpticalDisc(this);
195 break;
196 default:
197 break;
198 }
199 return iface;
200}
201
202bool Device::queryDeviceInterface(const Solid::DeviceInterface::Type &type) const
203{
204 switch (type) {
205 case Solid::DeviceInterface::GenericInterface:
206 return true;
207 case Solid::DeviceInterface::Block:
208 return isBlock() || isDrive();
209 case Solid::DeviceInterface::StorageVolume:
210 return isStorageVolume();
211 case Solid::DeviceInterface::StorageAccess:
212 return isStorageAccess();
213 case Solid::DeviceInterface::StorageDrive:
214 return isDrive();
215 case Solid::DeviceInterface::OpticalDrive:
216 return isOpticalDrive();
217 case Solid::DeviceInterface::OpticalDisc:
218 return isOpticalDisc();
219 default:
220 return false;
221 }
222}
223
224QStringList Device::emblems() const
225{
226 if (queryDeviceInterface(Solid::DeviceInterface::StorageAccess)) {
227 const UDisks2::StorageAccess accessIface(const_cast<Device *>(this));
228 if (accessIface.isAccessible()) {
229 if (isEncryptedContainer()) {
230 return {QStringLiteral("emblem-encrypted-unlocked")};
231 }
232 } else {
233 if (isEncryptedContainer()) {
234 return {QStringLiteral("emblem-encrypted-locked")};
235 } else {
236 return {QStringLiteral("emblem-unmounted")};
237 }
238 }
239 }
240
241 return {};
242}
243
244QString Device::description() const
245{
246 const QString hintName = property("HintName").toString(); // non-cached
247 if (!hintName.isEmpty()) {
248 return hintName;
249 }
250
251 if (isLoop()) {
252 return loopDescription();
253 } else if (isSwap()) {
254 return tr("Swap Space");
255 } else if (queryDeviceInterface(Solid::DeviceInterface::StorageDrive)) {
256 return storageDescription();
257 } else if (queryDeviceInterface(Solid::DeviceInterface::StorageVolume)) {
258 return volumeDescription();
259 } else {
260 return product();
261 }
262}
263
264QString Device::loopDescription() const
265{
266 const QString label = prop(QStringLiteral("IdLabel")).toString();
267 if (!label.isEmpty()) {
268 return label;
269 }
270
271 const QString backingFile = prop(QStringLiteral("BackingFile")).toString();
272 if (!backingFile.isEmpty()) {
273 return backingFile.section(QLatin1Char('/'), -1);
274 }
275
276 return tr("Loop Device");
277}
278
279QString Device::storageDescription() const
280{
281 QString description;
282 const UDisks2::StorageDrive storageDrive(const_cast<Device *>(this));
283 Solid::StorageDrive::DriveType drive_type = storageDrive.driveType();
284 const bool drive_is_hotpluggable = storageDrive.isHotpluggable();
285
286 if (drive_type == Solid::StorageDrive::CdromDrive) {
287 const UDisks2::OpticalDrive opticalDrive(const_cast<Device *>(this));
288 Solid::OpticalDrive::MediumTypes mediumTypes = opticalDrive.supportedMedia();
289 QString first;
290 QString second;
291
292 first = tr("CD-ROM", "First item of %1%2 Drive sentence");
293 if (mediumTypes & Solid::OpticalDrive::Cdr) {
294 first = tr("CD-R", "First item of %1%2 Drive sentence");
295 }
296 if (mediumTypes & Solid::OpticalDrive::Cdrw) {
297 first = tr("CD-RW", "First item of %1%2 Drive sentence");
298 }
299
300 if (mediumTypes & Solid::OpticalDrive::Dvd) {
301 second = tr("/DVD-ROM", "Second item of %1%2 Drive sentence");
302 }
303 if (mediumTypes & Solid::OpticalDrive::Dvdplusr) {
304 second = tr("/DVD+R", "Second item of %1%2 Drive sentence");
305 }
306 if (mediumTypes & Solid::OpticalDrive::Dvdplusrw) {
307 second = tr("/DVD+RW", "Second item of %1%2 Drive sentence");
308 }
309 if (mediumTypes & Solid::OpticalDrive::Dvdr) {
310 second = tr("/DVD-R", "Second item of %1%2 Drive sentence");
311 }
312 if (mediumTypes & Solid::OpticalDrive::Dvdrw) {
313 second = tr("/DVD-RW", "Second item of %1%2 Drive sentence");
314 }
315 if (mediumTypes & Solid::OpticalDrive::Dvdram) {
316 second = tr("/DVD-RAM", "Second item of %1%2 Drive sentence");
317 }
318 if ((mediumTypes & Solid::OpticalDrive::Dvdr) && (mediumTypes & Solid::OpticalDrive::Dvdplusr)) {
319 if (mediumTypes & Solid::OpticalDrive::Dvdplusdl) {
320 second = tr("/DVD±R DL", "Second item of %1%2 Drive sentence");
321 } else {
322 second = tr("/DVD±R", "Second item of %1%2 Drive sentence");
323 }
324 }
325 if ((mediumTypes & Solid::OpticalDrive::Dvdrw) && (mediumTypes & Solid::OpticalDrive::Dvdplusrw)) {
326 if ((mediumTypes & Solid::OpticalDrive::Dvdplusdl) || (mediumTypes & Solid::OpticalDrive::Dvdplusdlrw)) {
327 second = tr("/DVD±RW DL", "Second item of %1%2 Drive sentence");
328 } else {
329 second = tr("/DVD±RW", "Second item of %1%2 Drive sentence");
330 }
331 }
332 if (mediumTypes & Solid::OpticalDrive::Bd) {
333 second = tr("/BD-ROM", "Second item of %1%2 Drive sentence");
334 }
335 if (mediumTypes & Solid::OpticalDrive::Bdr) {
336 second = tr("/BD-R", "Second item of %1%2 Drive sentence");
337 }
338 if (mediumTypes & Solid::OpticalDrive::Bdre) {
339 second = tr("/BD-RE", "Second item of %1%2 Drive sentence");
340 }
341 if (mediumTypes & Solid::OpticalDrive::HdDvd) {
342 second = tr("/HD DVD-ROM", "Second item of %1%2 Drive sentence");
343 }
344 if (mediumTypes & Solid::OpticalDrive::HdDvdr) {
345 second = tr("/HD DVD-R", "Second item of %1%2 Drive sentence");
346 }
347 if (mediumTypes & Solid::OpticalDrive::HdDvdrw) {
348 second = tr("/HD DVD-RW", "Second item of %1%2 Drive sentence");
349 }
350
351 if (drive_is_hotpluggable) {
352 description = tr("External %1%2 Drive", "%1 is CD-ROM/CD-R/etc; %2 is '/DVD-ROM'/'/DVD-R'/etc (with leading slash)").arg(first, second);
353 } else {
354 description = tr("%1%2 Drive", "%1 is CD-ROM/CD-R/etc; %2 is '/DVD-ROM'/'/DVD-R'/etc (with leading slash)").arg(first, second);
355 }
356
357 return description;
358 }
359
360 if (drive_type == Solid::StorageDrive::Floppy) {
361 if (drive_is_hotpluggable) {
362 description = tr("External Floppy Drive");
363 } else {
364 description = tr("Floppy Drive");
365 }
366
367 return description;
368 }
369
370 const bool drive_is_removable = storageDrive.isRemovable();
371
372 if (drive_type == Solid::StorageDrive::HardDisk && !drive_is_removable) {
373 QString devName = storageDrive.device();
374 devName.remove(QLatin1String("/dev/"));
375 description = concatBlockDeviceDescription(devName, storageDrive.size(), drive_is_hotpluggable);
376
377 return description;
378 }
379
380 QString vendormodel_str;
381 QString model = product();
382 QString vendor_str = vendor();
383
384 if (vendor_str.isEmpty()) {
385 if (!model.isEmpty()) {
386 vendormodel_str = model;
387 }
388 } else {
389 if (model.isEmpty()) {
390 vendormodel_str = vendor_str;
391 } else {
392 if (model.startsWith(vendor_str)) {
393 // e.g. vendor is "Nokia" and model is "Nokia N950" we do not want "Nokia Nokia N950" as description
394 vendormodel_str = model;
395 } else {
396 vendormodel_str = tr("%1 %2", "%1 is the vendor, %2 is the model of the device").arg(vendor_str, model);
397 }
398 }
399 }
400
401 if (vendormodel_str.isEmpty()) {
402 description = tr("Drive");
403 } else {
404 description = vendormodel_str;
405 }
406
407 return description;
408}
409
410QString Device::volumeDescription() const
411{
412 QString description;
413 const UDisks2::StorageVolume storageVolume(const_cast<Device *>(this));
414 QString volume_label = prop(QStringLiteral("IdLabel")).toString();
415 if (volume_label.isEmpty()) {
416 volume_label = prop(QStringLiteral("Name")).toString();
417 }
418 if (!volume_label.isEmpty()) {
419 return volume_label;
420 }
421
422 UDisks2::Device storageDevice(drivePath());
423 const UDisks2::StorageDrive storageDrive(&storageDevice);
424 Solid::StorageDrive::DriveType drive_type = storageDrive.driveType();
425
426 // Handle media in optical drives
427 if (drive_type == Solid::StorageDrive::CdromDrive) {
428 const UDisks2::OpticalDisc disc(const_cast<Device *>(this));
429 switch (disc.discType()) {
430 case Solid::OpticalDisc::UnknownDiscType:
431 case Solid::OpticalDisc::CdRom:
432 description = tr("CD-ROM");
433 break;
434
435 case Solid::OpticalDisc::CdRecordable:
436 if (disc.isBlank()) {
437 description = tr("Blank CD-R");
438 } else {
439 description = tr("CD-R");
440 }
441 break;
442
443 case Solid::OpticalDisc::CdRewritable:
444 if (disc.isBlank()) {
445 description = tr("Blank CD-RW");
446 } else {
447 description = tr("CD-RW");
448 }
449 break;
450
451 case Solid::OpticalDisc::DvdRom:
452 description = tr("DVD-ROM");
453 break;
454
455 case Solid::OpticalDisc::DvdRam:
456 if (disc.isBlank()) {
457 description = tr("Blank DVD-RAM");
458 } else {
459 description = tr("DVD-RAM");
460 }
461 break;
462
463 case Solid::OpticalDisc::DvdRecordable:
464 if (disc.isBlank()) {
465 description = tr("Blank DVD-R");
466 } else {
467 description = tr("DVD-R");
468 }
469 break;
470
471 case Solid::OpticalDisc::DvdPlusRecordableDuallayer:
472 if (disc.isBlank()) {
473 description = tr("Blank DVD+R Dual-Layer");
474 } else {
475 description = tr("DVD+R Dual-Layer");
476 }
477 break;
478
479 case Solid::OpticalDisc::DvdRewritable:
480 if (disc.isBlank()) {
481 description = tr("Blank DVD-RW");
482 } else {
483 description = tr("DVD-RW");
484 }
485 break;
486
487 case Solid::OpticalDisc::DvdPlusRecordable:
488 if (disc.isBlank()) {
489 description = tr("Blank DVD+R");
490 } else {
491 description = tr("DVD+R");
492 }
493 break;
494
495 case Solid::OpticalDisc::DvdPlusRewritable:
496 if (disc.isBlank()) {
497 description = tr("Blank DVD+RW");
498 } else {
499 description = tr("DVD+RW");
500 }
501 break;
502
503 case Solid::OpticalDisc::DvdPlusRewritableDuallayer:
504 if (disc.isBlank()) {
505 description = tr("Blank DVD+RW Dual-Layer");
506 } else {
507 description = tr("DVD+RW Dual-Layer");
508 }
509 break;
510
511 case Solid::OpticalDisc::BluRayRom:
512 description = tr("BD-ROM");
513 break;
514
515 case Solid::OpticalDisc::BluRayRecordable:
516 if (disc.isBlank()) {
517 description = tr("Blank BD-R");
518 } else {
519 description = tr("BD-R");
520 }
521 break;
522
523 case Solid::OpticalDisc::BluRayRewritable:
524 if (disc.isBlank()) {
525 description = tr("Blank BD-RE");
526 } else {
527 description = tr("BD-RE");
528 }
529 break;
530
531 case Solid::OpticalDisc::HdDvdRom:
532 description = tr("HD DVD-ROM");
533 break;
534
535 case Solid::OpticalDisc::HdDvdRecordable:
536 if (disc.isBlank()) {
537 description = tr("Blank HD DVD-R");
538 } else {
539 description = tr("HD DVD-R");
540 }
541 break;
542
543 case Solid::OpticalDisc::HdDvdRewritable:
544 if (disc.isBlank()) {
545 description = tr("Blank HD DVD-RW");
546 } else {
547 description = tr("HD DVD-RW");
548 }
549 break;
550 }
551
552 // Special case for pure audio disc
553 if (disc.availableContent() == Solid::OpticalDisc::Audio) {
554 description = tr("Audio CD");
555 }
556
557 return description;
558 }
559
560 const bool drive_is_removable = storageDrive.isRemovable();
561
562 QString size_str = formatByteSize(storageVolume.size());
563 QString volumeName = storageVolume.device();
564 volumeName.remove(QLatin1String("/dev/"));
565 if (isEncryptedContainer()) {
566 if (storageVolume.size() > 0) {
567 description = tr("%1 Encrypted Drive", "%1 is the size").arg(size_str);
568 } else {
569 description = tr("Encrypted Drive");
570 }
571 } else if (drive_type == Solid::StorageDrive::HardDisk && !drive_is_removable) {
572 description = concatBlockDeviceDescription(volumeName, storageVolume.size(), storageDrive.isHotpluggable());
573 } else if (drive_type == Solid::StorageDrive::Floppy) {
574 description = tr("Floppy Disk");
575 } else {
576 if (drive_is_removable) {
577 if (storageVolume.size() > 0) {
578 description = tr("%1 Removable Media", "%1 is the size").arg(size_str);
579 } else {
580 description = tr("Removable Media");
581 }
582 } else {
583 if (storageVolume.size() > 0) {
584 description = tr("%1 Media", "%1 is the size").arg(size_str);
585 } else {
586 description = tr("Storage Media");
587 }
588 }
589 }
590
591 return description;
592}
593
594QString Device::icon() const
595{
596 QString iconName = property("HintIconName").toString(); // non-cached
597
598 if (!iconName.isEmpty()) {
599 return iconName;
600 } else if (isRoot()) {
601 return QStringLiteral("drive-harddisk-root");
602 } else if (isLoop()) {
603 const QString backingFile = prop(QStringLiteral("BackingFile")).toString();
604 if (!backingFile.isEmpty()) {
606 if (!type.isDefault()) {
607 return type.iconName();
608 }
609 }
610 return QStringLiteral("drive-harddisk");
611 } else if (isSwap()) {
612 return QStringLiteral("drive-harddisk");
613 } else if (isDrive()) {
614 const bool isRemovable = prop(QStringLiteral("Removable")).toBool();
615 const QString conn = prop(QStringLiteral("ConnectionBus")).toString();
616
617 if (isOpticalDrive()) {
618 return QStringLiteral("drive-optical");
619 } else if (isRemovable && !prop(QStringLiteral("Optical")).toBool()) {
620 if (conn == QLatin1String("usb")) {
621 return QStringLiteral("drive-removable-media-usb");
622 } else {
623 return QStringLiteral("drive-removable-media");
624 }
625 }
626 } else if (isBlock()) {
627 const QString drv = drivePath();
628 if (drv.isEmpty() || drv == QLatin1String("/")) {
629 return QStringLiteral("drive-harddisk"); // stuff like loop devices or swap which don't have the Drive prop set
630 }
631
632 Device drive(drv);
633
634 // handle media
635 const QString media = drive.prop(QStringLiteral("Media")).toString();
636
637 if (!media.isEmpty()) {
638 if (drive.prop(QStringLiteral("Optical")).toBool()) { // optical stuff
639 bool isWritable = drive.prop(QStringLiteral("OpticalBlank")).toBool();
640
641 const UDisks2::OpticalDisc disc(const_cast<Device *>(this));
642 Solid::OpticalDisc::ContentTypes availContent = disc.availableContent();
643
644 if (availContent & Solid::OpticalDisc::VideoDvd) { // Video DVD
645 return QStringLiteral("media-optical-dvd-video");
646 } else if ((availContent & Solid::OpticalDisc::VideoCd) || (availContent & Solid::OpticalDisc::SuperVideoCd)) { // Video CD
647 return QStringLiteral("media-optical-video");
648 } else if ((availContent & Solid::OpticalDisc::Data) && (availContent & Solid::OpticalDisc::Audio)) { // Mixed CD
649 return QStringLiteral("media-optical-mixed-cd");
650 } else if (availContent & Solid::OpticalDisc::Audio) { // Audio CD
651 return QStringLiteral("media-optical-audio");
652 } else if (availContent & Solid::OpticalDisc::Data) { // Data CD
653 return QStringLiteral("media-optical-data");
654 } else if (isWritable) {
655 return QStringLiteral("media-optical-recordable");
656 } else {
657 if (media.startsWith(QStringLiteral("optical_dvd")) || media.startsWith(QStringLiteral("optical_hddvd"))) { // DVD
658 return QStringLiteral("media-optical-dvd");
659 } else if (media.startsWith(QStringLiteral("optical_bd"))) { // BluRay
660 return QStringLiteral("media-optical-blu-ray");
661 }
662 }
663
664 // fallback for every other optical disc
665 return QStringLiteral("media-optical");
666 }
667
668 if (media == QLatin1String("flash_ms")) { // Flash & Co.
669 return QStringLiteral("media-flash-memory-stick");
670 } else if (media == QLatin1String("flash_sd") //
671 || media == QLatin1String("flash_sdhc") //
672 || media == QLatin1String("flash_sdxc") //
673 || media == QLatin1String("flash_mmc")) {
674 return QStringLiteral("media-flash-sd-mmc");
675 } else if (media == QLatin1String("flash_sm")) {
676 return QStringLiteral("media-flash-smart-media");
677 } else if (media == QLatin1String("thumb")) {
678 return QStringLiteral("drive-removable-media-usb-pendrive");
679 } else if (media.startsWith(QStringLiteral("flash"))) {
680 return QStringLiteral("media-flash");
681 } else if (media == QLatin1String("floppy")) { // the good ol' floppy
682 return QStringLiteral("media-floppy");
683 }
684 }
685
686 if (drive.prop(QStringLiteral("ConnectionBus")).toString() == QLatin1String("sdio")) { // hack for SD cards connected thru sdio bus
687 return QStringLiteral("media-flash-sd-mmc");
688 }
689
690 return drive.icon();
691 }
692
693 return QStringLiteral("drive-harddisk"); // general fallback
694}
695
696QString Device::product() const
697{
698 if (!isDrive()) {
699 Device drive(drivePath());
700 return drive.prop(QStringLiteral("Model")).toString();
701 }
702
703 return prop(QStringLiteral("Model")).toString();
704}
705
706QString Device::vendor() const
707{
708 if (!isDrive()) {
709 Device drive(drivePath());
710 return drive.prop(QStringLiteral("Vendor")).toString();
711 }
712
713 return prop(QStringLiteral("Vendor")).toString();
714}
715
716QString Device::parentUdi() const
717{
719
720 if (propertyExists(QStringLiteral("Drive"))) { // block
721 parent = drivePath();
722 } else if (propertyExists(QStringLiteral("Table"))) { // partition
723 parent = prop(QStringLiteral("Table")).value<QDBusObjectPath>().path();
724 } else if (parent.isEmpty() || parent == QLatin1String("/")) {
725 parent = QStringLiteral(UD2_UDI_DISKS_PREFIX);
726 }
727 return parent;
728}
729
730QString Device::errorToString(const QString &error) const
731{
732 if (error == QLatin1String(UD2_ERROR_UNAUTHORIZED) || error == QLatin1String(UD2_ERROR_NOT_AUTHORIZED)) {
733 return tr("You are not authorized to perform this operation");
734 } else if (error == QLatin1String(UD2_ERROR_BUSY)) {
735 return tr("The device is currently busy");
736 } else if (error == QLatin1String(UD2_ERROR_FAILED)) {
737 return tr("The requested operation has failed");
738 } else if (error == QLatin1String(UD2_ERROR_CANCELED)) {
739 return tr("The requested operation has been canceled");
740 } else if (error == QLatin1String(UD2_ERROR_INVALID_OPTION)) {
741 return tr("An invalid or malformed option has been given");
742 } else if (error == QLatin1String(UD2_ERROR_MISSING_DRIVER)) {
743 return tr("The kernel driver for this filesystem type is not available");
744 } else if (error == QLatin1String(UD2_ERROR_ALREADY_MOUNTED)) {
745 return tr("The device is already mounted");
746 } else if (error == QLatin1String(UD2_ERROR_NOT_MOUNTED)) {
747 return tr("The device is not mounted");
748 } else if (error == QLatin1String(UD2_ERROR_MOUNTED_BY_OTHER_USER)) {
749 return tr("The device is mounted by another user");
750 } else if (error == QLatin1String(UD2_ERROR_ALREADY_UNMOUNTING)) {
751 return tr("The device is already unmounting");
752 } else if (error == QLatin1String(UD2_ERROR_TIMED_OUT)) {
753 return tr("The operation timed out");
754 } else if (error == QLatin1String(UD2_ERROR_WOULD_WAKEUP)) {
755 return tr("The operation would wake up a disk that is in a deep-sleep state");
756 } else if (error == QLatin1String(UD2_ERROR_ALREADY_CANCELLED)) {
757 return tr("The operation has already been canceled");
758 } else if (error == QLatin1String(UD2_ERROR_NOT_AUTHORIZED_CAN_OBTAIN)) {
759 return tr("Cannot request authentication for this action. The PolicyKit authentication system appears to be not available.");
760 } else if (error == QLatin1String(UD2_ERROR_NOT_AUTHORIZED_DISMISSED)) {
761 return tr("The authentication prompt was canceled");
762 } else {
763 return tr("An unspecified error has occurred");
764 }
765}
766
767Solid::ErrorType Device::errorToSolidError(const QString &error) const
768{
769 if (error == QLatin1String(UD2_ERROR_BUSY)) {
770 return Solid::DeviceBusy;
771 } else if (error == QLatin1String(UD2_ERROR_FAILED)) {
772 return Solid::OperationFailed;
773 } else if (error == QLatin1String(UD2_ERROR_CANCELED)) {
774 return Solid::UserCanceled;
775 } else if (error == QLatin1String(UD2_ERROR_INVALID_OPTION)) {
776 return Solid::InvalidOption;
777 } else if (error == QLatin1String(UD2_ERROR_MISSING_DRIVER)) {
778 return Solid::MissingDriver;
779 } else if (error == QLatin1String(UD2_ERROR_NOT_AUTHORIZED_DISMISSED)) {
780 return Solid::UserCanceled;
781 } else {
782 return Solid::UnauthorizedOperation;
783 }
784}
785
786bool Device::isBlock() const
787{
788 return hasInterface(QStringLiteral(UD2_DBUS_INTERFACE_BLOCK));
789}
790
791bool Device::isPartition() const
792{
793 return hasInterface(QStringLiteral(UD2_DBUS_INTERFACE_PARTITION));
794}
795
796bool Device::isPartitionTable() const
797{
798 return hasInterface(QStringLiteral(UD2_DBUS_INTERFACE_PARTITIONTABLE));
799}
800
801bool Device::isStorageVolume() const
802{
803 return isPartition() || isPartitionTable() || isStorageAccess() || isOpticalDisc();
804}
805
806bool Device::isStorageAccess() const
807{
808 return hasInterface(QStringLiteral(UD2_DBUS_INTERFACE_FILESYSTEM)) || isEncryptedContainer();
809}
810
811bool Device::isDrive() const
812{
813 return hasInterface(QStringLiteral(UD2_DBUS_INTERFACE_DRIVE));
814}
815
816bool Device::isOpticalDrive() const
817{
818 return isDrive() && !prop(QStringLiteral("MediaCompatibility")).toStringList().filter(QStringLiteral("optical_")).isEmpty();
819}
820
821bool Device::isOpticalDisc() const
822{
823 const QString drv = drivePath();
824 if (drv.isEmpty() || drv == QLatin1String("/")) {
825 return false;
826 }
827
828 Device drive(drv);
829 return drive.prop(QStringLiteral("Optical")).toBool();
830}
831
832bool Device::mightBeOpticalDisc() const
833{
834 const QString drv = drivePath();
835 if (drv.isEmpty() || drv == QLatin1String("/")) {
836 return false;
837 }
838
839 Device drive(drv);
840 return drive.isOpticalDrive();
841}
842
843bool Device::isMounted() const
844{
845 QVariant mountPoints = prop(QStringLiteral("MountPoints"));
846 return mountPoints.isValid() && !qdbus_cast<QByteArrayList>(mountPoints).isEmpty();
847}
848
849bool Device::isEncryptedContainer() const
850{
851 return hasInterface(QStringLiteral(UD2_DBUS_INTERFACE_ENCRYPTED));
852}
853
854bool Device::isEncryptedCleartext() const
855{
856 const QString holderDevice = prop(QStringLiteral("CryptoBackingDevice")).value<QDBusObjectPath>().path();
857 if (holderDevice.isEmpty() || holderDevice == QLatin1String("/")) {
858 return false;
859 } else {
860 return true;
861 }
862}
863
864bool Device::isRoot() const
865{
866 if (isStorageAccess()) {
867 const UDisks2::StorageAccess accessIface(const_cast<Device *>(this));
868 return accessIface.filePath() == QLatin1String("/");
869 }
870 return false;
871}
872
873bool Device::isSwap() const
874{
875 return hasInterface(QStringLiteral(UD2_DBUS_INTERFACE_SWAP));
876}
877
878bool Device::isLoop() const
879{
880 return hasInterface(QStringLiteral(UD2_DBUS_INTERFACE_LOOP));
881}
882
883QString Device::drivePath() const
884{
885 return prop(QStringLiteral("Drive")).value<QDBusObjectPath>().path();
886}
887
888#include "moc_udisksdevice.cpp"
Type
This enum type defines the type of device interface that a Device can have.
DriveType
This enum type defines the type of drive a storage device can be.
char * toString(const EngineQuery &query)
QString path(const QString &relativePath)
VehicleSection::Type type(QStringView coachNumber, QStringView coachClassification)
QString label(StandardShortcut id)
The single responsibility of this class is to create arguments valid for logind Inhibit call.
Definition fakebattery.h:16
QString translate(const char *context, const char *sourceText, const char *disambiguation, int n)
bool isEmpty() const const
QMimeType mimeTypeForFile(const QFileInfo &fileInfo, MatchMode mode) const const
QObject * parent() const const
QVariant property(const char *name) const const
QString tr(const char *sourceText, const char *disambiguation, int n)
QString arg(Args &&... args) const const
bool isEmpty() const const
QString & remove(QChar ch, Qt::CaseSensitivity cs)
QString section(QChar sep, qsizetype start, qsizetype end, SectionFlags flags) const const
bool startsWith(QChar c, Qt::CaseSensitivity cs) const const
QStringList filter(QStringView str, Qt::CaseSensitivity cs) const const
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
bool isValid() const const
bool toBool() const const
QString toString() const const
QStringList toStringList() const const
T value() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Oct 11 2024 12:08:14 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.