1 /* 2 * Strawberry Music Player 3 * This file was part of Clementine. 4 * Copyright 2010, David Sansome <me@davidsansome.com> 5 * Copyright 2018-2021, Jonas Kvinge <jonas@jkvinge.net> 6 * 7 * Strawberry is free software: you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation, either version 3 of the License, or 10 * (at your option) any later version. 11 * 12 * Strawberry is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with Strawberry. If not, see <http://www.gnu.org/licenses/>. 19 * 20 */ 21 22 #ifndef MPRIS2_H 23 #define MPRIS2_H 24 25 #include "config.h" 26 27 #include <QtGlobal> 28 #include <QObject> 29 #include <QList> 30 #include <QMap> 31 #include <QSet> 32 #include <QMetaType> 33 #include <QVariant> 34 #include <QString> 35 #include <QStringList> 36 #include <QtDBus> 37 #include <QDBusArgument> 38 #include <qdbusextratypes.h> 39 #include <QJsonObject> 40 41 #include "engine/engine_fwd.h" 42 #include "covermanager/albumcoverloaderresult.h" 43 44 class Application; 45 class Song; 46 class Playlist; 47 48 typedef QList<QVariantMap> TrackMetadata; 49 typedef QList<QDBusObjectPath> Track_Ids; 50 Q_DECLARE_METATYPE(TrackMetadata) 51 52 struct MprisPlaylist { 53 QDBusObjectPath id; 54 QString name; 55 QString icon; // Uri 56 }; 57 typedef QList<MprisPlaylist> MprisPlaylistList; 58 Q_DECLARE_METATYPE(MprisPlaylist) 59 Q_DECLARE_METATYPE(MprisPlaylistList) 60 61 struct MaybePlaylist { 62 bool valid; 63 MprisPlaylist playlist; 64 }; 65 Q_DECLARE_METATYPE(MaybePlaylist) 66 67 QDBusArgument &operator<<(QDBusArgument &arg, const MprisPlaylist &playlist); 68 const QDBusArgument &operator>>(const QDBusArgument &arg, MprisPlaylist &playlist); 69 70 QDBusArgument &operator<<(QDBusArgument &arg, const MaybePlaylist &playlist); 71 const QDBusArgument &operator>>(const QDBusArgument &arg, MaybePlaylist &playlist); 72 73 namespace mpris { 74 75 class Mpris2 : public QObject { 76 Q_OBJECT 77 78 public: 79 explicit Mpris2(Application *app, QObject *parent = nullptr); 80 81 // org.mpris.MediaPlayer2 MPRIS 2.0 Root interface 82 Q_PROPERTY(bool CanQuit READ CanQuit) 83 Q_PROPERTY(bool CanRaise READ CanRaise) 84 Q_PROPERTY(bool HasTrackList READ HasTrackList) 85 Q_PROPERTY(QString Identity READ Identity) 86 Q_PROPERTY(QString DesktopEntry READ DesktopEntry) 87 Q_PROPERTY(QStringList SupportedUriSchemes READ SupportedUriSchemes) 88 Q_PROPERTY(QStringList SupportedMimeTypes READ SupportedMimeTypes) 89 90 // org.mpris.MediaPlayer2 MPRIS 2.2 Root interface 91 Q_PROPERTY(bool CanSetFullscreen READ CanSetFullscreen) 92 Q_PROPERTY(bool Fullscreen READ Fullscreen WRITE SetFullscreen) 93 94 // org.mpris.MediaPlayer2.Player MPRIS 2.0 Player interface 95 Q_PROPERTY(QString PlaybackStatus READ PlaybackStatus) 96 Q_PROPERTY(QString LoopStatus READ LoopStatus WRITE SetLoopStatus) 97 Q_PROPERTY(double Rate READ Rate WRITE SetRate) 98 Q_PROPERTY(bool Shuffle READ Shuffle WRITE SetShuffle) 99 Q_PROPERTY(QVariantMap Metadata READ Metadata) 100 Q_PROPERTY(double Volume READ Volume WRITE SetVolume) 101 Q_PROPERTY(qint64 Position READ Position) 102 Q_PROPERTY(double MinimumRate READ MinimumRate) 103 Q_PROPERTY(double MaximumRate READ MaximumRate) 104 Q_PROPERTY(bool CanGoNext READ CanGoNext) 105 Q_PROPERTY(bool CanGoPrevious READ CanGoPrevious) 106 Q_PROPERTY(bool CanPlay READ CanPlay) 107 Q_PROPERTY(bool CanPause READ CanPause) 108 Q_PROPERTY(bool CanSeek READ CanSeek) 109 Q_PROPERTY(bool CanControl READ CanControl) 110 111 // org.mpris.MediaPlayer2.TrackList MPRIS 2.0 Player interface 112 Q_PROPERTY(Track_Ids Tracks READ Tracks) 113 Q_PROPERTY(bool CanEditTracks READ CanEditTracks) 114 115 // org.mpris.MediaPlayer2.Playlists MPRIS 2.1 Playlists interface 116 Q_PROPERTY(quint32 PlaylistCount READ PlaylistCount) 117 Q_PROPERTY(QStringList Orderings READ Orderings) 118 Q_PROPERTY(MaybePlaylist ActivePlaylist READ ActivePlaylist) 119 120 // Root Properties 121 bool CanQuit() const; 122 bool CanRaise() const; 123 bool HasTrackList() const; 124 QString Identity() const; 125 QString DesktopEntry() const; 126 QStringList SupportedUriSchemes() const; 127 QStringList SupportedMimeTypes() const; 128 129 // Root Properties added in MPRIS 2.2 CanSetFullscreen()130 bool CanSetFullscreen() const { return false; } Fullscreen()131 bool Fullscreen() const { return false; } SetFullscreen(bool)132 void SetFullscreen(bool) {} 133 134 // Methods 135 void Raise(); 136 void Quit(); 137 138 // Player Properties 139 QString PlaybackStatus() const; 140 QString LoopStatus() const; 141 void SetLoopStatus(const QString &value); 142 double Rate() const; 143 void SetRate(double rate); 144 bool Shuffle() const; 145 void SetShuffle(bool enable); 146 QVariantMap Metadata() const; 147 double Volume() const; 148 void SetVolume(double value); 149 qint64 Position() const; 150 double MaximumRate() const; 151 double MinimumRate() const; 152 bool CanGoNext() const; 153 bool CanGoPrevious() const; 154 bool CanPlay() const; 155 bool CanPause() const; 156 bool CanSeek() const; 157 bool CanControl() const; 158 159 // Methods 160 void Next(); 161 void Previous(); 162 void Pause(); 163 void PlayPause(); 164 void Stop(); 165 void Play(); 166 void Seek(qint64 offset); 167 void SetPosition(const QDBusObjectPath &trackId, qint64 offset); 168 void OpenUri(const QString &uri); 169 170 // TrackList Properties 171 Track_Ids Tracks() const; 172 bool CanEditTracks() const; 173 174 // Methods 175 TrackMetadata GetTracksMetadata(const Track_Ids &tracks) const; 176 void AddTrack(const QString &uri, const QDBusObjectPath &afterTrack, bool setAsCurrent); 177 void RemoveTrack(const QDBusObjectPath &trackId); 178 void GoTo(const QDBusObjectPath &trackId); 179 180 // Playlist Properties 181 quint32 PlaylistCount() const; 182 QStringList Orderings() const; 183 MaybePlaylist ActivePlaylist() const; 184 185 // Methods 186 void ActivatePlaylist(const QDBusObjectPath &playlist_id); 187 MprisPlaylistList GetPlaylists(quint32 index, quint32 max_count, const QString &order, bool reverse_order); 188 189 signals: 190 // Player 191 void Seeked(qint64 position); 192 193 // TrackList 194 void TrackListReplaced(Track_Ids Tracks, QDBusObjectPath CurrentTrack); 195 void TrackAdded(TrackMetadata Metadata, QDBusObjectPath AfterTrack); 196 void TrackRemoved(QDBusObjectPath trackId); 197 void TrackMetadataChanged(QDBusObjectPath trackId, TrackMetadata metadata); 198 199 void RaiseMainWindow(); 200 201 // Playlist 202 void PlaylistChanged(MprisPlaylist playlist); 203 204 private slots: 205 void AlbumCoverLoaded(const Song &song, const AlbumCoverLoaderResult &result = AlbumCoverLoaderResult()); 206 void EngineStateChanged(Engine::State newState); 207 void VolumeChanged(); 208 209 void PlaylistManagerInitialized(); 210 void CurrentSongChanged(const Song &song); 211 void ShuffleModeChanged(); 212 void RepeatModeChanged(); 213 void PlaylistChangedSlot(Playlist *playlist); 214 void PlaylistCollectionChanged(Playlist *playlist); 215 216 private: 217 void EmitNotification(const QString &name); 218 void EmitNotification(const QString &name, const QVariant &val); 219 void EmitNotification(const QString &name, const QVariant &val, const QString &mprisEntity); 220 221 QString PlaybackStatus(Engine::State state) const; 222 223 QString current_track_id() const; 224 225 bool CanSeek(Engine::State state) const; 226 227 QString DesktopEntryAbsolutePath() const; 228 229 private: 230 static const char *kMprisObjectPath; 231 static const char *kServiceName; 232 static const char *kFreedesktopPath; 233 234 Application *app_; 235 236 QString app_name_; 237 QStringList data_dirs_; 238 QStringList desktop_files_; 239 QString desktop_file_; 240 QVariantMap last_metadata_; 241 242 }; 243 244 } // namespace mpris 245 246 247 #endif // MPRIS2_H 248