Update Kodi device plugin

master
Michael Zanetti 2019-09-18 02:04:02 +02:00
parent 5e73b33b87
commit 69a3a1835f
4 changed files with 224 additions and 216 deletions

View File

@ -60,8 +60,9 @@ void DevicePluginKodi::init()
connect(m_pluginTimer, &PluginTimer::timeout, this, &DevicePluginKodi::onPluginTimer);
}
Device::DeviceSetupStatus DevicePluginKodi::setupDevice(Device *device)
void DevicePluginKodi::setupDevice(DeviceSetupInfo *info)
{
Device *device = info->device();
qCDebug(dcKodi) << "Setup Kodi device" << device->paramValue(kodiDeviceIpParamTypeId).toString();
QString ipString = device->paramValue(kodiDeviceIpParamTypeId).toString();
int port = device->paramValue(kodiDevicePortParamTypeId).toInt();
@ -74,8 +75,7 @@ Device::DeviceSetupStatus DevicePluginKodi::setupDevice(Device *device)
connect(kodi, &Kodi::versionDataReceived, this, &DevicePluginKodi::versionDataReceived);
connect(kodi, &Kodi::updateDataReceived, this, &DevicePluginKodi::onSetupFinished);
connect(kodi, &Kodi::playbackStatusChanged, this, &DevicePluginKodi::onPlaybackStatusChanged);
connect(kodi, &Kodi::browseResult, this, &DevicePluginKodi::browseRequestFinished);
connect(kodi, &Kodi::browserItemResult, this, &DevicePluginKodi::browserItemRequestFinished);
connect(kodi, &Kodi::browserItemExecuted, this, &DevicePluginKodi::onBrowserItemExecuted);
connect(kodi, &Kodi::browserItemActionExecuted, this, &DevicePluginKodi::onBrowserItemActionExecuted);
connect(kodi, &Kodi::activePlayerChanged, device, [device](const QString &playerType){
@ -133,11 +133,10 @@ Device::DeviceSetupStatus DevicePluginKodi::setupDevice(Device *device)
}
});
m_kodis.insert(kodi, device);
m_asyncSetups.append(kodi);
m_asyncSetups.insert(kodi, info);
connect(info, &QObject::destroyed, this, [this, kodi](){ m_asyncSetups.remove(kodi); });
kodi->connectKodi();
return Device::DeviceSetupStatusAsync;
}
void DevicePluginKodi::deviceRemoved(Device *device)
@ -148,14 +147,17 @@ void DevicePluginKodi::deviceRemoved(Device *device)
kodi->deleteLater();
}
Device::DeviceError DevicePluginKodi::discoverDevices(const DeviceClassId &deviceClassId, const ParamList &params)
void DevicePluginKodi::discoverDevices(DeviceDiscoveryInfo *info)
{
Q_UNUSED(params)
Q_UNUSED(deviceClassId)
ZeroConfServiceBrowser *serviceBrowser = hardwareManager()->zeroConfController()->createServiceBrowser("_xbmc-jsonrpc._tcp");
connect(info, &QObject::destroyed, serviceBrowser, &QObject::deleteLater);
ZeroConfServiceBrowser *httpServiceBrowser = hardwareManager()->zeroConfController()->createServiceBrowser("_http._tcp");
QTimer::singleShot(5000, this, [this, serviceBrowser, httpServiceBrowser](){
connect(info, &QObject::destroyed, httpServiceBrowser, &QObject::deleteLater);
QTimer::singleShot(5000, info, [this, info, serviceBrowser, httpServiceBrowser](){
QHash<QString, DeviceDescriptor> descriptors;
foreach (const ZeroConfServiceEntry avahiEntry, serviceBrowser->serviceEntries()) {
@ -213,124 +215,122 @@ Device::DeviceError DevicePluginKodi::discoverDevices(const DeviceClassId &devic
foreach (const DeviceDescriptor &d, descriptors.values()) {
qCDebug(dcKodi()) << "Returning descritpor:" << d.params();
}
emit devicesDiscovered(kodiDeviceClassId, descriptors.values());
serviceBrowser->deleteLater();
httpServiceBrowser->deleteLater();
info->addDeviceDescriptors(descriptors.values());
info->finish(Device::DeviceErrorNoError);
});
return Device::DeviceErrorAsync;
}
Device::DeviceError DevicePluginKodi::executeAction(Device *device, const Action &action)
void DevicePluginKodi::executeAction(DeviceActionInfo *info)
{
if (device->deviceClassId() == kodiDeviceClassId) {
Kodi *kodi = m_kodis.key(device);
Action action = info->action();
Device *device = info->device();
Kodi *kodi = m_kodis.key(device);
// check connection state
if (!kodi->connected()) {
return Device::DeviceErrorHardwareNotAvailable;
}
// check connection state
if (!kodi->connected()) {
return info->finish(Device::DeviceErrorHardwareNotAvailable);
}
int commandId = -1;
if (action.actionTypeId() == kodiNotifyActionTypeId) {
commandId = kodi->showNotification(
action.param(kodiNotifyActionTitleParamTypeId).value().toString(),
action.param(kodiNotifyActionBodyParamTypeId).value().toString(),
8000,
action.param(kodiNotifyActionTypeParamTypeId).value().toString());
} else if (action.actionTypeId() == kodiVolumeActionTypeId) {
commandId = kodi->setVolume(action.param(kodiVolumeActionVolumeParamTypeId).value().toInt());
} else if (action.actionTypeId() == kodiMuteActionTypeId) {
commandId = kodi->setMuted(action.param(kodiMuteActionMuteParamTypeId).value().toBool());
} else if (action.actionTypeId() == kodiNavigateActionTypeId) {
commandId = kodi->navigate(action.param(kodiNavigateActionToParamTypeId).value().toString());
} else if (action.actionTypeId() == kodiSystemActionTypeId) {
commandId = kodi->systemCommand(action.param(kodiSystemActionSystemCommandParamTypeId).value().toString());
} else if(action.actionTypeId() == kodiSkipBackActionTypeId) {
commandId = kodi->navigate("skipprevious");
} else if(action.actionTypeId() == kodiFastRewindActionTypeId) {
commandId = kodi->navigate("rewind");
} else if(action.actionTypeId() == kodiStopActionTypeId) {
commandId = kodi->navigate("stop");
} else if(action.actionTypeId() == kodiPlayActionTypeId) {
commandId = kodi->navigate("play");
} else if(action.actionTypeId() == kodiPauseActionTypeId) {
commandId = kodi->navigate("pause");
} else if(action.actionTypeId() == kodiFastForwardActionTypeId) {
commandId = kodi->navigate("fastforward");
} else if(action.actionTypeId() == kodiSkipNextActionTypeId) {
commandId = kodi->navigate("skipnext");
} else if (action.actionTypeId() == kodiShuffleActionTypeId) {
commandId = kodi->setShuffle(action.param(kodiShuffleActionShuffleParamTypeId).value().toBool());
} else if (action.actionTypeId() == kodiRepeatActionTypeId) {
QString repeat = action.param(kodiRepeatActionRepeatParamTypeId).value().toString();
if (repeat == "One") {
commandId = kodi->setRepeat("one");
} else if (repeat == "All") {
commandId = kodi->setRepeat("all");
} else {
commandId = kodi->setRepeat("off");
}
int commandId = -1;
if (action.actionTypeId() == kodiNotifyActionTypeId) {
commandId = kodi->showNotification(
action.param(kodiNotifyActionTitleParamTypeId).value().toString(),
action.param(kodiNotifyActionBodyParamTypeId).value().toString(),
8000,
action.param(kodiNotifyActionTypeParamTypeId).value().toString());
} else if (action.actionTypeId() == kodiVolumeActionTypeId) {
commandId = kodi->setVolume(action.param(kodiVolumeActionVolumeParamTypeId).value().toInt());
} else if (action.actionTypeId() == kodiMuteActionTypeId) {
commandId = kodi->setMuted(action.param(kodiMuteActionMuteParamTypeId).value().toBool());
} else if (action.actionTypeId() == kodiNavigateActionTypeId) {
commandId = kodi->navigate(action.param(kodiNavigateActionToParamTypeId).value().toString());
} else if (action.actionTypeId() == kodiSystemActionTypeId) {
commandId = kodi->systemCommand(action.param(kodiSystemActionSystemCommandParamTypeId).value().toString());
} else if(action.actionTypeId() == kodiSkipBackActionTypeId) {
commandId = kodi->navigate("skipprevious");
} else if(action.actionTypeId() == kodiFastRewindActionTypeId) {
commandId = kodi->navigate("rewind");
} else if(action.actionTypeId() == kodiStopActionTypeId) {
commandId = kodi->navigate("stop");
} else if(action.actionTypeId() == kodiPlayActionTypeId) {
commandId = kodi->navigate("play");
} else if(action.actionTypeId() == kodiPauseActionTypeId) {
commandId = kodi->navigate("pause");
} else if(action.actionTypeId() == kodiFastForwardActionTypeId) {
commandId = kodi->navigate("fastforward");
} else if(action.actionTypeId() == kodiSkipNextActionTypeId) {
commandId = kodi->navigate("skipnext");
} else if (action.actionTypeId() == kodiShuffleActionTypeId) {
commandId = kodi->setShuffle(action.param(kodiShuffleActionShuffleParamTypeId).value().toBool());
} else if (action.actionTypeId() == kodiRepeatActionTypeId) {
QString repeat = action.param(kodiRepeatActionRepeatParamTypeId).value().toString();
if (repeat == "One") {
commandId = kodi->setRepeat("one");
} else if (repeat == "All") {
commandId = kodi->setRepeat("all");
} else {
qWarning(dcKodi()) << "Unhandled action type" << action.actionTypeId();
return Device::DeviceErrorActionTypeNotFound;
commandId = kodi->setRepeat("off");
}
m_pendingActions.insert(commandId, action.id());
return Device::DeviceErrorAsync;
} else {
qWarning(dcKodi()) << "Unhandled action type" << action.actionTypeId();
return info->finish(Device::DeviceErrorActionTypeNotFound);
}
return Device::DeviceErrorDeviceClassNotFound;
m_pendingActions.insert(commandId, info);
connect(info, &QObject::destroyed, this, [this, commandId](){ m_pendingActions.remove(commandId); });
}
Device::BrowseResult DevicePluginKodi::browseDevice(Device *device, Device::BrowseResult result, const QString &itemId, const QLocale &locale)
void DevicePluginKodi::browseDevice(BrowseResult *result)
{
Q_UNUSED(locale)
Kodi *kodi = m_kodis.key(device);
Kodi *kodi = m_kodis.key(result->device());
if (!kodi) {
result.status = Device::DeviceErrorHardwareNotAvailable;
return result;
result->finish(Device::DeviceErrorHardwareNotAvailable);
return;
}
return kodi->browse(itemId, result);
kodi->browse(result);
}
Device::BrowserItemResult DevicePluginKodi::browserItem(Device *device, Device::BrowserItemResult result, const QString &itemId, const QLocale &locale)
void DevicePluginKodi::browserItem(BrowserItemResult *result)
{
Q_UNUSED(locale)
Kodi *kodi = m_kodis.key(device);
Kodi *kodi = m_kodis.key(result->device());
if (!kodi) {
result.status = Device::DeviceErrorHardwareNotAvailable;
return result;
result->finish(Device::DeviceErrorHardwareNotAvailable);
return;
}
return kodi->browserItem(itemId, result);
kodi->browserItem(result);
}
Device::DeviceError DevicePluginKodi::executeBrowserItem(Device *device, const BrowserAction &browserAction)
void DevicePluginKodi::executeBrowserItem(BrowserActionInfo *info)
{
Kodi *kodi = m_kodis.key(device);
Kodi *kodi = m_kodis.key(info->device());
if (!kodi) {
return Device::DeviceErrorHardwareNotAvailable;
info->finish(Device::DeviceErrorHardwareNotAvailable);
return;
}
return kodi->launchBrowserItem(browserAction.itemId());
}
Device::DeviceError DevicePluginKodi::executeBrowserItemAction(Device *device, const BrowserItemAction &browserItemAction)
{
Kodi *kodi = m_kodis.key(device);
if (!kodi) {
return Device::DeviceErrorHardwareNotAvailable;
}
int id = kodi->executeBrowserItemAction(browserItemAction.itemId(), browserItemAction.actionTypeId());
int id = kodi->launchBrowserItem(info->browserAction().itemId());
if (id == -1) {
return Device::DeviceErrorHardwareFailure;
return info->finish(Device::DeviceErrorHardwareFailure);
}
m_pendingBrowserItemActions.insert(id, browserItemAction.id());
return Device::DeviceErrorAsync;
m_pendingBrowserActions.insert(id, info);
connect(info, &QObject::destroyed, this, [this, id](){ m_pendingBrowserActions.remove(id); });
}
void DevicePluginKodi::executeBrowserItemAction(BrowserItemActionInfo *info)
{
Kodi *kodi = m_kodis.key(info->device());
if (!kodi) {
return info->finish(Device::DeviceErrorHardwareNotAvailable);
}
int id = kodi->executeBrowserItemAction(info->browserItemAction().itemId(), info->browserItemAction().actionTypeId());
if (id == -1) {
return info->finish(Device::DeviceErrorHardwareFailure);
}
m_pendingBrowserItemActions.insert(id, info);
connect(info, &QObject::destroyed, this, [this, id](){ m_pendingBrowserItemActions.remove(id); });
}
void DevicePluginKodi::onPluginTimer()
@ -351,7 +351,6 @@ void DevicePluginKodi::onConnectionChanged()
if (kodi->connected()) {
// if this is the first setup, check version
if (m_asyncSetups.contains(kodi)) {
m_asyncSetups.removeAll(kodi);
kodi->checkVersion();
}
}
@ -374,7 +373,15 @@ void DevicePluginKodi::onActionExecuted(int actionId, bool success)
if (!m_pendingActions.contains(actionId)) {
return;
}
emit actionExecutionFinished(m_pendingActions.take(actionId), success ? Device::DeviceErrorNoError : Device::DeviceErrorInvalidParameter);
m_pendingActions.take(actionId)->finish(success ? Device::DeviceErrorNoError : Device::DeviceErrorInvalidParameter);
}
void DevicePluginKodi::onBrowserItemExecuted(int actionId, bool success)
{
if (!m_pendingBrowserActions.contains(actionId)) {
return;
}
m_pendingBrowserActions.take(actionId)->finish(success ? Device::DeviceErrorNoError : Device::DeviceErrorInvalidParameter);
}
void DevicePluginKodi::onBrowserItemActionExecuted(int actionId, bool success)
@ -382,13 +389,12 @@ void DevicePluginKodi::onBrowserItemActionExecuted(int actionId, bool success)
if (!m_pendingBrowserItemActions.contains(actionId)) {
return;
}
emit browserItemActionExecutionFinished(m_pendingBrowserItemActions.take(actionId), 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());
Device *device = m_kodis.value(kodi);
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());
@ -396,7 +402,10 @@ void DevicePluginKodi::versionDataReceived(const QVariantMap &data)
if (version.value("major").toInt() < 6) {
qCWarning(dcKodi) << "incompatible api version:" << apiVersion;
emit deviceSetupFinished(device, Device::DeviceSetupStatusFailure);
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();
@ -405,13 +414,14 @@ void DevicePluginKodi::versionDataReceived(const QVariantMap &data)
void DevicePluginKodi::onSetupFinished(const QVariantMap &data)
{
Kodi *kodi = static_cast<Kodi *>(sender());
Device *device = m_kodis.value(kodi);
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;
emit deviceSetupFinished(device, Device::DeviceSetupStatusSuccess);
if (m_asyncSetups.contains(kodi)) {
m_asyncSetups.take(kodi)->finish(Device::DeviceErrorNoError);
}
kodi->showNotification("nymea", tr("Connected"), 2000, "info");
}

View File

@ -42,29 +42,31 @@ public:
~DevicePluginKodi();
void init() override;
Device::DeviceSetupStatus setupDevice(Device *device) override;
void setupDevice(DeviceSetupInfo *info) override;
void deviceRemoved(Device *device) override;
Device::DeviceError discoverDevices(const DeviceClassId &deviceClassId, const ParamList &params) override;
Device::DeviceError executeAction(Device *device, const Action &action) override;
void discoverDevices(DeviceDiscoveryInfo *info) override;
void executeAction(DeviceActionInfo *info) override;
Device::BrowseResult browseDevice(Device *device, Device::BrowseResult result, const QString &itemId, const QLocale &locale) override;
Device::BrowserItemResult browserItem(Device *device, Device::BrowserItemResult result, const QString &itemId, const QLocale &locale) override;
Device::DeviceError executeBrowserItem(Device *device, const BrowserAction &browserAction) override;
Device::DeviceError executeBrowserItemAction(Device *device, const BrowserItemAction &browserItemAction) override;
void browseDevice(BrowseResult *result) override;
void browserItem(BrowserItemResult *result) override;
void executeBrowserItem(BrowserActionInfo *info) override;
void executeBrowserItemAction(BrowserItemActionInfo *info) override;
private:
PluginTimer *m_pluginTimer;
QHash<Kodi *, Device *> m_kodis;
QList<Kodi *> m_asyncSetups;
QHash<Kodi*, Device*> m_kodis;
QHash<Kodi*, DeviceSetupInfo*> m_asyncSetups;
QHash<int, ActionId> m_pendingActions;
QHash<int, ActionId> m_pendingBrowserItemActions;
QHash<int, DeviceActionInfo*> m_pendingActions;
QHash<int, BrowserActionInfo*> m_pendingBrowserActions;
QHash<int, BrowserItemActionInfo*> m_pendingBrowserItemActions;
private slots:
void onPluginTimer();
void onConnectionChanged();
void onStateChanged();
void onActionExecuted(int actionId, bool success);
void onBrowserItemExecuted(int actionId, bool success);
void onBrowserItemActionExecuted(int actionId, bool success);
void versionDataReceived(const QVariantMap &data);
void onSetupFinished(const QVariantMap &data);

View File

@ -301,24 +301,24 @@ void Kodi::disconnectKodi()
m_connection->disconnectKodi();
}
Device::BrowseResult Kodi::browse(const QString &itemId, Device::BrowseResult &result)
void Kodi::browse(BrowseResult *result)
{
// m_jsonHandler->sendData()
VirtualFsNode *node = m_virtualFs->findNode(itemId);
VirtualFsNode *node = m_virtualFs->findNode(result->itemId());
if (node) {
if (node->getMethod.isEmpty()) {
foreach (VirtualFsNode *child, node->childs) {
result.items.append(child->item);
result->addItem(child->item);
}
return result;
result->finish(Device::DeviceErrorNoError);
return;
}
qCDebug(dcKodi()) << "Sending:" << node->getMethod << node->getParams;
int id = m_jsonHandler->sendData(node->getMethod, node->getParams);
m_pendingBrowseRequests.insert(id, result);
result.status = Device::DeviceErrorAsync;
return result;
return;
}
QVariantMap sort;
@ -327,8 +327,8 @@ Device::BrowseResult Kodi::browse(const QString &itemId, Device::BrowseResult &r
QVariantList properties;
properties.append("thumbnail");
if (itemId.startsWith("artist:")) {
QString idString = itemId;
if (result->itemId().startsWith("artist:")) {
QString idString = result->itemId();
idString.remove(QRegExp("^artist:"));
QVariantMap filter;
filter.insert("artistid", idString.toInt());
@ -340,12 +340,11 @@ Device::BrowseResult Kodi::browse(const QString &itemId, Device::BrowseResult &r
params.insert("properties", albumProperties);
int id = m_jsonHandler->sendData("AudioLibrary.GetAlbums", params);
m_pendingBrowseRequests.insert(id, result);
result.status = Device::DeviceErrorAsync;
return result;
return;
}
if (itemId.startsWith("album:")) {
QString idString = itemId;
if (result->itemId().startsWith("album:")) {
QString idString = result->itemId();
idString.remove(QRegExp("^album:"));
QVariantMap filter;
filter.insert("albumid", idString.toInt());
@ -359,12 +358,11 @@ Device::BrowseResult Kodi::browse(const QString &itemId, Device::BrowseResult &r
params.insert("properties", songProperties);
int id = m_jsonHandler->sendData("AudioLibrary.GetSongs", params);
m_pendingBrowseRequests.insert(id, result);
result.status = Device::DeviceErrorAsync;
return result;
return;
}
if (itemId.startsWith("tvshow:")) {
QString idString = itemId;
if (result->itemId().startsWith("tvshow:")) {
QString idString = result->itemId();
idString.remove(QRegExp("^tvshow:"));
QVariantMap params;
params.insert("tvshowid", idString.toInt());
@ -376,12 +374,11 @@ Device::BrowseResult Kodi::browse(const QString &itemId, Device::BrowseResult &r
params.insert("properties", properties);
int id = m_jsonHandler->sendData("VideoLibrary.GetSeasons", params);
m_pendingBrowseRequests.insert(id, result);
result.status = Device::DeviceErrorAsync;
return result;
return;
}
if (itemId.startsWith("season:")) {
QString idString = itemId;
if (result->itemId().startsWith("season:")) {
QString idString = result->itemId();
idString.remove(QRegExp("^season:"));
int seasonId = idString.left(idString.indexOf(",")).toInt();
idString.remove(QRegExp("^[0-9]*,tvshow:"));
@ -397,12 +394,11 @@ Device::BrowseResult Kodi::browse(const QString &itemId, Device::BrowseResult &r
qCDebug(dcKodi()) << "getting episodes:" << params;
int id = m_jsonHandler->sendData("VideoLibrary.GetEpisodes", params);
m_pendingBrowseRequests.insert(id, result);
result.status = Device::DeviceErrorAsync;
return result;
return;
}
if (itemId.startsWith("addon:")) {
QString idString = itemId;
if (result->itemId().startsWith("addon:")) {
QString idString = result->itemId();
idString.remove(QRegExp("^addon:"));
QVariantMap params;
params.insert("directory", "plugin://" + idString);
@ -413,12 +409,11 @@ Device::BrowseResult Kodi::browse(const QString &itemId, Device::BrowseResult &r
qCDebug(dcKodi()) << "Sending" << params;
int id = m_jsonHandler->sendData("Files.GetDirectory", params);
m_pendingBrowseRequests.insert(id, result);
result.status = Device::DeviceErrorAsync;
return result;
return;
}
if (itemId.startsWith("file:")) {
QString idString = itemId;
if (result->itemId().startsWith("file:")) {
QString idString = result->itemId();
idString.remove(QRegExp("^file:"));
QVariantMap params;
params.insert("directory", idString);
@ -426,16 +421,15 @@ Device::BrowseResult Kodi::browse(const QString &itemId, Device::BrowseResult &r
qCDebug(dcKodi()) << "Sending" << params;
int id = m_jsonHandler->sendData("Files.GetDirectory", params);
m_pendingBrowseRequests.insert(id, result);
result.status = Device::DeviceErrorAsync;
return result;
return;
}
result.status = Device::DeviceErrorItemNotFound;
return result;
result->finish(Device::DeviceErrorItemNotFound);
}
Device::BrowserItemResult Kodi::browserItem(const QString &itemId, Device::BrowserItemResult &result)
void Kodi::browserItem(BrowserItemResult *result)
{
QString itemId = result->itemId();
qCDebug(dcKodi()) << "Getting details for" << itemId;
QString idString = itemId;
QString method;
@ -458,16 +452,14 @@ Device::BrowserItemResult Kodi::browserItem(const QString &itemId, Device::Brows
method = "VideoLibrary.GetMusicVideoDetails";
} else {
qCWarning(dcKodi()) << "Unhandled browserItem request!" << itemId;
result.status = Device::DeviceErrorUnsupportedFeature;
return result;
result->finish(Device::DeviceErrorItemNotFound);
return;
}
int id = m_jsonHandler->sendData(method, params);
m_pendingBrowserItemRequests.insert(id, result);
result.status = Device::DeviceErrorAsync;
return result;
}
Device::DeviceError Kodi::launchBrowserItem(const QString &itemId)
int Kodi::launchBrowserItem(const QString &itemId)
{
qCDebug(dcKodi()) << "Launching" << itemId;
QVariantMap playlistItem;
@ -507,15 +499,14 @@ Device::DeviceError Kodi::launchBrowserItem(const QString &itemId)
playlistItem.insert("file", idString);
} else {
qCWarning(dcKodi()) << "Unhandled launchBrowserItem request!" << itemId;
return Device::DeviceErrorItemNotFound;
return -1;
}
QVariantMap params;
params.clear();
params.insert("item", playlistItem);
qCDebug(dcKodi()) << "Player.Open" << params;
m_jsonHandler->sendData("Player.Open", params);
return Device::DeviceErrorNoError;
return m_jsonHandler->sendData("Player.Open", params);
}
int Kodi::executeBrowserItemAction(const QString &itemId, const ActionTypeId &actionTypeId)
@ -699,7 +690,7 @@ void Kodi::processResponse(int id, const QString &method, const QVariantMap &res
}
if (method == "AudioLibrary.GetArtists") {
Device::BrowseResult result = m_pendingBrowseRequests.take(id);
BrowseResult *result = m_pendingBrowseRequests.take(id);
foreach (const QVariant &artistVariant, response.value("result").toMap().value("artists").toList()) {
QVariantMap artist = artistVariant.toMap();
qCDebug(dcKodi()) << "Entry:" << artist;
@ -716,14 +707,14 @@ void Kodi::processResponse(int id, const QString &method, const QVariantMap &res
}
item.setDescription(description.join(" - "));
qCDebug(dcKodi()) << "Thumbnail" << item.thumbnail();
result.items.append(item);
result->addItem(item);
}
emit browseResult(result);
result->finish(Device::DeviceErrorNoError);
return;
}
if (method == "AudioLibrary.GetAlbums") {
Device::BrowseResult result = m_pendingBrowseRequests.take(id);
BrowseResult *result = m_pendingBrowseRequests.take(id);
foreach (const QVariant &albumVariant, response.value("result").toMap().value("albums").toList()) {
QVariantMap album = albumVariant.toMap();
BrowserItem item("album:" + album.value("albumid").toString(), album.value("label").toString());
@ -738,14 +729,14 @@ void Kodi::processResponse(int id, const QString &method, const QVariantMap &res
description.append(album.value("year").toString());
}
item.setDescription(description.join(" - "));
result.items.append(item);
result->addItem(item);
}
emit browseResult(result);
result->finish(Device::DeviceErrorNoError);
return;
}
if (method == "AudioLibrary.GetSongs") {
Device::BrowseResult result = m_pendingBrowseRequests.take(id);
BrowseResult *result = m_pendingBrowseRequests.take(id);
int i = 0;
foreach (const QVariant &songVariant, response.value("result").toMap().value("songs").toList()) {
QVariantMap song = songVariant.toMap();
@ -771,16 +762,16 @@ void Kodi::processResponse(int id, const QString &method, const QVariantMap &res
description.append(song.value("year").toString());
}
item.setDescription(description.join(" - "));
result.items.append(item);
result->addItem(item);
i++;
}
emit browseResult(result);
result->finish(Device::DeviceErrorNoError);
return;
}
if (method == "VideoLibrary.GetMovies") {
Device::BrowseResult result = m_pendingBrowseRequests.take(id);
BrowseResult *result = m_pendingBrowseRequests.take(id);
foreach (const QVariant &movieVariant, response.value("result").toMap().value("movies").toList()) {
QVariantMap movie = movieVariant.toMap();
qCDebug(dcKodi()) << "Entry:" << movie;
@ -803,14 +794,14 @@ void Kodi::processResponse(int id, const QString &method, const QVariantMap &res
QString duration;
duration = QString("%1:%2").arg(hours).arg(minutes, 2, 10, QChar('0'));
item.setDescription(movie.value("year").toString() + " - " + duration + " - " + rating);
result.items.append(item);
result->addItem(item);
}
emit browseResult(result);
result->finish(Device::DeviceErrorNoError);
return;
}
if (method == "VideoLibrary.GetTVShows") {
Device::BrowseResult result = m_pendingBrowseRequests.take(id);
BrowseResult *result = m_pendingBrowseRequests.take(id);
foreach (const QVariant &tvShowVariant, response.value("result").toMap().value("tvshows").toList()) {
QVariantMap tvShow = tvShowVariant.toMap();
qCDebug(dcKodi()) << "Entry:" << tvShow;
@ -827,14 +818,14 @@ void Kodi::processResponse(int id, const QString &method, const QVariantMap &res
}
}
item.setDescription(tvShow.value("year").toString() + " - " + tr("%1 seasons").arg(tvShow.value("season").toInt()) + " - " + rating);
result.items.append(item);
result->addItem(item);
}
emit browseResult(result);
result->finish(Device::DeviceErrorNoError);
return;
}
if (method == "VideoLibrary.GetSeasons") {
Device::BrowseResult result = m_pendingBrowseRequests.take(id);
BrowseResult *result = m_pendingBrowseRequests.take(id);
foreach (const QVariant &seasonVariant, response.value("result").toMap().value("seasons").toList()) {
QVariantMap season = seasonVariant.toMap();
qCDebug(dcKodi()) << "Entry:" << season;
@ -843,14 +834,14 @@ void Kodi::processResponse(int id, const QString &method, const QVariantMap &res
item.setIcon(BrowserItem::BrowserIconFolder);
item.setThumbnail(prepareThumbnail(season.value("thumbnail").toString()));
item.setDescription(season.value("showtitle").toString());
result.items.append(item);
result->addItem(item);
}
emit browseResult(result);
result->finish(Device::DeviceErrorNoError);
return;
}
if (method == "VideoLibrary.GetEpisodes") {
Device::BrowseResult result = m_pendingBrowseRequests.take(id);
BrowseResult *result = m_pendingBrowseRequests.take(id);
foreach (const QVariant &episodeVariant, response.value("result").toMap().value("episodes").toList()) {
QVariantMap episode = episodeVariant.toMap();
qCDebug(dcKodi()) << "Entry:" << episode;
@ -863,14 +854,14 @@ void Kodi::processResponse(int id, const QString &method, const QVariantMap &res
} else {
item.setDescription(episode.value("showtitle").toString());
}
result.items.append(item);
result->addItem(item);
}
emit browseResult(result);
result->finish(Device::DeviceErrorNoError);
return;
}
if (method == "VideoLibrary.GetMusicVideos") {
Device::BrowseResult result = m_pendingBrowseRequests.take(id);
BrowseResult *result = m_pendingBrowseRequests.take(id);
foreach (const QVariant &musicVideoVariant, response.value("result").toMap().value("musicvideos").toList()) {
QVariantMap musicVideo = musicVideoVariant.toMap();
qCDebug(dcKodi()) << "Entry:" << musicVideo;
@ -878,14 +869,14 @@ void Kodi::processResponse(int id, const QString &method, const QVariantMap &res
item.setExecutable(true);
item.setIcon(BrowserItem::BrowserIconVideo);
item.setThumbnail(prepareThumbnail(musicVideo.value("thumbnail").toString()));
result.items.append(item);
result->addItem(item);
}
emit browseResult(result);
result->finish(Device::DeviceErrorNoError);
return;
}
if (method == "Addons.GetAddons") {
Device::BrowseResult result = m_pendingBrowseRequests.take(id);
BrowseResult *result = m_pendingBrowseRequests.take(id);
foreach (const QVariant &addonVariant, response.value("result").toMap().value("addons").toList()) {
QVariantMap addon = addonVariant.toMap();
qCDebug(dcKodi()) << "Entry:" << addon;
@ -893,14 +884,14 @@ void Kodi::processResponse(int id, const QString &method, const QVariantMap &res
item.setBrowsable(true);
item.setIcon(BrowserItem::BrowserIconApplication);
item.setThumbnail(prepareThumbnail(addon.value("thumbnail").toString()));
result.items.append(item);
result->addItem(item);
}
emit browseResult(result);
result->finish(Device::DeviceErrorNoError);
return;
}
if (method == "Files.GetDirectory") {
Device::BrowseResult result = m_pendingBrowseRequests.take(id);
BrowseResult *result = m_pendingBrowseRequests.take(id);
foreach (const QVariant &fileVariant, response.value("result").toMap().value("files").toList()) {
QVariantMap file = fileVariant.toMap();
qCDebug(dcKodi()) << "Entry:" << file;
@ -916,45 +907,45 @@ void Kodi::processResponse(int id, const QString &method, const QVariantMap &res
item.setIcon(BrowserItem::BrowserIconMusic);
}
item.setThumbnail(prepareThumbnail(file.value("thumbnail").toString()));
result.items.append(item);
result->addItem(item);
}
emit browseResult(result);
result->finish(Device::DeviceErrorNoError);
return;
}
if (method == "AudioLibrary.GetSongDetails") {
Device::BrowserItemResult result = m_pendingBrowserItemRequests.take(id);
result.item.setId("song:" + response.value("result").toMap().value("songdetails").toMap().value("songid").toString());
result.item.setDisplayName(response.value("result").toMap().value("songdetails").toMap().value("label").toString());
qCDebug(dcKodi()) << "Song details:" << result.item.displayName();
emit browserItemResult(result);
BrowserItemResult *result = m_pendingBrowserItemRequests.take(id);
BrowserItem item("song:" + response.value("result").toMap().value("songdetails").toMap().value("songid").toString());
item.setDisplayName(response.value("result").toMap().value("songdetails").toMap().value("label").toString());
qCDebug(dcKodi()) << "Song details:" << item.displayName();
result->finish(item);
return;
}
if (method == "VideoLibrary.GetMovieDetails") {
Device::BrowserItemResult result = m_pendingBrowserItemRequests.take(id);
result.item.setId("movie:" + response.value("result").toMap().value("moviedetails").toMap().value("movieid").toString());
result.item.setDisplayName(response.value("result").toMap().value("moviedetails").toMap().value("label").toString());
qCDebug(dcKodi()) << "Movie details:" << result.item.displayName();
emit browserItemResult(result);
BrowserItemResult *result = m_pendingBrowserItemRequests.take(id);
BrowserItem item("movie:" + response.value("result").toMap().value("moviedetails").toMap().value("movieid").toString());
item.setDisplayName(response.value("result").toMap().value("moviedetails").toMap().value("label").toString());
qCDebug(dcKodi()) << "Movie details:" << item.displayName();
result->finish(item);
return;
}
if (method == "VideoLibrary.GetEpisodeDetails") {
Device::BrowserItemResult result = m_pendingBrowserItemRequests.take(id);
result.item.setId("movie:" + response.value("result").toMap().value("episodedetails").toMap().value("episodeid").toString());
result.item.setDisplayName(response.value("result").toMap().value("episodedetails").toMap().value("label").toString());
qCDebug(dcKodi()) << "Episode details:" << result.item.displayName();
emit browserItemResult(result);
BrowserItemResult *result = m_pendingBrowserItemRequests.take(id);
BrowserItem item("movie:" + response.value("result").toMap().value("episodedetails").toMap().value("episodeid").toString());
item.setDisplayName(response.value("result").toMap().value("episodedetails").toMap().value("label").toString());
qCDebug(dcKodi()) << "Episode details:" << item.displayName();
result->finish(item);
return;
}
if (method == "VideoLibrary.GetMusicVideoDetails") {
Device::BrowserItemResult result = m_pendingBrowserItemRequests.take(id);
result.item.setId("movie:" + response.value("result").toMap().value("musicvideodetails").toMap().value("musicvideoid").toString());
result.item.setDisplayName(response.value("result").toMap().value("musicvideodetails").toMap().value("label").toString());
qCDebug(dcKodi()) << "Episode details:" << result.item.displayName();
emit browserItemResult(result);
BrowserItemResult *result = m_pendingBrowserItemRequests.take(id);
BrowserItem item("movie:" + response.value("result").toMap().value("musicvideodetails").toMap().value("musicvideoid").toString());
item.setDisplayName(response.value("result").toMap().value("musicvideodetails").toMap().value("label").toString());
qCDebug(dcKodi()) << "Episode details:" << item.displayName();
result->finish(item);
return;
}
@ -968,6 +959,10 @@ void Kodi::processResponse(int id, const QString &method, const QVariantMap &res
return;
}
if (method == "Player.Open") {
emit browserItemExecuted(id, !response.contains("error"));
}
qCWarning(dcKodi()) << "unhandled reply" << method << response;
}

View File

@ -32,6 +32,8 @@
#include "types/browseritem.h"
#include "types/browseritemaction.h"
#include "devices/device.h"
#include "devices/browseresult.h"
#include "devices/browseritemresult.h"
class Kodi : public QObject
{
@ -66,9 +68,9 @@ public:
void connectKodi();
void disconnectKodi();
Device::BrowseResult browse(const QString &itemId, Device::BrowseResult &result);
Device::BrowserItemResult browserItem(const QString &itemId, Device::BrowserItemResult &result);
Device::DeviceError launchBrowserItem(const QString &itemId);
void browse(BrowseResult *result);
void browserItem(BrowserItemResult *result);
int launchBrowserItem(const QString &itemId);
int executeBrowserItemAction(const QString &itemId, const ActionTypeId &actionTypeId);
signals:
@ -76,15 +78,14 @@ signals:
void stateChanged();
void activePlayerChanged(const QString &playerType);
void actionExecuted(int actionId, bool success);
void browserItemExecuted(int actionId, bool success);
void browserItemActionExecuted(int actionId, bool success);
void updateDataReceived(const QVariantMap &data);
void versionDataReceived(const QVariantMap &data);
void playbackStatusChanged(const QString &playbackState);
void mediaMetadataChanged(const QString &title, const QString &artist, const QString &collection, const QString &artwork);
void shuffleChanged(bool shuffle);
void repeatChanged(const QString &repeat);
void browseResult(const Device::BrowseResult &result);
void browserItemResult(const Device::BrowserItemResult &result);
void browserItemActionExecuted(int actionId, bool success);
private slots:
void onVolumeChanged(const int &volume, const bool &muted);
@ -131,8 +132,8 @@ private:
};
VirtualFsNode* m_virtualFs = nullptr;
QHash<int, Device::BrowseResult> m_pendingBrowseRequests;
QHash<int, Device::BrowserItemResult> m_pendingBrowserItemRequests;
QHash<int, BrowseResult*> m_pendingBrowseRequests;
QHash<int, BrowserItemResult*> m_pendingBrowserItemRequests;
};