summaryrefslogtreecommitdiff
path: root/agents/musicconn.cc
diff options
context:
space:
mode:
Diffstat (limited to 'agents/musicconn.cc')
-rw-r--r--agents/musicconn.cc181
1 files changed, 181 insertions, 0 deletions
diff --git a/agents/musicconn.cc b/agents/musicconn.cc
new file mode 100644
index 0000000..cfc375d
--- /dev/null
+++ b/agents/musicconn.cc
@@ -0,0 +1,181 @@
+#include <QtCore/QDebug>
+#include <QtCore/QBuffer>
+#include <QtCore/QJsonDocument>
+#include <QtCore/QJsonObject>
+#include <QtGui/QImage>
+
+#include "sappeer.h"
+#include "musicconn.h"
+
+#if SAILFISH
+#include "libwatchfish/musiccontroller.h"
+
+static watchfish::MusicController *controller = 0;
+#endif
+
+MusicConn::MusicConn(SAPConnection *conn, QObject *parent)
+ : QObject(parent), _conn(conn), _socket(conn->getSocket(100))
+{
+ connect(_conn, SIGNAL(disconnected()), SLOT(deleteLater()));
+ connect(_conn, SIGNAL(destroyed()), SLOT(deleteLater()));
+ Q_ASSERT(_socket);
+ connect(_socket, SIGNAL(connected()), SLOT(handleConnected()));
+ connect(_socket, SIGNAL(messageReceived()), SLOT(handleMessageReceived()));
+}
+
+QString MusicConn::encodeAlbumArt(const QString &albumArt)
+{
+ QImage image;
+
+ if (image.load(albumArt)) {
+ QByteArray imgData;
+ QBuffer buf(&imgData);
+ buf.open(QIODevice::WriteOnly);
+ image = image.scaled(160, 160, Qt::KeepAspectRatio);
+ image.save(&buf, "JPEG", 60);
+ buf.close();
+
+ return QString::fromLatin1(imgData.toBase64());
+ } else {
+ return QString();
+ }
+}
+
+void MusicConn::sendMessage(const QJsonObject &msg)
+{
+ QJsonDocument doc(msg);
+ QByteArray data = doc.toJson(QJsonDocument::Compact);
+
+ qDebug() << data;
+
+ _socket->send(data);
+}
+
+void MusicConn::handleMessage(const QJsonObject &msg)
+{
+ const QString msgId = msg["msgId"].toString();
+ if (msgId == "music-mediachanged-req") {
+ sendResponse("music-mediachanged-rsp", "success", 0);
+ sendMediaChangedInd();
+ } else if (msgId == "music-getattribute-req") {
+ QJsonObject rsp;
+ rsp.insert("msgId", QLatin1String("music-getattribute-rsp"));
+ rsp.insert("result", QLatin1String("success"));
+ rsp.insert("reason", 0);
+ QString repeat("repeatoff"), shuffle("off");
+ int volume = 100;
+#if SAILFISH
+ switch (controller->repeat()) {
+ case watchfish::MusicController::RepeatNone:
+ repeat = "repeatoff";
+ break;
+ case watchfish::MusicController::RepeatTrack:
+ repeat = "repeatone";
+ break;
+ case watchfish::MusicController::RepeatPlaylist:
+ repeat = "repeatall";
+ break;
+ }
+
+ if (controller->shuffle()) {
+ shuffle = "on";
+ }
+#endif
+ rsp.insert("repeat", repeat);
+ rsp.insert("shuffle", shuffle);
+ rsp.insert("volume", volume);
+
+ sendMessage(rsp);
+ } else if (msgId == "music-remotecontrol-req") {
+ QString action = msg["action"].toString();
+ QString status = msg["status"].toString();
+ bool pressed = status == "pressed";
+
+#if SAILFISH
+ if (action == "playpause" && pressed) {
+ controller->playPause();
+ } else if (action == "forward" && pressed) {
+ controller->next();
+ } else if (action == "rewind" && pressed) {
+ controller->previous();
+ }
+#endif
+ }
+}
+
+void MusicConn::sendResponse(const QString &id, const QString &result, int reason)
+{
+ QJsonObject obj;
+ obj.insert("msgId", id);
+ obj.insert("result", result);
+ obj.insert("reason", reason);
+ sendMessage(obj);
+}
+
+void MusicConn::sendMediaChangedInd()
+{
+ QJsonObject obj;
+ obj.insert("msgId", QLatin1String("music-mediachanged-ind"));
+
+#if SAILFISH
+ obj.insert("artist", controller->artist());
+ obj.insert("album", controller->album());
+ obj.insert("title", controller->title());
+ obj.insert("duration", QString::number(controller->duration()));
+ obj.insert("audioId", QString());
+ obj.insert("artistId", QString());
+ obj.insert("albumId", QString());
+ obj.insert("albumArt", QString());
+ if (controller->status() == watchfish::MusicController::StatusPlaying) {
+ obj.insert("playStatus", QLatin1String("true"));
+ } else {
+ obj.insert("playStatus", QLatin1String("false"));
+ }
+ QString albumArtPath = controller->albumArt();
+ if (!albumArtPath.isEmpty()) {
+ obj.insert("image", encodeAlbumArt(albumArtPath));
+ } else {
+ obj.insert("image", QString());
+ }
+ obj.insert("favoriteStatus", QLatin1String("false"));
+#endif
+
+ sendMessage(obj);
+}
+
+void MusicConn::handleConnected()
+{
+ qDebug() << "Music connected";
+#if SAILFISH
+ if (!controller) {
+ controller = new watchfish::MusicController;
+ }
+ connect(controller, &watchfish::MusicController::metadataChanged,
+ this, &MusicConn::handleMetadataChanged);
+ connect(controller, &watchfish::MusicController::statusChanged,
+ this, &MusicConn::handleMetadataChanged);
+#endif
+}
+
+void MusicConn::handleMessageReceived()
+{
+ QByteArray data = _socket->receive();
+
+ qDebug() << "Music msg received" << data;
+
+ QJsonParseError error;
+ QJsonDocument json = QJsonDocument::fromJson(data, &error);
+
+ if (json.isObject()) {
+ handleMessage(json.object());
+ } else {
+ qWarning() << "Cannot parse JSON msg:" << error.errorString();
+ }
+}
+
+void MusicConn::handleMetadataChanged()
+{
+ if (_socket->isOpen()) {
+ sendMediaChangedInd();
+ }
+}