Skip to content

Commit

Permalink
[fsstorageplugin] Get disk labels from UDisks. Fixes JB#53587
Browse files Browse the repository at this point in the history
Memory cards mounting was recently changed so that mountpoint is
  /run/media/<USER>/<UUID>
instead of
  /run/media/<USER>/<LABEL>
and this causes memory cards to show up over mtp with long hex-only
names that are not really meant for human consumption.

Query block device information from UDisks2 D-Bus service, and
use disk label from block device associated with the mount point
when available.

For those mount points for which label information is not available,
enumerated "Card N" labels are used.

Synchronous D-Bus IPC is used as this is needed in procedural logic
executed before buteo-mtp enters mainloop.

As buteo-mtp does not use D-Bus SystemBus for other purpose, and
attempt is made to close connection after it is not needed anymore.

Signed-off-by: Simo Piiroinen <simo.piiroinen@jolla.com>
  • Loading branch information
spiiroin committed Mar 24, 2021
1 parent ffbe977 commit 01a518c
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 4 deletions.
1 change: 1 addition & 0 deletions mts/platform/storage/fsstorageplugin/fsstorageplugin.pro
Expand Up @@ -9,6 +9,7 @@ QT += dbus xml
QT -= gui

PKGCONFIG += blkid mount
PKGCONFIG += nemodbus

system($$[QT_INSTALL_BINS]/qdbusxml2cpp -c ThumbnailerProxy -p thumbnailerproxy.h:thumbnailerproxy.cpp -i thumbnailpathlist.h ./org.nemomobile.Thumbnailer.xml)

Expand Down
67 changes: 63 additions & 4 deletions mts/platform/storage/fsstorageplugin/fsstoragepluginfactory.cpp
@@ -1,9 +1,7 @@
/*
* This file is a part of buteo-mtp package.
*
* Copyright (C) 2014 Jolla Ltd.
*
* Contact: Jakub Adam <jakub.adam@jollamobile.com>
* Copyright (c) 2014 - 2021 Jolla Ltd.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
Expand Down Expand Up @@ -37,14 +35,75 @@
#include <QDirIterator>
#include <QDomDocument>
#include <QProcessEnvironment>
#include <QDBusInterface>
#include <QDBusReply>
#include <nemo-dbus/dbus.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <mntent.h>
#include <unistd.h>
#include <glob.h>

#include <udisks2defines.h> // systemsettings

using namespace meegomtp1dot0;

#define UDISKS2_MANAGER_METHOD_GETBLOCKDEVICES "GetBlockDevices"
#define UDISKS2_BLOCK_PROPERTY_IDLABEL "IdLabel"
#define UDISKS2_FILESYSTEM_PROPERTY_MOUNTPOINTS "MountPoints"
#define DBUS_OBJECT_PROPERTIES_METHOD_GET "Get"

static QHash<QString, QString> *generateDeviceLabelHash()
{
QHash<QString, QString> *deviceLabelHash = new QHash<QString, QString>;
/* Buteo-mtp does not otherwise need / connect to systembus -> use a connection that can be closed */
QString connectionName("privateSystemBusConnection");
QDBusConnection systemBus(QDBusConnection::connectToBus(QDBusConnection::SystemBus, connectionName));
QDBusInterface managerInterface(UDISKS2_SERVICE, UDISKS2_MANAGER_PATH, UDISKS2_MANAGER_INTERFACE, systemBus);
QVariantMap defaultOptions({{QLatin1String("auth.no_user_interaction"), QVariant(true)}});
QDBusReply<QList<QDBusObjectPath> > blockDevicesReply(managerInterface.call(UDISKS2_MANAGER_METHOD_GETBLOCKDEVICES, defaultOptions));
if (!blockDevicesReply.isValid()) {
QDBusError err(blockDevicesReply.error());
MTP_LOG_WARNING(QString("failed to get block device list from udisks: %1: %2").arg(err.name()).arg(err.message()));
} else {
for (const QDBusObjectPath &object : blockDevicesReply.value()) {
QDBusInterface propertiesInterface(UDISKS2_SERVICE, object.path(), DBUS_OBJECT_PROPERTIES_INTERFACE, systemBus);
QDBusReply<QVariant> deviceLabelReply(propertiesInterface.call(DBUS_OBJECT_PROPERTIES_METHOD_GET, UDISKS2_BLOCK_INTERFACE, UDISKS2_BLOCK_PROPERTY_IDLABEL));
if (!deviceLabelReply.isValid()) {
QDBusError err(deviceLabelReply.error());
MTP_LOG_WARNING(QString("failed to get disk label for %1: %2: %3").arg(object.path()).arg(err.name()).arg(err.message()));
continue;
}
QString deviceLabel(deviceLabelReply.value().toString());
if (deviceLabel.isEmpty())
continue;
QDBusReply<QVariant> mountPointsReply(propertiesInterface.call(DBUS_OBJECT_PROPERTIES_METHOD_GET, UDISKS2_FILESYSTEM_INTERFACE, UDISKS2_FILESYSTEM_PROPERTY_MOUNTPOINTS));
if (!mountPointsReply.isValid()) {
QDBusError err(mountPointsReply.error());
MTP_LOG_WARNING(QString("failed to get mountpoints for %1: %2: %3").arg(object.path()).arg(err.name()).arg(err.message()));
continue;
}
QByteArrayList mountPointsList(NemoDBus::demarshallArgument<QByteArrayList>(mountPointsReply.value()));
for (const QByteArray &bytes : mountPointsList)
deviceLabelHash->insert(QString(bytes.constData()), deviceLabel);
}
}
QDBusConnection::disconnectFromBus(connectionName);
return deviceLabelHash;
}

static QString generateLabel(const QString &path)
{
static unsigned cardCount = 0;
static QHash<QString, QString> *deviceLabelHash = nullptr;
if (!deviceLabelHash)
deviceLabelHash = generateDeviceLabelHash();
QString label(deviceLabelHash->value(path));
if (label.isEmpty())
(*deviceLabelHash)[path] = label = QString("Card %1").arg(++cardCount);
return label;
}

const char *FSStoragePluginFactory::CONFIG_DIR = "/etc/fsstorage.d";

QList<StoragePlugin *>FSStoragePluginFactory::create(quint32 storageId)
Expand Down Expand Up @@ -157,7 +216,7 @@ QList<StoragePlugin *>FSStoragePluginFactory::create(quint32 storageId)
QString desc(description);
description.clear();
if (desc.isEmpty())
desc = QFileInfo(path).baseName();
desc = generateLabel(path);
descs[desc] = path;
}
globfree(&gl);
Expand Down
1 change: 1 addition & 0 deletions rpm/buteo-mtp-qt5.spec
Expand Up @@ -21,6 +21,7 @@ BuildRequires: pkgconfig(mlite5)
BuildRequires: pkgconfig(Qt5Gui)
BuildRequires: ssu-devel >= 0.37.9
BuildRequires: pkgconfig(systemsettings) >= 0.2.25
BuildRequires: pkgconfig(nemodbus) >= 2.1.16
Requires: mtp-vendor-configuration
Requires: thumbnaild
Requires: libqt5sparql-tracker-direct
Expand Down

0 comments on commit 01a518c

Please sign in to comment.