diff options
| author | Javier <dev.git@javispedro.com> | 2014-12-12 02:33:03 +0100 |
|---|---|---|
| committer | Javier <dev.git@javispedro.com> | 2014-12-12 02:33:03 +0100 |
| commit | 617c632f245c44151f0e17917f9e158403c444c6 (patch) | |
| tree | a1e9ed4bf8f5471a1ac2a4254efc0680feaee1dc | |
| parent | 8c86d80504bec6524d9c5006d168438500130ca5 (diff) | |
move the mpris tracking into musicmanager
| -rw-r--r-- | daemon/dbusconnector.cpp | 24 | ||||
| -rw-r--r-- | daemon/dbusconnector.h | 11 | ||||
| -rw-r--r-- | daemon/manager.cpp | 69 | ||||
| -rw-r--r-- | daemon/manager.h | 15 | ||||
| -rw-r--r-- | daemon/musicmanager.cpp | 159 | ||||
| -rw-r--r-- | daemon/musicmanager.h | 14 |
6 files changed, 148 insertions, 144 deletions
diff --git a/daemon/dbusconnector.cpp b/daemon/dbusconnector.cpp index 8bde322..1f3ffc2 100644 --- a/daemon/dbusconnector.cpp +++ b/daemon/dbusconnector.cpp @@ -6,7 +6,6 @@ #include <QDBusReply> #include <QDBusArgument> #include <QDBusObjectPath> -#include <QDBusConnectionInterface> //dbus-send --system --dest=org.bluez --print-reply / org.bluez.Manager.ListAdapters //dbus-send --system --dest=org.bluez --print-reply $path org.bluez.Adapter.GetProperties @@ -16,17 +15,6 @@ DBusConnector::DBusConnector(QObject *parent) : QObject(parent) { - QDBusConnectionInterface *interface = QDBusConnection::sessionBus().interface(); - - QDBusReply<QStringList> serviceNames = interface->registeredServiceNames(); - if (serviceNames.isValid()) { - dbusServices = serviceNames.value(); - } - else { - logger()->error() << serviceNames.error().message(); - } - connect(interface, SIGNAL(serviceRegistered(const QString &)), SLOT(onServiceRegistered(const QString &))); - connect(interface, SIGNAL(serviceUnregistered(const QString &)), SLOT(onServiceUnregistered(const QString &))); } bool DBusConnector::findPebble() @@ -82,15 +70,3 @@ bool DBusConnector::findPebble() return false; } - -void DBusConnector::onServiceRegistered(const QString &name) -{ - logger()->debug() << "DBus service online:" << name; - if (!dbusServices.contains(name)) dbusServices.append(name); -} - -void DBusConnector::onServiceUnregistered(const QString &name) -{ - logger()->debug() << "DBus service offline:" << name; - if (dbusServices.contains(name)) dbusServices.removeAll(name); -} diff --git a/daemon/dbusconnector.h b/daemon/dbusconnector.h index c24bb9b..7ed3d56 100644 --- a/daemon/dbusconnector.h +++ b/daemon/dbusconnector.h @@ -6,33 +6,26 @@ #include <QVariantMap> #include <Log4Qt/Logger> +// TODO Remove this. + class DBusConnector : public QObject { Q_OBJECT LOG4QT_DECLARE_QCLASS_LOGGER Q_PROPERTY(QVariantMap pebble READ pebble NOTIFY pebbleChanged) - Q_PROPERTY(QStringList services READ services NOTIFY servicesChanged) - QVariantMap pebbleProps; - QStringList dbusServices; public: explicit DBusConnector(QObject *parent = 0); QVariantMap pebble() const { return pebbleProps; } - QStringList services() const { return dbusServices; } signals: void pebbleChanged(); - void servicesChanged(); public slots: bool findPebble(); - -protected slots: - void onServiceRegistered(const QString &); - void onServiceUnregistered(const QString &); }; #endif // DBUSCONNECTOR_H diff --git a/daemon/manager.cpp b/daemon/manager.cpp index dcf9c16..73b80e5 100644 --- a/daemon/manager.cpp +++ b/daemon/manager.cpp @@ -76,13 +76,6 @@ Manager::Manager(Settings *settings, QObject *parent) : defaultProfile = currentProfile.isEmpty() ? "ambience" : currentProfile; connect(watch, SIGNAL(connectedChanged()), SLOT(applyProfile())); - // Music Control interface - session.connect("", "/org/mpris/MediaPlayer2", - "org.freedesktop.DBus.Properties", "PropertiesChanged", - this, SLOT(onMprisPropertiesChanged(QString,QMap<QString,QVariant>,QStringList))); - - connect(this, SIGNAL(mprisMetadataChanged(QVariantMap)), music, SLOT(onMprisMetadataChanged(QVariantMap))); - // Set BT icon for notification notification.setImage("icon-system-bluetooth-device"); @@ -131,22 +124,6 @@ void Manager::onConnectedChanged() if (!notification.publish()) { logger()->debug() << "Failed publishing notification"; } - - if (watch->isConnected()) { - QString mpris = this->mpris(); - if (not mpris.isEmpty()) { - QDBusReply<QDBusVariant> Metadata = QDBusConnection::sessionBus().call( - QDBusMessage::createMethodCall(mpris, "/org/mpris/MediaPlayer2", "org.freedesktop.DBus.Properties", "Get") - << "org.mpris.MediaPlayer2.Player" << "Metadata"); - if (Metadata.isValid()) { - setMprisMetadata(Metadata.value().variant().value<QDBusArgument>()); - } - else { - logger()->error() << Metadata.error().message(); - setMprisMetadata(QVariantMap()); - } - } - } } void Manager::onActiveVoiceCallChanged() @@ -279,52 +256,6 @@ void Manager::onEmailNotify(const QString &sender, const QString &data,const QSt watch->sendEmailNotification(sender, data, subject); } -void Manager::onMprisPropertiesChanged(QString interface, QMap<QString,QVariant> changed, QStringList invalidated) -{ - logger()->debug() << interface << changed << invalidated; - - if (changed.contains("Metadata")) { - setMprisMetadata(changed.value("Metadata").value<QDBusArgument>()); - } - - if (changed.contains("PlaybackStatus")) { - QString PlaybackStatus = changed.value("PlaybackStatus").toString(); - if (PlaybackStatus == "Stopped") { - setMprisMetadata(QVariantMap()); - } - } - - lastSeenMpris = message().service(); - logger()->debug() << "lastSeenMpris:" << lastSeenMpris; -} - -QString Manager::mpris() const -{ - const QStringList &services = dbus->services(); - if (not lastSeenMpris.isEmpty() && services.contains(lastSeenMpris)) - return lastSeenMpris; - - foreach (QString service, services) - if (service.startsWith("org.mpris.MediaPlayer2.")) - return service; - - return QString(); -} - -void Manager::setMprisMetadata(QDBusArgument metadata) -{ - if (metadata.currentType() == QDBusArgument::MapType) { - metadata >> mprisMetadata; - emit mprisMetadataChanged(mprisMetadata); - } -} - -void Manager::setMprisMetadata(QVariantMap metadata) -{ - mprisMetadata = metadata; - emit mprisMetadataChanged(mprisMetadata); -} - QString Manager::getCurrentProfile() const { QDBusReply<QString> profile = QDBusConnection::sessionBus().call( diff --git a/daemon/manager.h b/daemon/manager.h index ad0428b..c191b0c 100644 --- a/daemon/manager.h +++ b/daemon/manager.h @@ -35,9 +35,6 @@ class Manager : public QObject, protected QDBusContext friend class PebbledProxy; - Q_PROPERTY(QString mpris READ mpris) - Q_PROPERTY(QVariantMap mprisMetadata READ getMprisMetadata WRITE setMprisMetadata NOTIFY mprisMetadataChanged) - QBluetoothLocalDevice btDevice; Settings *settings; @@ -63,9 +60,6 @@ class Manager : public QObject, protected QDBusContext QString defaultProfile; - QString lastSeenMpris; - QVariantMap mprisMetadata; - QUuid currentAppUuid; QScopedPointer<icu::Transliterator> transliterator; @@ -76,16 +70,10 @@ public: QString findPersonByNumber(QString number); QString getCurrentProfile() const; - QString mpris() const; - - inline QVariantMap getMprisMetadata() const { return mprisMetadata; } protected: void transliterateMessage(const QString &text); -signals: - void mprisMetadataChanged(const QVariantMap &metadata); - public slots: void applyProfile(); @@ -102,9 +90,6 @@ private slots: void onTwitterNotify(const QString &sender, const QString &data); void onFacebookNotify(const QString &sender, const QString &data); void onEmailNotify(const QString &sender, const QString &data,const QString &subject); - void onMprisPropertiesChanged(QString,QMap<QString,QVariant>,QStringList); - void setMprisMetadata(QDBusArgument metadata); - void setMprisMetadata(QVariantMap metadata); void onAppNotification(const QUuid &uuid, const QString &title, const QString &body); void onAppOpened(const QUuid &uuid); diff --git a/daemon/musicmanager.cpp b/daemon/musicmanager.cpp index abea715..e018e4c 100644 --- a/daemon/musicmanager.cpp +++ b/daemon/musicmanager.cpp @@ -4,28 +4,45 @@ MusicManager::MusicManager(WatchConnector *watch, QObject *parent) : QObject(parent), watch(watch) { + QDBusConnection bus = QDBusConnection::sessionBus(); + QDBusConnectionInterface *bus_iface = bus.interface(); + + // Listen for MPRIS signals from every player + bus.connect("", "/org/mpris/MediaPlayer2", "org.freedesktop.DBus.Properties", "PropertiesChanged", + this, SLOT(handleMprisPropertiesChanged(QString,QMap<QString,QVariant>,QStringList))); + + // Listen for D-Bus name registered signals to see if a MPRIS service comes up + connect(bus_iface, &QDBusConnectionInterface::serviceRegistered, + this, &MusicManager::handleServiceRegistered); + connect(bus_iface, &QDBusConnectionInterface::serviceUnregistered, + this, &MusicManager::handleServiceUnregistered); + connect(bus_iface, &QDBusConnectionInterface::serviceOwnerChanged, + this, &MusicManager::handleServiceOwnerChanged); + + // But also try to find an already active MPRIS service + const QStringList &services = bus_iface->registeredServiceNames(); + foreach (QString service, services) { + if (service.startsWith("org.mpris.MediaPlayer2.")) { + switchToService(service); + break; + } + } + + // Set up watch endpoint handler watch->setEndpointHandler(WatchConnector::watchMUSIC_CONTROL, [this](const QByteArray& data) { musicControl(WatchConnector::MusicControl(data.at(0))); return true; }); -} - -void MusicManager::onMprisMetadataChanged(QVariantMap metadata) -{ - QString track = metadata.value("xesam:title").toString(); - QString album = metadata.value("xesam:album").toString(); - QString artist = metadata.value("xesam:artist").toString(); - logger()->debug() << __FUNCTION__ << track << album << artist; - watch->sendMusicNowPlaying(track, album, artist); + connect(watch, &WatchConnector::connectedChanged, + this, &MusicManager::handleWatchConnected); } void MusicManager::musicControl(WatchConnector::MusicControl operation) { - logger()->debug() << "Operation:" << operation; + logger()->debug() << "operation from watch:" << operation; - QString mpris = parent()->property("mpris").toString(); - if (mpris.isEmpty()) { - logger()->debug() << "No mpris interface active"; + if (_curService.isEmpty()) { + logger()->info() << "No mpris interface active"; return; } @@ -50,11 +67,11 @@ void MusicManager::musicControl(WatchConnector::MusicControl operation) case WatchConnector::musicVOLUME_UP: case WatchConnector::musicVOLUME_DOWN: { QDBusConnection bus = QDBusConnection::sessionBus(); - QDBusReply<QDBusVariant> VolumeReply = bus.call( - QDBusMessage::createMethodCall(mpris, "/org/mpris/MediaPlayer2", "org.freedesktop.DBus.Properties", "Get") - << "org.mpris.MediaPlayer2.Player" << "Volume"); - if (VolumeReply.isValid()) { - double volume = VolumeReply.value().variant().toDouble(); + QDBusMessage call = QDBusMessage::createMethodCall(_curService, "/org/mpris/MediaPlayer2", "org.freedesktop.DBus.Properties", "Get"); + call << "org.mpris.MediaPlayer2.Player" << "Volume"; + QDBusReply<QDBusVariant> volumeReply = bus.call(call); + if (volumeReply.isValid()) { + double volume = volumeReply.value().variant().toDouble(); if (operation == WatchConnector::musicVOLUME_UP) { volume += 0.1; } @@ -62,22 +79,25 @@ void MusicManager::musicControl(WatchConnector::MusicControl operation) volume -= 0.1; } logger()->debug() << "Setting volume" << volume; - QDBusError err = QDBusConnection::sessionBus().call( - QDBusMessage::createMethodCall(mpris, "/org/mpris/MediaPlayer2", "org.freedesktop.DBus.Properties", "Set") - << "org.mpris.MediaPlayer2.Player" << "Volume" << QVariant::fromValue(QDBusVariant(volume))); + + call = QDBusMessage::createMethodCall(_curService, "/org/mpris/MediaPlayer2", "org.freedesktop.DBus.Properties", "Set"); + call << "org.mpris.MediaPlayer2.Player" << "Volume" << QVariant::fromValue(QDBusVariant(volume)); + + QDBusError err = QDBusConnection::sessionBus().call(call); if (err.isValid()) { logger()->error() << err.message(); } } else { - logger()->error() << VolumeReply.error().message(); + logger()->error() << volumeReply.error().message(); } } return; case WatchConnector::musicGET_NOW_PLAYING: - onMprisMetadataChanged(parent()->property("mprisMetadata").toMap()); + setMprisMetadata(_curMetadata); return; case WatchConnector::musicSEND_NOW_PLAYING: + default: logger()->warn() << "Operation" << operation << "not supported"; return; } @@ -89,9 +109,98 @@ void MusicManager::musicControl(WatchConnector::MusicControl operation) logger()->debug() << operation << "->" << method; - QDBusError err = QDBusConnection::sessionBus().call( - QDBusMessage::createMethodCall(mpris, "/org/mpris/MediaPlayer2", "org.mpris.MediaPlayer2.Player", method)); + QDBusMessage call = QDBusMessage::createMethodCall(_curService, "/org/mpris/MediaPlayer2", "org.mpris.MediaPlayer2.Player", method); + QDBusError err = QDBusConnection::sessionBus().call(call); if (err.isValid()) { logger()->error() << err.message(); } } + +void MusicManager::switchToService(const QString &service) +{ + if (_curService != service) { + logger()->debug() << "switching to mpris service" << service; + _curService = service; + } +} + +void MusicManager::setMprisMetadata(const QVariantMap &metadata) +{ + _curMetadata = metadata; + QString track = metadata.value("xesam:title").toString(); + QString album = metadata.value("xesam:album").toString(); + QString artist = metadata.value("xesam:artist").toString(); + logger()->debug() << "new mpris metadata:" << track << album << artist; + + if (watch->isConnected()) { + watch->sendMusicNowPlaying(track, album, artist); + } +} + +void MusicManager::handleServiceRegistered(const QString &service) +{ + if (service.startsWith("org.mpris.MediaPlayer2.")) { + if (_curService.isEmpty()) { + switchToService(service); + } + } +} + +void MusicManager::handleServiceUnregistered(const QString &service) +{ + if (service == _curService) { + // Oops! + setMprisMetadata(QVariantMap()); + switchToService(QString()); + } +} + +void MusicManager::handleServiceOwnerChanged(const QString &name, const QString &oldOwner, const QString &newOwner) +{ + Q_UNUSED(oldOwner); + if (newOwner.isEmpty()) { + handleServiceUnregistered(name); + } else { + handleServiceRegistered(name); + } +} + +void MusicManager::handleMprisPropertiesChanged(const QString &interface, const QMap<QString, QVariant> &changed, const QStringList &invalidated) +{ + Q_ASSERT(calledFromDBus()); + Q_UNUSED(interface); + Q_UNUSED(invalidated); + + if (changed.contains("Metadata")) { + QVariantMap metadata = qdbus_cast<QVariantMap>(changed.value("Metadata").value<QDBusArgument>()); + logger()->debug() << "received new metadata" << metadata; + setMprisMetadata(metadata); + } + + if (changed.contains("PlaybackStatus")) { + QString status = changed.value("PlaybackStatus").toString(); + if (status == "Stopped") { + setMprisMetadata(QVariantMap()); + } + } + + switchToService(message().service()); +} + +void MusicManager::handleWatchConnected() +{ + if (watch->isConnected()) { + if (!_curService.isEmpty()) { + QDBusMessage call = QDBusMessage::createMethodCall(_curService, "/org/mpris/MediaPlayer2", "org.freedesktop.DBus.Properties", "Get"); + call << "org.mpris.MediaPlayer2.Player" << "Metadata"; + QDBusReply<QDBusVariant> metadata = QDBusConnection::sessionBus().call(call); + if (metadata.isValid()) { + setMprisMetadata(qdbus_cast<QVariantMap>(metadata.value().variant().value<QDBusArgument>())); + // + } else { + logger()->error() << metadata.error().message(); + setMprisMetadata(QVariantMap()); + } + } + } +} diff --git a/daemon/musicmanager.h b/daemon/musicmanager.h index ca86ce3..88c46c3 100644 --- a/daemon/musicmanager.h +++ b/daemon/musicmanager.h @@ -2,9 +2,10 @@ #define MUSICMANAGER_H #include <QObject> +#include <QDBusContext> #include "watchconnector.h" -class MusicManager : public QObject +class MusicManager : public QObject, protected QDBusContext { Q_OBJECT LOG4QT_DECLARE_QCLASS_LOGGER @@ -14,12 +15,21 @@ public: private: void musicControl(WatchConnector::MusicControl operation); + void switchToService(const QString &service); + void setMprisMetadata(const QVariantMap &data); private slots: - void onMprisMetadataChanged(QVariantMap metadata); + void handleServiceRegistered(const QString &service); + void handleServiceUnregistered(const QString &service); + void handleServiceOwnerChanged(const QString &name, const QString &oldOwner, const QString &newOwner); + void handleMprisPropertiesChanged(const QString &interface, const QMap<QString,QVariant> &changed, const QStringList &invalidated); + void handleWatchConnected(); private: WatchConnector *watch; + + QVariantMap _curMetadata; + QString _curService; }; #endif // MUSICMANAGER_H |
