Merge PR #180: Kodi: Fix active player not updating properly in some circumstances

This commit is contained in:
Jenkins nymea 2019-10-22 01:09:54 +02:00
commit df314d06b7
4 changed files with 63 additions and 69 deletions

View File

@ -72,8 +72,6 @@ void DevicePluginKodi::setupDevice(DeviceSetupInfo *info)
connect(kodi, &Kodi::connectionStatusChanged, this, &DevicePluginKodi::onConnectionChanged); connect(kodi, &Kodi::connectionStatusChanged, this, &DevicePluginKodi::onConnectionChanged);
connect(kodi, &Kodi::stateChanged, this, &DevicePluginKodi::onStateChanged); connect(kodi, &Kodi::stateChanged, this, &DevicePluginKodi::onStateChanged);
connect(kodi, &Kodi::actionExecuted, this, &DevicePluginKodi::onActionExecuted); connect(kodi, &Kodi::actionExecuted, this, &DevicePluginKodi::onActionExecuted);
connect(kodi, &Kodi::versionDataReceived, this, &DevicePluginKodi::versionDataReceived);
connect(kodi, &Kodi::updateDataReceived, this, &DevicePluginKodi::onSetupFinished);
connect(kodi, &Kodi::playbackStatusChanged, this, &DevicePluginKodi::onPlaybackStatusChanged); connect(kodi, &Kodi::playbackStatusChanged, this, &DevicePluginKodi::onPlaybackStatusChanged);
connect(kodi, &Kodi::browserItemExecuted, this, &DevicePluginKodi::onBrowserItemExecuted); connect(kodi, &Kodi::browserItemExecuted, this, &DevicePluginKodi::onBrowserItemExecuted);
connect(kodi, &Kodi::browserItemActionExecuted, this, &DevicePluginKodi::onBrowserItemActionExecuted); connect(kodi, &Kodi::browserItemActionExecuted, this, &DevicePluginKodi::onBrowserItemActionExecuted);
@ -343,18 +341,24 @@ void DevicePluginKodi::onPluginTimer()
} }
} }
void DevicePluginKodi::onConnectionChanged() void DevicePluginKodi::onConnectionChanged(bool connected)
{ {
Kodi *kodi = static_cast<Kodi *>(sender()); Kodi *kodi = static_cast<Kodi *>(sender());
Device *device = m_kodis.value(kodi); Device *device = m_kodis.value(kodi);
if (kodi->connected()) { // Finish setup
// if this is the first setup, check version DeviceSetupInfo *info = m_asyncSetups.value(kodi);
if (m_asyncSetups.contains(kodi)) { if (info) {
kodi->checkVersion(); if (connected) {
info->finish(Device::DeviceErrorNoError);
} else {
//: Error setting up device
m_asyncSetups.take(kodi)->finish(Device::DeviceErrorHardwareFailure, QT_TR_NOOP("This installation of Kodi is too old. Please upgrade your Kodi system."));
} }
} }
kodi->showNotification("nymea", tr("Connected"), 2000, "info");
device->setStateValue(kodiConnectedStateTypeId, kodi->connected()); device->setStateValue(kodiConnectedStateTypeId, kodi->connected());
} }
@ -392,40 +396,6 @@ void DevicePluginKodi::onBrowserItemActionExecuted(int actionId, bool success)
m_pendingBrowserItemActions.take(actionId)->finish(success ? Device::DeviceErrorNoError : Device::DeviceErrorHardwareFailure); m_pendingBrowserItemActions.take(actionId)->finish(success ? Device::DeviceErrorNoError : Device::DeviceErrorHardwareFailure);
} }
void DevicePluginKodi::versionDataReceived(const QVariantMap &data)
{
Kodi *kodi = static_cast<Kodi *>(sender());
QVariantMap version = data.value("version").toMap();
QString apiVersion = QString("%1.%2.%3").arg(version.value("major").toString()).arg(version.value("minor").toString()).arg(version.value("patch").toString());
qCDebug(dcKodi) << "API Version:" << apiVersion;
if (version.value("major").toInt() < 6) {
qCWarning(dcKodi) << "incompatible api version:" << apiVersion;
if (m_asyncSetups.contains(kodi)) {
//: Error setting up device
m_asyncSetups.take(kodi)->finish(Device::DeviceErrorHardwareFailure, QT_TR_NOOP("This installation of Kodi is too old. Please upgrade your Kodi system."));
}
return;
}
kodi->update();
}
void DevicePluginKodi::onSetupFinished(const QVariantMap &data)
{
Kodi *kodi = static_cast<Kodi *>(sender());
QVariantMap version = data.value("version").toMap();
QString kodiVersion = QString("%1.%2 (%3)").arg(version.value("major").toString()).arg(version.value("minor").toString()).arg(version.value("tag").toString());
qCDebug(dcKodi) << "Version:" << kodiVersion;
if (m_asyncSetups.contains(kodi)) {
m_asyncSetups.take(kodi)->finish(Device::DeviceErrorNoError);
}
kodi->showNotification("nymea", tr("Connected"), 2000, "info");
}
void DevicePluginKodi::onPlaybackStatusChanged(const QString &playbackStatus) void DevicePluginKodi::onPlaybackStatusChanged(const QString &playbackStatus)
{ {
Kodi *kodi = static_cast<Kodi *>(sender()); Kodi *kodi = static_cast<Kodi *>(sender());

View File

@ -63,13 +63,11 @@ private:
private slots: private slots:
void onPluginTimer(); void onPluginTimer();
void onConnectionChanged(); void onConnectionChanged(bool connected);
void onStateChanged(); void onStateChanged();
void onActionExecuted(int actionId, bool success); void onActionExecuted(int actionId, bool success);
void onBrowserItemExecuted(int actionId, bool success); void onBrowserItemExecuted(int actionId, bool success);
void onBrowserItemActionExecuted(int actionId, bool success); void onBrowserItemActionExecuted(int actionId, bool success);
void versionDataReceived(const QVariantMap &data);
void onSetupFinished(const QVariantMap &data);
void onPlaybackStatusChanged(const QString &playbackStatus); void onPlaybackStatusChanged(const QString &playbackStatus);
}; };

View File

@ -33,7 +33,7 @@ Kodi::Kodi(const QHostAddress &hostAddress, int port, int httpPort, QObject *par
m_volume(-1) m_volume(-1)
{ {
m_connection = new KodiConnection(hostAddress, port, this); m_connection = new KodiConnection(hostAddress, port, this);
connect (m_connection, &KodiConnection::connectionStatusChanged, this, &Kodi::connectionStatusChanged); connect (m_connection, &KodiConnection::connectionStatusChanged, this, &Kodi::onConnectionStatusChanged);
m_jsonHandler = new KodiJsonHandler(m_connection, this); m_jsonHandler = new KodiJsonHandler(m_connection, this);
connect(m_jsonHandler, &KodiJsonHandler::notificationReceived, this, &Kodi::processNotification); connect(m_jsonHandler, &KodiJsonHandler::notificationReceived, this, &Kodi::processNotification);
@ -532,6 +532,15 @@ int Kodi::executeBrowserItemAction(const QString &itemId, const ActionTypeId &ac
return m_jsonHandler->sendData(scope + "." + method, QVariantMap()); return m_jsonHandler->sendData(scope + "." + method, QVariantMap());
} }
void Kodi::onConnectionStatusChanged()
{
if (m_connection->connected()) {
checkVersion();
} else {
emit connectionStatusChanged(false);
}
}
void Kodi::onVolumeChanged(const int &volume, const bool &muted) void Kodi::onVolumeChanged(const int &volume, const bool &muted)
{ {
if (m_volume != volume || m_muted != muted) { if (m_volume != volume || m_muted != muted) {
@ -565,7 +574,7 @@ void Kodi::activePlayersChanged(const QVariantList &data)
qCDebug(dcKodi) << "Active Player changed:" << m_activePlayer << data.first().toMap().value("type").toString(); qCDebug(dcKodi) << "Active Player changed:" << m_activePlayer << data.first().toMap().value("type").toString();
emit activePlayerChanged(data.first().toMap().value("type").toString()); emit activePlayerChanged(data.first().toMap().value("type").toString());
updatePlayerProperties(); updateMetadata();
} }
void Kodi::playerPropertiesReceived(const QVariantMap &properties) void Kodi::playerPropertiesReceived(const QVariantMap &properties)
@ -590,6 +599,9 @@ void Kodi::mediaMetaDataReceived(const QVariantMap &data)
QVariantMap item = data.value("item").toMap(); QVariantMap item = data.value("item").toMap();
QString title = item.value("title").toString(); QString title = item.value("title").toString();
if (title.isEmpty()) { // Fall back to label if not title present
title = item.value("label").toString();
}
QString artist; QString artist;
QString collection; QString collection;
if (item.value("type").toString() == "song") { if (item.value("type").toString() == "song") {
@ -633,14 +645,15 @@ void Kodi::processNotification(const QString &method, const QVariantMap &params)
if (method == "Application.OnVolumeChanged") { if (method == "Application.OnVolumeChanged") {
QVariantMap data = params.value("data").toMap(); QVariantMap data = params.value("data").toMap();
onVolumeChanged(data.value("volume").toInt(), data.value("muted").toBool()); onVolumeChanged(data.value("volume").toInt(), data.value("muted").toBool());
} else if (method == "Player.OnPlay" || method == "Player.OnResume") { return;
emit activePlayersChanged(QVariantList() << params.value("data").toMap().value("player")); }
onPlaybackStatusChanged("Playing");
} else if (method == "Player.OnPause") { if (method == "Player.OnPlay" ||
emit playbackStatusChanged("Paused"); method == "Player.OnResume" ||
} else if (method == "Player.OnStop") { method == "Player.OnPause" ||
emit playbackStatusChanged("Stopped"); method == "Player.OnStop" ||
emit activePlayersChanged(QVariantList()); method == "Player.OnAVChange") {
update();
} }
} }
@ -653,33 +666,49 @@ void Kodi::processResponse(int id, const QString &method, const QVariantMap &res
qCWarning(dcKodi) << "got error response for request " << method << ":" << response.value("error").toMap().value("message").toString(); qCWarning(dcKodi) << "got error response for request " << method << ":" << response.value("error").toMap().value("message").toString();
} }
if (method == "JSONRPC.Version") {
qCDebug(dcKodi) << "got version response" << method;
QVariantMap data = response.value("result").toMap();
QVariantMap version = data.value("version").toMap();
QString apiVersion = QString("%1.%2.%3").arg(version.value("major").toString()).arg(version.value("minor").toString()).arg(version.value("patch").toString());
qCDebug(dcKodi) << "API Version:" << apiVersion;
if (version.value("major").toInt() < 6) {
qCWarning(dcKodi) << "incompatible api version:" << apiVersion;
m_connection->disconnectKodi();
emit connectionStatusChanged(false);
return;
}
emit connectionStatusChanged(true);
update();
return;
}
if (method == "Application.GetProperties") { if (method == "Application.GetProperties") {
//qCDebug(dcKodi) << "got update response" << reply.method(); //qCDebug(dcKodi) << "got update response" << reply.method();
emit updateDataReceived(response.value("result").toMap()); emit updateDataReceived(response.value("result").toMap());
return; return;
} }
if (method == "JSONRPC.Version") {
qCDebug(dcKodi) << "got version response" << method;
emit versionDataReceived(response.value("result").toMap());
return;
}
if (method == "Player.GetActivePlayers") { if (method == "Player.GetActivePlayers") {
qCDebug(dcKodi) << "Active players changed" << response; qCDebug(dcKodi) << "Active players changed" << response;
emit activePlayersChanged(response.value("result").toList()); activePlayersChanged(response.value("result").toList());
updatePlayerProperties();
return; return;
} }
if (method == "Player.GetProperties") { if (method == "Player.GetProperties") {
qCDebug(dcKodi) << "Player properties received" << response; qCDebug(dcKodi) << "Player properties received" << response;
playerPropertiesReceived(response.value("result").toMap()); playerPropertiesReceived(response.value("result").toMap());
updateMetadata();
return; return;
} }
if (method == "Player.GetItem") { if (method == "Player.GetItem") {
qCDebug(dcKodi) << "Played item received" << response; qCDebug(dcKodi) << "Played item received" << response;
emit mediaMetaDataReceived(response.value("result").toMap()); mediaMetaDataReceived(response.value("result").toMap());
return; return;
} }
@ -949,11 +978,6 @@ void Kodi::processResponse(int id, const QString &method, const QVariantMap &res
return; return;
} }
if (method == "GUI.ShowNotification" || method == "Input.ExecuteAction") {
emit actionExecuted(id, !response.contains("error"));
return;
}
if (method == "VideoLibrary.Scan" || method == "VideoLibrary.Clean" || method == "AudioLibrary.Scan" || method == "AudioLibrary.Clean") { if (method == "VideoLibrary.Scan" || method == "VideoLibrary.Clean" || method == "AudioLibrary.Scan" || method == "AudioLibrary.Clean") {
emit browserItemActionExecuted(id, !response.contains("error")); emit browserItemActionExecuted(id, !response.contains("error"));
return; return;
@ -961,9 +985,11 @@ void Kodi::processResponse(int id, const QString &method, const QVariantMap &res
if (method == "Player.Open") { if (method == "Player.Open") {
emit browserItemExecuted(id, !response.contains("error")); emit browserItemExecuted(id, !response.contains("error"));
return;
} }
qCWarning(dcKodi()) << "unhandled reply" << method << response; // Default
emit actionExecuted(id, !response.contains("error"));
} }
void Kodi::updatePlayerProperties() void Kodi::updatePlayerProperties()

View File

@ -74,20 +74,20 @@ public:
int executeBrowserItemAction(const QString &itemId, const ActionTypeId &actionTypeId); int executeBrowserItemAction(const QString &itemId, const ActionTypeId &actionTypeId);
signals: signals:
void connectionStatusChanged(); void connectionStatusChanged(bool connected);
void stateChanged(); void stateChanged();
void activePlayerChanged(const QString &playerType); void activePlayerChanged(const QString &playerType);
void actionExecuted(int actionId, bool success); void actionExecuted(int actionId, bool success);
void browserItemExecuted(int actionId, bool success); void browserItemExecuted(int actionId, bool success);
void browserItemActionExecuted(int actionId, bool success); void browserItemActionExecuted(int actionId, bool success);
void updateDataReceived(const QVariantMap &data); void updateDataReceived(const QVariantMap &data);
void versionDataReceived(const QVariantMap &data);
void playbackStatusChanged(const QString &playbackState); void playbackStatusChanged(const QString &playbackState);
void mediaMetadataChanged(const QString &title, const QString &artist, const QString &collection, const QString &artwork); void mediaMetadataChanged(const QString &title, const QString &artist, const QString &collection, const QString &artwork);
void shuffleChanged(bool shuffle); void shuffleChanged(bool shuffle);
void repeatChanged(const QString &repeat); void repeatChanged(const QString &repeat);
private slots: private slots:
void onConnectionStatusChanged();
void onVolumeChanged(const int &volume, const bool &muted); void onVolumeChanged(const int &volume, const bool &muted);
void onUpdateFinished(const QVariantMap &data); void onUpdateFinished(const QVariantMap &data);
void activePlayersChanged(const QVariantList &data); void activePlayersChanged(const QVariantList &data);