File indexing completed on 2024-04-28 05:45:19

0001 /*
0002  * SPDX-FileCopyrightText: 2014 Frank Reininghaus <frank78ac@googlemail.com>
0003  *
0004  * SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #include "mountpointobservercache.h"
0008 
0009 #include "mountpointobserver.h"
0010 
0011 #include <KMountPoint>
0012 
0013 #include <QTimer>
0014 
0015 class MountPointObserverCacheSingleton
0016 {
0017 public:
0018     MountPointObserverCache instance;
0019 };
0020 Q_GLOBAL_STATIC(MountPointObserverCacheSingleton, s_MountPointObserverCache)
0021 
0022 MountPointObserverCache::MountPointObserverCache()
0023     : m_observerForMountPoint()
0024     , m_mountPointForObserver()
0025     , m_updateTimer(nullptr)
0026 {
0027     m_updateTimer = new QTimer(this);
0028 }
0029 
0030 MountPointObserverCache::~MountPointObserverCache()
0031 {
0032 }
0033 
0034 MountPointObserverCache *MountPointObserverCache::instance()
0035 {
0036     return &s_MountPointObserverCache->instance;
0037 }
0038 
0039 MountPointObserver *MountPointObserverCache::observerForUrl(const QUrl &url)
0040 {
0041     QUrl cachedObserverUrl;
0042     // If the url is a local path we can extract the root dir by checking the mount points.
0043     if (url.isLocalFile()) {
0044         // Try to share the observer with other paths that have the same mount point.
0045         KMountPoint::Ptr mountPoint = KMountPoint::currentMountPoints().findByPath(url.toLocalFile());
0046         if (mountPoint) {
0047             cachedObserverUrl = QUrl::fromLocalFile(mountPoint->mountPoint());
0048         } else {
0049             // Even if determining the mount point failed, the observer might still
0050             // be able to retrieve information about the url.
0051             cachedObserverUrl = url;
0052         }
0053     } else {
0054         cachedObserverUrl = url;
0055     }
0056 
0057     MountPointObserver *observer = m_observerForMountPoint.value(cachedObserverUrl);
0058     if (!observer) {
0059         observer = new MountPointObserver(cachedObserverUrl, this);
0060         m_observerForMountPoint.insert(cachedObserverUrl, observer);
0061         m_mountPointForObserver.insert(observer, cachedObserverUrl);
0062         Q_ASSERT(m_observerForMountPoint.count() == m_mountPointForObserver.count());
0063 
0064         connect(observer, &MountPointObserver::destroyed, this, &MountPointObserverCache::slotObserverDestroyed);
0065 
0066         if (!m_updateTimer->isActive()) {
0067             m_updateTimer->start(60000); // 1 minute
0068         }
0069 
0070         connect(m_updateTimer, &QTimer::timeout, observer, &MountPointObserver::update);
0071     }
0072 
0073     return observer;
0074 }
0075 
0076 void MountPointObserverCache::slotObserverDestroyed(QObject *observer)
0077 {
0078     Q_ASSERT(m_mountPointForObserver.contains(observer));
0079     const QUrl &url = m_mountPointForObserver.value(observer);
0080     Q_ASSERT(m_observerForMountPoint.contains(url));
0081     m_observerForMountPoint.remove(url);
0082     m_mountPointForObserver.remove(observer);
0083 
0084     Q_ASSERT(m_observerForMountPoint.count() == m_mountPointForObserver.count());
0085 
0086     if (m_mountPointForObserver.isEmpty()) {
0087         m_updateTimer->stop();
0088     }
0089 }
0090 
0091 #include "moc_mountpointobservercache.cpp"