File indexing completed on 2025-01-19 04:24:32
0001 /**************************************************************************************** 0002 * Copyright (c) 2006 Andy Kelk <andy@mopoke.co.uk> * 0003 * Copyright (c) 2008 Alejandro Wainzinger <aikawarazuni@gmail.com> * 0004 * Copyright (c) 2009 Mark Kretschmann <kretschmann@kde.org> * 0005 * * 0006 * This program is free software; you can redistribute it and/or modify it under * 0007 * the terms of the GNU General Public License as published by the Free Software * 0008 * Foundation; either version 2 of the License, or (at your option) version 3 or * 0009 * any later version accepted by the membership of KDE e.V. (or its successor approved * 0010 * by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of * 0011 * version 3 of the license. * 0012 * * 0013 * This program is distributed in the hope that it will be useful, but WITHOUT ANY * 0014 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * 0015 * PARTICULAR PURPOSE. See the GNU General Public License for more details. * 0016 * * 0017 * You should have received a copy of the GNU General Public License along with * 0018 * this program. If not, see <http://www.gnu.org/licenses/>. * 0019 ****************************************************************************************/ 0020 0021 #ifndef MTPHANDLER_H 0022 #define MTPHANDLER_H 0023 0024 #include <libmtp.h> 0025 0026 #include "MtpPlaylistCapability.h" 0027 #include "MtpReadCapability.h" 0028 #include "MtpWriteCapability.h" 0029 0030 #include "MediaDeviceMeta.h" 0031 #include "MediaDeviceHandler.h" 0032 0033 #include <KIO/Job> 0034 #include <ThreadWeaver/Job> 0035 #include <ThreadWeaver/Queue> 0036 0037 #include <QObject> 0038 #include <QMap> 0039 #include <QMultiMap> 0040 #include <QMutex> 0041 #include <QSet> 0042 #include <QTemporaryDir> 0043 #include <QTemporaryFile> 0044 0045 0046 class QString; 0047 class QMutex; 0048 class QStringList; 0049 0050 namespace Collections { 0051 class MtpCollection; 0052 } 0053 0054 namespace Meta 0055 { 0056 typedef QMultiMap<QString, Meta::TrackPtr> TitleMap; 0057 class WorkerThread; 0058 0059 /* The libmtp backend for all Mtp calls */ 0060 class MtpHandler : public MediaDeviceHandler 0061 { 0062 Q_OBJECT 0063 0064 public: 0065 explicit MtpHandler( Collections::MtpCollection *mc ); 0066 ~MtpHandler() override; 0067 0068 friend class WorkerThread; 0069 0070 void init() override; // collection 0071 bool isWritable() const override; 0072 0073 void getCopyableUrls( const Meta::TrackList &tracks ) override; 0074 0075 QString prettyName() const override; 0076 0077 void prepareToPlay( Meta::MediaDeviceTrackPtr &track ) override; 0078 0079 /// Capability-related methods 0080 0081 bool hasCapabilityInterface( Handler::Capability::Type type ) const override; 0082 Handler::Capability* createCapabilityInterface( Handler::Capability::Type type ) override; 0083 0084 friend class Handler::MtpPlaylistCapability; 0085 friend class Handler::MtpReadCapability; 0086 friend class Handler::MtpWriteCapability; 0087 0088 protected: 0089 /* Parsing of Tracks on Device */ 0090 virtual void prepareToParseTracks(); 0091 virtual bool isEndOfParseTracksList(); 0092 virtual void prepareToParseNextTrack(); 0093 virtual void nextTrackToParse(); 0094 0095 virtual void setAssociateTrack( const Meta::MediaDeviceTrackPtr track ); 0096 0097 virtual void prepareToParsePlaylists(); 0098 virtual bool isEndOfParsePlaylistsList(); 0099 virtual void prepareToParseNextPlaylist(); 0100 virtual void nextPlaylistToParse(); 0101 0102 virtual bool shouldNotParseNextPlaylist(); 0103 0104 virtual void prepareToParsePlaylistTracks(); 0105 virtual bool isEndOfParsePlaylist(); 0106 virtual void prepareToParseNextPlaylistTrack(); 0107 virtual void nextPlaylistTrackToParse(); 0108 0109 virtual QStringList supportedFormats(); 0110 0111 virtual void findPathToCopy( const Meta::TrackPtr &srcTrack, const Meta::MediaDeviceTrackPtr &destTrack ); 0112 virtual bool libCopyTrack( const Meta::TrackPtr &srcTrack, Meta::MediaDeviceTrackPtr &destTrack ); 0113 virtual bool libDeleteTrackFile( const Meta::MediaDeviceTrackPtr &track ); 0114 virtual void libCreateTrack( const Meta::MediaDeviceTrackPtr &track ); 0115 virtual void libDeleteTrack( const Meta::MediaDeviceTrackPtr &track ); 0116 0117 virtual Meta::MediaDeviceTrackPtr libGetTrackPtrForTrackStruct(); 0118 0119 virtual QString libGetPlaylistName(); 0120 virtual void setAssociatePlaylist( const Playlists::MediaDevicePlaylistPtr &playlist ); 0121 virtual void libSavePlaylist( const Playlists::MediaDevicePlaylistPtr &playlist, const QString& name ); 0122 virtual void deletePlaylist( const Playlists::MediaDevicePlaylistPtr &playlist ); 0123 virtual void renamePlaylist( const Playlists::MediaDevicePlaylistPtr &playlist ); 0124 0125 virtual void addTrackInDB( const Meta::MediaDeviceTrackPtr &track ) { Q_UNUSED( track ) } 0126 virtual void removeTrackFromDB( const Meta::MediaDeviceTrackPtr &track ) { Q_UNUSED( track ) } 0127 virtual void setDatabaseChanged(); 0128 0129 virtual QString libGetTitle( const Meta::MediaDeviceTrackPtr &track ); 0130 virtual QString libGetAlbum( const Meta::MediaDeviceTrackPtr &track ); 0131 virtual QString libGetArtist( const Meta::MediaDeviceTrackPtr &track ); 0132 virtual QString libGetAlbumArtist( const Meta::MediaDeviceTrackPtr &track ); 0133 virtual QString libGetComposer( const Meta::MediaDeviceTrackPtr &track ); 0134 virtual QString libGetGenre( const Meta::MediaDeviceTrackPtr &track ); 0135 virtual int libGetYear( const Meta::MediaDeviceTrackPtr &track ); 0136 virtual qint64 libGetLength( const Meta::MediaDeviceTrackPtr &track ); 0137 virtual int libGetTrackNumber( const Meta::MediaDeviceTrackPtr &track ); 0138 virtual QString libGetComment( const Meta::MediaDeviceTrackPtr &track ); 0139 virtual int libGetDiscNumber( const Meta::MediaDeviceTrackPtr &track ); 0140 virtual int libGetBitrate( const Meta::MediaDeviceTrackPtr &track ); 0141 virtual int libGetSamplerate( const Meta::MediaDeviceTrackPtr &track ); 0142 virtual qreal libGetBpm( const Meta::MediaDeviceTrackPtr &track ); 0143 virtual int libGetFileSize( const Meta::MediaDeviceTrackPtr &track ); 0144 virtual int libGetPlayCount( const Meta::MediaDeviceTrackPtr &track ); 0145 virtual QDateTime libGetLastPlayed( const Meta::MediaDeviceTrackPtr &track ); 0146 virtual int libGetRating( const Meta::MediaDeviceTrackPtr &track ) ; 0147 virtual QString libGetType( const Meta::MediaDeviceTrackPtr &track ); 0148 virtual QUrl libGetPlayableUrl( const Meta::MediaDeviceTrackPtr &track ); 0149 0150 virtual float usedCapacity() const; 0151 virtual float totalCapacity() const; 0152 0153 virtual void libSetTitle( Meta::MediaDeviceTrackPtr &track, const QString& title ); 0154 virtual void libSetAlbum( Meta::MediaDeviceTrackPtr &track, const QString& album ); 0155 virtual void libSetArtist( Meta::MediaDeviceTrackPtr &track, const QString& artist ); 0156 virtual void libSetAlbumArtist( Meta::MediaDeviceTrackPtr &track, const QString& albumArtist ); 0157 virtual void libSetComposer( Meta::MediaDeviceTrackPtr &track, const QString& composer ); 0158 virtual void libSetGenre( Meta::MediaDeviceTrackPtr &track, const QString& genre ); 0159 virtual void libSetYear( Meta::MediaDeviceTrackPtr &track, const QString& year ); 0160 virtual void libSetLength( Meta::MediaDeviceTrackPtr &track, int length ); 0161 virtual void libSetTrackNumber( Meta::MediaDeviceTrackPtr &track, int tracknum ); 0162 virtual void libSetComment( Meta::MediaDeviceTrackPtr &track, const QString& comment ); 0163 virtual void libSetDiscNumber( Meta::MediaDeviceTrackPtr &track, int discnum ); 0164 virtual void libSetBitrate( Meta::MediaDeviceTrackPtr &track, int bitrate ); 0165 virtual void libSetSamplerate( Meta::MediaDeviceTrackPtr &track, int samplerate ); 0166 virtual void libSetBpm( Meta::MediaDeviceTrackPtr &track, qreal bpm ); 0167 virtual void libSetFileSize( Meta::MediaDeviceTrackPtr &track, int filesize ); 0168 virtual void libSetPlayCount( Meta::MediaDeviceTrackPtr &track, int playcount ); 0169 virtual void libSetLastPlayed( Meta::MediaDeviceTrackPtr &track, const QDateTime &lastplayed ); 0170 virtual void libSetRating( Meta::MediaDeviceTrackPtr &track, int rating ) ; 0171 virtual void libSetType( Meta::MediaDeviceTrackPtr &track, const QString& type ); 0172 virtual void libSetPlayableUrl( Meta::MediaDeviceTrackPtr &destTrack, const Meta::TrackPtr &srcTrack ); 0173 0174 virtual void prepareToCopy() {} 0175 virtual void prepareToDelete() {} 0176 0177 /// libmtp-specific 0178 private Q_SLOTS: 0179 void slotDeviceMatchSucceeded( ThreadWeaver::JobPointer job ); 0180 void slotDeviceMatchFailed( ThreadWeaver::JobPointer job ); 0181 0182 private: 0183 bool iterateRawDevices( int numrawdevices, LIBMTP_raw_device_t* rawdevices ); 0184 void getDeviceInfo(); 0185 0186 void terminate(); 0187 0188 int getTrackToFile( const uint32_t id, const QString & filename ); 0189 0190 // Some internal stuff that must be public due to libmtp being in C 0191 static int progressCallback( uint64_t const sent, uint64_t const total, void const * const data ); 0192 0193 // file-copying related functions 0194 uint32_t checkFolderStructure( const Meta::TrackPtr track, bool create ); 0195 uint32_t getDefaultParentId( void ); 0196 uint32_t folderNameToID( char *name, LIBMTP_folder_t *folderlist ); 0197 uint32_t subfolderNameToID( const char *name, LIBMTP_folder_t *folderlist, uint32_t parent_id ); 0198 uint32_t createFolder( const char *name, uint32_t parent_id ); 0199 void updateFolders( void ); 0200 0201 QString setTempFile( Meta::MediaDeviceTrackPtr &track, const QString &format ); 0202 0203 virtual void updateTrack( Meta::MediaDeviceTrackPtr &track ); 0204 0205 // mtp database 0206 LIBMTP_mtpdevice_t *m_device; 0207 0208 float m_capacity; 0209 0210 QMap<int, QString> mtpFileTypes; 0211 0212 uint32_t m_default_parent_folder; 0213 LIBMTP_folder_t *m_folders; 0214 QString m_folderStructure; 0215 QString m_format; 0216 QString m_name; 0217 QStringList m_supportedFiles; 0218 0219 QMutex m_critical_mutex; 0220 0221 // KIO-related Vars (to be moved elsewhere eventually) 0222 bool m_isCanceled; 0223 bool m_wait; 0224 bool m_dbChanged; 0225 0226 LIBMTP_track_t* m_currentTrackList; 0227 LIBMTP_track_t* m_currentTrack; 0228 LIBMTP_playlist_t* m_currentPlaylistList; 0229 LIBMTP_playlist_t* m_currentPlaylist; 0230 0231 QHash<Playlists::MediaDevicePlaylistPtr, LIBMTP_playlist_t*> m_mtpPlaylisthash; 0232 0233 uint32_t m_trackcounter; 0234 0235 // Hash that associates an LIBMTP_track_t* to every Track* 0236 0237 QHash<Meta::MediaDeviceTrackPtr, LIBMTP_track_t*> m_mtpTrackHash; 0238 0239 // Keeps track of which tracks have been copied/cached for playing 0240 0241 QHash<Meta::MediaDeviceTrackPtr, QTemporaryFile*> m_cachedTracks; 0242 0243 // Maps id's to tracks 0244 0245 QHash<uint32_t, LIBMTP_track_t*> m_idTrackHash; 0246 0247 // parentid calculated for new track copied to device 0248 0249 uint32_t m_copyParentId; 0250 0251 // Used as temporary location for copying files from mtp 0252 0253 QTemporaryDir *m_tempDir; 0254 }; 0255 0256 class WorkerThread : public QObject, public ThreadWeaver::Job 0257 { 0258 Q_OBJECT 0259 0260 public: 0261 WorkerThread( int numrawdevices, LIBMTP_raw_device_t* rawdevices, MtpHandler* handler ); 0262 ~WorkerThread() override; 0263 0264 bool success() const override; 0265 0266 protected: 0267 void run(ThreadWeaver::JobPointer self = QSharedPointer<ThreadWeaver::Job>(), ThreadWeaver::Thread *thread = nullptr) override; 0268 void defaultBegin(const ThreadWeaver::JobPointer& job, ThreadWeaver::Thread *thread) override; 0269 void defaultEnd(const ThreadWeaver::JobPointer& job, ThreadWeaver::Thread *thread) override; 0270 0271 Q_SIGNALS: 0272 /** This signal is emitted when this job is being processed by a thread. */ 0273 void started(ThreadWeaver::JobPointer); 0274 /** This signal is emitted when the job has been finished (no matter if it succeeded or not). */ 0275 void done(ThreadWeaver::JobPointer); 0276 /** This job has failed. 0277 * This signal is emitted when success() returns false after the job is executed. */ 0278 void failed(ThreadWeaver::JobPointer); 0279 0280 private: 0281 bool m_success; 0282 int m_numrawdevices; 0283 LIBMTP_raw_device_t* m_rawdevices; 0284 MtpHandler *m_handler; 0285 }; 0286 0287 } 0288 #endif