From 568b7ffd3143496c0c30223083f0868bcd92f4c0 Mon Sep 17 00:00:00 2001 From: Boernsman Date: Thu, 16 Jan 2020 12:35:01 +0100 Subject: [PATCH] added source browsing --- bose/devicepluginbose.cpp | 74 ++++++++++++++++++++++++++++----------- bose/devicepluginbose.h | 2 +- bose/soundtouch.cpp | 70 +++++++++++++++++++++--------------- 3 files changed, 96 insertions(+), 50 deletions(-) diff --git a/bose/devicepluginbose.cpp b/bose/devicepluginbose.cpp index 958959bb..b253952b 100644 --- a/bose/devicepluginbose.cpp +++ b/bose/devicepluginbose.cpp @@ -32,6 +32,7 @@ #include "platform/platformzeroconfcontroller.h" #include "network/zeroconf/zeroconfservicebrowser.h" #include "network/zeroconf/zeroconfserviceentry.h" +#include "types/mediabrowseritem.h" #include #include @@ -44,10 +45,6 @@ DevicePluginBose::~DevicePluginBose() { } -void DevicePluginBose::init() -{ -} - void DevicePluginBose::setupDevice(DeviceSetupInfo *info) { @@ -67,11 +64,12 @@ void DevicePluginBose::setupDevice(DeviceSetupInfo *info) connect(soundTouch, &SoundTouch::zoneReceived, this, &DevicePluginBose::onZoneObjectReceived); connect(soundTouch, &SoundTouch::requestExecuted, this, &DevicePluginBose::onRequestExecuted); m_soundTouch.insert(info->device(), soundTouch); + return info->finish(Device::DeviceErrorNoError); - info->finish(Device::DeviceErrorNoError); - return; + } else { + qCWarning(dcBose()) << "DeviceClassId not found" << info->device()->deviceClassId(); + return info->finish(Device::DeviceErrorDeviceClassNotFound); } - info->finish(Device::DeviceErrorDeviceClassNotFound); } void DevicePluginBose::postSetupDevice(Device *device) @@ -81,7 +79,6 @@ void DevicePluginBose::postSetupDevice(Device *device) soundTouch->getInfo(); soundTouch->getNowPlaying(); soundTouch->getVolume(); - soundTouch->getSources(); soundTouch->getBass(); soundTouch->getBassCapabilities(); soundTouch->getZone(); @@ -102,6 +99,7 @@ void DevicePluginBose::deviceRemoved(Device *device) if (m_pluginTimer && myDevices().isEmpty()) { hardwareManager()->pluginTimerManager()->unregisterTimer(m_pluginTimer); + m_pluginTimer = nullptr; } } @@ -232,11 +230,12 @@ void DevicePluginBose::executeAction(DeviceActionInfo *info) connect(info, &DeviceActionInfo::aborted, this, [requestId, this] {m_pendingActions.remove(requestId);}); } else { - info->finish(Device::DeviceErrorActionTypeNotFound); - return; + qCWarning(dcBose()) << "ActionTypeId not found" << action.actionTypeId(); + return info->finish(Device::DeviceErrorActionTypeNotFound); } } else { - info->finish(Device::DeviceErrorDeviceClassNotFound); + qCWarning(dcBose()) << "DeviceClassId not found" << device->deviceClassId(); + return info->finish(Device::DeviceErrorDeviceClassNotFound); } } @@ -247,6 +246,7 @@ void DevicePluginBose::browseDevice(BrowseResult *result) SoundTouch *soundTouch = m_soundTouch.value(device); QUuid requestId = soundTouch->getSources(); m_asyncBrowseResults.insert(requestId, result); + connect(result, &BrowseResult::aborted, this, [this, requestId]{m_asyncBrowseResults.remove(requestId);}); } } @@ -265,11 +265,18 @@ void DevicePluginBose::executeBrowserItem(BrowserActionInfo *info) Device *device = info->device(); if (device->deviceClassId() == soundtouchDeviceClassId) { SoundTouch *soundTouch = m_soundTouch.value(device); - ContentItemObject contentItem; - contentItem.source = info->browserAction().itemId(); - QUuid requestId = soundTouch->setSource(contentItem); - m_asyncExecuteBroweItems.insert(requestId, info); - connect(info, &BrowserActionInfo::aborted, this, [this, requestId]{m_asyncExecuteBroweItems.remove(requestId);}); + SourcesObject sources = m_sourcesObjects.value(device); + foreach (SourceItemObject source, sources.sourceItems) { + if (source.source == info->browserAction().itemId()) { + ContentItemObject contentItem; + contentItem.source = source.source; + contentItem.sourceAccount = source.sourceAccount; + QUuid requestId = soundTouch->setSource(contentItem); + m_asyncExecuteBroweItems.insert(requestId, info); + connect(info, &BrowserActionInfo::aborted, this, [this, requestId]{m_asyncExecuteBroweItems.remove(requestId);}); + break; + } + } } } @@ -312,6 +319,13 @@ void DevicePluginBose::onRequestExecuted(QUuid requestId, bool success) BrowseResult *result = m_asyncBrowseResults.take(requestId); result->finish(Device::DeviceErrorHardwareFailure); } + } else if (m_asyncExecuteBroweItems.contains(requestId)) { + BrowserActionInfo *info = m_asyncExecuteBroweItems.take(requestId); + if (success) { + info->finish(Device::DeviceErrorNoError); + } else { + info->finish(Device::DeviceErrorHardwareFailure); + } } else { //This request was not an action or browse request } @@ -376,12 +390,33 @@ void DevicePluginBose::onVolumeObjectReceived(QUuid requestId, VolumeObject volu void DevicePluginBose::onSourcesObjectReceived(QUuid requestId, SourcesObject sources) { + SoundTouch *soundtouch = static_cast(sender()); + Device *device = m_soundTouch.key(soundtouch); + m_sourcesObjects.insert(device, sources); + if (m_asyncBrowseResults.contains(requestId)) { BrowseResult *result = m_asyncBrowseResults.value(requestId); foreach (SourceItemObject sourceItem, sources.sourceItems) { - qDebug(dcBose()) << "Source:" << sources.deviceId << sourceItem.source << sourceItem.displayName; - BrowserItem item("sources"+sourceItem.source, sourceItem.displayName, false, true); - result->addItem(item); + qDebug(dcBose()) << "Source:" << sourceItem.source; + if (sourceItem.source == "BLUETOOTH") { + MediaBrowserItem item(sourceItem.source, sourceItem.source, false, true); + item.setDescription(sourceItem.sourceAccount); + item.setIcon(BrowserItem::BrowserIcon::BrowserIconMusic); + item.setMediaIcon(MediaBrowserItem::MediaBrowserIcon::MediaBrowserIconRecentlyPlayed); + result->addItem(item); + } else if (sourceItem.source == "AUX") { + MediaBrowserItem item(sourceItem.source, sourceItem.source, false, true); + item.setDescription(sourceItem.sourceAccount); + item.setIcon(BrowserItem::BrowserIcon::BrowserIconMusic); + result->addItem(item); + item.setMediaIcon(MediaBrowserItem::MediaBrowserIcon::MediaBrowserIconAux); + } else if ((sourceItem.source == "SPOTIFY") && (sourceItem.status == SOURCE_STATUS_READY)) { + MediaBrowserItem item(sourceItem.source, sourceItem.source, false, true); + item.setDescription(sourceItem.sourceAccount); + item.setIcon(BrowserItem::BrowserIcon::BrowserIconMusic); + item.setMediaIcon(MediaBrowserItem::MediaBrowserIcon::MediaBrowserIconSpotify); + result->addItem(item); + } } result->finish(Device::DeviceErrorNoError); } else { @@ -415,7 +450,6 @@ void DevicePluginBose::onGroupObjectReceived(QUuid requestId, GroupObject group) void DevicePluginBose::onZoneObjectReceived(QUuid requestId, ZoneObject zone) { Q_UNUSED(requestId); - qDebug(dcBose()) << "Zone master" << zone.deviceID; foreach (MemberObject member, zone.members) { qDebug(dcBose()) << "-> member:" << member.deviceID; } diff --git a/bose/devicepluginbose.h b/bose/devicepluginbose.h index 4ffa5102..e5368e23 100644 --- a/bose/devicepluginbose.h +++ b/bose/devicepluginbose.h @@ -48,7 +48,6 @@ public: explicit DevicePluginBose(); ~DevicePluginBose() override; - void init() override; void discoverDevices(DeviceDiscoveryInfo *info) override; void setupDevice(DeviceSetupInfo *info) override; void postSetupDevice(Device *device) override; @@ -66,6 +65,7 @@ private: QHash m_pendingActions; QHash m_asyncBrowseResults; QHash m_asyncExecuteBroweItems; + QHash m_sourcesObjects; private slots: void onPluginTimer(); diff --git a/bose/soundtouch.cpp b/bose/soundtouch.cpp index b475f543..f03ae4b7 100644 --- a/bose/soundtouch.cpp +++ b/bose/soundtouch.cpp @@ -229,8 +229,9 @@ QUuid SoundTouch::setKey(KEY_VALUE keyValue) } xml.writeEndElement(); //key xml.writeEndDocument(); - //qDebug(dcBose) << "Sending request" << url << content; - QNetworkReply *reply = m_networkAccessManager->post(QNetworkRequest(url), content); + QNetworkRequest request(url); + request.setHeader(QNetworkRequest::ContentTypeHeader, "application/xml"); + QNetworkReply *reply = m_networkAccessManager->post(request, content); connect(reply, &QNetworkReply::finished, this, [requestId, reply, this] { reply->deleteLater(); emitRequestStatus(requestId, reply); @@ -251,7 +252,9 @@ QUuid SoundTouch::setKey(KEY_VALUE keyValue) xml.writeCharacters("POWER"); xml.writeEndElement(); //key xml.writeEndDocument(); - QNetworkReply *reply = m_networkAccessManager->post(QNetworkRequest(url), content); + QNetworkRequest request(url); + request.setHeader(QNetworkRequest::ContentTypeHeader, "application/xml"); + QNetworkReply *reply = m_networkAccessManager->post(request, content); connect(reply, &QNetworkReply::finished, this, [reply] {reply->deleteLater();}); } return requestId; @@ -269,8 +272,9 @@ QUuid SoundTouch::setVolume(int volume) content.append(""); content.append(QByteArray::number(volume)); content.append(""); - //qDebug(dcBose) << "Sending request" << url << content; - QNetworkReply *reply = m_networkAccessManager->post(QNetworkRequest(url), content); + QNetworkRequest request(url); + request.setHeader(QNetworkRequest::ContentTypeHeader, "application/xml"); + QNetworkReply *reply = m_networkAccessManager->post(request, content); connect(reply, &QNetworkReply::finished, this, [requestId, reply, this] { reply->deleteLater(); emitRequestStatus(requestId, reply); @@ -294,9 +298,9 @@ QUuid SoundTouch::setSource(ContentItemObject contentItem) xml.writeAttribute("sourceAccount", contentItem.sourceAccount); xml.writeEndElement(); //ContentItem xml.writeEndDocument(); - qDebug(dcBose) << "Sending request" << url << content; - - QNetworkReply *reply = m_networkAccessManager->post(QNetworkRequest(url), content); + QNetworkRequest request(url); + request.setHeader(QNetworkRequest::ContentTypeHeader, "application/xml"); + QNetworkReply *reply = m_networkAccessManager->post(request, content); connect(reply, &QNetworkReply::finished, this, [requestId, reply, this] { reply->deleteLater(); emitRequestStatus(requestId, reply); @@ -323,8 +327,9 @@ QUuid SoundTouch::setZone(ZoneObject zone) } xml.writeEndElement(); //zone xml.writeEndDocument(); - qDebug(dcBose) << "Sending request" << url << content; - QNetworkReply *reply = m_networkAccessManager->post(QNetworkRequest(url), content); + QNetworkRequest request(url); + request.setHeader(QNetworkRequest::ContentTypeHeader, "application/xml"); + QNetworkReply *reply = m_networkAccessManager->post(request, content); connect(reply, &QNetworkReply::finished, this, [requestId, reply, this] { reply->deleteLater(); emitRequestStatus(requestId, reply); @@ -351,8 +356,9 @@ QUuid SoundTouch::addZoneSlave(ZoneObject zone) } xml.writeEndElement(); //zone xml.writeEndDocument(); - qDebug(dcBose) << "Sending request" << url << content; - QNetworkReply *reply = m_networkAccessManager->post(QNetworkRequest(url), content); + QNetworkRequest request(url); + request.setHeader(QNetworkRequest::ContentTypeHeader, "application/xml"); + QNetworkReply *reply = m_networkAccessManager->post(request, content); connect(reply, &QNetworkReply::finished, this, [requestId, reply, this] { reply->deleteLater(); emitRequestStatus(requestId, reply); @@ -379,8 +385,9 @@ QUuid SoundTouch::removeZoneSlave(ZoneObject zone) } xml.writeEndElement(); //zone xml.writeEndDocument(); - qDebug(dcBose) << "Sending request" << url << content; - QNetworkReply *reply = m_networkAccessManager->post(QNetworkRequest(url), content); + QNetworkRequest request(url); + request.setHeader(QNetworkRequest::ContentTypeHeader, "application/xml"); + QNetworkReply *reply = m_networkAccessManager->post(request, content); connect(reply, &QNetworkReply::finished, this, [requestId, reply, this] { reply->deleteLater(); emitRequestStatus(requestId, reply); @@ -400,8 +407,9 @@ QUuid SoundTouch::setBass(int volume) content.append(""); content.append(QByteArray::number(volume)); content.append(""); - qDebug(dcBose) << "Sending request" << url << content; - QNetworkReply *reply = m_networkAccessManager->post(QNetworkRequest(url), content); + QNetworkRequest request(url); + request.setHeader(QNetworkRequest::ContentTypeHeader, "application/xml"); + QNetworkReply *reply = m_networkAccessManager->post(request, content); connect(reply, &QNetworkReply::finished, this, [requestId, reply, this] { reply->deleteLater(); emitRequestStatus(requestId, reply); @@ -421,8 +429,9 @@ QUuid SoundTouch::setName(QString name) content.append(""); content.append(name); content.append(""); - qDebug(dcBose) << "Sending request" << url << content; - QNetworkReply *reply = m_networkAccessManager->post(QNetworkRequest(url), content); + QNetworkRequest request(url); + request.setHeader(QNetworkRequest::ContentTypeHeader, "application/xml"); + QNetworkReply *reply = m_networkAccessManager->post(request, content); connect(reply, &QNetworkReply::finished, this, [requestId, reply, this] { reply->deleteLater(); emitRequestStatus(requestId, reply); @@ -450,8 +459,9 @@ QUuid SoundTouch::setSpeaker(PlayInfoObject playInfo) xml.writeTextElement("volume", QString::number(playInfo.volume)); xml.writeEndElement(); //play_info xml.writeEndDocument(); - qDebug(dcBose) << "Sending request" << url << content; - QNetworkReply *reply = m_networkAccessManager->post(QNetworkRequest(url), content); + QNetworkRequest request(url); + request.setHeader(QNetworkRequest::ContentTypeHeader, "application/xml"); + QNetworkReply *reply = m_networkAccessManager->post(request, content); connect(reply, &QNetworkReply::finished, this, [requestId, reply, this] { reply->deleteLater(); emitRequestStatus(requestId, reply); @@ -509,6 +519,7 @@ QUuid SoundTouch::sendGetRequest(QString path) if (reply->error() != QNetworkReply::NoError) { emit requestExecuted(requestId, false); emit connectionChanged(false); + qCWarning(dcBose()) << "Request error" << reply->errorString(); return; } emit connectionChanged(true); @@ -522,7 +533,6 @@ QUuid SoundTouch::sendGetRequest(QString path) QByteArray data = reply->readAll(); parseData(requestId, data); }); - connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(onRestRequestError(QNetworkReply::NetworkError))); return requestId; } @@ -542,6 +552,7 @@ void SoundTouch::emitRequestStatus(QUuid requestId, QNetworkReply *reply) return; } QByteArray data = reply->readAll(); + qCDebug(dcBose()) << "Request status" << data; QXmlStreamReader xml; xml.addData(data); @@ -732,7 +743,6 @@ void SoundTouch::parseData(QUuid requestId, const QByteArray &data) xml.skipCurrentElement(); } } - emit nowPlayingReceived(requestId, nowPlaying); } else if (xml.name() == "volume") { VolumeObject volumeObject; @@ -767,10 +777,12 @@ void SoundTouch::parseData(QUuid requestId, const QByteArray &data) if(xml.attributes().hasAttribute("source")) { //qDebug(dcBose) << "Source" << xml.attributes().value("source").toString(); sourceItem.source = xml.attributes().value("source").toString(); - } else if(xml.attributes().hasAttribute("sourceAccount")) { + } + if(xml.attributes().hasAttribute("sourceAccount")) { //qDebug(dcBose) << "Source Account" << xml.attributes().value("sourceAccount").toString(); sourceItem.sourceAccount = xml.attributes().value("sourceAccount").toString(); - } else if(xml.attributes().hasAttribute("status")) { + } + if(xml.attributes().hasAttribute("status")) { QString status = xml.attributes().value("status").toString().toUpper(); //UNAVAILABLE, READY //qDebug(dcBose) << "status" << status; if (status == "READY") { @@ -778,11 +790,13 @@ void SoundTouch::parseData(QUuid requestId, const QByteArray &data) } else { sourceItem.status = SOURCE_STATUS_UNAVAILABLE; } - } else if(xml.attributes().hasAttribute("isLocal")) { + } + if(xml.attributes().hasAttribute("isLocal")) { //qDebug(dcBose) << "is Local" << xml.attributes().value("isLocal").toString(); sourceItem.isLocal = ( xml.attributes().value("isLocal").toString().toUpper() == "TRUE" ); - } else if(xml.attributes().hasAttribute("multiroomallowed")) { - //Debug(dcBose) << "multiroom allowed" << xml.attributes().value("multiroomallowed").toString(); + } + if(xml.attributes().hasAttribute("multiroomallowed")) { + //qCDebug(dcBose) << "multiroom allowed" << xml.attributes().value("multiroomallowed").toString(); sourceItem.multiroomallowed = ( xml.attributes().value("multiroomallowed").toString().toUpper() == "TRUE" ); } sourceItem.displayName = xml.readElementText(); @@ -812,11 +826,9 @@ void SoundTouch::parseData(QUuid requestId, const QByteArray &data) emit bassReceived(requestId, bassObject); } else if (xml.name() == "bassCapabilities") { BassCapabilitiesObject bassCapabilities; - if(xml.attributes().hasAttribute("deviceID")) { bassCapabilities.deviceID = xml.attributes().value("deviceID").toString(); } - while(xml.readNextStartElement()){ if(xml.name() == "bassAvailable"){ //qDebug(dcBose) << "BassAvailable" << xml.readElementText();