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"
19#include <solid/device.h>
20#include <solid/genericinterface.h>
23#include <QMimeDatabase>
25using namespace Solid::Backends::UDisks2;
28static QString formatByteSize(
double size)
40 if (size >= 1073741824.0) {
49 else if (size >= 1048576.0) {
54 else if (size >= 1024.0) {
69static QString concatBlockDeviceDescription(
const QString &name, qulonglong size,
bool isExternal)
73 const QString sizeStr = formatByteSize(size);
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);
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);
81 description =
QObject::tr(
"External Drive (%1)",
"%1 is the block device name e.g. sda, sda1").
arg(name);
83 description =
QObject::tr(
"Internal Drive (%1)",
"%1 is the block device name e.g. sda, sda1").
arg(name);
90Device::Device(
const QString &udi)
91 :
Solid::Ifaces::Device()
92 , m_backend(DeviceBackend::backendForUDI(udi))
95 connect(m_backend, &DeviceBackend::changed,
this, &Device::changed);
96 connect(m_backend, &DeviceBackend::propertyChanged,
this, &Device::propertyChanged);
98 qCDebug(UDISKS2) <<
"Created invalid Device for udi" << udi;
109 return m_backend->udi();
118 return m_backend->prop(key);
124bool Device::propertyExists(
const QString &key)
const
127 return m_backend->propertyExists(key);
133QVariantMap Device::allProperties()
const
136 return m_backend->allProperties();
139 return QVariantMap();
142bool Device::hasInterface(
const QString &name)
const
145 return m_backend->interfaces().contains(name);
154 return m_backend->interfaces();
160void Device::invalidateCache()
163 return m_backend->invalidateProperties();
169 if (!queryDeviceInterface(type)) {
173 DeviceInterface *iface =
nullptr;
175 case Solid::DeviceInterface::GenericInterface:
176 iface =
new GenericInterface(
this);
178 case Solid::DeviceInterface::Block:
179 iface =
new Block(
this);
181 case Solid::DeviceInterface::StorageAccess:
182 iface =
new StorageAccess(
this);
184 case Solid::DeviceInterface::StorageDrive:
185 iface =
new StorageDrive(
this);
187 case Solid::DeviceInterface::OpticalDrive:
188 iface =
new OpticalDrive(
this);
190 case Solid::DeviceInterface::StorageVolume:
191 iface =
new StorageVolume(
this);
193 case Solid::DeviceInterface::OpticalDisc:
194 iface =
new OpticalDisc(
this);
205 case Solid::DeviceInterface::GenericInterface:
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:
215 case Solid::DeviceInterface::OpticalDrive:
216 return isOpticalDrive();
217 case Solid::DeviceInterface::OpticalDisc:
218 return isOpticalDisc();
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";
235 if (isEncryptedContainer()) {
236 res <<
"emblem-encrypted-locked";
238 res <<
"emblem-unmounted";
246QString Device::description()
const
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();
266QString Device::loopDescription()
const
278 return tr(
"Loop Device");
281QString Device::storageDescription()
const
284 const UDisks2::StorageDrive storageDrive(
const_cast<Device *
>(
this));
286 const bool drive_is_hotpluggable = storageDrive.isHotpluggable();
288 if (drive_type == Solid::StorageDrive::CdromDrive) {
289 const UDisks2::OpticalDrive opticalDrive(
const_cast<Device *
>(
this));
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");
298 if (mediumTypes & Solid::OpticalDrive::Cdrw) {
299 first =
tr(
"CD-RW",
"First item of %1%2 Drive sentence");
302 if (mediumTypes & Solid::OpticalDrive::Dvd) {
303 second =
tr(
"/DVD-ROM",
"Second item of %1%2 Drive sentence");
305 if (mediumTypes & Solid::OpticalDrive::Dvdplusr) {
306 second =
tr(
"/DVD+R",
"Second item of %1%2 Drive sentence");
308 if (mediumTypes & Solid::OpticalDrive::Dvdplusrw) {
309 second =
tr(
"/DVD+RW",
"Second item of %1%2 Drive sentence");
311 if (mediumTypes & Solid::OpticalDrive::Dvdr) {
312 second =
tr(
"/DVD-R",
"Second item of %1%2 Drive sentence");
314 if (mediumTypes & Solid::OpticalDrive::Dvdrw) {
315 second =
tr(
"/DVD-RW",
"Second item of %1%2 Drive sentence");
317 if (mediumTypes & Solid::OpticalDrive::Dvdram) {
318 second =
tr(
"/DVD-RAM",
"Second item of %1%2 Drive sentence");
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");
324 second =
tr(
"/DVD±R",
"Second item of %1%2 Drive sentence");
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");
331 second =
tr(
"/DVD±RW",
"Second item of %1%2 Drive sentence");
334 if (mediumTypes & Solid::OpticalDrive::Bd) {
335 second =
tr(
"/BD-ROM",
"Second item of %1%2 Drive sentence");
337 if (mediumTypes & Solid::OpticalDrive::Bdr) {
338 second =
tr(
"/BD-R",
"Second item of %1%2 Drive sentence");
340 if (mediumTypes & Solid::OpticalDrive::Bdre) {
341 second =
tr(
"/BD-RE",
"Second item of %1%2 Drive sentence");
343 if (mediumTypes & Solid::OpticalDrive::HdDvd) {
344 second =
tr(
"/HD DVD-ROM",
"Second item of %1%2 Drive sentence");
346 if (mediumTypes & Solid::OpticalDrive::HdDvdr) {
347 second =
tr(
"/HD DVD-R",
"Second item of %1%2 Drive sentence");
349 if (mediumTypes & Solid::OpticalDrive::HdDvdrw) {
350 second =
tr(
"/HD DVD-RW",
"Second item of %1%2 Drive sentence");
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);
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);
362 if (drive_type == Solid::StorageDrive::Floppy) {
363 if (drive_is_hotpluggable) {
364 description =
tr(
"External Floppy Drive");
366 description =
tr(
"Floppy Drive");
372 const bool drive_is_removable = storageDrive.isRemovable();
374 if (drive_type == Solid::StorageDrive::HardDisk && !drive_is_removable) {
375 QString devName = storageDrive.device();
377 description = concatBlockDeviceDescription(devName, storageDrive.size(), drive_is_hotpluggable);
388 vendormodel_str = model;
392 vendormodel_str = vendor_str;
396 vendormodel_str = model;
398 vendormodel_str =
tr(
"%1 %2",
"%1 is the vendor, %2 is the model of the device").
arg(vendor_str, model);
403 if (vendormodel_str.
isEmpty()) {
404 description =
tr(
"Drive");
406 description = vendormodel_str;
412QString Device::volumeDescription()
const
415 const UDisks2::StorageVolume storageVolume(
const_cast<Device *
>(
this));
418 volume_label = prop(
"Name").
toString();
424 UDisks2::Device storageDevice(drivePath());
425 const UDisks2::StorageDrive storageDrive(&storageDevice);
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");
437 case Solid::OpticalDisc::CdRecordable:
438 if (disc.isBlank()) {
439 description =
tr(
"Blank CD-R");
441 description =
tr(
"CD-R");
445 case Solid::OpticalDisc::CdRewritable:
446 if (disc.isBlank()) {
447 description =
tr(
"Blank CD-RW");
449 description =
tr(
"CD-RW");
453 case Solid::OpticalDisc::DvdRom:
454 description =
tr(
"DVD-ROM");
457 case Solid::OpticalDisc::DvdRam:
458 if (disc.isBlank()) {
459 description =
tr(
"Blank DVD-RAM");
461 description =
tr(
"DVD-RAM");
465 case Solid::OpticalDisc::DvdRecordable:
466 if (disc.isBlank()) {
467 description =
tr(
"Blank DVD-R");
469 description =
tr(
"DVD-R");
473 case Solid::OpticalDisc::DvdPlusRecordableDuallayer:
474 if (disc.isBlank()) {
475 description =
tr(
"Blank DVD+R Dual-Layer");
477 description =
tr(
"DVD+R Dual-Layer");
481 case Solid::OpticalDisc::DvdRewritable:
482 if (disc.isBlank()) {
483 description =
tr(
"Blank DVD-RW");
485 description =
tr(
"DVD-RW");
489 case Solid::OpticalDisc::DvdPlusRecordable:
490 if (disc.isBlank()) {
491 description =
tr(
"Blank DVD+R");
493 description =
tr(
"DVD+R");
497 case Solid::OpticalDisc::DvdPlusRewritable:
498 if (disc.isBlank()) {
499 description =
tr(
"Blank DVD+RW");
501 description =
tr(
"DVD+RW");
505 case Solid::OpticalDisc::DvdPlusRewritableDuallayer:
506 if (disc.isBlank()) {
507 description =
tr(
"Blank DVD+RW Dual-Layer");
509 description =
tr(
"DVD+RW Dual-Layer");
513 case Solid::OpticalDisc::BluRayRom:
514 description =
tr(
"BD-ROM");
517 case Solid::OpticalDisc::BluRayRecordable:
518 if (disc.isBlank()) {
519 description =
tr(
"Blank BD-R");
521 description =
tr(
"BD-R");
525 case Solid::OpticalDisc::BluRayRewritable:
526 if (disc.isBlank()) {
527 description =
tr(
"Blank BD-RE");
529 description =
tr(
"BD-RE");
533 case Solid::OpticalDisc::HdDvdRom:
534 description =
tr(
"HD DVD-ROM");
537 case Solid::OpticalDisc::HdDvdRecordable:
538 if (disc.isBlank()) {
539 description =
tr(
"Blank HD DVD-R");
541 description =
tr(
"HD DVD-R");
545 case Solid::OpticalDisc::HdDvdRewritable:
546 if (disc.isBlank()) {
547 description =
tr(
"Blank HD DVD-RW");
549 description =
tr(
"HD DVD-RW");
555 if (disc.availableContent() == Solid::OpticalDisc::Audio) {
556 description =
tr(
"Audio CD");
562 const bool drive_is_removable = storageDrive.isRemovable();
564 QString size_str = formatByteSize(storageVolume.size());
565 QString volumeName = storageVolume.device();
567 if (isEncryptedContainer()) {
568 if (storageVolume.size() > 0) {
569 description =
tr(
"%1 Encrypted Drive",
"%1 is the size").
arg(size_str);
571 description =
tr(
"Encrypted Drive");
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");
578 if (drive_is_removable) {
579 if (storageVolume.size() > 0) {
580 description =
tr(
"%1 Removable Media",
"%1 is the size").
arg(size_str);
582 description =
tr(
"Removable Media");
585 if (storageVolume.size() > 0) {
586 description =
tr(
"%1 Media",
"%1 is the size").
arg(size_str);
588 description =
tr(
"Storage Media");
602 }
else if (isRoot()) {
603 return QStringLiteral(
"drive-harddisk-root");
604 }
else if (isLoop()) {
608 if (!
type.isDefault()) {
609 return type.iconName();
612 return QStringLiteral(
"drive-harddisk");
613 }
else if (isSwap()) {
614 return "drive-harddisk";
615 }
else if (isDrive()) {
616 const bool isRemovable = prop(
"Removable").
toBool();
619 if (isOpticalDrive()) {
620 return "drive-optical";
621 }
else if (isRemovable && !prop(
"Optical").toBool()) {
623 return "drive-removable-media-usb";
625 return "drive-removable-media";
628 }
else if (isBlock()) {
629 const QString drv = drivePath();
630 if (drv.
isEmpty() || drv ==
"/") {
631 return "drive-harddisk";
637 const QString media = drive.prop(
"Media").toString();
640 if (drive.prop(
"Optical").toBool()) {
641 bool isWritable = drive.prop(
"OpticalBlank").toBool();
643 const UDisks2::OpticalDisc disc(
const_cast<Device *
>(
this));
646 if (availContent & Solid::OpticalDisc::VideoDvd) {
647 return "media-optical-dvd-video";
648 }
else if ((availContent & Solid::OpticalDisc::VideoCd) || (availContent & Solid::OpticalDisc::SuperVideoCd)) {
649 return "media-optical-video";
650 }
else if ((availContent & Solid::OpticalDisc::Data) && (availContent & Solid::OpticalDisc::Audio)) {
651 return "media-optical-mixed-cd";
652 }
else if (availContent & Solid::OpticalDisc::Audio) {
653 return "media-optical-audio";
654 }
else if (availContent & Solid::OpticalDisc::Data) {
655 return "media-optical-data";
656 }
else if (isWritable) {
657 return "media-optical-recordable";
660 return "media-optical-dvd";
662 return "media-optical-blu-ray";
667 return "media-optical";
670 if (media ==
"flash_ms") {
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";
679 return "media-flash";
680 }
else if (media ==
"floppy") {
681 return "media-floppy";
685 if (drive.prop(
"ConnectionBus").toString() ==
"sdio") {
686 return "media-flash-sd-mmc";
692 return "drive-harddisk";
698 Device drive(drivePath());
699 return drive.prop(
"Model").toString();
708 Device drive(drivePath());
709 return drive.prop(
"Vendor").toString();
715QString Device::parentUdi()
const
719 if (propertyExists(
"Drive")) {
721 }
else if (propertyExists(
"Table")) {
724 parent = UD2_UDI_DISKS_PREFIX;
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");
762 return tr(
"An unspecified error has occurred");
766Solid::ErrorType Device::errorToSolidError(
const QString &error)
const
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;
781 return Solid::UnauthorizedOperation;
785bool Device::isBlock()
const
787 return hasInterface(QStringLiteral(UD2_DBUS_INTERFACE_BLOCK));
790bool Device::isPartition()
const
792 return hasInterface(QStringLiteral(UD2_DBUS_INTERFACE_PARTITION));
795bool Device::isPartitionTable()
const
797 return hasInterface(QStringLiteral(UD2_DBUS_INTERFACE_PARTITIONTABLE));
800bool Device::isStorageVolume()
const
802 return isPartition() || isPartitionTable() || isStorageAccess() || isOpticalDisc();
805bool Device::isStorageAccess()
const
807 return hasInterface(QStringLiteral(UD2_DBUS_INTERFACE_FILESYSTEM)) || isEncryptedContainer();
810bool Device::isDrive()
const
812 return hasInterface(QStringLiteral(UD2_DBUS_INTERFACE_DRIVE));
815bool Device::isOpticalDrive()
const
820bool Device::isOpticalDisc()
const
822 const QString drv = drivePath();
823 if (drv.
isEmpty() || drv ==
"/") {
828 return drive.prop(
"Optical").toBool();
831bool Device::mightBeOpticalDisc()
const
833 const QString drv = drivePath();
834 if (drv.
isEmpty() || drv ==
"/") {
839 return drive.isOpticalDrive();
842bool Device::isMounted()
const
844 QVariant mountPoints = prop(QStringLiteral(
"MountPoints"));
845 return mountPoints.
isValid() && !qdbus_cast<QByteArrayList>(mountPoints).isEmpty();
848bool Device::isEncryptedContainer()
const
850 return hasInterface(QStringLiteral(UD2_DBUS_INTERFACE_ENCRYPTED));
853bool Device::isEncryptedCleartext()
const
856 if (holderDevice.
isEmpty() || holderDevice ==
"/") {
863bool Device::isRoot()
const
865 if (isStorageAccess()) {
866 const UDisks2::StorageAccess accessIface(
const_cast<Device *
>(
this));
872bool Device::isSwap()
const
874 return hasInterface(QStringLiteral(UD2_DBUS_INTERFACE_SWAP));
877bool Device::isLoop()
const
879 return hasInterface(QStringLiteral(UD2_DBUS_INTERFACE_LOOP));
882QString Device::drivePath()
const
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.
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