Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[systemsettings] Follow udisks2 File System and Encrypted interface c…
…hanges. Contributes to JB#42526
  • Loading branch information
rainemak committed Aug 29, 2018
1 parent a8551e9 commit cec3b79
Show file tree
Hide file tree
Showing 6 changed files with 254 additions and 91 deletions.
2 changes: 1 addition & 1 deletion src/partitionmanager_p.h
Expand Up @@ -43,7 +43,7 @@ namespace UDisks2 {
class Monitor;
}

static const auto externalDevice = QStringLiteral("mmcblk(?!0)\\d+(?:p\\d+$)?|(sd[a-z]\\d*)");
static const auto externalDevice = QStringLiteral("mmcblk(?!0)\\d+(?:p\\d+$)?|(sd[a-z]\\d*)|(dm[_-]\\d+(?:d\\d+)?)");

class PartitionManagerPrivate : public QObject, public QSharedData
{
Expand Down
149 changes: 141 additions & 8 deletions src/udisks2block.cpp
Expand Up @@ -7,21 +7,24 @@
#include <QDBusPendingCallWatcher>
#include <QDBusPendingReply>

UDisks2::Block::Block(const QString &path, const QVariantMap &data, QObject *parent)
UDisks2::Block::Block(const QString &path, const InterfaceAndPropertyMap &interfacePropertyMap, QObject *parent)
: QObject(parent)
, m_path(path)
, m_data(data)
, m_interfacePropertyMap(interfacePropertyMap)
, m_data(interfacePropertyMap.value(UDISKS2_BLOCK_INTERFACE))
, m_connection(QDBusConnection::systemBus())
, m_mountable(false)
, m_mountable(interfacePropertyMap.contains(UDISKS2_FILESYSTEM_INTERFACE))
, m_encrypted(interfacePropertyMap.contains(UDISKS2_ENCRYPTED_INTERFACE))
, m_formatting(false)
, m_pendingFileSystem(nullptr)
, m_pendingBlock(nullptr)
, m_pendingEncrypted(nullptr)
{
if (!m_connection.connect(
UDISKS2_SERVICE,
m_path,
DBUS_OBJECT_PROPERTIES_INTERFACE,
QStringLiteral("PropertiesChanged"),
UDisks2::propertiesChangedSignal,
this,
SLOT(updateProperties(QDBusMessage)))) {
qCWarning(lcMemoryCardLog) << "Failed to connect to Block properties change interface" << m_path << m_connection.lastError().message();
Expand All @@ -32,10 +35,11 @@ UDisks2::Block::Block(const QString &path, const QVariantMap &data, QObject *par
DBUS_OBJECT_PROPERTIES_INTERFACE,
m_connection);

qCInfo(lcMemoryCardLog) << "Creating a new block. Mountable:" << m_mountable << ", object path:" << m_path << ", data is empty:" << m_data.isEmpty();
getFileSystemInterface();
qCInfo(lcMemoryCardLog) << "Creating a new block. Mountable:" << m_mountable << ", encrypted:" << m_encrypted << "object path:" << m_path << "data is empty:" << m_data.isEmpty();

if (m_data.isEmpty()) {
getFileSystemInterface();
getEncryptedInterface();
QDBusPendingCall pendingCall = dbusPropertyInterface.asyncCall(DBUS_GET_ALL, UDISKS2_BLOCK_INTERFACE);
m_pendingBlock = new QDBusPendingCallWatcher(pendingCall, this);
connect(m_pendingBlock, &QDBusPendingCallWatcher::finished, this, [this, path](QDBusPendingCallWatcher *watcher) {
Expand All @@ -54,10 +58,53 @@ UDisks2::Block::Block(const QString &path, const QVariantMap &data, QObject *par
complete();
});
} else {
if (m_mountable) {
QVariantMap map = interfacePropertyMap.value(UDISKS2_FILESYSTEM_INTERFACE);
updateMountPoint(map);
}

// We have either org.freedesktop.UDisks2.Filesystem or org.freedesktop.UDisks2.Encrypted interface.
complete();
}
}

// Use when morphing a block e.g. updating encrypted block to crypto backing block device (e.i. to a block that implements file system).
UDisks2::Block &UDisks2::Block::operator=(const UDisks2::Block &other)
{
if (&other == this)
return *this;

if (!this->m_connection.disconnect(
UDISKS2_SERVICE,
m_path,
DBUS_OBJECT_PROPERTIES_INTERFACE,
UDisks2::propertiesChangedSignal,
this,
SLOT(updateProperties(QDBusMessage)))) {
qCWarning(lcMemoryCardLog) << "Failed to disconnect to Block properties change interface" << m_path << m_connection.lastError().message();
}

this->m_path = other.m_path;

if (!this->m_connection.connect(
UDISKS2_SERVICE,
this->m_path,
DBUS_OBJECT_PROPERTIES_INTERFACE,
UDisks2::propertiesChangedSignal,
this,
SLOT(updateProperties(QDBusMessage)))) {
qCWarning(lcMemoryCardLog) << "Failed to connect to Block properties change interface" << m_path << m_connection.lastError().message();
}

m_interfacePropertyMap = other.m_interfacePropertyMap;
m_data = other.m_data;
m_mountable = other.m_mountable;
m_mountPath = other.m_mountPath;
m_encrypted = other.m_encrypted;

return *this;
}

UDisks2::Block::~Block()
{
}
Expand Down Expand Up @@ -99,9 +146,43 @@ qint64 UDisks2::Block::size() const
return value(QStringLiteral("Size")).toLongLong();
}

bool UDisks2::Block::hasCryptoBackingDevice() const
{
const QString cryptoBackingDev = cryptoBackingDeviceObjectPath();
return cryptoBackingDev != QLatin1String("/");
}

QString UDisks2::Block::cryptoBackingDeviceName() const
{
const QString object = cryptoBackingDeviceObjectPath();
return Block::cryptoBackingDeviceName(object);
}

QString UDisks2::Block::cryptoBackingDeviceObjectPath() const
{
return value(UDisks2::cryptoBackingDeviceKey).toString();
}

bool UDisks2::Block::isEncrypted() const
{
return m_encrypted;
}

void UDisks2::Block::setEncrypted(bool encrypted)
{
if (m_encrypted != encrypted) {
m_encrypted = encrypted;
blockSignals(true);
setMountable(!m_encrypted);
blockSignals(false);

emit updated();
}
}

bool UDisks2::Block::isMountable() const
{
return m_mountable && value(QStringLiteral("HintAuto")).toBool();
return m_mountable;
}

void UDisks2::Block::setMountable(bool mountable)
Expand All @@ -128,6 +209,12 @@ bool UDisks2::Block::isReadOnly() const
return value(QStringLiteral("ReadOnly")).toBool();
}

bool UDisks2::Block::isExternal() const
{
const QString prefDevice = preferredDevice();
return prefDevice != QStringLiteral("/dev/sailfish/home") && prefDevice != QStringLiteral("/dev/sailfish/root");
}

QString UDisks2::Block::idType() const
{
return value(QStringLiteral("IdType")).toString();
Expand Down Expand Up @@ -163,6 +250,28 @@ bool UDisks2::Block::hasData() const
return !m_data.isEmpty();
}

void UDisks2::Block::dumpInfo() const
{
qCInfo(lcMemoryCardLog) << "Block device:" << device() << "Preferred device:" << preferredDevice();
qCInfo(lcMemoryCardLog) << "- drive:" << drive() << "dNumber:" << deviceNumber();
qCInfo(lcMemoryCardLog) << "- id:" << id() << "size:" << size();
qCInfo(lcMemoryCardLog) << "- isreadonly:" << isReadOnly() << "idtype:" << idType();
qCInfo(lcMemoryCardLog) << "- idversion:" << idVersion() << "idlabel:" << idLabel();
qCInfo(lcMemoryCardLog) << "- iduuid:" << idUUID();
qCInfo(lcMemoryCardLog) << "- ismountable:" << isMountable() << "mount path:" << mountPath();
qCInfo(lcMemoryCardLog) << "- isencrypted:" << isEncrypted() << "crypto backing device:" << cryptoBackingDeviceName();
}

QString UDisks2::Block::cryptoBackingDeviceName(const QString &objectPath)
{
if (objectPath == QLatin1String("/") || objectPath.isEmpty()) {
return QString();
} else {
QString deviceName = objectPath.section(QChar('/'), 5);
return QString("/dev/%1").arg(deviceName);
}
}

void UDisks2::Block::updateProperties(const QDBusMessage &message)
{
QList<QVariant> arguments = message.arguments();
Expand Down Expand Up @@ -199,7 +308,7 @@ void UDisks2::Block::updateMountPoint(const QVariant &mountPoints)

void UDisks2::Block::complete()
{
if (!m_pendingFileSystem && !m_pendingBlock) {
if (!m_pendingFileSystem && !m_pendingBlock && !m_pendingEncrypted) {
QMetaObject::invokeMethod(this, "completed", Qt::QueuedConnection);
}
}
Expand Down Expand Up @@ -228,3 +337,27 @@ void UDisks2::Block::getFileSystemInterface()
complete();
});
}

void UDisks2::Block::getEncryptedInterface()
{
QDBusInterface dbusPropertyInterface(UDISKS2_SERVICE,
m_path,
DBUS_OBJECT_PROPERTIES_INTERFACE,
m_connection);
QDBusPendingCall pendingCall = dbusPropertyInterface.asyncCall(DBUS_GET_ALL, UDISKS2_ENCRYPTED_INTERFACE);
m_pendingEncrypted = new QDBusPendingCallWatcher(pendingCall, this);
connect(m_pendingEncrypted, &QDBusPendingCallWatcher::finished, this, [this](QDBusPendingCallWatcher *watcher) {
if (watcher->isValid() && watcher->isFinished()) {
QDBusPendingReply<> reply = *watcher;
QDBusMessage message = reply.reply();
m_encrypted = true;
} else {
QDBusError error = watcher->error();
qCWarning(lcMemoryCardLog) << "Error reading encrypted properties:" << error.name() << error.message() << m_path;
m_encrypted = false;
}
m_pendingEncrypted->deleteLater();
m_pendingEncrypted = nullptr;
complete();
});
}
24 changes: 23 additions & 1 deletion src/udisks2block_p.h
Expand Up @@ -36,6 +36,10 @@
#include <QVariantMap>
#include <QDBusConnection>

typedef QMap<QString, QVariantMap> InterfaceAndPropertyMap;

Q_DECLARE_METATYPE(InterfaceAndPropertyMap)

class QDBusPendingCallWatcher;

namespace UDisks2 {
Expand All @@ -45,7 +49,9 @@ class Block : public QObject
Q_OBJECT

public:
Block(const QString &path, const QVariantMap &data, QObject *parent = nullptr);
Block(const QString &path, const InterfaceAndPropertyMap &interfacePropertyMap, QObject *parent = nullptr);
Block& operator=(const Block& other);

~Block();

QString path() const;
Expand All @@ -59,13 +65,21 @@ class Block : public QObject

qint64 size() const;

bool hasCryptoBackingDevice() const;
QString cryptoBackingDeviceName() const;
QString cryptoBackingDeviceObjectPath() const;

bool isEncrypted() const;
void setEncrypted(bool encrypted);

bool isMountable() const;
void setMountable(bool mountable);

bool isFormatting() const;
void setFormatting();

bool isReadOnly() const;
bool isExternal() const;

QString idType() const;
QString idVersion() const;
Expand All @@ -78,6 +92,10 @@ class Block : public QObject

bool hasData() const;

void dumpInfo() const;

static QString cryptoBackingDeviceName(const QString &objectPath);

signals:
void completed();
void updated();
Expand All @@ -91,16 +109,20 @@ private slots:
void updateMountPoint(const QVariant &mountPoints);
void complete();
void getFileSystemInterface();
void getEncryptedInterface();

QString m_path;
InterfaceAndPropertyMap m_interfacePropertyMap;
QVariantMap m_data;
QDBusConnection m_connection;
QString m_mountPath;
bool m_mountable;
bool m_encrypted;
bool m_formatting;

QDBusPendingCallWatcher *m_pendingFileSystem;
QDBusPendingCallWatcher *m_pendingBlock;
QDBusPendingCallWatcher *m_pendingEncrypted;
};

}
Expand Down
6 changes: 6 additions & 0 deletions src/udisks2defines.h
Expand Up @@ -32,6 +32,12 @@
#ifndef UDISKS2_DEFINES
#define UDISKS2_DEFINES

namespace UDisks2 {
static const auto propertiesChangedSignal = QStringLiteral("PropertiesChanged");
static const auto cryptoBackingDeviceKey = QStringLiteral("CryptoBackingDevice");
}


#define DBUS_OBJECT_MANAGER_INTERFACE QLatin1String("org.freedesktop.DBus.ObjectManager")
#define DBUS_OBJECT_PROPERTIES_INTERFACE QLatin1String("org.freedesktop.DBus.Properties")
#define DBUS_GET_ALL QLatin1String("GetAll")
Expand Down

0 comments on commit cec3b79

Please sign in to comment.