From efe804588f0a1d8560ef188515da82e31ce5d2df Mon Sep 17 00:00:00 2001 From: iaom Date: Tue, 4 Apr 2023 14:49:50 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0volume=20manager=E7=94=A8?= =?UTF-8?q?=E4=BA=8E=E8=8E=B7=E5=8F=96=E8=AE=BE=E5=A4=87=E6=8C=82=E8=BD=BD?= =?UTF-8?q?=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dirwatcher/dir-watcher-dbus.pri | 6 +- .../dirwatcher/volume-manager.cpp | 158 ++++++++++++++++++ .../dirwatcher/volume-manager.h | 53 ++++++ 3 files changed, 215 insertions(+), 2 deletions(-) create mode 100644 ukui-search-service-dir-manager/dirwatcher/volume-manager.cpp create mode 100644 ukui-search-service-dir-manager/dirwatcher/volume-manager.h diff --git a/ukui-search-service-dir-manager/dirwatcher/dir-watcher-dbus.pri b/ukui-search-service-dir-manager/dirwatcher/dir-watcher-dbus.pri index 9661b77..6d49f2a 100644 --- a/ukui-search-service-dir-manager/dirwatcher/dir-watcher-dbus.pri +++ b/ukui-search-service-dir-manager/dirwatcher/dir-watcher-dbus.pri @@ -2,8 +2,10 @@ INCLUDEPATH += $$PWD HEADERS += \ $$PWD/dir-watcher-adaptor.h \ - $$PWD/dir-watcher.h + $$PWD/dir-watcher.h \ + $$PWD/volume-manager.h SOURCES += \ $$PWD/dir-watcher-adaptor.cpp \ - $$PWD/dir-watcher.cpp + $$PWD/dir-watcher.cpp \ + $$PWD/volume-manager.cpp diff --git a/ukui-search-service-dir-manager/dirwatcher/volume-manager.cpp b/ukui-search-service-dir-manager/dirwatcher/volume-manager.cpp new file mode 100644 index 0000000..c502509 --- /dev/null +++ b/ukui-search-service-dir-manager/dirwatcher/volume-manager.cpp @@ -0,0 +1,158 @@ +#include "volume-manager.h" +#include +#include +#include +static std::once_flag flag; +static VolumeManager *global_intance = nullptr; + +Volume::Volume() +{ +} + +Volume::Volume(const QString& device) +{ + m_device = device; +} + +QString Volume::device() +{ + return m_device; +} + +QStringList Volume::duplicatesMountPoints() const +{ + QStringList tmp; + for (auto iter = m_mountPoints.constBegin(); iter != m_mountPoints.constEnd(); ++iter) { + if(iter.value().isEmpty()) { + tmp.append(iter.key()); + } + } + if(tmp.size() == 1) { + tmp.clear(); + } + return tmp; +} + +QMap Volume::subVolumes() const +{ + QMap tmp; + for (auto iter = m_mountPoints.constBegin(); iter != m_mountPoints.constEnd(); ++iter) { + if(!iter.value().isEmpty()) { + tmp.insert(iter.key(), iter.value()); + } + } + return tmp; +} + +QStringList Volume::mountPoints() const +{ + return m_mountPoints.keys(); +} + +void Volume::setDevice(const QString& device) +{ + m_device = device; +} + +void Volume::addMountPoint(const QString &mountPoint, const QString &subVolume) +{ + m_mountPoints.insert(mountPoint, subVolume); +} + +VolumeManager *VolumeManager::self() +{ + std::call_once(flag, [ & ] { + global_intance = new VolumeManager(); + }); + return global_intance; +} + +VolumeManager::VolumeManager(QObject *parent) + : QObject{parent} +{ + this->refresh(); + m_volumeMonitor = g_volume_monitor_get(); + if (!m_volumeMonitor) { + qDebug() << "Fail to init volume monitor"; + return; + } + + m_mountAddHandle = g_signal_connect(m_volumeMonitor, "mount-added", G_CALLBACK(mountAddCallback), this); + m_mountRemoveHandle = g_signal_connect(m_volumeMonitor, "mount-removed", G_CALLBACK(mountRemoveCallback), this); +} + +VolumeManager::~VolumeManager() +{ + if(m_volumeMonitor){ + g_signal_handler_disconnect(m_volumeMonitor, m_mountAddHandle); + g_signal_handler_disconnect(m_volumeMonitor, m_mountRemoveHandle); + g_object_unref(m_volumeMonitor); + m_volumeMonitor = nullptr; + } +} + +QVector VolumeManager::getDuplicates() +{ + QMutexLocker locker(&m_mutex); + QVector tmp; + for (auto iter = m_volumes.constBegin(); iter != m_volumes.constEnd(); ++iter) { + QStringList duplicates = iter.value().duplicatesMountPoints(); + if(!duplicates.isEmpty()) { + tmp.append(duplicates); + } + } + return tmp; + +} + +QVector VolumeManager::volumesHaveSubVolumes() +{ + QMutexLocker locker(&m_mutex); + QVector tmp; + for (auto iter = m_volumes.constBegin(); iter != m_volumes.constEnd(); ++iter) { + if(!iter.value().subVolumes().isEmpty()) { + tmp.append(iter.value()); + } + } + return tmp; +} + +QVector VolumeManager::volumes() +{ + QMutexLocker locker(&m_mutex); + return m_volumes.values().toVector(); +} + +void VolumeManager::refresh() +{ + QMutexLocker locker(&m_mutex); + m_volumes.clear(); + //遍历当前系统所有挂载设备 + for (const QStorageInfo &storage: QStorageInfo::mountedVolumes()) { + if (storage.isValid() and storage.isReady()) { + Volume volume(storage.device()); + if(m_volumes.contains(storage.device())) { + volume = m_volumes.value(storage.device()); + } + volume.addMountPoint(storage.rootPath(), storage.subvolume()); + m_volumes.insert(storage.device(), volume); + } + } + Q_EMIT VolumeDataUpdated(); +} + +void VolumeManager::mountAddCallback(GVolumeMonitor *monitor, GMount *gmount, VolumeManager *pThis) +{ + Q_UNUSED(monitor) + Q_UNUSED(gmount) + //TODO 识别U盘等移动设备 + pThis->refresh(); +} + +void VolumeManager::mountRemoveCallback(GVolumeMonitor *monitor, GMount *gmount, VolumeManager *pThis) +{ + Q_UNUSED(monitor) + Q_UNUSED(gmount) + pThis->refresh(); +} + diff --git a/ukui-search-service-dir-manager/dirwatcher/volume-manager.h b/ukui-search-service-dir-manager/dirwatcher/volume-manager.h new file mode 100644 index 0000000..88e50ee --- /dev/null +++ b/ukui-search-service-dir-manager/dirwatcher/volume-manager.h @@ -0,0 +1,53 @@ +#ifndef VOLUMEMANAGER_H +#define VOLUMEMANAGER_H +#include +#include +#include +#include +#include +#include +#include + +class Volume +{ +public: + Volume(); + Volume(const QString& device); + QString device(); + QStringList duplicatesMountPoints() const; + QMap subVolumes() const; + QStringList mountPoints() const; + + void setDevice(const QString& device); + void addMountPoint(const QString& mountPoint, const QString& subVolume = QString()); +private: + QString m_device; + QMap m_mountPoints; //挂载点->子卷路径 +}; + +class VolumeManager : public QObject +{ + Q_OBJECT +public: + static VolumeManager *self(); + ~VolumeManager(); + QVector getDuplicates(); + QVector volumesHaveSubVolumes(); + QVector volumes(); +Q_SIGNALS: + void VolumeDataUpdated(); + +private: + explicit VolumeManager(QObject *parent = nullptr); + void refresh(); + static void mountAddCallback(GVolumeMonitor *monitor, GMount *gmount, VolumeManager *pThis); + static void mountRemoveCallback(GVolumeMonitor *monitor, GMount *gmount, VolumeManager *pThis); + GVolumeMonitor* m_volumeMonitor = nullptr; + quint64 m_mountAddHandle; + quint64 m_mountRemoveHandle; + QMap m_volumes; //device -> Volume + QMutex m_mutex; +}; + + +#endif // VOLUMEMANAGER_H