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 QStringList res;
227
228 if (queryDeviceInterface(Solid::DeviceInterface::StorageAccess)) {
229 const UDisks2::StorageAccess accessIface(const_cast<Device *>(this));
230 if (accessIface.isAccessible()) {
231 if (isEncryptedContainer()) {
232 res << "emblem-encrypted-unlocked";
233 }
234 } else {
235 if (isEncryptedContainer()) {
236 res << "emblem-encrypted-locked";
237 } else {
238 res << "emblem-unmounted";
239 }
240 }
241 }
242
243 return res;
244}
245
246QString Device::description() const
247{
248 const QString hintName = property("HintName").toString(); // non-cached
249 if (!hintName.isEmpty()) {
250 return hintName;
251 }
252
253 if (isLoop()) {
254 return loopDescription();
255 } else if (isSwap()) {
256 return tr("Swap Space");
257 } else if (queryDeviceInterface(Solid::DeviceInterface::StorageDrive)) {
258 return storageDescription();
259 } else if (queryDeviceInterface(Solid::DeviceInterface::StorageVolume)) {
260 return volumeDescription();
261 } else {
262 return product();
263 }
264}
265
266QString Device::loopDescription() const
267{
268 const QString label = prop("IdLabel").toString();
269 if (!label.isEmpty()) {
270 return label;
271 }
272
273 const QString backingFile = prop("BackingFile").toString();
274 if (!backingFile.isEmpty()) {
275 return backingFile.section(QLatin1Char('/'), -1);
276 }
277
278 return tr("Loop Device");
279}
280
281QString Device::storageDescription() const
282{
283 QString description;
284 const UDisks2::StorageDrive storageDrive(const_cast<Device *>(this));
285 Solid::StorageDrive::DriveType drive_type = storageDrive.driveType();
286 const bool drive_is_hotpluggable = storageDrive.isHotpluggable();
287
288 if (drive_type == Solid::StorageDrive::CdromDrive) {
289 const UDisks2::OpticalDrive opticalDrive(const_cast<Device *>(this));
290 Solid::OpticalDrive::MediumTypes mediumTypes = opticalDrive.supportedMedia();
291 QString first;
292 QString second;
293
294 first = tr("CD-ROM", "First item of %1%2 Drive sentence");
295 if (mediumTypes & Solid::OpticalDrive::Cdr) {
296 first = tr("CD-R", "First item of %1%2 Drive sentence");
297 }
298 if (mediumTypes & Solid::OpticalDrive::Cdrw) {
299 first = tr("CD-RW", "First item of %1%2 Drive sentence");
300 }
301
302 if (mediumTypes & Solid::OpticalDrive::Dvd) {
303 second = tr("/DVD-ROM", "Second item of %1%2 Drive sentence");
304 }
305 if (mediumTypes & Solid::OpticalDrive::Dvdplusr) {
306 second = tr("/DVD+R", "Second item of %1%2 Drive sentence");
307 }
308 if (mediumTypes & Solid::OpticalDrive::Dvdplusrw) {
309 second = tr("/DVD+RW", "Second item of %1%2 Drive sentence");
310 }
311 if (mediumTypes & Solid::OpticalDrive::Dvdr) {
312 second = tr("/DVD-R", "Second item of %1%2 Drive sentence");
313 }
314 if (mediumTypes & Solid::OpticalDrive::Dvdrw) {
315 second = tr("/DVD-RW", "Second item of %1%2 Drive sentence");
316 }
317 if (mediumTypes & Solid::OpticalDrive::Dvdram) {
318 second = tr("/DVD-RAM", "Second item of %1%2 Drive sentence");
319 }
320 if ((mediumTypes & Solid::OpticalDrive::Dvdr) && (mediumTypes & Solid::OpticalDrive::Dvdplusr)) {
321 if (mediumTypes & Solid::OpticalDrive::Dvdplusdl) {
322 second = tr("/DVD±R DL", "Second item of %1%2 Drive sentence");
323 } else {
324 second = tr("/DVD±R", "Second item of %1%2 Drive sentence");
325 }
326 }
327 if ((mediumTypes & Solid::OpticalDrive::Dvdrw) && (mediumTypes & Solid::OpticalDrive::Dvdplusrw)) {
328 if ((mediumTypes & Solid::OpticalDrive::Dvdplusdl) || (mediumTypes & Solid::OpticalDrive::Dvdplusdlrw)) {
329 second = tr("/DVD±RW DL", "Second item of %1%2 Drive sentence");
330 } else {
331 second = tr("/DVD±RW", "Second item of %1%2 Drive sentence");
332 }
333 }
334 if (mediumTypes & Solid::OpticalDrive::Bd) {
335 second = tr("/BD-ROM", "Second item of %1%2 Drive sentence");
336 }
337 if (mediumTypes & Solid::OpticalDrive::Bdr) {
338 second = tr("/BD-R", "Second item of %1%2 Drive sentence");
339 }
340 if (mediumTypes & Solid::OpticalDrive::Bdre) {
341 second = tr("/BD-RE", "Second item of %1%2 Drive sentence");
342 }
343 if (mediumTypes & Solid::OpticalDrive::HdDvd) {
344 second = tr("/HD DVD-ROM", "Second item of %1%2 Drive sentence");
345 }
346 if (mediumTypes & Solid::OpticalDrive::HdDvdr) {
347 second = tr("/HD DVD-R", "Second item of %1%2 Drive sentence");
348 }
349 if (mediumTypes & Solid::OpticalDrive::HdDvdrw) {
350 second = tr("/HD DVD-RW", "Second item of %1%2 Drive sentence");
351 }
352
353 if (drive_is_hotpluggable) {
354 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);
355 } else {
356 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);
357 }
358
359 return description;
360 }
361
362 if (drive_type == Solid::StorageDrive::Floppy) {
363 if (drive_is_hotpluggable) {
364 description = tr("External Floppy Drive");
365 } else {
366 description = tr("Floppy Drive");
367 }
368
369 return description;
370 }
371
372 const bool drive_is_removable = storageDrive.isRemovable();
373
374 if (drive_type == Solid::StorageDrive::HardDisk && !drive_is_removable) {
375 QString devName = storageDrive.device();
376 devName.remove(QLatin1String("/dev/"));
377 description = concatBlockDeviceDescription(devName, storageDrive.size(), drive_is_hotpluggable);
378
379 return description;
380 }
381
382 QString vendormodel_str;
383 QString model = product();
384 QString vendor_str = vendor();
385
386 if (vendor_str.isEmpty()) {
387 if (!model.isEmpty()) {
388 vendormodel_str = model;
389 }
390 } else {
391 if (model.isEmpty()) {
392 vendormodel_str = vendor_str;
393 } else {
394 if (model.startsWith(vendor_str)) {
395 // e.g. vendor is "Nokia" and model is "Nokia N950" we do not want "Nokia Nokia N950" as description
396 vendormodel_str = model;
397 } else {
398 vendormodel_str = tr("%1 %2", "%1 is the vendor, %2 is the model of the device").arg(vendor_str, model);
399 }
400 }
401 }
402
403 if (vendormodel_str.isEmpty()) {
404 description = tr("Drive");
405 } else {
406 description = vendormodel_str;
407 }
408
409 return description;
410}
411
412QString Device::volumeDescription() const
413{
414 QString description;
415 const UDisks2::StorageVolume storageVolume(const_cast<Device *>(this));
416 QString volume_label = prop("IdLabel").toString();
417 if (volume_label.isEmpty()) {
418 volume_label = prop("Name").toString();
419 }
420 if (!volume_label.isEmpty()) {
421 return volume_label;
422 }
423
424 UDisks2::Device storageDevice(drivePath());
425 const UDisks2::StorageDrive storageDrive(&storageDevice);
426 Solid::StorageDrive::DriveType drive_type = storageDrive.driveType();
427
428 // Handle media in optical drives
429 if (drive_type == Solid::StorageDrive::CdromDrive) {
430 const UDisks2::OpticalDisc disc(const_cast<Device *>(this));
431 switch (disc.discType()) {
432 case Solid::OpticalDisc::UnknownDiscType:
433 case Solid::OpticalDisc::CdRom:
434 description = tr("CD-ROM");
435 break;
436
437 case Solid::OpticalDisc::CdRecordable:
438 if (disc.isBlank()) {
439 description = tr("Blank CD-R");
440 } else {
441 description = tr("CD-R");
442 }
443 break;
444
445 case Solid::OpticalDisc::CdRewritable:
446 if (disc.isBlank()) {
447 description = tr("Blank CD-RW");
448 } else {
449 description = tr("CD-RW");
450 }
451 break;
452
453 case Solid::OpticalDisc::DvdRom:
454 description = tr("DVD-ROM");
455 break;
456
457 case Solid::OpticalDisc::DvdRam:
458 if (disc.isBlank()) {
459 description = tr("Blank DVD-RAM");
460 } else {
461 description = tr("DVD-RAM");
462 }
463 break;
464
465 case Solid::OpticalDisc::DvdRecordable:
466 if (disc.isBlank()) {
467 description = tr("Blank DVD-R");
468 } else {
469 description = tr("DVD-R");
470 }
471 break;
472
473 case Solid::OpticalDisc::DvdPlusRecordableDuallayer:
474 if (disc.isBlank()) {
475 description = tr("Blank DVD+R Dual-Layer");
476 } else {
477 description = tr("DVD+R Dual-Layer");
478 }
479 break;
480
481 case Solid::OpticalDisc::DvdRewritable:
482 if (disc.isBlank()) {
483 description = tr("Blank DVD-RW");
484 } else {
485 description = tr("DVD-RW");
486 }
487 break;
488
489 case Solid::OpticalDisc::DvdPlusRecordable:
490 if (disc.isBlank()) {
491 description = tr("Blank DVD+R");
492 } else {
493 description = tr("DVD+R");
494 }
495 break;
496
497 case Solid::OpticalDisc::DvdPlusRewritable:
498 if (disc.isBlank()) {
499 description = tr("Blank DVD+RW");
500 } else {
501 description = tr("DVD+RW");
502 }
503 break;
504
505 case Solid::OpticalDisc::DvdPlusRewritableDuallayer:
506 if (disc.isBlank()) {
507 description = tr("Blank DVD+RW Dual-Layer");
508 } else {
509 description = tr("DVD+RW Dual-Layer");
510 }
511 break;
512
513 case Solid::OpticalDisc::BluRayRom:
514 description = tr("BD-ROM");
515 break;
516
517 case Solid::OpticalDisc::BluRayRecordable:
518 if (disc.isBlank()) {
519 description = tr("Blank BD-R");
520 } else {
521 description = tr("BD-R");
522 }
523 break;
524
525 case Solid::OpticalDisc::BluRayRewritable:
526 if (disc.isBlank()) {
527 description = tr("Blank BD-RE");
528 } else {
529 description = tr("BD-RE");
530 }
531 break;
532
533 case Solid::OpticalDisc::HdDvdRom:
534 description = tr("HD DVD-ROM");
535 break;
536
537 case Solid::OpticalDisc::HdDvdRecordable:
538 if (disc.isBlank()) {
539 description = tr("Blank HD DVD-R");
540 } else {
541 description = tr("HD DVD-R");
542 }
543 break;
544
545 case Solid::OpticalDisc::HdDvdRewritable:
546 if (disc.isBlank()) {
547 description = tr("Blank HD DVD-RW");
548 } else {
549 description = tr("HD DVD-RW");
550 }
551 break;
552 }
553
554 // Special case for pure audio disc
555 if (disc.availableContent() == Solid::OpticalDisc::Audio) {
556 description = tr("Audio CD");
557 }
558
559 return description;
560 }
561
562 const bool drive_is_removable = storageDrive.isRemovable();
563
564 QString size_str = formatByteSize(storageVolume.size());
565 QString volumeName = storageVolume.device();
566 volumeName.remove(QLatin1String("/dev/"));
567 if (isEncryptedContainer()) {
568 if (storageVolume.size() > 0) {
569 description = tr("%1 Encrypted Drive", "%1 is the size").arg(size_str);
570 } else {
571 description = tr("Encrypted Drive");
572 }
573 } else if (drive_type == Solid::StorageDrive::HardDisk && !drive_is_removable) {
574 description = concatBlockDeviceDescription(volumeName, storageVolume.size(), storageDrive.isHotpluggable());
575 } else if (drive_type == Solid::StorageDrive::Floppy) {
576 description = tr("Floppy Disk");
577 } else {
578 if (drive_is_removable) {
579 if (storageVolume.size() > 0) {
580 description = tr("%1 Removable Media", "%1 is the size").arg(size_str);
581 } else {
582 description = tr("Removable Media");
583 }
584 } else {
585 if (storageVolume.size() > 0) {
586 description = tr("%1 Media", "%1 is the size").arg(size_str);
587 } else {
588 description = tr("Storage Media");
589 }
590 }
591 }
592
593 return description;
594}
595
596QString Device::icon() const
597{
598 QString iconName = property("HintIconName").toString(); // non-cached
599
600 if (!iconName.isEmpty()) {
601 return iconName;
602 } else if (isRoot()) {
603 return QStringLiteral("drive-harddisk-root");
604 } else if (isLoop()) {
605 const QString backingFile = prop("BackingFile").toString();
606 if (!backingFile.isEmpty()) {
608 if (!type.isDefault()) {
609 return type.iconName();
610 }
611 }
612 return QStringLiteral("drive-harddisk");
613 } else if (isSwap()) {
614 return "drive-harddisk";
615 } else if (isDrive()) {
616 const bool isRemovable = prop("Removable").toBool();
617 const QString conn = prop("ConnectionBus").toString();
618
619 if (isOpticalDrive()) {
620 return "drive-optical";
621 } else if (isRemovable && !prop("Optical").toBool()) {
622 if (conn == "usb") {
623 return "drive-removable-media-usb";
624 } else {
625 return "drive-removable-media";
626 }
627 }
628 } else if (isBlock()) {
629 const QString drv = drivePath();
630 if (drv.isEmpty() || drv == "/") {
631 return "drive-harddisk"; // stuff like loop devices or swap which don't have the Drive prop set
632 }
633
634 Device drive(drv);
635
636 // handle media
637 const QString media = drive.prop("Media").toString();
638
639 if (!media.isEmpty()) {
640 if (drive.prop("Optical").toBool()) { // optical stuff
641 bool isWritable = drive.prop("OpticalBlank").toBool();
642
643 const UDisks2::OpticalDisc disc(const_cast<Device *>(this));
644 Solid::OpticalDisc::ContentTypes availContent = disc.availableContent();
645
646 if (availContent & Solid::OpticalDisc::VideoDvd) { // Video DVD
647 return "media-optical-dvd-video";
648 } else if ((availContent & Solid::OpticalDisc::VideoCd) || (availContent & Solid::OpticalDisc::SuperVideoCd)) { // Video CD
649 return "media-optical-video";
650 } else if ((availContent & Solid::OpticalDisc::Data) && (availContent & Solid::OpticalDisc::Audio)) { // Mixed CD
651 return "media-optical-mixed-cd";
652 } else if (availContent & Solid::OpticalDisc::Audio) { // Audio CD
653 return "media-optical-audio";
654 } else if (availContent & Solid::OpticalDisc::Data) { // Data CD
655 return "media-optical-data";
656 } else if (isWritable) {
657 return "media-optical-recordable";
658 } else {
659 if (media.startsWith("optical_dvd") || media.startsWith("optical_hddvd")) { // DVD
660 return "media-optical-dvd";
661 } else if (media.startsWith("optical_bd")) { // BluRay
662 return "media-optical-blu-ray";
663 }
664 }
665
666 // fallback for every other optical disc
667 return "media-optical";
668 }
669
670 if (media == "flash_ms") { // Flash & Co.
671 return "media-flash-memory-stick";
672 } else if (media == "flash_sd" || media == "flash_sdhc" || media == "flash_sdxc" || media == "flash_mmc") {
673 return "media-flash-sd-mmc";
674 } else if (media == "flash_sm") {
675 return "media-flash-smart-media";
676 } else if (media == "thumb") {
677 return "drive-removable-media-usb-pendrive";
678 } else if (media.startsWith("flash")) {
679 return "media-flash";
680 } else if (media == "floppy") { // the good ol' floppy
681 return "media-floppy";
682 }
683 }
684
685 if (drive.prop("ConnectionBus").toString() == "sdio") { // hack for SD cards connected thru sdio bus
686 return "media-flash-sd-mmc";
687 }
688
689 return drive.icon();
690 }
691
692 return "drive-harddisk"; // general fallback
693}
694
695QString Device::product() const
696{
697 if (!isDrive()) {
698 Device drive(drivePath());
699 return drive.prop("Model").toString();
700 }
701
702 return prop("Model").toString();
703}
704
705QString Device::vendor() const
706{
707 if (!isDrive()) {
708 Device drive(drivePath());
709 return drive.prop("Vendor").toString();
710 }
711
712 return prop("Vendor").toString();
713}
714
715QString Device::parentUdi() const
716{
718
719 if (propertyExists("Drive")) { // block
720 parent = drivePath();
721 } else if (propertyExists("Table")) { // partition
722 parent = prop("Table").value<QDBusObjectPath>().path();
723 } else if (parent.isEmpty() || parent == "/") {
724 parent = UD2_UDI_DISKS_PREFIX;
725 }
726 return parent;
727}
728
729QString Device::errorToString(const QString &error) const
730{
731 if (error == UD2_ERROR_UNAUTHORIZED || error == UD2_ERROR_NOT_AUTHORIZED) {
732 return tr("You are not authorized to perform this operation");
733 } else if (error == UD2_ERROR_BUSY) {
734 return tr("The device is currently busy");
735 } else if (error == UD2_ERROR_FAILED) {
736 return tr("The requested operation has failed");
737 } else if (error == UD2_ERROR_CANCELED) {
738 return tr("The requested operation has been canceled");
739 } else if (error == UD2_ERROR_INVALID_OPTION) {
740 return tr("An invalid or malformed option has been given");
741 } else if (error == UD2_ERROR_MISSING_DRIVER) {
742 return tr("The kernel driver for this filesystem type is not available");
743 } else if (error == UD2_ERROR_ALREADY_MOUNTED) {
744 return tr("The device is already mounted");
745 } else if (error == UD2_ERROR_NOT_MOUNTED) {
746 return tr("The device is not mounted");
747 } else if (error == UD2_ERROR_MOUNTED_BY_OTHER_USER) {
748 return tr("The device is mounted by another user");
749 } else if (error == UD2_ERROR_ALREADY_UNMOUNTING) {
750 return tr("The device is already unmounting");
751 } else if (error == UD2_ERROR_TIMED_OUT) {
752 return tr("The operation timed out");
753 } else if (error == UD2_ERROR_WOULD_WAKEUP) {
754 return tr("The operation would wake up a disk that is in a deep-sleep state");
755 } else if (error == UD2_ERROR_ALREADY_CANCELLED) {
756 return tr("The operation has already been canceled");
757 } else if (error == UD2_ERROR_NOT_AUTHORIZED_CAN_OBTAIN) {
758 return tr("Cannot request authentication for this action. The PolicyKit authentication system appears to be not available.");
759 } else if (error == UD2_ERROR_NOT_AUTHORIZED_DISMISSED) {
760 return tr("The authentication prompt was canceled");
761 } else {
762 return tr("An unspecified error has occurred");
763 }
764}
765
766Solid::ErrorType Device::errorToSolidError(const QString &error) const
767{
768 if (error == UD2_ERROR_BUSY) {
769 return Solid::DeviceBusy;
770 } else if (error == UD2_ERROR_FAILED) {
771 return Solid::OperationFailed;
772 } else if (error == UD2_ERROR_CANCELED) {
773 return Solid::UserCanceled;
774 } else if (error == UD2_ERROR_INVALID_OPTION) {
775 return Solid::InvalidOption;
776 } else if (error == UD2_ERROR_MISSING_DRIVER) {
777 return Solid::MissingDriver;
778 } else if (error == UD2_ERROR_NOT_AUTHORIZED_DISMISSED) {
779 return Solid::UserCanceled;
780 } else {
781 return Solid::UnauthorizedOperation;
782 }
783}
784
785bool Device::isBlock() const
786{
787 return hasInterface(QStringLiteral(UD2_DBUS_INTERFACE_BLOCK));
788}
789
790bool Device::isPartition() const
791{
792 return hasInterface(QStringLiteral(UD2_DBUS_INTERFACE_PARTITION));
793}
794
795bool Device::isPartitionTable() const
796{
797 return hasInterface(QStringLiteral(UD2_DBUS_INTERFACE_PARTITIONTABLE));
798}
799
800bool Device::isStorageVolume() const
801{
802 return isPartition() || isPartitionTable() || isStorageAccess() || isOpticalDisc();
803}
804
805bool Device::isStorageAccess() const
806{
807 return hasInterface(QStringLiteral(UD2_DBUS_INTERFACE_FILESYSTEM)) || isEncryptedContainer();
808}
809
810bool Device::isDrive() const
811{
812 return hasInterface(QStringLiteral(UD2_DBUS_INTERFACE_DRIVE));
813}
814
815bool Device::isOpticalDrive() const
816{
817 return isDrive() && !prop("MediaCompatibility").toStringList().filter("optical_").isEmpty();
818}
819
820bool Device::isOpticalDisc() const
821{
822 const QString drv = drivePath();
823 if (drv.isEmpty() || drv == "/") {
824 return false;
825 }
826
827 Device drive(drv);
828 return drive.prop("Optical").toBool();
829}
830
831bool Device::mightBeOpticalDisc() const
832{
833 const QString drv = drivePath();
834 if (drv.isEmpty() || drv == "/") {
835 return false;
836 }
837
838 Device drive(drv);
839 return drive.isOpticalDrive();
840}
841
842bool Device::isMounted() const
843{
844 QVariant mountPoints = prop(QStringLiteral("MountPoints"));
845 return mountPoints.isValid() && !qdbus_cast<QByteArrayList>(mountPoints).isEmpty();
846}
847
848bool Device::isEncryptedContainer() const
849{
850 return hasInterface(QStringLiteral(UD2_DBUS_INTERFACE_ENCRYPTED));
851}
852
853bool Device::isEncryptedCleartext() const
854{
855 const QString holderDevice = prop("CryptoBackingDevice").value<QDBusObjectPath>().path();
856 if (holderDevice.isEmpty() || holderDevice == "/") {
857 return false;
858 } else {
859 return true;
860 }
861}
862
863bool Device::isRoot() const
864{
865 if (isStorageAccess()) {
866 const UDisks2::StorageAccess accessIface(const_cast<Device *>(this));
867 return accessIface.filePath() == QLatin1String("/");
868 }
869 return false;
870}
871
872bool Device::isSwap() const
873{
874 return hasInterface(QStringLiteral(UD2_DBUS_INTERFACE_SWAP));
875}
876
877bool Device::isLoop() const
878{
879 return hasInterface(QStringLiteral(UD2_DBUS_INTERFACE_LOOP));
880}
881
882QString Device::drivePath() const
883{
884 return prop("Drive").value<QDBusObjectPath>().path();
885}
886
887#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.
Type type(const QSqlDatabase &db)
char * toString(const EngineQuery &query)
QString path(const QString &relativePath)
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 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.