Skip to content

Commit

Permalink
[systemsettings] Ability to rename SD card and partitions. JB#54905
Browse files Browse the repository at this point in the history
  • Loading branch information
Alexandr Makarik committed Aug 25, 2021
1 parent cdd4a33 commit 552eb9f
Show file tree
Hide file tree
Showing 10 changed files with 119 additions and 8 deletions.
3 changes: 2 additions & 1 deletion src/partition.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ class SYSTEMSETTINGS_EXPORT Partition
Unlocking,
Unlocked,
Locking,
Locked
Locked,
Renamed
};

Q_DECLARE_FLAGS(StorageTypes, StorageType)
Expand Down
11 changes: 11 additions & 0 deletions src/partitionmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ PartitionManagerPrivate::PartitionManagerPrivate()
connect(m_udisksMonitor.data(), &UDisks2::Monitor::mountError, this, &PartitionManagerPrivate::mountError);
connect(m_udisksMonitor.data(), &UDisks2::Monitor::unmountError, this, &PartitionManagerPrivate::unmountError);
connect(m_udisksMonitor.data(), &UDisks2::Monitor::formatError, this, &PartitionManagerPrivate::formatError);
connect(m_udisksMonitor.data(), &UDisks2::Monitor::setLabelError, this, &PartitionManagerPrivate::setLabelError);
connect(UDisks2::BlockDevices::instance(), &UDisks2::BlockDevices::externalStoragesPopulated,
this, &PartitionManagerPrivate::externalStoragesPopulatedChanged);

Expand Down Expand Up @@ -344,6 +345,16 @@ void PartitionManagerPrivate::unmount(const Partition &partition)
}
}

void PartitionManagerPrivate::setLabel(const Partition &partition, const QString &label)
{
qCInfo(lcMemoryCardLog) << "Can setLabel:" << externalMedia.match(partition.deviceName()).hasMatch() << partition.devicePath();
if (externalMedia.match(partition.deviceName()).hasMatch()) {
m_udisksMonitor->setLabel(partition.devicePath(), label);
} else {
qCWarning(lcMemoryCardLog) << "setLabel allowed only for external memory cards," << partition.devicePath() << "is not allowed";
}
}

void PartitionManagerPrivate::format(const QString &devicePath, const QString &filesystemType, const QVariantMap &arguments)
{
QString deviceName = devicePath.section(QChar('/'), 2);
Expand Down
2 changes: 2 additions & 0 deletions src/partitionmanager_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ class PartitionManagerPrivate : public QObject, public QSharedData
void mount(const Partition &partition);
void unmount(const Partition &partition);
void format(const QString &devicePath, const QString &filesystemType, const QVariantMap &arguments);
void setLabel(const Partition &partition, const QString &label);

QString objectPath(const QString &devicePath) const;

Expand All @@ -90,6 +91,7 @@ class PartitionManagerPrivate : public QObject, public QSharedData
void mountError(Partition::Error error);
void unmountError(Partition::Error error);
void formatError(Partition::Error error);
void setLabelError(Partition::Error error);

private:
// TODO: This is leaking (Disks2::Monitor is never free'ed).
Expand Down
13 changes: 13 additions & 0 deletions src/partitionmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ PartitionModel::PartitionModel(QObject *parent)
connect(m_manager.data(), &PartitionManagerPrivate::formatError, this, [this](Partition::Error error) {
emit formatError(static_cast<PartitionModel::Error>(error));
});
connect(m_manager.data(), &PartitionManagerPrivate::setLabelError, this, [this](Partition::Error error) {
emit setLabelError(static_cast<PartitionModel::Error>(error));
});
}

PartitionModel::~PartitionModel()
Expand Down Expand Up @@ -162,6 +165,16 @@ void PartitionModel::unmount(const QString &devicePath)
}
}

void PartitionModel::setLabel(const QString &devicePath, const QString &label)
{
qCInfo(lcMemoryCardLog) << Q_FUNC_INFO << devicePath << m_partitions.count();
if (const Partition *partition = getPartition(devicePath)) {
m_manager->setLabel(*partition, label);
} else {
qCWarning(lcMemoryCardLog) << "Unable to rename unknown device:" << devicePath;
}
}

void PartitionModel::format(const QString &devicePath, const QVariantMap &arguments)
{
QString filesystemType = arguments.value(QLatin1String("filesystemType"), QString()).toString();
Expand Down
2 changes: 2 additions & 0 deletions src/partitionmodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ class SYSTEMSETTINGS_EXPORT PartitionModel : public QAbstractListModel
Q_INVOKABLE void mount(const QString &devicePath);
Q_INVOKABLE void unmount(const QString &devicePath);
Q_INVOKABLE void format(const QString &devicePath, const QVariantMap &arguments);
Q_INVOKABLE void setLabel(const QString &devicePath, const QString &label);

Q_INVOKABLE QString objectPath(const QString &devicePath) const;

Expand All @@ -162,6 +163,7 @@ class SYSTEMSETTINGS_EXPORT PartitionModel : public QAbstractListModel
void mountError(Error error);
void unmountError(Error error);
void formatError(Error error);
void setLabelError(Error error);

private:
void update();
Expand Down
16 changes: 9 additions & 7 deletions src/udisks2defines.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,25 +64,27 @@ Q_DECLARE_METATYPE(UDisks2::InterfacePropertyMap)
#define UDISKS2_JOB_INTERFACE QLatin1String("org.freedesktop.UDisks2.Job")

// Jobs
#define UDISKS2_JOB_OP_ENC_LOCK QLatin1String("encrypted-lock")
#define UDISKS2_JOB_OP_ENC_UNLOCK QLatin1String("encrypted-unlock")
#define UDISKS2_JOB_OP_FS_UNMOUNT QLatin1String("filesystem-unmount")
#define UDISKS2_JOB_OP_FS_MOUNT QLatin1String("filesystem-mount")
#define UDISKS2_JOB_OP_CLEANUP QLatin1String("cleanup")
#define UDISKS2_JOB_OF_FS_FORMAT QLatin1String("format-mkfs")
#define UDISKS2_JOB_OP_ENC_LOCK QLatin1String("encrypted-lock")
#define UDISKS2_JOB_OP_ENC_UNLOCK QLatin1String("encrypted-unlock")
#define UDISKS2_JOB_OP_FS_UNMOUNT QLatin1String("filesystem-unmount")
#define UDISKS2_JOB_OP_FS_MOUNT QLatin1String("filesystem-mount")
#define UDISKS2_JOB_OP_FS_SETLABEL QLatin1String("filesystem-setlabel")
#define UDISKS2_JOB_OP_CLEANUP QLatin1String("cleanup")
#define UDISKS2_JOB_OF_FS_FORMAT QLatin1String("format-mkfs")

// Job keys
#define UDISKS2_JOB_KEY_OPERATION QLatin1String("Operation")
#define UDISKS2_JOB_KEY_OBJECTS QLatin1String("Objects")

// Lock, Unlock, Mount, Unmount, Format
// Lock, Unlock, Mount, Unmount, Format, SetLabel
#define UDISKS2_BLOCK_DEVICE_PATH QString(QLatin1String("/org/freedesktop/UDisks2/block_devices/%1"))
#define UDISKS2_BLOCK_FORMAT QLatin1String("Format")
#define UDISKS2_ENCRYPTED_LOCK QLatin1String("Lock")
#define UDISKS2_ENCRYPTED_UNLOCK QLatin1String("Unlock")
#define UDISKS2_FILESYSTEM_MOUNT QLatin1String("Mount")
#define UDISKS2_FILESYSTEM_UNMOUNT QLatin1String("Unmount")
#define UDISKS2_BLOCK_RESCAN QLatin1String("Rescan")
#define UDISKS2_BLOCK_SETLABEL QLatin1String("SetLabel")

// Errors
#define UDISKS2_ERROR_DEVICE_BUSY QLatin1String("org.freedesktop.UDisks2.Error.DeviceBusy")
Expand Down
2 changes: 2 additions & 0 deletions src/udisks2job.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,8 @@ UDisks2::Job::Operation UDisks2::Job::operation() const
return Lock;
} else if (operation == UDISKS2_JOB_OP_ENC_UNLOCK) {
return Unlock;
} else if (operation == UDISKS2_JOB_OP_FS_SETLABEL) {
return SetLabel;
} else {
return Unknown;
}
Expand Down
1 change: 1 addition & 0 deletions src/udisks2job_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ class Job : public QObject
Mount,
Unmount,
Format,
SetLabel,
Unknown
};
Q_ENUM(Operation)
Expand Down
74 changes: 74 additions & 0 deletions src/udisks2monitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,42 @@ void UDisks2::Monitor::unmount(const QString &devicePath)
startMountOperation(devicePath, UDISKS2_FILESYSTEM_UNMOUNT, m_blockDevices->objectPath(devicePath), arguments);
}

void UDisks2::Monitor::setLabel(const QString &devicePath, const QString &label)
{
if (m_blockDevices->find(devicePath)) {
QVariantList args;
QVariantMap opts;
args << opts;

const QString dbusMethod = UDISKS2_FILESYSTEM_UNMOUNT;

QDBusMessage method = QDBusMessage::createMethodCall(
UDISKS2_SERVICE,
m_blockDevices->objectPath(devicePath),
UDISKS2_FILESYSTEM_INTERFACE,
dbusMethod);
method.setArguments(args);
QDBusPendingCall pendingCall = QDBusConnection::systemBus().asyncCall(method);
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingCall, this);
connect(watcher, &QDBusPendingCallWatcher::finished,
this, [this, devicePath, label](QDBusPendingCallWatcher *watcher) {
if (watcher->isValid() && watcher->isFinished()) {
QVariantList arguments;
arguments << label;
QVariantMap options;
arguments << options;

doSetLabel(devicePath, m_blockDevices->objectPath(devicePath), arguments);
}
watcher->deleteLater();
});

}
else {
qCWarning(lcMemoryCardLog) << "Block device" << devicePath << "not found";
}
}

void UDisks2::Monitor::format(const QString &devicePath, const QString &filesystemType, const QVariantMap &arguments)
{
if (devicePath.isEmpty()) {
Expand Down Expand Up @@ -651,6 +687,44 @@ void UDisks2::Monitor::doFormat(const QString &devicePath, const QString &dbusOb
});
}

void UDisks2::Monitor::doSetLabel(const QString &devicePath, const QString &dbusObjectPath, const QVariantList &arguments)
{
const QString dbusMethod = UDISKS2_BLOCK_SETLABEL;
if (devicePath.isEmpty()) {
qCCritical(lcMemoryCardLog) << "Cannot" << dbusMethod.toLower() << "without device name";
return;
}

QDBusInterface udisks2Interface(UDISKS2_SERVICE,
dbusObjectPath,
UDISKS2_FILESYSTEM_INTERFACE,
QDBusConnection::systemBus());

QDBusPendingCall pendingCall = udisks2Interface.asyncCallWithArgumentList(dbusMethod, arguments);
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingCall, this);
connect(watcher, &QDBusPendingCallWatcher::finished,
this, [this, devicePath, dbusMethod](QDBusPendingCallWatcher *watcher) {
if (watcher->isValid() && watcher->isFinished()) {
emit status(devicePath, Partition::Renamed);
mount(devicePath);
} else if (watcher->isError()) {
QDBusError error = watcher->error();
QByteArray errorData = error.name().toLocal8Bit();
const char *errorCStr = errorData.constData();
qCWarning(lcMemoryCardLog) << dbusMethod << "error:" << errorCStr;

for (uint i = 0; i < sizeof(dbus_error_entries) / sizeof(ErrorEntry); i++) {
if (strcmp(dbus_error_entries[i].dbusErrorName, errorCStr) == 0) {
emit setLabelError(dbus_error_entries[i].errorCode);
break;
}
}
}

watcher->deleteLater();
});
}

void UDisks2::Monitor::getBlockDevices()
{
QDBusInterface managerInterface(UDISKS2_SERVICE,
Expand Down
3 changes: 3 additions & 0 deletions src/udisks2monitor_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ class Monitor : public QObject
void unmount(const QString &devicePath);

void format(const QString &devicePath, const QString &filesystemType, const QVariantMap &arguments);
void setLabel(const QString &devicePath, const QString &label);

signals:
void status(const QString &devicePath, Partition::Status);
Expand All @@ -95,12 +96,14 @@ class Monitor : public QObject
void mountError(Partition::Error error);
void unmountError(Partition::Error error);
void formatError(Partition::Error error);
void setLabelError(Partition::Error error);

private slots:
void interfacesAdded(const QDBusObjectPath &objectPath, const UDisks2::InterfacePropertyMap &interfaces);
void interfacesRemoved(const QDBusObjectPath &objectPath, const QStringList &interfaces);
void doFormat(const QString &devicePath, const QString &dbusObjectPath, const QString &filesystemType, const QVariantMap &arguments);
void handleNewBlock(UDisks2::Block *block);
void doSetLabel(const QString &devicePath, const QString &dbusObjectPath, const QVariantList &arguments);

private:
void setPartitionProperties(QExplicitlySharedDataPointer<PartitionPrivate> &partition, const Block *blockDevice);
Expand Down

0 comments on commit 552eb9f

Please sign in to comment.