File indexing completed on 2025-01-05 04:25:59

0001 /****************************************************************************************
0002  * Copyright (c) 2006-2007 Maximilian Kossick <maximilian.kossick@googlemail.com>       *
0003  *                                                                                      *
0004  * This program is free software; you can redistribute it and/or modify it under        *
0005  * the terms of the GNU General Public License as published by the Free Software        *
0006  * Foundation; either version 2 of the License, or (at your option) any later           *
0007  * version.                                                                             *
0008  *                                                                                      *
0009  * This program is distributed in the hope that it will be useful, but WITHOUT ANY      *
0010  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A      *
0011  * PARTICULAR PURPOSE. See the GNU General Public License for more details.             *
0012  *                                                                                      *
0013  * You should have received a copy of the GNU General Public License along with         *
0014  * this program.  If not, see <http://www.gnu.org/licenses/>.                           *
0015  ****************************************************************************************/
0016 
0017 #ifndef AMAROK_MOUNTPOINTMANAGER_H
0018 #define AMAROK_MOUNTPOINTMANAGER_H
0019 
0020 #include "core-impl/collections/db/sql/amarok_sqlcollection_export.h"
0021 
0022 #include <KSharedConfig>
0023 
0024 #include <QMap>
0025 #include <QMutex>
0026 #include <QObject>
0027 #include <QSharedPointer>
0028 #include <QUrl>
0029 
0030 class DeviceHandler;
0031 class DeviceHandlerFactory;
0032 class SqlStorage;
0033 class QUrl;
0034 namespace Solid {
0035     class Device;
0036 }
0037 
0038 typedef QList<int> IdList;
0039 typedef QList<DeviceHandlerFactory*> FactoryList;
0040 typedef QMap<int, DeviceHandler*> HandlerMap;
0041 
0042 class DeviceHandlerFactory : public QObject
0043 {
0044     Q_OBJECT
0045 
0046 public:
0047     explicit DeviceHandlerFactory( QObject *parent ) : QObject( parent ) {}
0048     ~DeviceHandlerFactory() override {}
0049 
0050     /**
0051      * checks whether a DeviceHandler subclass can handle a given Medium.
0052      * @param device the connected solid volume
0053      * @return true if the DeviceHandler implementation can handle the medium,
0054      * false otherwise
0055      */
0056     virtual bool canHandle( const Solid::Device &device ) const = 0;
0057 
0058     /**
0059      * tells the MountPointManager whether it makes sense to ask the factory to
0060      * create a Devicehandler when a new Medium was connected
0061      * @return true if the factory can create DeviceHandlers from Medium instances
0062      */
0063     virtual bool canCreateFromMedium() const = 0;
0064 
0065     /**
0066      * creates a DeviceHandler which represents the Medium.
0067      * @param device the Volume for which a DeviceHandler is required
0068      * @param udi the device UUID
0069      * @param s SQL storage
0070      * @return a DeviceHandler or 0 if the factory cannot handle the Medium
0071      */
0072     virtual DeviceHandler* createHandler( const Solid::Device &device, const QString &udi, QSharedPointer<SqlStorage> s ) const = 0;
0073 
0074     virtual bool canCreateFromConfig() const = 0;
0075 
0076     virtual DeviceHandler* createHandler( const KSharedConfigPtr &c, QSharedPointer<SqlStorage> s ) const = 0;
0077 
0078     /**
0079      * returns the type of the DeviceHandler. Should be the same as the value used in
0080      * ~/.config/amarokrc
0081      * @return a QString describing the type of the DeviceHandler
0082      */
0083     virtual QString type() const = 0;
0084 };
0085 
0086 class DeviceHandler
0087 {
0088 public:
0089     DeviceHandler() {}
0090     virtual ~DeviceHandler() {}
0091 
0092 
0093     virtual bool isAvailable() const = 0;
0094 
0095     /**
0096      * returns the type of the DeviceHandler. Should be the same as the value used in
0097      * ~/.kde/share/config/amarokrc
0098      * @return a QString describing the type of the DeviceHandler
0099      */
0100     virtual QString type() const = 0;
0101 
0102     /**
0103      * returns an absolute path which is guaranteed to be playable by amarok's current engine. (based on an
0104      * idea by andrewt512: this method would only be called when we actually want to play the file, not when we
0105      * simply want to show it to the user. It could for example download a file using KIO and return a path to a
0106      * temporary file. Needs some more thought and is not actually used at the moment.
0107      * @param absoluteUrl
0108      * @param relativeUrl
0109      */
0110     virtual void getPlayableURL( QUrl &absoluteUrl, const QUrl &relativeUrl ) = 0;
0111 
0112     /**
0113      * builds an absolute path from a relative path and DeviceHandler specific information. The absolute path
0114      * is not necessarily playable! (based on an idea by andrewt512: allows better handling of files stored in remote  * collections. this method would return a "pretty" URL which might not be playable by amarok's engines.
0115      * @param absoluteUrl the not necessarily playbale absolute path
0116      * @param relativeUrl the device specific relative path
0117      */
0118     virtual void getURL( QUrl &absoluteUrl, const QUrl &relativeUrl ) = 0;
0119 
0120     /**
0121      * retrieves the unique database id of a given Medium. Implementations are responsible
0122      * for generating a (sufficiently) unique value which identifies the Medium.
0123      * Additionally, implementations must recognize unknown mediums and store the necessary
0124      * information to recognize them the next time they are connected in the database.
0125      * @return unique identifier which can be used as a foreign key to the media table.
0126      */
0127     virtual int getDeviceID() = 0;
0128 
0129     virtual const QString &getDevicePath() const = 0;
0130 
0131     /**
0132      * allows MountPointManager to check if a device handler handles a specific medium.
0133      * @param udi
0134      * @return true if the device handler handles the Medium m
0135      */
0136     virtual bool deviceMatchesUdi( const QString &udi ) const = 0;
0137 };
0138 
0139 /**
0140  *  @author Maximilian Kossick <maximilian.kossick@googlemail.com>
0141  */
0142 class AMAROK_SQLCOLLECTION_EXPORT MountPointManager : public QObject
0143 {
0144     Q_OBJECT
0145 
0146 public:
0147     MountPointManager( QObject *parent, QSharedPointer<SqlStorage> storage );
0148     ~MountPointManager() override;
0149 
0150     /**
0151      *
0152      * @param url
0153      * @return
0154      */
0155     virtual int getIdForUrl( const QUrl &url );
0156 
0157     /**
0158      *
0159      * @param id
0160      * @return
0161      */
0162     virtual QString getMountPointForId( const int id ) const;
0163 
0164     /**
0165      * builds the absolute path from the mount point of the medium and the given relative
0166      * path.
0167      * @param deviceId the medium(device)'s unique id
0168      * @param relativePath relative path on the medium
0169      * @return the absolute path
0170      */
0171     virtual QString getAbsolutePath( const int deviceId, const QString& relativePath ) const;
0172 
0173     /**
0174      * calculates a file's/directory's relative path on a given device.
0175      * @param deviceId the unique id which identifies the device the file/directory is supposed to be on
0176      * @param absolutePath the file's/directory's absolute path
0177      */
0178     virtual QString getRelativePath( const int deviceId, const QString& absolutePath ) const;
0179 
0180     /**
0181      * allows calling code to access the ids of all active devices
0182      * @return the ids of all devices which are currently mounted or otherwise accessible
0183      */
0184     virtual IdList getMountedDeviceIds() const;
0185 
0186     virtual QStringList collectionFolders() const;
0187     virtual void setCollectionFolders( const QStringList &folders );
0188 
0189 Q_SIGNALS:
0190     void deviceAdded( int id );
0191     void deviceRemoved( int id );
0192 
0193 private:
0194     void createDeviceFactories();
0195 
0196     /**
0197      * Old Amarok versions used to have "Use MusicLocation" config option which caused
0198      * problems (bug 316216). This method converts out of it and needs to be run after
0199      * MountPointManager has initialized.
0200      */
0201     void handleMusicLocation();
0202 
0203     /**
0204      * checks whether a medium identified by its unique database id is currently mounted.
0205      * Note: does not handle deviceId = -1! It only checks real devices
0206      * @param deviceId the mediums unique id
0207      * @return true if the medium is mounted, false otherwise
0208      */
0209     bool isMounted ( const int deviceId ) const;
0210 
0211     QSharedPointer<SqlStorage> m_storage;
0212     /**
0213      * maps a device id to a mount point. does only work for mountable filesystems and needs to be
0214      * changed for the real Dynamic Collection implementation.
0215      */
0216     HandlerMap m_handlerMap;
0217     mutable QMutex m_handlerMapMutex;
0218     FactoryList m_mediumFactories;
0219     FactoryList m_remoteFactories;
0220     bool m_ready;
0221 
0222 //Solid specific
0223     void createHandlerFromDevice( const Solid::Device &device, const QString &udi );
0224 private Q_SLOTS:
0225     void slotDeviceAdded( const QString &udi );
0226     void slotDeviceRemoved( const QString &udi );
0227 
0228 };
0229 
0230 #endif