File indexing completed on 2025-03-23 04:34:33
0001 /** 0002 * SPDX-FileCopyrightText: 2019 Matthijs Tijink <matthijstijink@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 */ 0006 0007 #include "mprisremoteplayermediaplayer2player.h" 0008 #include "mprisremoteplayer.h" 0009 #include "mprisremoteplugin.h" 0010 0011 #include <QDBusMessage> 0012 0013 MprisRemotePlayerMediaPlayer2Player::MprisRemotePlayerMediaPlayer2Player(MprisRemotePlayer *parent, MprisRemotePlugin *plugin) 0014 : QDBusAbstractAdaptor{parent} 0015 , m_parent{parent} 0016 , m_plugin{plugin} 0017 , m_controlsChanged{false} 0018 , m_trackInfoChanged{false} 0019 , m_positionChanged{false} 0020 , m_volumeChanged{false} 0021 , m_playingChanged{false} 0022 { 0023 connect(m_parent, &MprisRemotePlayer::controlsChanged, this, &MprisRemotePlayerMediaPlayer2Player::controlsChanged); 0024 connect(m_parent, &MprisRemotePlayer::trackInfoChanged, this, &MprisRemotePlayerMediaPlayer2Player::trackInfoChanged); 0025 connect(m_parent, &MprisRemotePlayer::positionChanged, this, &MprisRemotePlayerMediaPlayer2Player::positionChanged); 0026 connect(m_parent, &MprisRemotePlayer::volumeChanged, this, &MprisRemotePlayerMediaPlayer2Player::volumeChanged); 0027 connect(m_parent, &MprisRemotePlayer::playingChanged, this, &MprisRemotePlayerMediaPlayer2Player::playingChanged); 0028 } 0029 0030 QString MprisRemotePlayerMediaPlayer2Player::PlaybackStatus() const 0031 { 0032 if (m_parent->playing()) { 0033 return QStringLiteral("Playing"); 0034 } else { 0035 return QStringLiteral("Paused"); 0036 } 0037 } 0038 0039 double MprisRemotePlayerMediaPlayer2Player::Rate() const 0040 { 0041 return 1.0; 0042 } 0043 0044 QVariantMap MprisRemotePlayerMediaPlayer2Player::Metadata() const 0045 { 0046 QVariantMap metadata; 0047 metadata[QStringLiteral("mpris:trackid")] = QVariant::fromValue<QDBusObjectPath>(QDBusObjectPath("/org/mpris/MediaPlayer2")); 0048 0049 if (m_parent->length() > 0) { 0050 metadata[QStringLiteral("mpris:length")] = QVariant::fromValue<qlonglong>(m_parent->length() * qlonglong(1000)); 0051 } 0052 if (!m_parent->title().isEmpty()) { 0053 metadata[QStringLiteral("xesam:title")] = m_parent->title(); 0054 } 0055 if (!m_parent->artist().isEmpty()) { 0056 metadata[QStringLiteral("xesam:artist")] = QStringList{m_parent->artist()}; 0057 } 0058 if (!m_parent->album().isEmpty()) { 0059 metadata[QStringLiteral("xesam:album")] = m_parent->album(); 0060 } 0061 return metadata; 0062 } 0063 0064 double MprisRemotePlayerMediaPlayer2Player::Volume() const 0065 { 0066 return m_parent->volume() / 100.0; 0067 } 0068 0069 void MprisRemotePlayerMediaPlayer2Player::setVolume(double volume) const 0070 { 0071 m_plugin->setPlayer(m_parent->identity()); 0072 m_plugin->setVolume(volume * 100.0 + 0.5); 0073 } 0074 0075 qlonglong MprisRemotePlayerMediaPlayer2Player::Position() const 0076 { 0077 return m_plugin->position() * qlonglong(1000); 0078 } 0079 0080 double MprisRemotePlayerMediaPlayer2Player::MinimumRate() const 0081 { 0082 return 1.0; 0083 } 0084 0085 double MprisRemotePlayerMediaPlayer2Player::MaximumRate() const 0086 { 0087 return 1.0; 0088 } 0089 0090 bool MprisRemotePlayerMediaPlayer2Player::CanGoNext() const 0091 { 0092 return m_parent->canGoNext(); 0093 } 0094 0095 bool MprisRemotePlayerMediaPlayer2Player::CanGoPrevious() const 0096 { 0097 return m_parent->canGoPrevious(); 0098 } 0099 0100 bool MprisRemotePlayerMediaPlayer2Player::CanPlay() const 0101 { 0102 return m_parent->canPlay(); 0103 } 0104 0105 bool MprisRemotePlayerMediaPlayer2Player::CanPause() const 0106 { 0107 return m_parent->canPause(); 0108 } 0109 0110 bool MprisRemotePlayerMediaPlayer2Player::CanSeek() const 0111 { 0112 return m_parent->canSeek(); 0113 } 0114 0115 bool MprisRemotePlayerMediaPlayer2Player::CanControl() const 0116 { 0117 return true; 0118 } 0119 0120 void MprisRemotePlayerMediaPlayer2Player::Next() 0121 { 0122 m_plugin->setPlayer(m_parent->identity()); 0123 m_plugin->sendAction(QStringLiteral("Next")); 0124 } 0125 0126 void MprisRemotePlayerMediaPlayer2Player::Previous() 0127 { 0128 m_plugin->setPlayer(m_parent->identity()); 0129 m_plugin->sendAction(QStringLiteral("Previous")); 0130 } 0131 0132 void MprisRemotePlayerMediaPlayer2Player::Pause() 0133 { 0134 m_plugin->setPlayer(m_parent->identity()); 0135 m_plugin->sendAction(QStringLiteral("Pause")); 0136 } 0137 0138 void MprisRemotePlayerMediaPlayer2Player::PlayPause() 0139 { 0140 m_plugin->setPlayer(m_parent->identity()); 0141 m_plugin->sendAction(QStringLiteral("PlayPause")); 0142 } 0143 0144 void MprisRemotePlayerMediaPlayer2Player::Stop() 0145 { 0146 m_plugin->setPlayer(m_parent->identity()); 0147 m_plugin->sendAction(QStringLiteral("Stop")); 0148 } 0149 0150 void MprisRemotePlayerMediaPlayer2Player::Play() 0151 { 0152 m_plugin->setPlayer(m_parent->identity()); 0153 m_plugin->sendAction(QStringLiteral("Play")); 0154 } 0155 0156 void MprisRemotePlayerMediaPlayer2Player::Seek(qlonglong Offset) 0157 { 0158 m_plugin->setPlayer(m_parent->identity()); 0159 m_plugin->seek(Offset); 0160 } 0161 0162 void MprisRemotePlayerMediaPlayer2Player::SetPosition(QDBusObjectPath /*TrackId*/, qlonglong Position) 0163 { 0164 m_plugin->setPlayer(m_parent->identity()); 0165 m_plugin->setPosition(Position / 1000); 0166 } 0167 0168 void MprisRemotePlayerMediaPlayer2Player::OpenUri(QString /*Uri*/) 0169 { 0170 } 0171 0172 void MprisRemotePlayerMediaPlayer2Player::controlsChanged() 0173 { 0174 m_controlsChanged = true; 0175 QMetaObject::invokeMethod(this, &MprisRemotePlayerMediaPlayer2Player::emitPropertiesChanged, Qt::QueuedConnection); 0176 } 0177 0178 void MprisRemotePlayerMediaPlayer2Player::playingChanged() 0179 { 0180 m_playingChanged = true; 0181 QMetaObject::invokeMethod(this, &MprisRemotePlayerMediaPlayer2Player::emitPropertiesChanged, Qt::QueuedConnection); 0182 } 0183 0184 void MprisRemotePlayerMediaPlayer2Player::positionChanged() 0185 { 0186 m_positionChanged = true; 0187 QMetaObject::invokeMethod(this, &MprisRemotePlayerMediaPlayer2Player::emitPropertiesChanged, Qt::QueuedConnection); 0188 } 0189 0190 void MprisRemotePlayerMediaPlayer2Player::trackInfoChanged() 0191 { 0192 m_trackInfoChanged = true; 0193 QMetaObject::invokeMethod(this, &MprisRemotePlayerMediaPlayer2Player::emitPropertiesChanged, Qt::QueuedConnection); 0194 } 0195 0196 void MprisRemotePlayerMediaPlayer2Player::volumeChanged() 0197 { 0198 m_volumeChanged = true; 0199 QMetaObject::invokeMethod(this, &MprisRemotePlayerMediaPlayer2Player::emitPropertiesChanged, Qt::QueuedConnection); 0200 } 0201 0202 void MprisRemotePlayerMediaPlayer2Player::emitPropertiesChanged() 0203 { 0204 // Always invoked "queued", so we can send all changes at once 0205 // Check if things really changed (we might get called multiple times) 0206 if (!m_controlsChanged && !m_trackInfoChanged && !m_positionChanged && !m_volumeChanged && !m_playingChanged) 0207 return; 0208 0209 // Qt doesn't automatically send the "org.freedesktop.DBus.Properties PropertiesChanged" signal, so do it manually 0210 // With the current setup, it's hard to discover what properties changed. So just send all properties (not too large, usually) 0211 QVariantMap properties; 0212 if (m_trackInfoChanged) { 0213 properties[QStringLiteral("Metadata")] = Metadata(); 0214 } 0215 if (m_trackInfoChanged || m_positionChanged) { 0216 properties[QStringLiteral("Position")] = Position(); 0217 } 0218 0219 if (m_controlsChanged) { 0220 properties[QStringLiteral("CanGoNext")] = CanGoNext(); 0221 properties[QStringLiteral("CanGoPrevious")] = CanGoPrevious(); 0222 properties[QStringLiteral("CanPlay")] = CanPlay(); 0223 properties[QStringLiteral("CanPause")] = CanPause(); 0224 properties[QStringLiteral("CanSeek")] = CanSeek(); 0225 } 0226 0227 if (m_playingChanged) { 0228 properties[QStringLiteral("PlaybackStatus")] = PlaybackStatus(); 0229 } 0230 0231 if (m_volumeChanged) { 0232 properties[QStringLiteral("Volume")] = Volume(); 0233 } 0234 0235 QList<QVariant> args; 0236 args.push_back(QVariant(QStringLiteral("org.mpris.MediaPlayer2.Player"))); 0237 args.push_back(properties); 0238 args.push_back(QStringList{}); 0239 QDBusMessage message = QDBusMessage::createSignal(QStringLiteral("/org/mpris/MediaPlayer2"), 0240 QStringLiteral("org.freedesktop.DBus.Properties"), 0241 QStringLiteral("PropertiesChanged")); 0242 message.setArguments(args); 0243 // Send it over the correct DBus connection 0244 m_parent->dbus().send(message); 0245 0246 if (m_positionChanged || m_trackInfoChanged) { 0247 Q_EMIT Seeked(Position()); 0248 } 0249 0250 m_controlsChanged = false; 0251 m_trackInfoChanged = false; 0252 m_playingChanged = false; 0253 m_positionChanged = false; 0254 m_volumeChanged = false; 0255 } 0256 0257 #include "moc_mprisremoteplayermediaplayer2player.cpp"