From 00ef929df6f1d618ef9a292140f81b4990b5466b Mon Sep 17 00:00:00 2001 From: Raine Makelainen Date: Tue, 30 Oct 2018 15:57:02 +0200 Subject: [PATCH] [nemo-partitionmodel] Expose drive's connection bus from partition model. Contributes to JB#43642 Further, try to keep to devices connected via sdio bus in the model before devices that are connected through usb bus. --- src/partition.cpp | 5 ++++ src/partition.h | 8 ++++++ src/partition_p.h | 2 ++ src/partitionmanager.cpp | 20 ++++++++++---- src/partitionmanager_p.h | 2 +- src/partitionmodel.cpp | 3 ++ src/partitionmodel.h | 11 +++++++- src/udisks2block.cpp | 59 ++++++++++++++++++++++++++++++++++++++-- src/udisks2block_p.h | 7 +++++ src/udisks2monitor.cpp | 16 +++++++++-- 10 files changed, 120 insertions(+), 13 deletions(-) diff --git a/src/partition.cpp b/src/partition.cpp index a7a795b..b456449 100644 --- a/src/partition.cpp +++ b/src/partition.cpp @@ -101,6 +101,11 @@ Partition::StorageType Partition::storageType() const return d ? d->storageType : Invalid; } +Partition::ConnectionBus Partition::connectionBus() const +{ + return d ? d->connectionBus : UnknownBus; +} + QString Partition::devicePath() const { return d ? d->devicePath : QString(); diff --git a/src/partition.h b/src/partition.h index 5dc02e0..bf144de 100644 --- a/src/partition.h +++ b/src/partition.h @@ -56,6 +56,13 @@ class SYSTEMSETTINGS_EXPORT Partition Any = System | User | Mass | External }; + enum ConnectionBus { + SDIO, + USB, + IEEE1394, + UnknownBus + }; + enum Status { Unmounted, Mounting, @@ -108,6 +115,7 @@ class SYSTEMSETTINGS_EXPORT Partition QString cryptoBackingDevicePath() const; StorageType storageType() const; + ConnectionBus connectionBus() const; QString devicePath() const; QString deviceName() const; diff --git a/src/partition_p.h b/src/partition_p.h index 1044af1..11b9c0c 100644 --- a/src/partition_p.h +++ b/src/partition_p.h @@ -45,6 +45,7 @@ class PartitionPrivate : public QSharedData , bytesTotal(0) , bytesFree(0) , storageType(Partition::Invalid) + , connectionBus(Partition::UnknownBus) , status(Partition::Unmounted) , readOnly(true) , canMount(false) @@ -75,6 +76,7 @@ class PartitionPrivate : public QSharedData qint64 bytesTotal; qint64 bytesFree; Partition::StorageType storageType; + Partition::ConnectionBus connectionBus; Partition::Status status; bool readOnly; bool canMount; diff --git a/src/partitionmanager.cpp b/src/partitionmanager.cpp index 00d3fe2..e77493c 100644 --- a/src/partitionmanager.cpp +++ b/src/partitionmanager.cpp @@ -64,12 +64,14 @@ PartitionManagerPrivate::PartitionManagerPrivate() QExplicitlySharedDataPointer root(new PartitionPrivate(this)); root->storageType = Partition::System; + root->connectionBus = Partition::SDIO; root->mountPath = QStringLiteral("/"); m_partitions.append(root); QExplicitlySharedDataPointer home(new PartitionPrivate(this)); home->storageType = Partition::User; + home->connectionBus = Partition::SDIO; home->mountPath = QStringLiteral("/home"); m_partitions.append(home); @@ -146,14 +148,20 @@ QVector PartitionManagerPrivate::partitions(const Partition::StorageT return partitions; } -void PartitionManagerPrivate::add(Partitions &partitions) +void PartitionManagerPrivate::add(QExplicitlySharedDataPointer partition) { - m_partitions.append(partitions); - refresh(partitions, partitions); - - for (const auto partition : partitions) { - emit partitionAdded(Partition(partition)); + int insertIndex = 0; + for (const auto existingPartition : m_partitions) { + if (existingPartition->connectionBus <= partition->connectionBus) + ++insertIndex; + else + break; } + + m_partitions.insert(insertIndex, partition); + Partitions addedPartitions = { partition }; + refresh(addedPartitions, addedPartitions); + emit partitionAdded(Partition(partition)); } void PartitionManagerPrivate::remove(const Partitions &partitions) diff --git a/src/partitionmanager_p.h b/src/partitionmanager_p.h index b97b701..fa3bfb1 100644 --- a/src/partitionmanager_p.h +++ b/src/partitionmanager_p.h @@ -59,7 +59,7 @@ class PartitionManagerPrivate : public QObject, public QSharedData Partition root() const; QVector partitions(Partition::StorageTypes types) const; - void add(Partitions &partitions); + void add(QExplicitlySharedDataPointer partition); void remove(const Partitions &partitions); void refresh(); diff --git a/src/partitionmodel.cpp b/src/partitionmodel.cpp index 0cbccb7..4dacded 100644 --- a/src/partitionmodel.cpp +++ b/src/partitionmodel.cpp @@ -261,6 +261,7 @@ QHash PartitionModel::roleNames() const { IsSupportedFileSystemType, "isSupportedFileSystemType"}, { IsEncryptedRoles, "isEncrypted"}, { CryptoBackingDevicePath, "cryptoBackingDevicePath"}, + { ConnectionBusRole, "connectionBus"}, }; return roleNames; @@ -315,6 +316,8 @@ QVariant PartitionModel::data(const QModelIndex &index, int role) const return partition.isEncrypted(); case CryptoBackingDevicePath: return partition.cryptoBackingDevicePath(); + case ConnectionBusRole: + return partition.connectionBus(); default: return QVariant(); } diff --git a/src/partitionmodel.h b/src/partitionmodel.h index f23b086..719bfcc 100644 --- a/src/partitionmodel.h +++ b/src/partitionmodel.h @@ -65,7 +65,8 @@ class SYSTEMSETTINGS_EXPORT PartitionModel : public QAbstractListModel IsCryptoDeviceRoles, IsSupportedFileSystemType, IsEncryptedRoles, - CryptoBackingDevicePath + CryptoBackingDevicePath, + ConnectionBusRole, }; // For Status role @@ -95,6 +96,14 @@ class SYSTEMSETTINGS_EXPORT PartitionModel : public QAbstractListModel Any = Partition::Any }; + enum ConnectionBus { + SDIO = Partition::SDIO, + USB = Partition::USB, + IEEE1394 = Partition::IEEE1394, + UnknownBus = Partition::UnknownBus + }; + Q_ENUM(ConnectionBus) + enum Error { ErrorFailed = Partition::ErrorFailed, ErrorCancelled = Partition::ErrorCancelled, diff --git a/src/udisks2block.cpp b/src/udisks2block.cpp index a66b93d..ffe0bbd 100644 --- a/src/udisks2block.cpp +++ b/src/udisks2block.cpp @@ -20,6 +20,7 @@ UDisks2::Block::Block(const QString &path, const UDisks2::InterfacePropertyMap & , m_pendingFileSystem(nullptr) , m_pendingBlock(nullptr) , m_pendingEncrypted(nullptr) + , m_pendingDrive(nullptr) { if (!m_connection.connect( UDISKS2_SERVICE, @@ -50,6 +51,7 @@ UDisks2::Block::Block(const QString &path, const UDisks2::InterfacePropertyMap & QVariantMap blockProperties = NemoDBus::demarshallArgument(message.arguments().at(0)); qCInfo(lcMemoryCardLog) << "Block properties:" << blockProperties; m_data = blockProperties; + getDriveProperties(); } else { QDBusError error = watcher->error(); qCWarning(lcMemoryCardLog) << "Error reading block properties:" << error.name() << error.message(); @@ -63,6 +65,7 @@ UDisks2::Block::Block(const QString &path, const UDisks2::InterfacePropertyMap & QVariantMap map = interfacePropertyMap.value(UDISKS2_FILESYSTEM_INTERFACE); updateMountPoint(map); } + getDriveProperties(); // We have either org.freedesktop.UDisks2.Filesystem or org.freedesktop.UDisks2.Encrypted interface. complete(); @@ -103,6 +106,7 @@ UDisks2::Block &UDisks2::Block::operator=(const UDisks2::Block &other) m_interfacePropertyMap = other.m_interfacePropertyMap; m_data = other.m_data; + m_drive = other.m_drive; m_mountable = other.m_mountable; m_mountPath = other.m_mountPath; m_encrypted = other.m_encrypted; @@ -138,6 +142,25 @@ QString UDisks2::Block::drive() const return value(QStringLiteral("Drive")).toString(); } +QString UDisks2::Block::connectionBus() const +{ + QString bus = NemoDBus::demarshallDBusArgument(m_drive.value(QStringLiteral("ConnectionBus"))).toString(); + + // Do a bit of guesswork as we're missing connection between unlocked crypto block to crypto backing block device + // from where we could see the drive where this block belongs to. + if (bus != QLatin1String("/") && hasCryptoBackingDevice()) { + QString cryptoBackingPath = cryptoBackingDevicePath(); + if (cryptoBackingPath.contains(QLatin1String("mmcblk"))) { + return QStringLiteral("sdio"); + } else if (cryptoBackingPath.startsWith(QLatin1String("/dev/sd"))) { + return QStringLiteral("usb"); + } + return QStringLiteral("ieee1394"); + } + + return bus; +} + qint64 UDisks2::Block::deviceNumber() const { return value(QStringLiteral("DeviceNumber")).toLongLong(); @@ -153,6 +176,11 @@ qint64 UDisks2::Block::size() const return value(QStringLiteral("Size")).toLongLong(); } +bool UDisks2::Block::isCryptoBlock() const +{ + return isEncrypted() || hasCryptoBackingDevice(); +} + bool UDisks2::Block::hasCryptoBackingDevice() const { const QString cryptoBackingDev = cryptoBackingDeviceObjectPath(); @@ -274,7 +302,7 @@ bool UDisks2::Block::hasData() const void UDisks2::Block::dumpInfo() const { qCInfo(lcMemoryCardLog) << "Block device:" << device() << "Preferred device:" << preferredDevice(); - qCInfo(lcMemoryCardLog) << "- drive:" << drive() << "dNumber:" << deviceNumber(); + qCInfo(lcMemoryCardLog) << "- drive:" << drive() << "device number:" << deviceNumber() << "connection bus:" << connectionBus(); qCInfo(lcMemoryCardLog) << "- id:" << id() << "size:" << size(); qCInfo(lcMemoryCardLog) << "- isreadonly:" << isReadOnly() << "idtype:" << idType(); qCInfo(lcMemoryCardLog) << "- idversion:" << idVersion() << "idlabel:" << idLabel(); @@ -313,7 +341,7 @@ void UDisks2::Block::updateProperties(const QDBusMessage &message) bool UDisks2::Block::isCompleted() const { - return !m_pendingFileSystem && !m_pendingBlock && !m_pendingEncrypted; + return !m_pendingFileSystem && !m_pendingBlock && !m_pendingEncrypted && !m_pendingDrive; } void UDisks2::Block::updateMountPoint(const QVariant &mountPoints) @@ -403,3 +431,30 @@ void UDisks2::Block::getEncryptedInterface() complete(); }); } + +void UDisks2::Block::getDriveProperties() +{ + QDBusInterface drivePropertyInterface(UDISKS2_SERVICE, + drive(), + DBUS_OBJECT_PROPERTIES_INTERFACE, + m_connection); + QDBusPendingCall pendingCall = drivePropertyInterface.asyncCall(DBUS_GET_ALL, UDISKS2_DRIVE_INTERFACE); + m_pendingDrive = new QDBusPendingCallWatcher(pendingCall, this); + connect(m_pendingDrive, &QDBusPendingCallWatcher::finished, this, [this](QDBusPendingCallWatcher *watcher) { + if (watcher->isValid() && watcher->isFinished()) { + QDBusPendingReply<> reply = *watcher; + QDBusMessage message = reply.reply(); + QVariantMap driveProperties = NemoDBus::demarshallArgument(message.arguments().at(0)); + qCInfo(lcMemoryCardLog) << "Drive properties:" << driveProperties; + m_drive = driveProperties; + } else { + QDBusError error = watcher->error(); + qCWarning(lcMemoryCardLog) << "Error reading drive properties:" << error.name() << error.message(); + m_drive.clear(); + } + + m_pendingDrive->deleteLater(); + m_pendingDrive = nullptr; + complete(); + }); +} diff --git a/src/udisks2block_p.h b/src/udisks2block_p.h index 07f799f..43b0a04 100644 --- a/src/udisks2block_p.h +++ b/src/udisks2block_p.h @@ -45,6 +45,7 @@ namespace UDisks2 { class Block : public QObject { Q_OBJECT + Q_PROPERTY(QString connectionBus READ connectionBus NOTIFY updated) public: Block(const QString &path, const UDisks2::InterfacePropertyMap &interfacePropertyMap, QObject *parent = nullptr); @@ -57,12 +58,15 @@ class Block : public QObject QString device() const; QString preferredDevice() const; QString drive() const; + QString connectionBus() const; qint64 deviceNumber() const; QString id() const; qint64 size() const; + bool isCryptoBlock() const; + bool hasCryptoBackingDevice() const; QString cryptoBackingDevicePath() const; QString cryptoBackingDeviceObjectPath() const; @@ -114,10 +118,12 @@ private slots: void getFileSystemInterface(); void getEncryptedInterface(); + void getDriveProperties(); QString m_path; UDisks2::InterfacePropertyMap m_interfacePropertyMap; QVariantMap m_data; + QVariantMap m_drive; QDBusConnection m_connection; QString m_mountPath; bool m_mountable; @@ -128,6 +134,7 @@ private slots: QDBusPendingCallWatcher *m_pendingFileSystem; QDBusPendingCallWatcher *m_pendingBlock; QDBusPendingCallWatcher *m_pendingEncrypted; + QDBusPendingCallWatcher *m_pendingDrive; }; } diff --git a/src/udisks2monitor.cpp b/src/udisks2monitor.cpp index 4e7198c..0da8f30 100644 --- a/src/udisks2monitor.cpp +++ b/src/udisks2monitor.cpp @@ -335,9 +335,20 @@ void UDisks2::Monitor::setPartitionProperties(QExplicitlySharedDataPointerstatus = Partition::Mounted; } - partition->isCryptoDevice = blockDevice->isEncrypted() || blockDevice->hasCryptoBackingDevice(); + partition->isCryptoDevice = blockDevice->isCryptoBlock(); partition->isEncrypted = blockDevice->isEncrypted(); partition->cryptoBackingDevicePath = blockDevice->cryptoBackingDevicePath(); + + QString connectionBus = blockDevice->connectionBus(); + if (connectionBus == QLatin1String("sdio")) { + partition->connectionBus = Partition::SDIO; + } else if (connectionBus == QLatin1String("usb")) { + partition->connectionBus = Partition::USB; + } else if (connectionBus == QLatin1String("ieee1394")) { + partition->connectionBus = Partition::IEEE1394; + } else { + partition->connectionBus = Partition::UnknownBus; + } } void UDisks2::Monitor::updatePartitionProperties(const UDisks2::Block *blockDevice) @@ -603,8 +614,7 @@ void UDisks2::Monitor::createPartition(const UDisks2::Block *block) partition->bytesTotal = block->size(); setPartitionProperties(partition, block); partition->valid = true; - PartitionManagerPrivate::Partitions addedPartitions = { partition }; - m_manager->add(addedPartitions); + m_manager->add(partition); } UDisks2::Block *UDisks2::Monitor::createBlockDevice(const QString &dbusObjectPath, const UDisks2::InterfacePropertyMap &interfacePropertyMap)