UDisks2.Job interface support
This commit is contained in:
parent
68001ff7e8
commit
ed986d3863
|
@ -973,6 +973,8 @@ if(HAVE_DBUS)
|
||||||
PROPERTIES NO_NAMESPACE dbus/udisks2block INCLUDE dbus/metatypes.h)
|
PROPERTIES NO_NAMESPACE dbus/udisks2block INCLUDE dbus/metatypes.h)
|
||||||
set_source_files_properties(dbus/org.freedesktop.UDisks2.Drive.xml
|
set_source_files_properties(dbus/org.freedesktop.UDisks2.Drive.xml
|
||||||
PROPERTIES NO_NAMESPACE dbus/udisks2drive INCLUDE dbus/metatypes.h)
|
PROPERTIES NO_NAMESPACE dbus/udisks2drive INCLUDE dbus/metatypes.h)
|
||||||
|
set_source_files_properties(dbus/org.freedesktop.UDisks2.Job.xml
|
||||||
|
PROPERTIES NO_NAMESPACE dbus/udisks2job INCLUDE dbus/metatypes.h)
|
||||||
qt4_add_dbus_interface(SOURCES
|
qt4_add_dbus_interface(SOURCES
|
||||||
dbus/org.freedesktop.DBus.ObjectManager.xml
|
dbus/org.freedesktop.DBus.ObjectManager.xml
|
||||||
dbus/objectmanager)
|
dbus/objectmanager)
|
||||||
|
@ -985,6 +987,9 @@ if(HAVE_DBUS)
|
||||||
qt4_add_dbus_interface(SOURCES
|
qt4_add_dbus_interface(SOURCES
|
||||||
dbus/org.freedesktop.UDisks2.Drive.xml
|
dbus/org.freedesktop.UDisks2.Drive.xml
|
||||||
dbus/udisks2drive)
|
dbus/udisks2drive)
|
||||||
|
qt4_add_dbus_interface(SOURCES
|
||||||
|
dbus/org.freedesktop.UDisks2.Job.xml
|
||||||
|
dbus/udisks2job)
|
||||||
endif(HAVE_UDISKS2)
|
endif(HAVE_UDISKS2)
|
||||||
|
|
||||||
# Wiimotedev interface classes
|
# Wiimotedev interface classes
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
||||||
|
<node name="/" xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd">
|
||||||
|
<interface name="org.freedesktop.UDisks2.Job">
|
||||||
|
<property name="Operation" type="s" access="read"/>
|
||||||
|
<property name="Objects" type="ao" access="read"/>
|
||||||
|
<signal name="Completed">
|
||||||
|
<arg name="success" type="b"/>
|
||||||
|
<arg name="message" type="s"/>
|
||||||
|
</signal>
|
||||||
|
</interface>
|
||||||
|
</node>
|
|
@ -8,6 +8,7 @@
|
||||||
#include "dbus/udisks2filesystem.h"
|
#include "dbus/udisks2filesystem.h"
|
||||||
#include "dbus/udisks2block.h"
|
#include "dbus/udisks2block.h"
|
||||||
#include "dbus/udisks2drive.h"
|
#include "dbus/udisks2drive.h"
|
||||||
|
#include "dbus/udisks2job.h"
|
||||||
|
|
||||||
const QString Udisks2Lister::udisks2service_ = "org.freedesktop.UDisks2";
|
const QString Udisks2Lister::udisks2service_ = "org.freedesktop.UDisks2";
|
||||||
|
|
||||||
|
@ -165,6 +166,16 @@ void Udisks2Lister::DBusInterfaceAdded(const QDBusObjectPath &path,
|
||||||
if (interface.key() != "org.freedesktop.UDisks2.Job")
|
if (interface.key() != "org.freedesktop.UDisks2.Job")
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
std::shared_ptr<OrgFreedesktopUDisks2JobInterface> job = std::make_shared<OrgFreedesktopUDisks2JobInterface>(
|
||||||
|
udisks2service_,
|
||||||
|
path.path(),
|
||||||
|
QDBusConnection::systemBus());
|
||||||
|
|
||||||
|
if (!job->isValid())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// For some reason access through Job interface returns all properties
|
||||||
|
// as invalid for unmount job so we're doing this the hard way
|
||||||
bool isMountJob = false;
|
bool isMountJob = false;
|
||||||
if (interface.value()["Operation"] == "filesystem-mount")
|
if (interface.value()["Operation"] == "filesystem-mount")
|
||||||
isMountJob = true;
|
isMountJob = true;
|
||||||
|
@ -173,30 +184,24 @@ void Udisks2Lister::DBusInterfaceAdded(const QDBusObjectPath &path,
|
||||||
else
|
else
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const QDBusArgument &objects = interface.value()["Objects"].value<QDBusArgument>();
|
QList<QDBusObjectPath> mountedParititons
|
||||||
|
= GetMountedPartitionsFromDBusArgument(interface.value()["Objects"].value<QDBusArgument>());
|
||||||
QList<QDBusObjectPath> mountedParititons;
|
|
||||||
objects.beginArray();
|
|
||||||
while (!objects.atEnd()) {
|
|
||||||
QDBusObjectPath extractedPath;
|
|
||||||
objects >> extractedPath;
|
|
||||||
mountedParititons.push_back(extractedPath);
|
|
||||||
}
|
|
||||||
objects.endArray();
|
|
||||||
|
|
||||||
if (mountedParititons.isEmpty()) {
|
if (mountedParititons.isEmpty()) {
|
||||||
qLog(Warning) << "Empty Udisks2 mount/umount job " << path.path();
|
qLog(Warning) << "Empty Udisks2 mount/umount job " << path.path();
|
||||||
return;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
qLog(Debug) << "Adding Udisks job " << path.path()
|
|
||||||
<< " | Operation = " << interface.value()["Operation"].toString()
|
|
||||||
<< " with first path: " << mountedParititons.at(0).path();
|
|
||||||
|
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&jobs_lock_);
|
QMutexLocker locker(&jobs_lock_);
|
||||||
mounting_jobs_[path.path()].isMount = isMountJob;
|
qLog(Debug) << "Adding pending job | DBus Path = " << job->path()
|
||||||
mounting_jobs_[path.path()].mount_paths = mountedParititons;
|
<< " | IsMountJob = " << isMountJob
|
||||||
|
<< " | First partition = " << mountedParititons.at(0).path();
|
||||||
|
mounting_jobs_[path].dbus_interface = job;
|
||||||
|
mounting_jobs_[path].isMount = isMountJob;
|
||||||
|
mounting_jobs_[path].mounted_partitions = mountedParititons;
|
||||||
|
connect(job.get(), SIGNAL(Completed(bool, const QString&)),
|
||||||
|
SLOT(JobCompleted(bool, const QString&)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -207,47 +212,12 @@ void Udisks2Lister::DBusInterfaceRemoved(const QDBusObjectPath &path, const QStr
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Udisks2Lister::isPendingJob(const QDBusObjectPath &jobPath) {
|
bool Udisks2Lister::isPendingJob(const QDBusObjectPath &jobPath) {
|
||||||
// should be actually done with a succcess signal from job, I guess, but it makes it kinda complicated
|
|
||||||
QMutexLocker locker(&jobs_lock_);
|
QMutexLocker locker(&jobs_lock_);
|
||||||
|
|
||||||
if (!mounting_jobs_.contains(jobPath.path()))
|
if (!mounting_jobs_.contains(jobPath))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const auto &mountPaths = mounting_jobs_[jobPath.path()].mount_paths;
|
mounting_jobs_.remove(jobPath);
|
||||||
const auto &isMount = mounting_jobs_[jobPath.path()].isMount;
|
|
||||||
for (const auto &partition : mountPaths) {
|
|
||||||
auto data = ReadPartitionData(partition, true);
|
|
||||||
if (!data.dbus_path.isEmpty()) {
|
|
||||||
if (isMount) {
|
|
||||||
qLog(Debug) << "UDisks2 mount job finished: Drive = " << data.dbus_drive_path
|
|
||||||
<< " | Partition = " << data.dbus_path;
|
|
||||||
QWriteLocker locker(&device_data_lock_);
|
|
||||||
device_data_[data.unique_id()] = data;
|
|
||||||
DeviceAdded(data.unique_id());
|
|
||||||
} else {
|
|
||||||
QWriteLocker locker(&device_data_lock_);
|
|
||||||
QString id;
|
|
||||||
for (auto &data : device_data_) {
|
|
||||||
if (data.mount_paths.contains(partition.path())) {
|
|
||||||
qLog(Debug) << "UDisks2 umount job finished, found corresponding device: Drive = " << data.dbus_drive_path
|
|
||||||
<< " | Partition = " << data.dbus_path;
|
|
||||||
data.mount_paths.removeOne(partition.path());
|
|
||||||
if (data.mount_paths.empty())
|
|
||||||
id = data.unique_id();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!id.isEmpty())
|
|
||||||
{
|
|
||||||
qLog(Debug) << "Partition " << data.dbus_path << " has no more mount points, removing it from device list";
|
|
||||||
device_data_.remove(id);
|
|
||||||
DeviceRemoved(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mounting_jobs_.remove(jobPath.path());
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -269,6 +239,67 @@ void Udisks2Lister::RemoveDevice(const QDBusObjectPath &devicePath) {
|
||||||
DeviceRemoved(id);
|
DeviceRemoved(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QList<QDBusObjectPath> Udisks2Lister::GetMountedPartitionsFromDBusArgument(const QDBusArgument &input) {
|
||||||
|
QList<QDBusObjectPath> result;
|
||||||
|
|
||||||
|
input.beginArray();
|
||||||
|
while (!input.atEnd()) {
|
||||||
|
QDBusObjectPath extractedPath;
|
||||||
|
input >> extractedPath;
|
||||||
|
result.push_back(extractedPath);
|
||||||
|
}
|
||||||
|
input.endArray();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Udisks2Lister::JobCompleted(bool success, const QString &message) {
|
||||||
|
auto job = qobject_cast<OrgFreedesktopUDisks2JobInterface*>(sender());
|
||||||
|
QDBusObjectPath jobPath(job->path());
|
||||||
|
|
||||||
|
if (!job->isValid()
|
||||||
|
|| !success
|
||||||
|
|| !mounting_jobs_.contains(jobPath))
|
||||||
|
return;
|
||||||
|
|
||||||
|
qLog(Debug) << "Pending Job Completed | Path = " << job->path()
|
||||||
|
<< " | Mount? = " << mounting_jobs_[jobPath].isMount
|
||||||
|
<< " | Success = " << success;
|
||||||
|
|
||||||
|
for (const auto &mountedObject : mounting_jobs_[jobPath].mounted_partitions) {
|
||||||
|
auto data = ReadPartitionData(mountedObject, false);
|
||||||
|
if (data.dbus_path.isEmpty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (mounting_jobs_[jobPath].isMount) {
|
||||||
|
qLog(Debug) << "UDisks2 mount job finished: Drive = " << data.dbus_drive_path
|
||||||
|
<< " | Partition = " << data.dbus_path;
|
||||||
|
QWriteLocker locker(&device_data_lock_);
|
||||||
|
device_data_[data.unique_id()] = data;
|
||||||
|
DeviceAdded(data.unique_id());
|
||||||
|
} else {
|
||||||
|
QWriteLocker locker(&device_data_lock_);
|
||||||
|
QString id;
|
||||||
|
for (auto &data : device_data_) {
|
||||||
|
if (data.mount_paths.contains(mountedObject.path())) {
|
||||||
|
qLog(Debug) << "UDisks2 umount job finished, found corresponding device: Drive = " << data.dbus_drive_path
|
||||||
|
<< " | Partition = " << data.dbus_path;
|
||||||
|
data.mount_paths.removeOne(mountedObject.path());
|
||||||
|
if (data.mount_paths.empty())
|
||||||
|
id = data.unique_id();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!id.isEmpty()) {
|
||||||
|
qLog(Debug) << "Partition " << data.dbus_path << " has no more mount points, removing it from device list";
|
||||||
|
device_data_.remove(id);
|
||||||
|
DeviceRemoved(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Udisks2Lister::PartitionData Udisks2Lister::ReadPartitionData(const QDBusObjectPath &path,
|
Udisks2Lister::PartitionData Udisks2Lister::ReadPartitionData(const QDBusObjectPath &path,
|
||||||
bool beingMounted) {
|
bool beingMounted) {
|
||||||
PartitionData result;
|
PartitionData result;
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
|
|
||||||
#include "dbus/objectmanager.h"
|
#include "dbus/objectmanager.h"
|
||||||
|
|
||||||
|
class OrgFreedesktopUDisks2JobInterface;
|
||||||
|
|
||||||
class Udisks2Lister : public DeviceLister {
|
class Udisks2Lister : public DeviceLister {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
@ -35,20 +37,23 @@ protected:
|
||||||
private slots:
|
private slots:
|
||||||
void DBusInterfaceAdded(const QDBusObjectPath &path, const InterfacesAndProperties &ifaces);
|
void DBusInterfaceAdded(const QDBusObjectPath &path, const InterfacesAndProperties &ifaces);
|
||||||
void DBusInterfaceRemoved(const QDBusObjectPath &path, const QStringList &ifaces);
|
void DBusInterfaceRemoved(const QDBusObjectPath &path, const QStringList &ifaces);
|
||||||
|
void JobCompleted(bool success, const QString &message);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool isPendingJob(const QDBusObjectPath &jobPath);
|
bool isPendingJob(const QDBusObjectPath &jobPath);
|
||||||
void RemoveDevice(const QDBusObjectPath &devicePath);
|
void RemoveDevice(const QDBusObjectPath &devicePath);
|
||||||
|
QList<QDBusObjectPath> GetMountedPartitionsFromDBusArgument(const QDBusArgument &input);
|
||||||
|
|
||||||
class MountJob
|
class Udisks2Job
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bool isMount = true;
|
bool isMount = true;
|
||||||
QList<QDBusObjectPath> mount_paths;
|
QList<QDBusObjectPath> mounted_partitions;
|
||||||
|
std::shared_ptr<OrgFreedesktopUDisks2JobInterface> dbus_interface;
|
||||||
};
|
};
|
||||||
|
|
||||||
QMutex jobs_lock_;
|
QMutex jobs_lock_;
|
||||||
QMap<QString, MountJob> mounting_jobs_;
|
QMap<QDBusObjectPath, Udisks2Job> mounting_jobs_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class PartitionData {
|
class PartitionData {
|
||||||
|
|
Loading…
Reference in New Issue