#include #include #include #include #include #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(); } }