diff --git a/src/solid/devices/backends/shared/udevqtclient.h b/src/solid/devices/backends/shared/udevqtclient.h --- a/src/solid/devices/backends/shared/udevqtclient.h +++ b/src/solid/devices/backends/shared/udevqtclient.h @@ -50,6 +50,12 @@ DeviceList allDevices(); DeviceList devicesByProperty(const QString &property, const QVariant &value); DeviceList devicesBySubsystem(const QString &subsystem); + /** + * Returns a list of devices matching any of the given subsystems AND any of the properties. + * + * (subsystem1 || subsystem2 || ...) && (property1 || property2 || ...) + */ + DeviceList devicesBySubsystemsAndProperties(const QStringList &subsystems, const QVariantMap &properties); Device deviceByDeviceFile(const QString &deviceFile); Device deviceBySysfsPath(const QString &sysfsPath); Device deviceBySubsystemAndName(const QString &subsystem, const QString &name); diff --git a/src/solid/devices/backends/shared/udevqtclient.cpp b/src/solid/devices/backends/shared/udevqtclient.cpp --- a/src/solid/devices/backends/shared/udevqtclient.cpp +++ b/src/solid/devices/backends/shared/udevqtclient.cpp @@ -215,6 +215,25 @@ return d->deviceListFromEnumerate(en); } +DeviceList Client::devicesBySubsystemsAndProperties(const QStringList &subsystems, const QVariantMap &properties) +{ + struct udev_enumerate *en = udev_enumerate_new(d->udev); + + for (const QString &subsystem : subsystems) { + udev_enumerate_add_match_subsystem(en, subsystem.toLatin1().constData()); + } + + for (auto it = properties.begin(), end = properties.end(); it != end; ++it) { + if (it.value().isValid()) { + udev_enumerate_add_match_property(en, it.key().toLatin1().constData(), it.value().toString().toLatin1().constData()); + } else { + udev_enumerate_add_match_property(en, it.key().toLatin1().constData(), nullptr); + } + } + + return d->deviceListFromEnumerate(en); +} + Device Client::deviceByDeviceFile(const QString &deviceFile) { QT_STATBUF sb; diff --git a/src/solid/devices/backends/udev/udevdevice.cpp b/src/solid/devices/backends/udev/udevdevice.cpp --- a/src/solid/devices/backends/udev/udevdevice.cpp +++ b/src/solid/devices/backends/udev/udevdevice.cpp @@ -147,10 +147,10 @@ return m_device.subsystem() == QLatin1String("cpu"); case Solid::DeviceInterface::Camera: - return property("ID_GPHOTO2").toInt() == 1; + return m_device.subsystem() == QLatin1String("usb") && property("ID_GPHOTO2").isValid(); case Solid::DeviceInterface::PortableMediaPlayer: - return m_device.subsystem() == QLatin1String("usb") && !property("ID_MEDIA_PLAYER").toString().isEmpty(); + return m_device.subsystem() == QLatin1String("usb") && property("ID_MEDIA_PLAYER").isValid(); case Solid::DeviceInterface::Block: return !property("MAJOR").toString().isEmpty(); diff --git a/src/solid/devices/backends/udev/udevmanager.cpp b/src/solid/devices/backends/udev/udevmanager.cpp --- a/src/solid/devices/backends/udev/udevmanager.cpp +++ b/src/solid/devices/backends/udev/udevmanager.cpp @@ -199,10 +199,18 @@ deviceList = d->m_client->devicesBySubsystem(QStringLiteral("processor")) + d->m_client->devicesBySubsystem(QStringLiteral("cpu")); } else if (type == Solid::DeviceInterface::Camera) { - deviceList = d->m_client->devicesByProperty("ID_GPHOTO2", 1); + deviceList = d->m_client->devicesBySubsystemsAndProperties({ + QStringLiteral("usb"), + }, { + {QStringLiteral("ID_GPHOTO2"), QStringLiteral("*")} // match any + }); } else if (type == Solid::DeviceInterface::PortableMediaPlayer) { - deviceList = d->m_client->devicesBySubsystem(QStringLiteral("usb")); - } else if (type != Solid::DeviceInterface::Unknown) { + deviceList = d->m_client->devicesBySubsystemsAndProperties({ + QStringLiteral("usb"), + }, { + {QStringLiteral("ID_MEDIA_PLAYER"), QStringLiteral("*")} // match any + }); + } else { deviceList = d->m_client->allDevices(); }