diff options
author | Dominik Holland <dominik.holland@pelagicore.com> | 2019-04-15 15:43:50 +0200 |
---|---|---|
committer | Dominik Holland <dominik.holland@pelagicore.com> | 2019-05-10 09:28:39 +0000 |
commit | 07c631aa4c1ac5199b4919087e43815a00154867 (patch) | |
tree | 860b44dbf4429aaa253ffc2f87138d5de4f0f07a | |
parent | 60e22b2cd3c11e36fc993e78e0f9ae7474de2536 (diff) |
Add a QtRO-based media backend and media-simulation-server
The media-simulation is the same as from the simulation plugin
and is reused in the server.
Change-Id: Ie20f62b7aee1579322425278de167d2032c6bba1
Fixes: AUTOSUITE-814
Reviewed-by: Robert Griebl <robert.griebl@pelagicore.com>
41 files changed, 2982 insertions, 13 deletions
diff --git a/src/ivimedia/configure.json b/src/ivimedia/configure.json index eac47f4..ee9d309 100644 --- a/src/ivimedia/configure.json +++ b/src/ivimedia/configure.json @@ -55,6 +55,16 @@ "label": "Tuner Simulation Backend", "output": [ "privateFeature" ] }, + "media_qtro_backend" : { + "label": "Mediaplayer Qt Remote Objects Backend", + "condition": "features.remoteobjects", + "output": [ "privateFeature" ] + }, + "media_qtro_simulation_server" : { + "label": "Mediaplayer Qt Remote Objects Simulation Server", + "condition": "features.remoteobjects", + "output": [ "privateFeature" ] + }, "ivimedia" : { "label": "Qt IVI Media", "condition": "features.ivicore", @@ -94,10 +104,12 @@ Please make sure the QtMultimedia module is available." "entries": [ "taglib", "system-taglib", + "media_qtro_simulation_server", { "section": "Backends", "entries": [ "media_simulation_backend", + "media_qtro_backend", "tuner_simulation_backend" ] } diff --git a/src/plugins/ivimedia/ivimedia.pro b/src/plugins/ivimedia/ivimedia.pro index 75018ec..99d46b5 100644 --- a/src/plugins/ivimedia/ivimedia.pro +++ b/src/plugins/ivimedia/ivimedia.pro @@ -4,6 +4,7 @@ QT_FOR_CONFIG += ivimedia-private qtConfig(tuner_simulation_backend): SUBDIRS += tuner_simulator qtConfig(media_simulation_backend): SUBDIRS += media_simulator +qtConfig(media_qtro_backend): SUBDIRS += media_qtro OTHER_FILES += \ $$PWD/doc/*.qdocconf \ diff --git a/src/plugins/ivimedia/media_qtro/media_qtro.json b/src/plugins/ivimedia/media_qtro/media_qtro.json new file mode 100644 index 0000000..277fbc6 --- /dev/null +++ b/src/plugins/ivimedia/media_qtro/media_qtro.json @@ -0,0 +1,9 @@ +{ + "interfaces" : [ + "org.qt-project.qtivi.MediaPlayer/1.0", + "org.qt-project.qtivi.SearchAndBrowseModel/1.0", + "org.qt-project.qtivi.MediaDiscovery/1.0", + "org.qt-project.qtivi.MediaIndexer/1.0", + "org.qt-project.qtivi.MediaDiscovery/1.0" + ] +} diff --git a/src/plugins/ivimedia/media_qtro/media_qtro.pro b/src/plugins/ivimedia/media_qtro/media_qtro.pro new file mode 100644 index 0000000..6967890 --- /dev/null +++ b/src/plugins/ivimedia/media_qtro/media_qtro.pro @@ -0,0 +1,33 @@ +TARGET = media_qtro + +PLUGIN_TYPE = qtivi +PLUGIN_EXTENDS = ivimedia +PLUGIN_CLASS_NAME = MediaPlugin + +load(qt_plugin) + +DISTFILES += media_qtro.json + +QT += ivicore ivimedia remoteobjects + +HEADERS += \ + mediaplugin.h \ + mediaplayerbackend.h \ + mediaindexerbackend.h \ + searchandbrowsemodel.h \ + mediadiscoverybackend.h \ + usbdevice.h + +SOURCES += \ + mediaplugin.cpp \ + mediaplayerbackend.cpp \ + mediaindexerbackend.cpp \ + searchandbrowsemodel.cpp \ + mediadiscoverybackend.cpp \ + usbdevice.cpp + +REPC_REPLICA += \ + $$PWD/../../../tools/media-simulation-server/qivimediaindexer.rep \ + $$PWD/../../../tools/media-simulation-server/qivimediaplayer.rep \ + $$PWD/../../../tools/media-simulation-server/qivisearchandbrowsemodel.rep \ + $$PWD/../../../tools/media-simulation-server/qivimediadiscoverymodel.rep \ diff --git a/src/plugins/ivimedia/media_qtro/mediadiscoverybackend.cpp b/src/plugins/ivimedia/media_qtro/mediadiscoverybackend.cpp new file mode 100644 index 0000000..30ae5b8 --- /dev/null +++ b/src/plugins/ivimedia/media_qtro/mediadiscoverybackend.cpp @@ -0,0 +1,125 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Luxoft Sweden AB +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtIvi module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL-QTAS$ +** Commercial License Usage +** Licensees holding valid commercial Qt Automotive Suite licenses may use +** this file in accordance with the commercial license agreement provided +** with the Software or, alternatively, in accordance with the terms +** contained in a written agreement between you and The Qt Company. For +** licensing terms and conditions see https://www.qt.io/terms-conditions. +** For further information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +** SPDX-License-Identifier: LGPL-3.0 +** +****************************************************************************/ + +#include "mediadiscoverybackend.h" +#include "usbdevice.h" + +#include <QtDebug> +#include <QTimer> + +Q_LOGGING_CATEGORY(qLcROQIviMediaDiscovery, "qtivi.media.qivimediadiscoverybackend.remoteobjects", QtInfoMsg) + +MediaDiscoveryBackend::MediaDiscoveryBackend(QRemoteObjectNode *node, QObject *parent) + : QIviMediaDeviceDiscoveryModelBackendInterface(parent) + , m_initialized(false) +{ + m_replica.reset(node->acquire<QIviMediaDiscoveryModelReplica>(QStringLiteral("QtIviMedia.QIviMediaDiscoveryModel"))); + + connect(node, &QRemoteObjectNode::error, this, &MediaDiscoveryBackend::onNodeError); + connect(m_replica.data(), &QRemoteObjectReplica::initialized, this, &QIviFeatureInterface::initializationDone); + connect(m_replica.data(), &QRemoteObjectReplica::stateChanged, this, &MediaDiscoveryBackend::onReplicaStateChanged); + connect(m_replica.data(), &QIviMediaDiscoveryModelReplica::devicesChanged, this, &MediaDiscoveryBackend::onDevicesChanged); + connect(m_replica.data(), &QIviMediaDiscoveryModelReplica::deviceAdded, this, &MediaDiscoveryBackend::onDeviceAdded); + connect(m_replica.data(), &QIviMediaDiscoveryModelReplica::deviceRemoved, this, &MediaDiscoveryBackend::onDeviceRemoved); + + QTimer::singleShot(3000, this, [this](){ + if (!m_replica->isInitialized()) + qCCritical(qLcROQIviMediaDiscovery) << "QtIviMedia.QIviMediaDiscoveryModel wasn't initialized within the timeout period. Please make sure the server is running."; + }); +} + +void MediaDiscoveryBackend::initialize() +{ + if (m_replica->isInitialized()) { + onDevicesChanged(m_replica->devices()); + emit initializationDone(); + } +} + +void MediaDiscoveryBackend::onDevicesChanged(const QStringList &devices) +{ + if (m_initialized) + return; + + for (const QString &device : devices) { + qCInfo(qLcROQIviMediaDiscovery) << "Adding USB Device: " << device; + m_deviceMap.insert(device, new USBDevice(device)); + } + emit availableDevices(m_deviceMap.values()); + m_initialized = true; +} + +void MediaDiscoveryBackend::onDeviceAdded(const QString &device) +{ + USBDevice *dev = new USBDevice(device); + m_deviceMap.insert(device, dev); + emit deviceAdded(dev); +} + +void MediaDiscoveryBackend::onDeviceRemoved(const QString &device) +{ + QIviServiceObject *dev = m_deviceMap.take(device); + emit deviceRemoved(dev); + dev->deleteLater(); +} + +void MediaDiscoveryBackend::onReplicaStateChanged(QRemoteObjectReplica::State newState, QRemoteObjectReplica::State oldState) +{ + Q_UNUSED(oldState) + + if (newState == QRemoteObjectReplica::Suspect) { + qCWarning(qLcROQIviMediaDiscovery) << "QRemoteObjectReplica error, connection to the source lost"; + emit errorChanged(QIviAbstractFeature::Unknown, + "QRemoteObjectReplica error, connection to the source lost"); + } else if (newState == QRemoteObjectReplica::SignatureMismatch) { + qCWarning(qLcROQIviMediaDiscovery) << "QRemoteObjectReplica error, signature mismatch"; + emit errorChanged(QIviAbstractFeature::Unknown, + "QRemoteObjectReplica error, signature mismatch"); + } else if (newState==QRemoteObjectReplica::Valid) { + emit errorChanged(QIviAbstractFeature::NoError, ""); + } +} + +void MediaDiscoveryBackend::onNodeError(QRemoteObjectNode::ErrorCode code) +{ + qCWarning(qLcROQIviMediaDiscovery) << "QRemoteObjectNode error, code: " << code; + emit errorChanged(QIviAbstractFeature::Unknown, "QRemoteObjectNode error, code: " + code); +} diff --git a/src/plugins/ivimedia/media_qtro/mediadiscoverybackend.h b/src/plugins/ivimedia/media_qtro/mediadiscoverybackend.h new file mode 100644 index 0000000..14e78c1 --- /dev/null +++ b/src/plugins/ivimedia/media_qtro/mediadiscoverybackend.h @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Luxoft Sweden AB +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtIvi module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL-QTAS$ +** Commercial License Usage +** Licensees holding valid commercial Qt Automotive Suite licenses may use +** this file in accordance with the commercial license agreement provided +** with the Software or, alternatively, in accordance with the terms +** contained in a written agreement between you and The Qt Company. For +** licensing terms and conditions see https://www.qt.io/terms-conditions. +** For further information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +** SPDX-License-Identifier: LGPL-3.0 +** +****************************************************************************/ + +#ifndef MEDIADISCOVERYBACKEND_H +#define MEDIADISCOVERYBACKEND_H + +#include <QtIviMedia/QIviMediaDeviceDiscoveryModelBackendInterface> +#include <QtIviCore/QIviServiceObject> +#include <QRemoteObjectNode> + +#include "rep_qivimediadiscoverymodel_replica.h" + +class MediaDiscoveryBackend : public QIviMediaDeviceDiscoveryModelBackendInterface +{ + Q_OBJECT + +public: + MediaDiscoveryBackend(QRemoteObjectNode *node, QObject *parent = nullptr); + + void initialize() override; + +public Q_SLOTS: + void onReplicaStateChanged(QRemoteObjectReplica::State newState, + QRemoteObjectReplica::State oldState); + void onNodeError(QRemoteObjectNode::ErrorCode code); + + void onDevicesChanged(const QStringList &devices); + void onDeviceAdded(const QString &device); + void onDeviceRemoved(const QString &device); + +private: + QSharedPointer<QIviMediaDiscoveryModelReplica> m_replica; + QHash<QString, QIviServiceObject*> m_deviceMap; + bool m_initialized; +}; + +#endif // MEDIADISCOVERYBACKEND_H diff --git a/src/plugins/ivimedia/media_qtro/mediaindexerbackend.cpp b/src/plugins/ivimedia/media_qtro/mediaindexerbackend.cpp new file mode 100644 index 0000000..bdc26ab --- /dev/null +++ b/src/plugins/ivimedia/media_qtro/mediaindexerbackend.cpp @@ -0,0 +1,105 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Luxoft Sweden AB +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtIVI module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL-QTAS$ +** Commercial License Usage +** Licensees holding valid commercial Qt Automotive Suite licenses may use +** this file in accordance with the commercial license agreement provided +** with the Software or, alternatively, in accordance with the terms +** contained in a written agreement between you and The Qt Company. For +** licensing terms and conditions see https://www.qt.io/terms-conditions. +** For further information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +** SPDX-License-Identifier: LGPL-3.0 +** +****************************************************************************/ + +#include "mediaindexerbackend.h" + +#include <QTimer> + +Q_LOGGING_CATEGORY(qLcROQIviMediaIndexer, "qtivi.media.qivimediaindexerbackend.remoteobjects", QtInfoMsg) + +MediaIndexerBackend::MediaIndexerBackend(QRemoteObjectNode *node, QObject *parent) + : QIviMediaIndexerControlBackendInterface(parent) +{ + m_replica.reset(node->acquire<QIviMediaIndexerReplica>(QStringLiteral("QtIviMedia.QIviMediaIndexer"))); + + connect(node, &QRemoteObjectNode::error, this, &MediaIndexerBackend::onNodeError); + connect(m_replica.data(), &QRemoteObjectReplica::initialized, this, &QIviFeatureInterface::initializationDone); + connect(m_replica.data(), &QRemoteObjectReplica::stateChanged, this, &MediaIndexerBackend::onReplicaStateChanged); + connect(m_replica.data(), &QIviMediaIndexerReplica::stateChanged, this, &MediaIndexerBackend::stateChanged); + connect(m_replica.data(), &QIviMediaIndexerReplica::progressChanged, this, &MediaIndexerBackend::progressChanged); + + QTimer::singleShot(3000, this, [this](){ + if (!m_replica->isInitialized()) + qCCritical(qLcROQIviMediaIndexer) << "QtIviMedia.QIviMediaIndexer wasn't initialized within the timeout period. Please make sure the server is running."; + }); +} + +void MediaIndexerBackend::initialize() +{ + if (m_replica->isInitialized()) { + emit progressChanged(m_replica->progress()); + emit stateChanged(m_replica->state()); + emit initializationDone(); + } +} + +void MediaIndexerBackend::pause() +{ + m_replica->pause(); +} + +void MediaIndexerBackend::resume() +{ + m_replica->resume(); +} + +void MediaIndexerBackend::onReplicaStateChanged(QRemoteObjectReplica::State newState, QRemoteObjectReplica::State oldState) +{ + Q_UNUSED(oldState) + + if (newState == QRemoteObjectReplica::Suspect) { + qCWarning(qLcROQIviMediaIndexer) << "QRemoteObjectReplica error, connection to the source lost"; + emit errorChanged(QIviAbstractFeature::Unknown, + "QRemoteObjectReplica error, connection to the source lost"); + } else if (newState == QRemoteObjectReplica::SignatureMismatch) { + qCWarning(qLcROQIviMediaIndexer) << "QRemoteObjectReplica error, signature mismatch"; + emit errorChanged(QIviAbstractFeature::Unknown, + "QRemoteObjectReplica error, signature mismatch"); + } else if (newState==QRemoteObjectReplica::Valid) { + emit errorChanged(QIviAbstractFeature::NoError, ""); + } +} + +void MediaIndexerBackend::onNodeError(QRemoteObjectNode::ErrorCode code) +{ + qCWarning(qLcROQIviMediaIndexer) << "QRemoteObjectNode error, code: " << code; + emit errorChanged(QIviAbstractFeature::Unknown, "QRemoteObjectNode error, code: " + code); +} diff --git a/src/plugins/ivimedia/media_qtro/mediaindexerbackend.h b/src/plugins/ivimedia/media_qtro/mediaindexerbackend.h new file mode 100644 index 0000000..add4010 --- /dev/null +++ b/src/plugins/ivimedia/media_qtro/mediaindexerbackend.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Luxoft Sweden AB +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtIVI module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL-QTAS$ +** Commercial License Usage +** Licensees holding valid commercial Qt Automotive Suite licenses may use +** this file in accordance with the commercial license agreement provided +** with the Software or, alternatively, in accordance with the terms +** contained in a written agreement between you and The Qt Company. For +** licensing terms and conditions see https://www.qt.io/terms-conditions. +** For further information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +** SPDX-License-Identifier: LGPL-3.0 +** +****************************************************************************/ + +#ifndef MEDIAINDEXERBACKEND_H +#define MEDIAINDEXERBACKEND_H + +#include <QtIviMedia/QIviMediaIndexerControlBackendInterface> +#include <QRemoteObjectNode> + +#include "rep_qivimediaindexer_replica.h" + +class MediaIndexerBackend : public QIviMediaIndexerControlBackendInterface +{ +public: + MediaIndexerBackend(QRemoteObjectNode *node, QObject *parent = nullptr); + +public: + void initialize() override; + void pause() override; + void resume() override; + +public Q_SLOTS: + void onReplicaStateChanged(QRemoteObjectReplica::State newState, + QRemoteObjectReplica::State oldState); + void onNodeError(QRemoteObjectNode::ErrorCode code); + +private: + QSharedPointer<QIviMediaIndexerReplica> m_replica; +}; + +#endif // MEDIAINDEXERBACKEND_H diff --git a/src/plugins/ivimedia/media_qtro/mediaplayerbackend.cpp b/src/plugins/ivimedia/media_qtro/mediaplayerbackend.cpp new file mode 100644 index 0000000..983dd35 --- /dev/null +++ b/src/plugins/ivimedia/media_qtro/mediaplayerbackend.cpp @@ -0,0 +1,192 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Luxoft Sweden AB +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtIVI module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL-QTAS$ +** Commercial License Usage +** Licensees holding valid commercial Qt Automotive Suite licenses may use +** this file in accordance with the commercial license agreement provided +** with the Software or, alternatively, in accordance with the terms +** contained in a written agreement between you and The Qt Company. For +** licensing terms and conditions see https://www.qt.io/terms-conditions. +** For further information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +** SPDX-License-Identifier: LGPL-3.0 +** +****************************************************************************/ + +#include "mediaplayerbackend.h" +#include "qiviqmlconversion_helper.h" + +#include <QTimer> + +Q_LOGGING_CATEGORY(qLcROQIviMediaPlayer, "qtivi.media.qivimediaplayerbackend.remoteobjects", QtInfoMsg) + +MediaPlayerBackend::MediaPlayerBackend(QRemoteObjectNode *node, QObject *parent) + : QIviMediaPlayerBackendInterface(parent) +{ + qRegisterMetaType<QIviPlayableItem>(); + qRegisterMetaType<QIviAudioTrackItem>(); + qRegisterMetaTypeStreamOperators<QIviAudioTrackItem>(); + + m_replica.reset(node->acquire<QIviMediaPlayerReplica>(QStringLiteral("QtIviMedia.QIviMediaPlayer"))); + + connect(node, &QRemoteObjectNode::error, this, &MediaPlayerBackend::onNodeError); + connect(m_replica.data(), &QRemoteObjectReplica::initialized, this, &QIviFeatureInterface::initializationDone); + connect(m_replica.data(), &QRemoteObjectReplica::stateChanged, this, &MediaPlayerBackend::onReplicaStateChanged); + connect(m_replica.data(), &QIviMediaPlayerReplica::playModeChanged, this, &MediaPlayerBackend::playModeChanged); + connect(m_replica.data(), &QIviMediaPlayerReplica::playStateChanged, this, &MediaPlayerBackend::playStateChanged); + connect(m_replica.data(), &QIviMediaPlayerReplica::positionChanged, this, &MediaPlayerBackend::positionChanged); + connect(m_replica.data(), &QIviMediaPlayerReplica::durationChanged, this, &MediaPlayerBackend::durationChanged); + connect(m_replica.data(), &QIviMediaPlayerReplica::currentTrackChanged, this, &MediaPlayerBackend::currentTrackChanged); + connect(m_replica.data(), &QIviMediaPlayerReplica::currentIndexChanged, this, &MediaPlayerBackend::currentIndexChanged); + connect(m_replica.data(), &QIviMediaPlayerReplica::volumeChanged, this, &MediaPlayerBackend::volumeChanged); + connect(m_replica.data(), &QIviMediaPlayerReplica::mutedChanged, this, &MediaPlayerBackend::mutedChanged); + connect(m_replica.data(), &QIviMediaPlayerReplica::countChanged, this, &MediaPlayerBackend::countChanged); + connect(m_replica.data(), &QIviMediaPlayerReplica::canReportCountChanged, this, &MediaPlayerBackend::canReportCountChanged); + connect(m_replica.data(), &QIviMediaPlayerReplica::dataFetched, this, &MediaPlayerBackend::dataFetched); + connect(m_replica.data(), &QIviMediaPlayerReplica::dataChanged, this, &MediaPlayerBackend::dataChanged); + + QTimer::singleShot(3000, this, [this](){ + if (!m_replica->isInitialized()) + qCCritical(qLcROQIviMediaPlayer) << "QtIviMedia.QIviMediaPlayer wasn't initialized within the timeout period. Please make sure the server is running."; + }); +} + +void MediaPlayerBackend::initialize() +{ + if (m_replica->isInitialized()) { + emit canReportCountChanged(m_replica->canReportCount()); + emit playModeChanged(m_replica->playMode()); + emit playStateChanged(m_replica->playState()); + emit positionChanged(m_replica->position()); + emit durationChanged(m_replica->duration()); + emit currentTrackChanged(m_replica->currentTrack()); + emit currentIndexChanged(m_replica->currentIndex()); + emit volumeChanged(m_replica->volume()); + emit mutedChanged(m_replica->muted()); + emit initializationDone(); + } +} + +void MediaPlayerBackend::play() +{ + m_replica->play(); +} + +void MediaPlayerBackend::pause() +{ + m_replica->pause(); +} + +void MediaPlayerBackend::stop() +{ + m_replica->stop(); +} + +void MediaPlayerBackend::seek(qint64 offset) +{ + m_replica->seek(offset); +} + +void MediaPlayerBackend::next() +{ + m_replica->next(); +} + +void MediaPlayerBackend::previous() +{ + m_replica->previous(); +} + +void MediaPlayerBackend::setPlayMode(QIviMediaPlayer::PlayMode playMode) +{ + m_replica->pushPlayMode(playMode); +} + +void MediaPlayerBackend::setPosition(qint64 position) +{ + m_replica->pushPosition(position); +} + +void MediaPlayerBackend::setCurrentIndex(int currentIndex) +{ + m_replica->pushCurrentIndex(currentIndex); +} + +void MediaPlayerBackend::setVolume(int volume) +{ + m_replica->pushVolume(volume); +} + +void MediaPlayerBackend::setMuted(bool muted) +{ + m_replica->pushMuted(muted); +} + +void MediaPlayerBackend::fetchData(const QUuid &identifier, int start, int count) +{ + m_replica->fetchData(identifier, start, count); +} + +void MediaPlayerBackend::insert(int index, const QVariant &item) +{ + m_replica->insert(index, item); +} + +void MediaPlayerBackend::remove(int index) +{ + m_replica->remove(index); +} + +void MediaPlayerBackend::move(int currentIndex, int newIndex) +{ + m_replica->move(currentIndex, newIndex); +} + +void MediaPlayerBackend::onReplicaStateChanged(QRemoteObjectReplica::State newState, QRemoteObjectReplica::State oldState) +{ + Q_UNUSED(oldState) + + if (newState == QRemoteObjectReplica::Suspect) { + qCWarning(qLcROQIviMediaPlayer) << "QRemoteObjectReplica error, connection to the source lost"; + emit errorChanged(QIviAbstractFeature::Unknown, + "QRemoteObjectReplica error, connection to the source lost"); + } else if (newState == QRemoteObjectReplica::SignatureMismatch) { + qCWarning(qLcROQIviMediaPlayer) << "QRemoteObjectReplica error, signature mismatch"; + emit errorChanged(QIviAbstractFeature::Unknown, + "QRemoteObjectReplica error, signature mismatch"); + } else if (newState==QRemoteObjectReplica::Valid) { + emit errorChanged(QIviAbstractFeature::NoError, ""); + } +} + +void MediaPlayerBackend::onNodeError(QRemoteObjectNode::ErrorCode code) +{ + qCWarning(qLcROQIviMediaPlayer) << "QRemoteObjectNode error, code: " << code; + emit errorChanged(QIviAbstractFeature::Unknown, "QRemoteObjectNode error, code: " + code); +} diff --git a/src/plugins/ivimedia/media_qtro/mediaplayerbackend.h b/src/plugins/ivimedia/media_qtro/mediaplayerbackend.h new file mode 100644 index 0000000..3f951e4 --- /dev/null +++ b/src/plugins/ivimedia/media_qtro/mediaplayerbackend.h @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Luxoft Sweden AB +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtIVI module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL-QTAS$ +** Commercial License Usage +** Licensees holding valid commercial Qt Automotive Suite licenses may use +** this file in accordance with the commercial license agreement provided +** with the Software or, alternatively, in accordance with the terms +** contained in a written agreement between you and The Qt Company. For +** licensing terms and conditions see https://www.qt.io/terms-conditions. +** For further information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +** SPDX-License-Identifier: LGPL-3.0 +** +****************************************************************************/ + +#ifndef MEDIAPLAYERBACKEND_H +#define MEDIAPLAYERBACKEND_H + +#include <QtIviMedia/QIviMediaPlayerBackendInterface> +#include <QRemoteObjectNode> +#include "rep_qivimediaplayer_replica.h" + +class MediaPlayerBackend : public QIviMediaPlayerBackendInterface +{ +public: + MediaPlayerBackend(QRemoteObjectNode *node, QObject *parent = nullptr); + +public: + void initialize() override; + void play() override; + void pause() override; + void stop() override; + void seek(qint64 offset) override; + void next() override; + void previous() override; + void setPlayMode(QIviMediaPlayer::PlayMode playMode) override; + void setPosition(qint64 position) override; + void setCurrentIndex(int currentIndex) override; + void setVolume(int volume) override; + void setMuted(bool muted) override; + void fetchData(const QUuid &identifier, int start, int count) override; + void insert(int index, const QVariant &item) override; + void remove(int index) override; + void move(int currentIndex, int newIndex) override; + +public Q_SLOTS: + void onReplicaStateChanged(QRemoteObjectReplica::State newState, + QRemoteObjectReplica::State oldState); + void onNodeError(QRemoteObjectNode::ErrorCode code); + +private: + QSharedPointer<QIviMediaPlayerReplica> m_replica; +}; + +#endif // MEDIAPLAYERBACKEND_H diff --git a/src/plugins/ivimedia/media_qtro/mediaplugin.cpp b/src/plugins/ivimedia/media_qtro/mediaplugin.cpp new file mode 100644 index 0000000..1a0b5e0 --- /dev/null +++ b/src/plugins/ivimedia/media_qtro/mediaplugin.cpp @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtIvi module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL-QTAS$ +** Commercial License Usage +** Licensees holding valid commercial Qt Automotive Suite licenses may use +** this file in accordance with the commercial license agreement provided +** with the Software or, alternatively, in accordance with the terms +** contained in a written agreement between you and The Qt Company. For +** licensing terms and conditions see https://www.qt.io/terms-conditions. +** For further information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +** SPDX-License-Identifier: LGPL-3.0 +** +****************************************************************************/ + +#include "mediaplugin.h" +#include "mediaplayerbackend.h" +#include "mediaindexerbackend.h" +#include "searchandbrowsemodel.h" +#include "mediadiscoverybackend.h" + +#include <QtIviMedia/QIviMediaPlayer> + +#include <QCoreApplication> +#include <QStringList> +#include <QtDebug> +#include <QSettings> +#include <QRemoteObjectNode> + +MediaPlugin::MediaPlugin(QObject *parent) + : QObject(parent) +{ + QString configPath(QStringLiteral("./server.conf")); + if (qEnvironmentVariableIsSet("SERVER_CONF_PATH")) + configPath = QString::fromLocal8Bit(qgetenv("SERVER_CONF_PATH")); + else + qInfo() << "Environment variable SERVER_CONF_PATH not defined, using " << configPath; + QSettings settings(configPath, QSettings::IniFormat); + settings.beginGroup(QStringLiteral("remote")); + QUrl url = QUrl(settings.value(QStringLiteral("Registry"), QStringLiteral("local:qtivimedia")).toString()); + QRemoteObjectNode *node = new QRemoteObjectNode(url); + + m_player = new MediaPlayerBackend(node, this); + m_indexer = new MediaIndexerBackend(node, this); + m_searchModel = new SearchAndBrowseModel(node, this); + m_discovery = new MediaDiscoveryBackend(node, this); +} + +QStringList MediaPlugin::interfaces() const +{ + QStringList list; + + list << QStringLiteral(QIviMediaPlayer_iid); + list << QStringLiteral(QIviMediaIndexer_iid); + list << QStringLiteral(QIviSearchAndBrowseModel_iid); + list << QStringLiteral(QIviMediaDeviceDiscovery_iid); + return list; +} + +QIviFeatureInterface *MediaPlugin::interfaceInstance(const QString &interface) const +{ + if (interface == QStringLiteral(QIviMediaPlayer_iid)) + return m_player; + else if (interface == QStringLiteral(QIviMediaIndexer_iid)) + return m_indexer; + else if (interface == QStringLiteral(QIviSearchAndBrowseModel_iid)) + return m_searchModel; + else if (interface == QStringLiteral(QIviMediaDeviceDiscovery_iid)) + return m_discovery; + + return nullptr; +} diff --git a/src/plugins/ivimedia/media_qtro/mediaplugin.h b/src/plugins/ivimedia/media_qtro/mediaplugin.h new file mode 100644 index 0000000..79bad77 --- /dev/null +++ b/src/plugins/ivimedia/media_qtro/mediaplugin.h @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Luxoft Sweden AB +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtIvi module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL-QTAS$ +** Commercial License Usage +** Licensees holding valid commercial Qt Automotive Suite licenses may use +** this file in accordance with the commercial license agreement provided +** with the Software or, alternatively, in accordance with the terms +** contained in a written agreement between you and The Qt Company. For +** licensing terms and conditions see https://www.qt.io/terms-conditions. +** For further information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +** SPDX-License-Identifier: LGPL-3.0 +** +****************************************************************************/ + +#ifndef MEDIAPLUGIN_H +#define MEDIAPLUGIN_H + +#include <QtIviCore/QIviServiceInterface> + +class MediaPlayerBackend; +class MediaIndexerBackend; +class SearchAndBrowseModel; +class MediaDiscoveryBackend; + +class MediaPlugin : public QObject, QIviServiceInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID QIviServiceInterface_iid FILE "media_qtro.json") + Q_INTERFACES(QIviServiceInterface) + +public: + explicit MediaPlugin(QObject *parent = nullptr); + + QStringList interfaces() const override; + QIviFeatureInterface *interfaceInstance(const QString &interface) const override; + +private: + + MediaPlayerBackend *m_player; + MediaIndexerBackend *m_indexer; + SearchAndBrowseModel *m_searchModel; + MediaDiscoveryBackend *m_discovery; +}; + +#endif // MEDIAPLUGIN_H diff --git a/src/plugins/ivimedia/media_qtro/searchandbrowsemodel.cpp b/src/plugins/ivimedia/media_qtro/searchandbrowsemodel.cpp new file mode 100644 index 0000000..6297b5a --- /dev/null +++ b/src/plugins/ivimedia/media_qtro/searchandbrowsemodel.cpp @@ -0,0 +1,384 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Luxoft Sweden AB +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtIVI module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL-QTAS$ +** Commercial License Usage +** Licensees holding valid commercial Qt Automotive Suite licenses may use +** this file in accordance with the commercial license agreement provided +** with the Software or, alternatively, in accordance with the terms +** contained in a written agreement between you and The Qt Company. For +** licensing terms and conditions see https://www.qt.io/terms-conditions. +** For further information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +** SPDX-License-Identifier: LGPL-3.0 +** +****************************************************************************/ + +#include "searchandbrowsemodel.h" +#include "qiviqmlconversion_helper.h" + +#include <QTimer> + +Q_LOGGING_CATEGORY(qLcROQIviSearchAndBrowseModel, "qtivi.media.qivisearchandbrowsebackend.remoteobjects", QtInfoMsg) + +QDataStream &operator<<(QDataStream &stream, const SearchAndBrowseItem &obj) +{ + stream << obj.name(); + stream << obj.type(); + stream << obj.url(); + stream << QVariant(obj.data()); + return stream; +} + +QDataStream &operator>>(QDataStream &stream, SearchAndBrowseItem &obj) +{ + QString name; + QString type; + QUrl url; + QVariant data; + stream >> name; + stream >> type; + stream >> url; + stream >> data; + obj.setName(name); + obj.setType(type); + obj.setUrl(url); + obj.setData(data.toMap()); + return stream; +} + +SearchAndBrowseModel::SearchAndBrowseModel(QRemoteObjectNode *node, QObject *parent) + : QIviSearchAndBrowseModelInterface(parent) +{ + qRegisterMetaType<SearchAndBrowseItem>(); + qRegisterMetaTypeStreamOperators<SearchAndBrowseItem>(); + qRegisterMetaType<QIviAudioTrackItem>(); + qRegisterMetaTypeStreamOperators<QIviAudioTrackItem>(); + + m_replica.reset(node->acquire<QIviSearchAndBrowseModelReplica>(QStringLiteral("QIviSearchAndBrowseModel"))); + + connect(node, &QRemoteObjectNode::error, this, &SearchAndBrowseModel::onNodeError); + connect(m_replica.data(), &QRemoteObjectReplica::initialized, this, &QIviFeatureInterface::initializationDone); + connect(m_replica.data(), &QRemoteObjectReplica::stateChanged, this, &SearchAndBrowseModel::onReplicaStateChanged); + connect(m_replica.data(), &QIviSearchAndBrowseModelReplica::pendingResultAvailable, this, &SearchAndBrowseModel::onPendingResultAvailable); + connect(m_replica.data(), &QIviSearchAndBrowseModelReplica::canGoBackChanged, this, &SearchAndBrowseModel::canGoBackChanged); + connect(m_replica.data(), &QIviSearchAndBrowseModelReplica::canGoForwardChanged, this, &SearchAndBrowseModel::canGoForwardChanged); + connect(m_replica.data(), &QIviSearchAndBrowseModelReplica::supportedCapabilitiesChanged, this, &SearchAndBrowseModel::supportedCapabilitiesChanged); + connect(m_replica.data(), &QIviSearchAndBrowseModelReplica::queryIdentifiersChanged, this, &SearchAndBrowseModel::queryIdentifiersChanged); + connect(m_replica.data(), &QIviSearchAndBrowseModelReplica::availableContentTypesChanged, this, &SearchAndBrowseModel::availableContentTypesChanged); + connect(m_replica.data(), &QIviSearchAndBrowseModelReplica::contentTypeChanged, this, &SearchAndBrowseModel::contentTypeChanged); + connect(m_replica.data(), &QIviSearchAndBrowseModelReplica::countChanged, this, &SearchAndBrowseModel::countChanged); + connect(m_replica.data(), &QIviSearchAndBrowseModelReplica::dataFetched, this, &SearchAndBrowseModel::dataFetched); + connect(m_replica.data(), &QIviSearchAndBrowseModelReplica::dataChanged, this, &SearchAndBrowseModel::dataChanged); + + QTimer::singleShot(3000, this, [this](){ + if (!m_replica->isInitialized()) + qCCritical(qLcROQIviSearchAndBrowseModel) << "QIviSearchAndBrowseModel wasn't initialized within the timeout period. Please make sure the server is running."; + }); +} + +void SearchAndBrowseModel::initialize() +{ + if (m_replica->isInitialized()) { + emit availableContentTypesChanged(m_replica->availableContentTypes()); + emit initializationDone(); + } +} + +void SearchAndBrowseModel::registerInstance(const QUuid &identifier) +{ + m_replica->registerInstance(identifier); +} + +void SearchAndBrowseModel::unregisterInstance(const QUuid &identifier) +{ + m_replica->unregisterInstance(identifier); +} + +void SearchAndBrowseModel::fetchData(const QUuid &identifier, int start, int count) +{ + m_replica->fetchData(identifier, start, count); +} + +void SearchAndBrowseModel::setContentType(const QUuid &identifier, const QString &contentType) +{ + m_replica->setContentType(identifier, contentType); +} + +void SearchAndBrowseModel::setupFilter(const QUuid &identifier, QIviAbstractQueryTerm *term, const QList<QIviOrderTerm> &orderTerms) +{ + QByteArray data; + QDataStream stream(&data, QIODevice::WriteOnly); + if (term) + stream << term; + m_replica->setupFilter(identifier, QVariant(data), orderTerms); +} + +QIviPendingReply<QString> SearchAndBrowseModel::goBack(const QUuid &identifier) +{ + QIviPendingReply<QString> iviReply; + QRemoteObjectPendingReply<QVariant> reply = m_replica->goBack(identifier); + auto watcher = new QRemoteObjectPendingCallWatcher(reply); + connect(watcher, &QRemoteObjectPendingCallWatcher::finished, this, [this, iviReply](QRemoteObjectPendingCallWatcher *self) mutable { + if (self->error() == QRemoteObjectPendingCallWatcher::NoError) { +#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 1) + QVariant value = self->returnValue(); +#else + QVariant value = self->returnValue().value<QVariant>(); +#endif + if (value.canConvert<QIviSearchAndBrowseModelPendingResult>()) { + QIviSearchAndBrowseModelPendingResult result = value.value<QIviSearchAndBrowseModelPendingResult>(); + if (result.failed()) { + qCDebug(qLcROQIviSearchAndBrowseModel) << "Pending Result with id:" << result.id() << "failed"; + iviReply.setFailed(); + } else { + qCDebug(qLcROQIviSearchAndBrowseModel) << "Result not available yet. Waiting for id:" << result.id(); + m_pendingReplies.insert(result.id(), iviReply); + } + } else { + qCDebug(qLcROQIviSearchAndBrowseModel) << "Got the value right away:" << value.value<QString>(); + iviReply.setSuccess(value.toString()); + } + } else { + iviReply.setFailed(); + emit errorChanged(QIviAbstractFeature::InvalidOperation, QStringLiteral("remote call of method insert failed")); + } + self->deleteLater(); + }); + return iviReply; +} + +QIviPendingReply<QString> SearchAndBrowseModel::goForward(const QUuid &identifier, int index) +{ + QIviPendingReply<QString> iviReply; + QRemoteObjectPendingReply<QVariant> reply = m_replica->goForward(identifier, index); + auto watcher = new QRemoteObjectPendingCallWatcher(reply); + connect(watcher, &QRemoteObjectPendingCallWatcher::finished, this, [this, iviReply](QRemoteObjectPendingCallWatcher *self) mutable { + if (self->error() == QRemoteObjectPendingCallWatcher::NoError) { +#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 1) + QVariant value = self->returnValue(); +#else + QVariant value = self->returnValue().value<QVariant>(); +#endif + if (value.canConvert<QIviSearchAndBrowseModelPendingResult>()) { + QIviSearchAndBrowseModelPendingResult result = value.value<QIviSearchAndBrowseModelPendingResult>(); + if (result.failed()) { + qCDebug(qLcROQIviSearchAndBrowseModel) << "Pending Result with id:" << result.id() << "failed"; + iviReply.setFailed(); + } else { + qCDebug(qLcROQIviSearchAndBrowseModel) << "Result not available yet. Waiting for id:" << result.id(); + m_pendingReplies.insert(result.id(), iviReply); + } + } else { + qCDebug(qLcROQIviSearchAndBrowseModel) << "Got the value right away:" << value.value<QString>(); + iviReply.setSuccess(value.toString()); + } + } else { + iviReply.setFailed(); + emit errorChanged(QIviAbstractFeature::InvalidOperation, QStringLiteral("remote call of method insert failed")); + } + self->deleteLater(); + }); + return iviReply; +} + +QIviPendingReply<void> SearchAndBrowseModel::insert(const QUuid &identifier, int index, const QVariant &item) +{ + QIviPendingReply<void> iviReply; + QRemoteObjectPendingReply<QVariant> reply = m_replica->insert(identifier, index, item); + auto watcher = new QRemoteObjectPendingCallWatcher(reply); + connect(watcher, &QRemoteObjectPendingCallWatcher::finished, this, [this, iviReply](QRemoteObjectPendingCallWatcher *self) mutable { + if (self->error() == QRemoteObjectPendingCallWatcher::NoError) { +#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 1) + QVariant value = self->returnValue(); +#else + QVariant value = self->returnValue().value<QVariant>(); +#endif + if (value.canConvert<QIviSearchAndBrowseModelPendingResult>()) { + QIviSearchAndBrowseModelPendingResult result = value.value<QIviSearchAndBrowseModelPendingResult>(); + if (result.failed()) { + qCDebug(qLcROQIviSearchAndBrowseModel) << "Pending Result with id:" << result.id() << "failed"; + iviReply.setFailed(); + } else { + qCDebug(qLcROQIviSearchAndBrowseModel) << "Result not available yet. Waiting for id:" << result.id(); + m_pendingReplies.insert(result.id(), iviReply); + } + } else { + qCDebug(qLcROQIviSearchAndBrowseModel) << "Got the value right away: void"; + iviReply.setSuccess(); + } + } else { + iviReply.setFailed(); + emit errorChanged(QIviAbstractFeature::InvalidOperation, QStringLiteral("remote call of method insert failed")); + } + self->deleteLater(); + }); + return iviReply; +} + +QIviPendingReply<void> SearchAndBrowseModel::remove(const QUuid &identifier, int index) +{ + QIviPendingReply<void> iviReply; + QRemoteObjectPendingReply<QVariant> reply = m_replica->remove(identifier, index); + auto watcher = new QRemoteObjectPendingCallWatcher(reply); + connect(watcher, &QRemoteObjectPendingCallWatcher::finished, this, [this, iviReply](QRemoteObjectPendingCallWatcher *self) mutable { + if (self->error() == QRemoteObjectPendingCallWatcher::NoError) { +#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 1) + QVariant value = self->returnValue(); +#else + QVariant value = self->returnValue().value<QVariant>(); +#endif + if (value.canConvert<QIviSearchAndBrowseModelPendingResult>()) { + QIviSearchAndBrowseModelPendingResult result = value.value<QIviSearchAndBrowseModelPendingResult>(); + if (result.failed()) { + qCDebug(qLcROQIviSearchAndBrowseModel) << "Pending Result with id:" << result.id() << "failed"; + iviReply.setFailed(); + } else { + qCDebug(qLcROQIviSearchAndBrowseModel) << "Result not available yet. Waiting for id:" << result.id(); + m_pendingReplies.insert(result.id(), iviReply); + } + } else { + qCDebug(qLcROQIviSearchAndBrowseModel) << "Got the value right away: void"; + iviReply.setSuccess(); + } + } else { + iviReply.setFailed(); + emit errorChanged(QIviAbstractFeature::InvalidOperation, QStringLiteral("remote call of method remove failed")); + } + self->deleteLater(); + }); + return iviReply; +} + +QIviPendingReply<void> SearchAndBrowseModel::move(const QUuid &identifier, int currentIndex, int newIndex) +{ + QIviPendingReply<void> iviReply; + QRemoteObjectPendingReply<QVariant> reply = m_replica->move(identifier, currentIndex, newIndex); + auto watcher = new QRemoteObjectPendingCallWatcher(reply); + connect(watcher, &QRemoteObjectPendingCallWatcher::finished, this, [this, iviReply](QRemoteObjectPendingCallWatcher *self) mutable { + if (self->error() == QRemoteObjectPendingCallWatcher::NoError) { +#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 1) + QVariant value = self->returnValue(); +#else + QVariant value = self->returnValue().value<QVariant>(); +#endif + if (value.canConvert<QIviSearchAndBrowseModelPendingResult>()) { + QIviSearchAndBrowseModelPendingResult result = value.value<QIviSearchAndBrowseModelPendingResult>(); + if (result.failed()) { + qCDebug(qLcROQIviSearchAndBrowseModel) << "Pending Result with id:" << result.id() << "failed"; + iviReply.setFailed(); + } else { + qCDebug(qLcROQIviSearchAndBrowseModel) << "Result not available yet. Waiting for id:" << result.id(); + m_pendingReplies.insert(result.id(), iviReply); + } + } else { + qCDebug(qLcROQIviSearchAndBrowseModel) << "Got the value right away: void"; + iviReply.setSuccess(); + } + } else { + iviReply.setFailed(); + emit errorChanged(QIviAbstractFeature::InvalidOperation, QStringLiteral("remote call of method move failed")); + } + self->deleteLater(); + }); + return iviReply; +} + +QIviPendingReply<int> SearchAndBrowseModel::indexOf(const QUuid &identifier, const QVariant &item) +{ + QIviPendingReply<int> iviReply; + QRemoteObjectPendingReply<QVariant> reply = m_replica->indexOf(identifier, item); + auto watcher = new QRemoteObjectPendingCallWatcher(reply); + connect(watcher, &QRemoteObjectPendingCallWatcher::finished, this, [this, iviReply](QRemoteObjectPendingCallWatcher *self) mutable { + if (self->error() == QRemoteObjectPendingCallWatcher::NoError) { +#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 1) + QVariant value = self->returnValue(); +#else + QVariant value = self->returnValue().value<QVariant>(); +#endif + if (value.canConvert<QIviSearchAndBrowseModelPendingResult>()) { + QIviSearchAndBrowseModelPendingResult result = value.value<QIviSearchAndBrowseModelPendingResult>(); + if (result.failed()) { + qCDebug(qLcROQIviSearchAndBrowseModel) << "Pending Result with id:" << result.id() << "failed"; + iviReply.setFailed(); + } else { + qCDebug(qLcROQIviSearchAndBrowseModel) << "Result not available yet. Waiting for id:" << result.id(); + m_pendingReplies.insert(result.id(), iviReply); + } + } else { + qCDebug(qLcROQIviSearchAndBrowseModel) << "Got the value right away:" << value.value<int>(); + iviReply.setSuccess(value.value<int>()); + } + } else { + iviReply.setFailed(); + emit errorChanged(QIviAbstractFeature::InvalidOperation, QStringLiteral("remote call of method remove failed")); + } + self->deleteLater(); + }); + return iviReply; +} + +void SearchAndBrowseModel::onReplicaStateChanged(QRemoteObjectReplica::State newState, QRemoteObjectReplica::State oldState) +{ + Q_UNUSED(oldState) + + if (newState == QRemoteObjectReplica::Suspect) { + qCWarning(qLcROQIviSearchAndBrowseModel) << "QRemoteObjectReplica error, connection to the source lost"; + emit errorChanged(QIviAbstractFeature::Unknown, + "QRemoteObjectReplica error, connection to the source lost"); + } else if (newState == QRemoteObjectReplica::SignatureMismatch) { + qCWarning(qLcROQIviSearchAndBrowseModel) << "QRemoteObjectReplica error, signature mismatch"; + emit errorChanged(QIviAbstractFeature::Unknown, + "QRemoteObjectReplica error, signature mismatch"); + } else if (newState == QRemoteObjectReplica::Valid) { + emit errorChanged(QIviAbstractFeature::NoError, ""); + } +} + +void SearchAndBrowseModel::onNodeError(QRemoteObjectNode::ErrorCode code) +{ + qCWarning(qLcROQIviSearchAndBrowseModel) << "QRemoteObjectNode error, code: " << code; + emit errorChanged(QIviAbstractFeature::Unknown, "QRemoteObjectNode error, code: " + code); +} + +void SearchAndBrowseModel::onPendingResultAvailable(quint64 id, bool isSuccess, const QVariant &value) +{ + qCDebug(qLcROQIviSearchAndBrowseModel) << "pending result available" << id; + if (!m_pendingReplies.contains(id)) { + qCDebug(qLcROQIviSearchAndBrowseModel) << "Received a result for an unexpected id:" << id << ". Ignoring!"; + return; + } + + QIviPendingReplyBase iviReply = m_pendingReplies.take(id); + + if (isSuccess) + iviReply.setSuccess(value); + else + iviReply.setFailed(); +} + diff --git a/src/plugins/ivimedia/media_qtro/searchandbrowsemodel.h b/src/plugins/ivimedia/media_qtro/searchandbrowsemodel.h new file mode 100644 index 0000000..4a7b23c --- /dev/null +++ b/src/plugins/ivimedia/media_qtro/searchandbrowsemodel.h @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Luxoft Sweden AB +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtIVI module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL-QTAS$ +** Commercial License Usage +** Licensees holding valid commercial Qt Automotive Suite licenses may use +** this file in accordance with the commercial license agreement provided +** with the Software or, alternatively, in accordance with the terms +** contained in a written agreement between you and The Qt Company. For +** licensing terms and conditions see https://www.qt.io/terms-conditions. +** For further information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +** SPDX-License-Identifier: LGPL-3.0 +** +****************************************************************************/ + +#ifndef SEARCHANDBROWSEMODEL_H +#define SEARCHANDBROWSEMODEL_H + +#include <QtIviCore/QIviSearchAndBrowseModelInterface> +#include <QtIviMedia/QIviPlayableItem> +#include <QRemoteObjectNode> +#include "rep_qivisearchandbrowsemodel_replica.h" + +class SearchAndBrowseItem : public QIviPlayableItem +{ + Q_GADGET + +public: + QString id() const override { return m_name; } + QString name() const override { return m_name; } + void setName(const QString &name) { m_name = name; } + QString type() const override { return m_type; } + void setType(const QString &type) { m_type = type; } + +private: + QString m_name; + QString m_type; +}; +Q_DECLARE_METATYPE(SearchAndBrowseItem) + +QDataStream &operator<<(QDataStream &stream, const SearchAndBrowseItem &obj); +QDataStream &operator>>(QDataStream &stream, SearchAndBrowseItem &obj); + +class SearchAndBrowseModel : public QIviSearchAndBrowseModelInterface +{ + Q_OBJECT +public: + SearchAndBrowseModel(QRemoteObjectNode *node, QObject *parent = nullptr); + + void initialize() override; + void registerInstance(const QUuid &identifier) override; + void unregisterInstance(const QUuid &identifier) override; + void fetchData(const QUuid &identifier, int start, int count) override; + + void setContentType(const QUuid &identifier, const QString &contentType) override; + void setupFilter(const QUuid &identifier, QIviAbstractQueryTerm *term, const QList<QIviOrderTerm> &orderTerms) override; + QIviPendingReply<QString> goBack(const QUuid &identifier) override; + QIviPendingReply<QString> goForward(const QUuid &identifier, int index) override; + QIviPendingReply<void> insert(const QUuid &identifier, int index, const QVariant &item) override; + QIviPendingReply<void> remove(const QUuid &identifier, int index) override; + QIviPendingReply<void> move(const QUuid &identifier, int currentIndex, int newIndex) override; + QIviPendingReply<int> indexOf(const QUuid &identifier, const QVariant &item) override; + +public Q_SLOTS: + void onReplicaStateChanged(QRemoteObjectReplica::State newState, + QRemoteObjectReplica::State oldState); + void onNodeError(QRemoteObjectNode::ErrorCode code); + void onPendingResultAvailable(quint64 id, bool isSuccess, const QVariant &value); +private: + QSharedPointer<QIviSearchAndBrowseModelReplica> m_replica; + QHash<quint64, QIviPendingReplyBase> m_pendingReplies; +}; + +#endif // SEARCHANDBROWSEMODEL_H diff --git a/src/plugins/ivimedia/media_qtro/usbdevice.cpp b/src/plugins/ivimedia/media_qtro/usbdevice.cpp new file mode 100644 index 0000000..b5ab341 --- /dev/null +++ b/src/plugins/ivimedia/media_qtro/usbdevice.cpp @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Luxoft Sweden AB +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtIvi module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL-QTAS$ +** Commercial License Usage +** Licensees holding valid commercial Qt Automotive Suite licenses may use +** this file in accordance with the commercial license agreement provided +** with the Software or, alternatively, in accordance with the terms +** contained in a written agreement between you and The Qt Company. For +** licensing terms and conditions see https://www.qt.io/terms-conditions. +** For further information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +** SPDX-License-Identifier: LGPL-3.0 +** +****************************************************************************/ + +#include "searchandbrowsemodel.h" +#include "usbdevice.h" + +USBDevice::USBDevice(const QString &name, QObject *parent) + : QIviMediaUsbDevice(parent) + , m_name(name) +{ + QUrl url = QUrl(QStringLiteral("local:qtivimedia_") + name); + QRemoteObjectNode *node = new QRemoteObjectNode(url, this); + + m_browseModel = new SearchAndBrowseModel(node, this); +} + +QString USBDevice::name() const +{ + return m_name; +} + +void USBDevice::eject() +{ + qWarning() << "Ejecting a USB Device is not supported in the simulation"; +} + +QStringList USBDevice::interfaces() const +{ + QStringList list; + list << QStringLiteral(QIviSearchAndBrowseModel_iid); + return list; +} + +QIviFeatureInterface *USBDevice::interfaceInstance(const QString &interface) const +{ + if (interface == QStringLiteral(QIviSearchAndBrowseModel_iid)) + return m_browseModel; + + return nullptr; +} diff --git a/src/plugins/ivimedia/media_qtro/usbdevice.h b/src/plugins/ivimedia/media_qtro/usbdevice.h new file mode 100644 index 0000000..535f4de --- /dev/null +++ b/src/plugins/ivimedia/media_qtro/usbdevice.h @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Luxoft Sweden AB +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtIvi module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL-QTAS$ +** Commercial License Usage +** Licensees holding valid commercial Qt Automotive Suite licenses may use +** this file in accordance with the commercial license agreement provided +** with the Software or, alternatively, in accordance with the terms +** contained in a written agreement between you and The Qt Company. For +** licensing terms and conditions see https://www.qt.io/terms-conditions. +** For further information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +** SPDX-License-Identifier: LGPL-3.0 +** +****************************************************************************/ + +#ifndef USBDEVICE_H +#define USBDEVICE_H + +#include <QtIviMedia/QIviMediaDevice> + +class SearchAndBrowseModel; + +class USBDevice : public QIviMediaUsbDevice +{ + Q_OBJECT +public: + explicit USBDevice(const QString &name, QObject *parent = nullptr); + + QString name() const override; + void eject() override; + + QStringList interfaces() const override; + QIviFeatureInterface *interfaceInstance(const QString &interface) const override; + +private: + SearchAndBrowseModel *m_browseModel; + QString m_name; +}; + +#endif // USBDEVICE_H diff --git a/src/plugins/ivimedia/media_simulator/mediaindexerbackend.cpp b/src/plugins/ivimedia/media_simulator/mediaindexerbackend.cpp index acc0679..5c11b28 100644 --- a/src/plugins/ivimedia/media_simulator/mediaindexerbackend.cpp +++ b/src/plugins/ivimedia/media_simulator/mediaindexerbackend.cpp @@ -114,6 +114,16 @@ void MediaIndexerBackend::resume() emit errorChanged(QIviAbstractFeature::InvalidOperation, error); } +qreal MediaIndexerBackend::progress() const +{ + return m_progress; +} + +QIviMediaIndexerControl::State MediaIndexerBackend::state() const +{ + return m_state; +} + void MediaIndexerBackend::addMediaFolder(const QString &path) { ScanData data; @@ -243,10 +253,10 @@ bool MediaIndexerBackend::scanWorker(const QString &mediaDir, bool removeData) sqlError(this, query.lastQuery(), query.lastError().text()); return false; } else { - emit progressChanged(qreal(++currentFileIndex)/qreal(totalFileCount)); + setProgress(qreal(++currentFileIndex)/qreal(totalFileCount)); } #else - emit progressChanged(qreal(++currentFileIndex)/qreal(totalFileCount)); + setProgress(qreal(++currentFileIndex)/qreal(totalFileCount)); #endif // QTIVI_NO_TAGLIB } @@ -264,7 +274,7 @@ void MediaIndexerBackend::onScanFinished() #ifdef QTIVI_NO_TAGLIB qCCritical(media) << "No data was added, this is just a simulation"; #endif - emit progressChanged(1); + setProgress(1); emit indexingDone(); @@ -283,6 +293,12 @@ void MediaIndexerBackend::scanNext() m_watcher.setFuture(QtConcurrent::run(this, &MediaIndexerBackend::scanWorker, m_currentFolder, data.remove)); } +void MediaIndexerBackend::setProgress(qreal progress) +{ + m_progress = progress; + emit progressChanged(progress); +} + void MediaIndexerBackend::setState(QIviMediaIndexerControl::State state) { m_state = state; diff --git a/src/plugins/ivimedia/media_simulator/mediaindexerbackend.h b/src/plugins/ivimedia/media_simulator/mediaindexerbackend.h index 1f07b64..83802b4 100644 --- a/src/plugins/ivimedia/media_simulator/mediaindexerbackend.h +++ b/src/plugins/ivimedia/media_simulator/mediaindexerbackend.h @@ -62,6 +62,9 @@ public: void pause() override; void resume() override; + qreal progress() const; + QIviMediaIndexerControl::State state() const; + signals: void indexingDone(); void removeFromQueue(int index); @@ -76,6 +79,7 @@ private slots: private: void scanNext(); + void setProgress(qreal progress); void setState(QIviMediaIndexerControl::State state); QSqlDatabase m_db; @@ -84,6 +88,7 @@ private: QString folder; }; + qreal m_progress; QIviMediaIndexerControl::State m_state; QQueue<ScanData> m_folderQueue; QString m_currentFolder; diff --git a/src/plugins/ivimedia/media_simulator/mediaplayerbackend.cpp b/src/plugins/ivimedia/media_simulator/mediaplayerbackend.cpp index b804ce4..7ca958c 100644 --- a/src/plugins/ivimedia/media_simulator/mediaplayerbackend.cpp +++ b/src/plugins/ivimedia/media_simulator/mediaplayerbackend.cpp @@ -62,6 +62,9 @@ MediaPlayerBackend::MediaPlayerBackend(const QSqlDatabase &database, QObject *pa , m_threadPool(new QThreadPool(this)) , m_player(new QMediaPlayer(this)) { + qRegisterMetaType<QIviAudioTrackItem>(); + qRegisterMetaTypeStreamOperators<QIviAudioTrackItem>(); + m_threadPool->setMaxThreadCount(1); connect(m_player, &QMediaPlayer::durationChanged, this, &MediaPlayerBackend::onDurationChanged); @@ -253,6 +256,51 @@ void MediaPlayerBackend::move(int cur_index, int new_index) queries, QUuid(), cur_index, new_index); } +QIviMediaPlayer::PlayMode MediaPlayerBackend::playMode() const +{ + return m_playMode; +} + +QIviMediaPlayer::PlayState MediaPlayerBackend::playState() const +{ + return m_state; +} + +qint64 MediaPlayerBackend::position() const +{ + return m_player->position(); +} + +qint64 MediaPlayerBackend::duration() const +{ + return m_player->duration(); +} + +QVariant MediaPlayerBackend::currentTrack() const +{ + return m_currentTrack; +} + +int MediaPlayerBackend::currentIndex() const +{ + return m_currentIndex; +} + +int MediaPlayerBackend::volume() const +{ + return m_player->volume(); +} + +bool MediaPlayerBackend::isMuted() const +{ + return m_player->isMuted(); +} + +bool MediaPlayerBackend::canReportCount() const +{ + return true; +} + void MediaPlayerBackend::doSqlOperation(MediaPlayerBackend::OperationType type, const QStringList &queries, const QUuid &identifier, int start, int count) { m_db.transaction(); @@ -303,6 +351,7 @@ void MediaPlayerBackend::doSqlOperation(MediaPlayerBackend::OperationType type, auto item = list.at(0).value<QIviAudioTrackItem>(); emit playTrack(item.url()); emit currentIndexChanged(start); + m_currentTrack = list.at(0); emit currentTrackChanged(list.at(0)); } else if (type == MediaPlayerBackend::Insert && start <= m_currentIndex) { // A new Item has been inserted before currentIndex diff --git a/src/plugins/ivimedia/media_simulator/mediaplayerbackend.h b/src/plugins/ivimedia/media_simulator/mediaplayerbackend.h index 2b6494f..1450cf1 100644 --- a/src/plugins/ivimedia/media_simulator/mediaplayerbackend.h +++ b/src/plugins/ivimedia/media_simulator/mediaplayerbackend.h @@ -54,6 +54,14 @@ QT_FORWARD_DECLARE_CLASS(QThreadPool); class MediaPlayerBackend : public QIviMediaPlayerBackendInterface { Q_OBJECT + Q_PROPERTY(QIviMediaPlayer::PlayMode playMode READ playMode WRITE setPlayMode NOTIFY playModeChanged) + Q_PROPERTY(QIviMediaPlayer::PlayState playState READ playState NOTIFY playStateChanged) + Q_PROPERTY(qint64 position READ position WRITE setPosition NOTIFY positionChanged) + Q_PROPERTY(qint64 duration READ duration NOTIFY durationChanged) + Q_PROPERTY(QVariant currentTrack READ currentTrack NOTIFY currentTrackChanged) + Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged) + Q_PROPERTY(int volume READ volume WRITE setVolume NOTIFY volumeChanged) + Q_PROPERTY(bool muted READ isMuted WRITE setMuted NOTIFY mutedChanged) public: enum OperationType { @@ -74,6 +82,20 @@ public: void seek(qint64 offset) override; void next() override; void previous() override; + + QIviMediaPlayer::PlayMode playMode() const; + QIviMediaPlayer::PlayState playState() const; + qint64 position() const; + qint64 duration() const; + QVariant currentTrack() const; + int currentIndex() const; + int volume() const; + bool isMuted() const; + bool canReportCount() const; + +signals: + void playTrack(const QUrl& url); +public Q_SLOTS: void setPlayMode(QIviMediaPlayer::PlayMode playMode) override; void setPosition(qint64 position) override; void setCurrentIndex(int index) override; @@ -86,9 +108,6 @@ public: void remove(int index) override; void move(int cur_index, int new_index) override; -signals: - void playTrack(const QUrl& url); -public Q_SLOTS: void doSqlOperation(MediaPlayerBackend::OperationType type, const QStringList &queries, const QUuid &identifier, int start, int count); private Q_SLOTS: @@ -101,6 +120,7 @@ private: int m_count; int m_currentIndex; + QVariant m_currentTrack; QIviMediaPlayer::PlayMode m_playMode; QIviMediaPlayer::PlayState m_requestedState; QIviMediaPlayer::PlayState m_state; diff --git a/src/plugins/ivimedia/media_simulator/searchandbrowsebackend.cpp b/src/plugins/ivimedia/media_simulator/searchandbrowsebackend.cpp index 20abfcf..f6049fe 100644 --- a/src/plugins/ivimedia/media_simulator/searchandbrowsebackend.cpp +++ b/src/plugins/ivimedia/media_simulator/searchandbrowsebackend.cpp @@ -54,6 +54,32 @@ static const QString artistLiteral = QStringLiteral("artist"); static const QString albumLiteral = QStringLiteral("album"); static const QString trackLiteral = QStringLiteral("track"); +QDataStream &operator<<(QDataStream &stream, const SearchAndBrowseItem &obj) +{ + stream << obj.name(); + stream << obj.type(); + stream << obj.url(); + stream << QVariant(obj.data()); + return stream; +} + +QDataStream &operator>>(QDataStream &stream, SearchAndBrowseItem &obj) +{ + QString name; + QString type; + QUrl url; + QVariant data; + stream >> name; + stream >> type; + stream >> url; + stream >> data; + obj.setName(name); + obj.setType(type); + obj.setUrl(url); + obj.setData(data.toMap()); + return stream; +} + SearchAndBrowseBackend::SearchAndBrowseBackend(const QSqlDatabase &database, QObject *parent) : QIviSearchAndBrowseModelInterface(parent) , m_threadPool(new QThreadPool(this)) @@ -61,6 +87,9 @@ SearchAndBrowseBackend::SearchAndBrowseBackend(const QSqlDatabase &database, QOb m_threadPool->setMaxThreadCount(1); qRegisterMetaType<SearchAndBrowseItem>(); + qRegisterMetaTypeStreamOperators<SearchAndBrowseItem>(); + qRegisterMetaType<QIviAudioTrackItem>(); + qRegisterMetaTypeStreamOperators<QIviAudioTrackItem>(); m_db = database; m_db.open(); @@ -70,6 +99,11 @@ SearchAndBrowseBackend::SearchAndBrowseBackend(const QSqlDatabase &database, QOb m_contentTypes << trackLiteral; } +QStringList SearchAndBrowseBackend::availableContentTypes() const +{ + return m_contentTypes; +} + void SearchAndBrowseBackend::initialize() { emit availableContentTypesChanged(m_contentTypes); diff --git a/src/plugins/ivimedia/media_simulator/searchandbrowsebackend.h b/src/plugins/ivimedia/media_simulator/searchandbrowsebackend.h index 0478a76..3fcd3f2 100644 --- a/src/plugins/ivimedia/media_simulator/searchandbrowsebackend.h +++ b/src/plugins/ivimedia/media_simulator/searchandbrowsebackend.h @@ -69,12 +69,19 @@ private: }; Q_DECLARE_METATYPE(SearchAndBrowseItem) +QDataStream &operator<<(QDataStream &stream, const SearchAndBrowseItem &obj); +QDataStream &operator>>(QDataStream &stream, SearchAndBrowseItem &obj); + class SearchAndBrowseBackend : public QIviSearchAndBrowseModelInterface { Q_OBJECT + + Q_PROPERTY(QStringList availableContentTypes READ availableContentTypes CONSTANT) public: explicit SearchAndBrowseBackend(const QSqlDatabase &database, QObject *parent = nullptr); + QStringList availableContentTypes() const; + void initialize() override; void registerInstance(const QUuid &identifier) override; void unregisterInstance(const QUuid &identifier) override; diff --git a/src/plugins/ivimedia/media_simulator/usbbrowsebackend.cpp b/src/plugins/ivimedia/media_simulator/usbbrowsebackend.cpp index 3561c20..899f93b 100644 --- a/src/plugins/ivimedia/media_simulator/usbbrowsebackend.cpp +++ b/src/plugins/ivimedia/media_simulator/usbbrowsebackend.cpp @@ -54,6 +54,11 @@ UsbBrowseBackend::UsbBrowseBackend(const QString &path, QObject *parent) qRegisterMetaType<SearchAndBrowseItem>(); } +QStringList UsbBrowseBackend::availableContentTypes() const +{ + return QStringList(fileLiteral); +} + void UsbBrowseBackend::initialize() { emit availableContentTypesChanged(QStringList(fileLiteral)); diff --git a/src/plugins/ivimedia/media_simulator/usbbrowsebackend.h b/src/plugins/ivimedia/media_simulator/usbbrowsebackend.h index 3adfd56..688d1bf 100644 --- a/src/plugins/ivimedia/media_simulator/usbbrowsebackend.h +++ b/src/plugins/ivimedia/media_simulator/usbbrowsebackend.h @@ -49,9 +49,12 @@ class UsbBrowseBackend : public QIviSearchAndBrowseModelInterface { Q_OBJECT + Q_PROPERTY(QStringList availableContentTypes READ availableContentTypes CONSTANT) public: UsbBrowseBackend(const QString &path, QObject *parent = nullptr); + QStringList availableContentTypes() const; + void initialize() override; void registerInstance(const QUuid &identifier) override; void unregisterInstance(const QUuid &identifier) override; diff --git a/src/src.pro b/src/src.pro index 00be01a..9873684 100644 --- a/src/src.pro +++ b/src/src.pro @@ -9,7 +9,10 @@ include($$OUT_PWD/geniviextras/qtgeniviextras-config.pri) include($$OUT_PWD/ivicore/qtivicore-config.pri) include($$OUT_PWD/ivivehiclefunctions/qtivivehiclefunctions-config.pri) include($$OUT_PWD/ivimedia/qtivimedia-config.pri) -QT_FOR_CONFIG += geniviextras geniviextras-private ivicore ivicore-private ivivehiclefunctions ivivehiclefunctions-private ivimedia +QT_FOR_CONFIG += geniviextras geniviextras-private \ + ivicore ivicore-private \ + ivivehiclefunctions ivivehiclefunctions-private \ + ivimedia ivimedia-private !qtConfig(host-tools-only) { !qtConfig(geniviextras-only):qtConfig(ivicore) { @@ -31,12 +34,22 @@ QT_FOR_CONFIG += geniviextras geniviextras-private ivicore ivicore-private ivive imports.depends += ivimedia } - qtConfig(remoteobjects):qtConfig(vehiclefunctions_qtro_simulation_server) { - src_tools_vehiclefunctions-simulation-server.subdir = tools/vehiclefunctions-simulation-server - !qtConfig(system-ivigenerator): src_tools_vehiclefunctions-simulation-server.depends += sub-ivigenerator - src_tools_vehiclefunctions-simulation-server.depends += ivicore ivivehiclefunctions - src_tools_vehiclefunctions-simulation-server.target = sub-vehiclefunctions-simulation-server - SUBDIRS += src_tools_vehiclefunctions-simulation-server + qtConfig(remoteobjects): { + + qtConfig(vehiclefunctions_qtro_simulation_server) { + src_tools_vehiclefunctions-simulation-server.subdir = tools/vehiclefunctions-simulation-server + !qtConfig(system-ivigenerator): src_tools_vehiclefunctions-simulation-server.depends += sub-ivigenerator + src_tools_vehiclefunctions-simulation-server.depends += ivicore ivivehiclefunctions + src_tools_vehiclefunctions-simulation-server.target = sub-vehiclefunctions-simulation-server + SUBDIRS += src_tools_vehiclefunctions-simulation-server + } + + qtConfig(media_qtro_simulation_server) { + src_tools_media-simulation-server.subdir = tools/media-simulation-server + src_tools_media-simulation-server.depends += ivicore ivimedia + src_tools_media-simulation-server.target = sub-media-simulation-server + SUBDIRS += src_tools_media-simulation-server + } } } diff --git a/src/tools/media-simulation-server/core.cpp b/src/tools/media-simulation-server/core.cpp new file mode 100644 index 0000000..a668614 --- /dev/null +++ b/src/tools/media-simulation-server/core.cpp @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Luxoft Sweden AB +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtIVI module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL-QTAS$ +** Commercial License Usage +** Licensees holding valid commercial Qt Automotive Suite licenses may use +** this file in accordance with the commercial license agreement provided +** with the Software or, alternatively, in accordance with the terms +** contained in a written agreement between you and The Qt Company. For +** licensing terms and conditions see https://www.qt.io/terms-conditions. +** For further information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +** SPDX-License-Identifier: LGPL-3.0 +** +****************************************************************************/ + +#include "core.h" +#include <QCoreApplication> +#include <QSettings> + +QT_BEGIN_NAMESPACE + +Core* Core::s_instance(nullptr); + +Core::Core(QObject *parent) + : QObject(parent) + , m_host(nullptr) +{ + init(); +} + +Core::~Core() +{ +} + +void Core::init() +{ + QString configPath(QStringLiteral("./server.conf")); + if (qEnvironmentVariableIsSet("SERVER_CONF_PATH")) + configPath = QString::fromLocal8Bit(qgetenv("SERVER_CONF_PATH")); + else + qDebug() << "Environment variable SERVER_CONF_PATH not defined, using " << configPath; + QSettings settings(configPath, QSettings::IniFormat); + settings.beginGroup(QStringLiteral("qtivivehiclefunctions")); + QUrl url = QUrl(settings.value(QStringLiteral("Registry"), QStringLiteral("local:qtivimedia")).toString()); + m_host = new QRemoteObjectRegistryHost(url); + qDebug() << "registry at: " << m_host->registryUrl().toString(); + connect(m_host, &QRemoteObjectNode::error, this, &Core::reportError); +} + +Core* Core::instance() +{ + if (!s_instance) + s_instance = new Core(QCoreApplication::instance()); + Q_ASSERT(s_instance); + return s_instance; +} + +QRemoteObjectRegistryHost* Core::host() const +{ + Q_ASSERT(m_host); + return m_host; +} + +void Core::reportError(QRemoteObjectNode::ErrorCode code) +{ + qWarning() << "QRemoteObjects Error: " << code; +} + +QT_END_NAMESPACE diff --git a/src/tools/media-simulation-server/core.h b/src/tools/media-simulation-server/core.h new file mode 100644 index 0000000..2cacb52 --- /dev/null +++ b/src/tools/media-simulation-server/core.h @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Luxoft Sweden AB +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtIVI module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL-QTAS$ +** Commercial License Usage +** Licensees holding valid commercial Qt Automotive Suite licenses may use +** this file in accordance with the commercial license agreement provided +** with the Software or, alternatively, in accordance with the terms +** contained in a written agreement between you and The Qt Company. For +** licensing terms and conditions see https://www.qt.io/terms-conditions. +** For further information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +** SPDX-License-Identifier: LGPL-3.0 +** +****************************************************************************/ + + +#ifndef CORE_H +#define CORE_H + +#include <QRemoteObjectNode> + +QT_BEGIN_NAMESPACE + +class Core : public QObject +{ + Q_OBJECT +private: + Core(QObject *parent=nullptr); + +public: + virtual ~Core(); + void init(); + static Core* instance(); + QRemoteObjectRegistryHost* host() const; + +private: + void reportError(QRemoteObjectNode::ErrorCode code); + + static Core* s_instance; + QRemoteObjectRegistryHost* m_host; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/tools/media-simulation-server/main.cpp b/src/tools/media-simulation-server/main.cpp new file mode 100644 index 0000000..04fcda7 --- /dev/null +++ b/src/tools/media-simulation-server/main.cpp @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Luxoft Sweden AB +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtIVI module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL-QTAS$ +** Commercial License Usage +** Licensees holding valid commercial Qt Automotive Suite licenses may use +** this file in accordance with the commercial license agreement provided +** with the Software or, alternatively, in accordance with the terms +** contained in a written agreement between you and The Qt Company. For +** licensing terms and conditions see https://www.qt.io/terms-conditions. +** For further information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +** SPDX-License-Identifier: LGPL-3.0 +** +****************************************************************************/ + +#include <QCoreApplication> + +#include "database_helper.h" + +#include "mediaplayerbackend.h" +#include "qivimediaplayerqtroadapter.h" + +#include "mediaindexerbackend.h" +#include "qivimediaindexerqtroadapter.h" + +#include "mediadiscoverybackend.h" +#include "qivimediadiscoveryqtroadapter.h" + +#include "searchandbrowsebackend.h" +#include "qivisearchandbrowsemodelqtroadapter.h" +#include "usbdevice.h" + +#include "core.h" + +int main(int argc, char *argv[]) +{ + QCoreApplication app(argc, argv); + + QString dbFile = mediaDatabaseFile(); + createMediaDatabase(dbFile); + + MediaIndexerBackend *indexerBackend = new MediaIndexerBackend(createDatabaseConnection(QStringLiteral("indexer"), dbFile), qApp); + MediaPlayerBackend *playerBackend = new MediaPlayerBackend(createDatabaseConnection(QStringLiteral("player"), dbFile), qApp); + MediaDiscoveryBackend *discoveryBackend = new MediaDiscoveryBackend(qApp); + SearchAndBrowseBackend *searchAndBrowseBackend = new SearchAndBrowseBackend(createDatabaseConnection(QStringLiteral("model"), dbFile), qApp); + + auto deviceMap = discoveryBackend->deviceMap(); + for (auto it = deviceMap.cbegin(); it != deviceMap.cend(); it++) { + USBDevice *device = qobject_cast<USBDevice*>(it.value()); + if (!device) + continue; + indexerBackend->addMediaFolder(device->folder()); + } + + QObject::connect(indexerBackend, &MediaIndexerBackend::removeFromQueue, + playerBackend, &MediaPlayerBackend::remove); + QObject::connect(discoveryBackend, &MediaDiscoveryBackend::mediaDirectoryAdded, + indexerBackend, &MediaIndexerBackend::addMediaFolder); + QObject::connect(discoveryBackend, &MediaDiscoveryBackend::mediaDirectoryRemoved, + indexerBackend, &MediaIndexerBackend::removeMediaFolder); + + //initialize all our backends + indexerBackend->initialize(); + playerBackend->initialize(); + discoveryBackend->initialize(); + searchAndBrowseBackend->initialize(); + + //Start Remoting the backends + Core::instance()->host()->enableRemoting<QIviMediaIndexerAddressWrapper>(new QIviMediaIndexerQtRoAdapter(indexerBackend)); + Core::instance()->host()->enableRemoting<QIviMediaPlayerAddressWrapper>(new QIviMediaPlayerQtRoAdapter(playerBackend)); + Core::instance()->host()->enableRemoting<QIviMediaDiscoveryModelAddressWrapper>(new QIviMediaDiscoveryModelQtRoAdapter(discoveryBackend)); + Core::instance()->host()->enableRemoting<QIviSearchAndBrowseModelAddressWrapper>(new QIviSearchAndBrowseModelQtRoAdapter(searchAndBrowseBackend)); + + return app.exec(); +} diff --git a/src/tools/media-simulation-server/media-simulation-server.pro b/src/tools/media-simulation-server/media-simulation-server.pro new file mode 100644 index 0000000..bc08347 --- /dev/null +++ b/src/tools/media-simulation-server/media-simulation-server.pro @@ -0,0 +1,29 @@ +TARGET = media-simulation-server +TEMPLATE = app +QT = core ivicore remoteobjects ivimedia +CONFIG += c++11 + +load(qt_tool) + +include($$PWD/../../plugins/ivimedia/media_simulator/media_simulator.pri) + +HEADERS += \ + core.h \ + qivimediaindexerqtroadapter.h \ + qivimediaplayerqtroadapter.h \ + qivimediadiscoveryqtroadapter.h \ + qivisearchandbrowsemodelqtroadapter.h + +SOURCES += \ + main.cpp \ + core.cpp \ + qivimediaindexerqtroadapter.cpp \ + qivimediaplayerqtroadapter.cpp \ + qivimediadiscoveryqtroadapter.cpp \ + qivisearchandbrowsemodelqtroadapter.cpp + +REPC_SOURCE += \ + $$PWD/qivimediaindexer.rep \ + $$PWD/qivimediaplayer.rep \ + $$PWD/qivimediadiscoverymodel.rep \ + $$PWD/qivisearchandbrowsemodel.rep \ diff --git a/src/tools/media-simulation-server/qivimediadiscoverymodel.rep b/src/tools/media-simulation-server/qivimediadiscoverymodel.rep new file mode 100644 index 0000000..8905bc5 --- /dev/null +++ b/src/tools/media-simulation-server/qivimediadiscoverymodel.rep @@ -0,0 +1,8 @@ + +class QIviMediaDiscoveryModel +{ + PROP(QStringList devices READONLY); + + SIGNAL(deviceAdded(const QString &device)); + SIGNAL(deviceRemoved(const QString &device)); +}; diff --git a/src/tools/media-simulation-server/qivimediadiscoveryqtroadapter.cpp b/src/tools/media-simulation-server/qivimediadiscoveryqtroadapter.cpp new file mode 100644 index 0000000..8bc739b --- /dev/null +++ b/src/tools/media-simulation-server/qivimediadiscoveryqtroadapter.cpp @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Luxoft Sweden AB +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtIVI module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL-QTAS$ +** Commercial License Usage +** Licensees holding valid commercial Qt Automotive Suite licenses may use +** this file in accordance with the commercial license agreement provided +** with the Software or, alternatively, in accordance with the terms +** contained in a written agreement between you and The Qt Company. For +** licensing terms and conditions see https://www.qt.io/terms-conditions. +** For further information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +** SPDX-License-Identifier: LGPL-3.0 +** +****************************************************************************/ + +#include "qivimediadiscoveryqtroadapter.h" +#include "qivisearchandbrowsemodelqtroadapter.h" + +#include <QIviMediaDevice> +#include <QRemoteObjectRegistryHost> + +QIviMediaDiscoveryModelQtRoAdapter::QIviMediaDiscoveryModelQtRoAdapter(MediaDiscoveryBackend *parent) + : QIviMediaDiscoveryModelSource (parent) + , m_backend(parent) +{ + QMap<QString, QIviServiceObject*> deviceMap = m_backend->deviceMap(); + + for (auto it = deviceMap.cbegin(); it != deviceMap.cend(); it++) { + QIviMediaDevice *mediaDevice = qobject_cast<QIviMediaDevice *>(it.value()); + if (mediaDevice) + createDeviceAdapter(mediaDevice); + } + + connect(m_backend, &MediaDiscoveryBackend::deviceAdded, this, &QIviMediaDiscoveryModelQtRoAdapter::onDeviceAdded); + connect(m_backend, &MediaDiscoveryBackend::deviceRemoved, this, &QIviMediaDiscoveryModelQtRoAdapter::onDeviceRemoved); +} + +QStringList QIviMediaDiscoveryModelQtRoAdapter::devices() const +{ + return QStringList(m_hostMap.keys()); +} + +void QIviMediaDiscoveryModelQtRoAdapter::onDeviceAdded(QIviServiceObject *device) +{ + QIviMediaDevice *mediaDevice = qobject_cast<QIviMediaDevice *>(device); + if (!mediaDevice) + return; + + createDeviceAdapter(mediaDevice); + emit deviceAdded(mediaDevice->name()); +} + +void QIviMediaDiscoveryModelQtRoAdapter::onDeviceRemoved(QIviServiceObject *device) +{ + QIviMediaDevice *mediaDevice = qobject_cast<QIviMediaDevice *>(device); + if (!mediaDevice) + return; + + emit deviceRemoved(mediaDevice->name()); + auto host = m_hostMap.take(mediaDevice->name()); + qDebug() << "Removing host:" << host->registryUrl().toString(); + delete host; +} + +void QIviMediaDiscoveryModelQtRoAdapter::createDeviceAdapter(QIviMediaDevice *device) +{ + auto m_host = new QRemoteObjectRegistryHost(QUrl("local:qtivimedia_" + device->name())); + qDebug() << "Adding host at: " << m_host->registryUrl().toString(); + + QIviSearchAndBrowseModelInterface *searchAndBrowseBackend = qivi_interface_cast<QIviSearchAndBrowseModelInterface *>(device->interfaceInstance(QStringLiteral(QIviSearchAndBrowseModel_iid))); + + searchAndBrowseBackend->initialize(); + m_host->enableRemoting<QIviSearchAndBrowseModelAddressWrapper>(new QIviSearchAndBrowseModelQtRoAdapter(searchAndBrowseBackend)); + + m_hostMap.insert(device->name(), m_host); +} diff --git a/src/tools/media-simulation-server/qivimediadiscoveryqtroadapter.h b/src/tools/media-simulation-server/qivimediadiscoveryqtroadapter.h new file mode 100644 index 0000000..70193a2 --- /dev/null +++ b/src/tools/media-simulation-server/qivimediadiscoveryqtroadapter.h @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Luxoft Sweden AB +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtIVI module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL-QTAS$ +** Commercial License Usage +** Licensees holding valid commercial Qt Automotive Suite licenses may use +** this file in accordance with the commercial license agreement provided +** with the Software or, alternatively, in accordance with the terms +** contained in a written agreement between you and The Qt Company. For +** licensing terms and conditions see https://www.qt.io/terms-conditions. +** For further information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +** SPDX-License-Identifier: LGPL-3.0 +** +****************************************************************************/ + +#ifndef QIVIMEDIADISCOVERYMODELQTROADAPTER_H +#define QIVIMEDIADISCOVERYMODELQTROADAPTER_H + +#include "mediadiscoverybackend.h" +#include "rep_qivimediadiscoverymodel_source.h" + +#include <QRemoteObjectRegistryHost> + +template <class ObjectType> +struct QIviMediaDiscoveryModelAddressWrapper: public QIviMediaDiscoveryModelSourceAPI<ObjectType> { + QIviMediaDiscoveryModelAddressWrapper(ObjectType *object, const QString &name = QStringLiteral("QtIviMedia.QIviMediaDiscoveryModel")) + : QIviMediaDiscoveryModelSourceAPI<ObjectType>(object, name) + {} +}; + +class QIviMediaDiscoveryModelQtRoAdapter : public QIviMediaDiscoveryModelSource +{ +public: + QIviMediaDiscoveryModelQtRoAdapter(MediaDiscoveryBackend *parent); + +public Q_SLOTS: + QStringList devices() const override; + void onDeviceAdded(QIviServiceObject *device); + void onDeviceRemoved(QIviServiceObject *device); + +private: + void createDeviceAdapter(QIviMediaDevice *device); + + MediaDiscoveryBackend *m_backend; + QHash<QString, QRemoteObjectRegistryHost*> m_hostMap; +}; + +#endif // QIVIMEDIAINDEXERQTROADAPTER_H diff --git a/src/tools/media-simulation-server/qivimediaindexer.rep b/src/tools/media-simulation-server/qivimediaindexer.rep new file mode 100644 index 0000000..b47e846 --- /dev/null +++ b/src/tools/media-simulation-server/qivimediaindexer.rep @@ -0,0 +1,11 @@ + +#include <QtIviMedia/QIviMediaIndexerControl> + +class QIviMediaIndexer +{ + PROP(QIviMediaIndexerControl::State state READONLY) + PROP(qreal progress READONLY) + + SLOT(QVariant pause()); + SLOT(QVariant resume()); +}; diff --git a/src/tools/media-simulation-server/qivimediaindexerqtroadapter.cpp b/src/tools/media-simulation-server/qivimediaindexerqtroadapter.cpp new file mode 100644 index 0000000..4b7552c --- /dev/null +++ b/src/tools/media-simulation-server/qivimediaindexerqtroadapter.cpp @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Luxoft Sweden AB +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtIVI module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL-QTAS$ +** Commercial License Usage +** Licensees holding valid commercial Qt Automotive Suite licenses may use +** this file in accordance with the commercial license agreement provided +** with the Software or, alternatively, in accordance with the terms +** contained in a written agreement between you and The Qt Company. For +** licensing terms and conditions see https://www.qt.io/terms-conditions. +** For further information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +** SPDX-License-Identifier: LGPL-3.0 +** +****************************************************************************/ + +#include "qivimediaindexerqtroadapter.h" + +QIviMediaIndexerQtRoAdapter::QIviMediaIndexerQtRoAdapter(MediaIndexerBackend *parent) + : QIviMediaIndexerSource (parent) + , m_backend(parent) +{ + connect(m_backend, &MediaIndexerBackend::progressChanged, this, &QIviMediaIndexerQtRoAdapter::progressChanged); + connect(m_backend, &MediaIndexerBackend::stateChanged, this, &QIviMediaIndexerQtRoAdapter::stateChanged); +} + +QIviMediaIndexerControl::State QIviMediaIndexerQtRoAdapter::state() const +{ + return m_backend->state(); +} + +qreal QIviMediaIndexerQtRoAdapter::progress() const +{ + return m_backend->progress(); +} + +QVariant QIviMediaIndexerQtRoAdapter::pause() +{ + m_backend->pause(); + return QVariant(); +} + +QVariant QIviMediaIndexerQtRoAdapter::resume() +{ + m_backend->resume(); + return QVariant(); +} diff --git a/src/tools/media-simulation-server/qivimediaindexerqtroadapter.h b/src/tools/media-simulation-server/qivimediaindexerqtroadapter.h new file mode 100644 index 0000000..ac5b6ed --- /dev/null +++ b/src/tools/media-simulation-server/qivimediaindexerqtroadapter.h @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Luxoft Sweden AB +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtIVI module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL-QTAS$ +** Commercial License Usage +** Licensees holding valid commercial Qt Automotive Suite licenses may use +** this file in accordance with the commercial license agreement provided +** with the Software or, alternatively, in accordance with the terms +** contained in a written agreement between you and The Qt Company. For +** licensing terms and conditions see https://www.qt.io/terms-conditions. +** For further information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +** SPDX-License-Identifier: LGPL-3.0 +** +****************************************************************************/ + +#ifndef QIVIMEDIAINDEXERQTROADAPTER_H +#define QIVIMEDIAINDEXERQTROADAPTER_H + +#include "mediaindexerbackend.h" +#include "rep_qivimediaindexer_source.h" + +template <class ObjectType> +struct QIviMediaIndexerAddressWrapper: public QIviMediaIndexerSourceAPI<ObjectType> { + QIviMediaIndexerAddressWrapper(ObjectType *object, const QString &name = QStringLiteral("QtIviMedia.QIviMediaIndexer")) + : QIviMediaIndexerSourceAPI<ObjectType>(object, name) + {} +}; + +class QIviMediaIndexerQtRoAdapter : public QIviMediaIndexerSource +{ +public: + QIviMediaIndexerQtRoAdapter(MediaIndexerBackend *parent); + + QIviMediaIndexerControl::State state() const override; + qreal progress() const override; + +public Q_SLOTS: + QVariant pause() override; + QVariant resume() override; + +private: + MediaIndexerBackend *m_backend; +}; + +#endif // QIVIMEDIAINDEXERQTROADAPTER_H diff --git a/src/tools/media-simulation-server/qivimediaplayer.rep b/src/tools/media-simulation-server/qivimediaplayer.rep new file mode 100644 index 0000000..d296b0d --- /dev/null +++ b/src/tools/media-simulation-server/qivimediaplayer.rep @@ -0,0 +1,35 @@ + +#include <QtIviMedia/QIviMediaPlayer> +#include <QtCore/QUuid> + +POD QIviMediaPlayerPendingResult(quint64 id, bool failed) + +class QIviMediaPlayer +{ + PROP(QIviMediaPlayer::PlayMode playMode); + PROP(QIviMediaPlayer::PlayState playState READONLY); + PROP(qint64 position); + PROP(qint64 duration READONLY); + PROP(QVariant currentTrack READONLY); + PROP(int currentIndex); + PROP(int volume); + PROP(bool muted); + PROP(bool canReportCount READONLY); + + SLOT(void play()); + SLOT(void pause()); + SLOT(void stop()); + SLOT(void seek(qint64 offset)); + SLOT(void next()); + SLOT(void previous()); + + SLOT(void fetchData(const QUuid &identifier, int start, int count)); + + SLOT(void insert(int index, const QVariant &item)); + SLOT(void remove(int index)); + SLOT(void move(int currentIndex, int newIndex)); + + SIGNAL(countChanged(int newLength)); + SIGNAL(dataFetched(const QUuid &identifier, const QList<QVariant> &data, int start, bool moreAvailable)); + SIGNAL(dataChanged(const QList<QVariant> &data, int start, int count)); +}; diff --git a/src/tools/media-simulation-server/qivimediaplayerqtroadapter.cpp b/src/tools/media-simulation-server/qivimediaplayerqtroadapter.cpp new file mode 100644 index 0000000..cadb389 --- /dev/null +++ b/src/tools/media-simulation-server/qivimediaplayerqtroadapter.cpp @@ -0,0 +1,185 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Luxoft Sweden AB +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtIVI module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL-QTAS$ +** Commercial License Usage +** Licensees holding valid commercial Qt Automotive Suite licenses may use +** this file in accordance with the commercial license agreement provided +** with the Software or, alternatively, in accordance with the terms +** contained in a written agreement between you and The Qt Company. For +** licensing terms and conditions see https://www.qt.io/terms-conditions. +** For further information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +** SPDX-License-Identifier: LGPL-3.0 +** +****************************************************************************/ + +#include "qivimediaplayerqtroadapter.h" +#include "qiviqmlconversion_helper.h" + +QIviMediaPlayerQtRoAdapter::QIviMediaPlayerQtRoAdapter(MediaPlayerBackend *parent) + : QIviMediaPlayerSource(parent) + , m_backend(parent) + , m_replyCounter(0) +{ + connect(m_backend, &MediaPlayerBackend::playModeChanged, this, &QIviMediaPlayerQtRoAdapter::playModeChanged); + connect(m_backend, &MediaPlayerBackend::playStateChanged, this, &QIviMediaPlayerQtRoAdapter::playStateChanged); + connect(m_backend, &MediaPlayerBackend::positionChanged, this, &QIviMediaPlayerQtRoAdapter::positionChanged); + connect(m_backend, &MediaPlayerBackend::durationChanged, this, &QIviMediaPlayerQtRoAdapter::durationChanged); + connect(m_backend, &MediaPlayerBackend::currentIndexChanged, this, &QIviMediaPlayerQtRoAdapter::currentIndexChanged); + connect(m_backend, &MediaPlayerBackend::currentTrackChanged, this, [this](const QVariant ¤tTrack) { + emit currentTrackChanged(QVariant(QMetaType::QVariant, ¤tTrack)); + }); + connect(m_backend, &MediaPlayerBackend::volumeChanged, this, &QIviMediaPlayerQtRoAdapter::volumeChanged); + connect(m_backend, &MediaPlayerBackend::mutedChanged, this, &QIviMediaPlayerQtRoAdapter::mutedChanged); + connect(m_backend, &MediaPlayerBackend::dataFetched, this, &QIviMediaPlayerQtRoAdapter::dataFetched); + connect(m_backend, &MediaPlayerBackend::dataChanged, this, &QIviMediaPlayerQtRoAdapter::dataChanged); + connect(m_backend, &MediaPlayerBackend::countChanged, this, &QIviMediaPlayerQtRoAdapter::countChanged); +} + +QIviMediaPlayer::PlayMode QIviMediaPlayerQtRoAdapter::playMode() const +{ + return m_backend->playMode(); +} + +QIviMediaPlayer::PlayState QIviMediaPlayerQtRoAdapter::playState() const +{ + return m_backend->playState(); +} + +qint64 QIviMediaPlayerQtRoAdapter::position() const +{ + return m_backend->position(); +} + +qint64 QIviMediaPlayerQtRoAdapter::duration() const +{ + return m_backend->duration(); +} + +QVariant QIviMediaPlayerQtRoAdapter::currentTrack() const +{ + //Workaround QtRO problem + QVariant v = m_backend->currentTrack(); + return QVariant(QMetaType::QVariant, &v); +} + +int QIviMediaPlayerQtRoAdapter::currentIndex() const +{ + return m_backend->currentIndex(); +} + +int QIviMediaPlayerQtRoAdapter::volume() const +{ + return m_backend->volume(); +} + +bool QIviMediaPlayerQtRoAdapter::muted() const +{ + return m_backend->isMuted(); +} + +bool QIviMediaPlayerQtRoAdapter::canReportCount() const +{ + return m_backend->canReportCount(); +} + +void QIviMediaPlayerQtRoAdapter::setPlayMode(QIviMediaPlayer::PlayMode playMode) +{ + m_backend->setPlayMode(playMode); +} + +void QIviMediaPlayerQtRoAdapter::setPosition(qint64 position) +{ + m_backend->setPosition(position); +} + +void QIviMediaPlayerQtRoAdapter::setCurrentIndex(int currentIndex) +{ + m_backend->setCurrentIndex(currentIndex); +} + +void QIviMediaPlayerQtRoAdapter::setVolume(int volume) +{ + m_backend->setVolume(volume); +} + +void QIviMediaPlayerQtRoAdapter::setMuted(bool muted) +{ + m_backend->setMuted(muted); +} + +void QIviMediaPlayerQtRoAdapter::play() +{ + m_backend->play(); +} + +void QIviMediaPlayerQtRoAdapter::pause() +{ + m_backend->pause(); +} + +void QIviMediaPlayerQtRoAdapter::stop() +{ + m_backend->stop(); +} + +void QIviMediaPlayerQtRoAdapter::seek(qint64 offset) +{ + m_backend->seek(offset); +} + +void QIviMediaPlayerQtRoAdapter::next() +{ + m_backend->next(); +} + +void QIviMediaPlayerQtRoAdapter::previous() +{ + m_backend->previous(); +} + +void QIviMediaPlayerQtRoAdapter::fetchData(const QUuid &identifier, int start, int count) +{ + m_backend->fetchData(identifier, start, count); +} + +void QIviMediaPlayerQtRoAdapter::insert(int index, const QVariant &item) +{ + m_backend->insert(index, item); +} + +void QIviMediaPlayerQtRoAdapter::remove(int index) +{ + m_backend->remove(index); +} + +void QIviMediaPlayerQtRoAdapter::move(int currentIndex, int newIndex) +{ + m_backend->move(currentIndex, newIndex); +} diff --git a/src/tools/media-simulation-server/qivimediaplayerqtroadapter.h b/src/tools/media-simulation-server/qivimediaplayerqtroadapter.h new file mode 100644 index 0000000..887ab55 --- /dev/null +++ b/src/tools/media-simulation-server/qivimediaplayerqtroadapter.h @@ -0,0 +1,94 @@ + +/**************************************************************************** +** +** Copyright (C) 2019 Luxoft Sweden AB +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtIVI module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL-QTAS$ +** Commercial License Usage +** Licensees holding valid commercial Qt Automotive Suite licenses may use +** this file in accordance with the commercial license agreement provided +** with the Software or, alternatively, in accordance with the terms +** contained in a written agreement between you and The Qt Company. For +** licensing terms and conditions see https://www.qt.io/terms-conditions. +** For further information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +** SPDX-License-Identifier: LGPL-3.0 +** +****************************************************************************/ + +#ifndef QIVIMEDIAPLAYERQTROADAPTER_H +#define QIVIMEDIAPLAYERQTROADAPTER_H + +#include "mediaplayerbackend.h" +#include "rep_qivimediaplayer_source.h" + +template <class ObjectType> +struct QIviMediaPlayerAddressWrapper: public QIviMediaPlayerSourceAPI<ObjectType> { + QIviMediaPlayerAddressWrapper(ObjectType *object, const QString &name = QStringLiteral("QtIviMedia.QIviMediaPlayer")) + : QIviMediaPlayerSourceAPI<ObjectType>(object, name) + {} +}; + +class QIviMediaPlayerQtRoAdapter : public QIviMediaPlayerSource +{ +public: + QIviMediaPlayerQtRoAdapter(MediaPlayerBackend *parent); + +public: + QIviMediaPlayer::PlayMode playMode() const override; + QIviMediaPlayer::PlayState playState() const override; + qint64 position() const override; + qint64 duration() const override; + QVariant currentTrack() const override; + int currentIndex() const override; + int volume() const override; + bool muted() const override; + bool canReportCount() const override; + void setPlayMode(QIviMediaPlayer::PlayMode playMode) override; + void setPosition(qint64 position) override; + void setCurrentIndex(int currentIndex) override; + void setVolume(int volume) override; + void setMuted(bool muted) override; + +public Q_SLOTS: + void play() override; + void pause() override; + void stop() override; + void seek(qint64 offset) override; + void next() override; + void previous() override; + void fetchData(const QUuid &identifier, int start, int count) override; + void insert(int index, const QVariant &item) override; + void remove(int index) override; + void move(int currentIndex, int newIndex) override; + +private: + MediaPlayerBackend *m_backend; + quint64 m_replyCounter; +}; + +#endif // QIVIMEDIAPLAYERQTROADAPTER_H diff --git a/src/tools/media-simulation-server/qivisearchandbrowsemodel.rep b/src/tools/media-simulation-server/qivisearchandbrowsemodel.rep new file mode 100644 index 0000000..03b385b --- /dev/null +++ b/src/tools/media-simulation-server/qivisearchandbrowsemodel.rep @@ -0,0 +1,38 @@ + +#include <QtIviCore/QIviSearchAndBrowseModel> +#include <QtIviCore/QIviFilterTerm> +#include <QtCore/QUuid> + +POD QIviSearchAndBrowseModelPendingResult(quint64 id, bool failed) + +class QIviSearchAndBrowseModel +{ + PROP(QStringList availableContentTypes READONLY) + + SLOT(void setContentType(const QUuid &identifier, const QString &contentType)); + SLOT(void setupFilter(const QUuid &identifier, const QVariant &term, const QList<QIviOrderTerm> &orderTerms)); + + SLOT(QVariant goBack(const QUuid &identifier)); + SLOT(QVariant goForward(const QUuid &identifier, int index)); + SLOT(QVariant insert(const QUuid &identifier, int index, const QVariant &item)); + SLOT(QVariant remove(const QUuid &identifier, int index)); + SLOT(QVariant move(const QUuid &identifier, int currentIndex, int newIndex)); + SLOT(QVariant indexOf(const QUuid &identifier, const QVariant &item)); + + //PagingModel + SLOT(void registerInstance(const QUuid &identifier)) + SLOT(void unregisterInstance(const QUuid &identifier)) + SLOT(void fetchData(const QUuid &identifier, int start, int count)) + + SIGNAL(canGoForwardChanged(const QUuid &identifier, const QVector<bool> &indexes, int start)) + SIGNAL(canGoBackChanged(const QUuid &identifier, bool canGoBack)) + SIGNAL(supportedCapabilitiesChanged(const QUuid &identifier, QtIviCoreModule::ModelCapabilities capabilities)) + SIGNAL(contentTypeChanged(const QUuid &identifier, const QString &contentType)) + SIGNAL(queryIdentifiersChanged(const QUuid &identifier, const QSet<QString> &queryIdentifiers)) + SIGNAL(countChanged(const QUuid &identifier, int newLength)) + SIGNAL(dataFetched(const QUuid &identifier, const QList<QVariant> &data, int start, bool moreAvailable)) + SIGNAL(dataChanged(const QUuid &identifier, const QList<QVariant> &data, int start, int count)) + + //generic async support + SIGNAL(pendingResultAvailable(quint64 id, bool isSuccess, const QVariant &value)) +}; diff --git a/src/tools/media-simulation-server/qivisearchandbrowsemodelqtroadapter.cpp b/src/tools/media-simulation-server/qivisearchandbrowsemodelqtroadapter.cpp new file mode 100644 index 0000000..098f94e --- /dev/null +++ b/src/tools/media-simulation-server/qivisearchandbrowsemodelqtroadapter.cpp @@ -0,0 +1,248 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Luxoft Sweden AB +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtIVI module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL-QTAS$ +** Commercial License Usage +** Licensees holding valid commercial Qt Automotive Suite licenses may use +** this file in accordance with the commercial license agreement provided +** with the Software or, alternatively, in accordance with the terms +** contained in a written agreement between you and The Qt Company. For +** licensing terms and conditions see https://www.qt.io/terms-conditions. +** For further information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +** SPDX-License-Identifier: LGPL-3.0 +** +****************************************************************************/ + +#include "qivisearchandbrowsemodelqtroadapter.h" +#include "qiviqmlconversion_helper.h" + +Q_LOGGING_CATEGORY(qLcROQIviSearchAndBrowseModel, "qtivi.qivisearchandbrowsemodel.remoteobjects", QtInfoMsg) + +QIviSearchAndBrowseModelQtRoAdapter::QIviSearchAndBrowseModelQtRoAdapter(QIviSearchAndBrowseModelInterface *parent) + : QIviSearchAndBrowseModelSource(parent) + , m_backend(parent) + , m_replyCounter(0) +{ + connect(m_backend, &SearchAndBrowseBackend::dataFetched, this, &QIviSearchAndBrowseModelQtRoAdapter::dataFetched); + connect(m_backend, &SearchAndBrowseBackend::dataChanged, this, &QIviSearchAndBrowseModelQtRoAdapter::dataChanged); + connect(m_backend, &SearchAndBrowseBackend::countChanged, this, &QIviSearchAndBrowseModelQtRoAdapter::countChanged); + connect(m_backend, &SearchAndBrowseBackend::canGoBackChanged, this, &QIviSearchAndBrowseModelQtRoAdapter::canGoBackChanged); + connect(m_backend, &SearchAndBrowseBackend::canGoForwardChanged, this, &QIviSearchAndBrowseModelQtRoAdapter::canGoForwardChanged); + connect(m_backend, &SearchAndBrowseBackend::supportedCapabilitiesChanged, this, &QIviSearchAndBrowseModelQtRoAdapter::supportedCapabilitiesChanged); + connect(m_backend, &SearchAndBrowseBackend::availableContentTypesChanged, this, &QIviSearchAndBrowseModelQtRoAdapter::availableContentTypesChanged); + connect(m_backend, &SearchAndBrowseBackend::contentTypeChanged, this, &QIviSearchAndBrowseModelQtRoAdapter::contentTypeChanged); + connect(m_backend, &SearchAndBrowseBackend::queryIdentifiersChanged, this, &QIviSearchAndBrowseModelQtRoAdapter::queryIdentifiersChanged); +} + +QStringList QIviSearchAndBrowseModelQtRoAdapter::availableContentTypes() const +{ + return m_backend->property("availableContentTypes").toStringList(); +} + +void QIviSearchAndBrowseModelQtRoAdapter::setContentType(const QUuid &identifier, const QString &contentType) +{ + m_backend->setContentType(identifier, contentType); +} + +void QIviSearchAndBrowseModelQtRoAdapter::setupFilter(const QUuid &identifier, const QVariant &term, const QList<QIviOrderTerm> &orderTerms) +{ + QByteArray data = term.toByteArray(); + QDataStream stream(data); + QIviAbstractQueryTerm *t = nullptr; + if (!data.isEmpty()) + stream >> &t; + m_backend->setupFilter(identifier, t, orderTerms); +} + +QVariant QIviSearchAndBrowseModelQtRoAdapter::goBack(const QUuid &identifier) +{ + QIviPendingReplyBase pendingReply = m_backend->goBack(identifier); + qCDebug(qLcROQIviSearchAndBrowseModel) << Q_FUNC_INFO; + if (pendingReply.isSuccessful()) { + qCDebug(qLcROQIviSearchAndBrowseModel) << "Returning result right away"; + return pendingReply.value(); + } else { //reply not yet ready or failed + const quint64 id = ++m_replyCounter; + if (pendingReply.isResultAvailable()) { // the call failed + qCDebug(qLcROQIviSearchAndBrowseModel) << "Returning failed reply"; + return QVariant::fromValue(QIviSearchAndBrowseModelPendingResult(id, true /* failed */)); + } + QIviSearchAndBrowseModelPendingResult result = QIviSearchAndBrowseModelPendingResult(id, false /* failed */); + qCDebug(qLcROQIviSearchAndBrowseModel) << "Returning a pending result: id:" << id; + connect(pendingReply.watcher(), &QIviPendingReplyWatcher::valueChanged, this, [this, pendingReply, id] (const QVariant &value) { + qCDebug(qLcROQIviSearchAndBrowseModel) << "Value for pending result available: id:" << id << "value:" << value; + emit pendingResultAvailable(id, pendingReply.isSuccessful(), value); + }); + return QVariant::fromValue(result); + } + + return QVariant(); +} + +QVariant QIviSearchAndBrowseModelQtRoAdapter::goForward(const QUuid &identifier, int index) +{ + QIviPendingReplyBase pendingReply = m_backend->goForward(identifier, index); + qCDebug(qLcROQIviSearchAndBrowseModel) << Q_FUNC_INFO; + if (pendingReply.isSuccessful()) { + qCDebug(qLcROQIviSearchAndBrowseModel) << "Returning result right away"; + return pendingReply.value(); + } else { //reply not yet ready or failed + const quint64 id = ++m_replyCounter; + if (pendingReply.isResultAvailable()) { // the call failed + qCDebug(qLcROQIviSearchAndBrowseModel) << "Returning failed reply"; + return QVariant::fromValue(QIviSearchAndBrowseModelPendingResult(id, true /* failed */)); + } + QIviSearchAndBrowseModelPendingResult result = QIviSearchAndBrowseModelPendingResult(id, false /* failed */); + qCDebug(qLcROQIviSearchAndBrowseModel) << "Returning a pending result: id:" << id; + connect(pendingReply.watcher(), &QIviPendingReplyWatcher::valueChanged, this, [this, pendingReply, id] (const QVariant &value) { + qCDebug(qLcROQIviSearchAndBrowseModel) << "Value for pending result available: id:" << id << "value:" << value; + emit pendingResultAvailable(id, pendingReply.isSuccessful(), value); + }); + return QVariant::fromValue(result); + } + + return QVariant(); +} + +void QIviSearchAndBrowseModelQtRoAdapter::registerInstance(const QUuid &identifier) +{ + m_backend->registerInstance(identifier); +} + +void QIviSearchAndBrowseModelQtRoAdapter::unregisterInstance(const QUuid &identifier) +{ + m_backend->unregisterInstance(identifier); +} + +void QIviSearchAndBrowseModelQtRoAdapter::fetchData(const QUuid &identifier, int start, int count) +{ + m_backend->fetchData(identifier, start, count); +} + +QVariant QIviSearchAndBrowseModelQtRoAdapter::insert(const QUuid &identifier, int index, const QVariant &item) +{ + QIviPendingReplyBase pendingReply = m_backend->insert(identifier, index, item); + qCDebug(qLcROQIviSearchAndBrowseModel) << Q_FUNC_INFO; + if (pendingReply.isSuccessful()) { + qCDebug(qLcROQIviSearchAndBrowseModel) << "Returning result right away"; + return pendingReply.value(); + } else { //reply not yet ready or failed + const quint64 id = ++m_replyCounter; + if (pendingReply.isResultAvailable()) { // the call failed + qCDebug(qLcROQIviSearchAndBrowseModel) << "Returning failed reply"; + return QVariant::fromValue(QIviSearchAndBrowseModelPendingResult(id, true /* failed */)); + } + QIviSearchAndBrowseModelPendingResult result = QIviSearchAndBrowseModelPendingResult(id, false /* failed */); + qCDebug(qLcROQIviSearchAndBrowseModel) << "Returning a pending result: id:" << id; + connect(pendingReply.watcher(), &QIviPendingReplyWatcher::valueChanged, this, [this, pendingReply, id] (const QVariant &value) { + qCDebug(qLcROQIviSearchAndBrowseModel) << "Value for pending result available: id:" << id << "value:" << value; + emit pendingResultAvailable(id, pendingReply.isSuccessful(), value); + }); + return QVariant::fromValue(result); + } + + return QVariant(); +} + +QVariant QIviSearchAndBrowseModelQtRoAdapter::remove(const QUuid &identifier, int index) +{ + QIviPendingReplyBase pendingReply = m_backend->remove(identifier, index); + qCDebug(qLcROQIviSearchAndBrowseModel) << Q_FUNC_INFO; + if (pendingReply.isSuccessful()) { + qCDebug(qLcROQIviSearchAndBrowseModel) << "Returning result right away"; + return pendingReply.value(); + } else { //reply not yet ready or failed + const quint64 id = ++m_replyCounter; + if (pendingReply.isResultAvailable()) { // the call failed + qCDebug(qLcROQIviSearchAndBrowseModel) << "Returning failed reply"; + return QVariant::fromValue(QIviSearchAndBrowseModelPendingResult(id, true /* failed */)); + } + QIviSearchAndBrowseModelPendingResult result = QIviSearchAndBrowseModelPendingResult(id, false /* failed */); + qCDebug(qLcROQIviSearchAndBrowseModel) << "Returning a pending result: id:" << id; + connect(pendingReply.watcher(), &QIviPendingReplyWatcher::valueChanged, this, [this, pendingReply, id] (const QVariant &value) { + qCDebug(qLcROQIviSearchAndBrowseModel) << "Value for pending result available: id:" << id << "value:" << value; + emit pendingResultAvailable(id, pendingReply.isSuccessful(), value); + }); + return QVariant::fromValue(result); + } + + return QVariant(); +} + +QVariant QIviSearchAndBrowseModelQtRoAdapter::move(const QUuid &identifier, int currentIndex, int newIndex) +{ + QIviPendingReplyBase pendingReply = m_backend->move(identifier, currentIndex, newIndex); + qCDebug(qLcROQIviSearchAndBrowseModel) << Q_FUNC_INFO; + if (pendingReply.isSuccessful()) { + qCDebug(qLcROQIviSearchAndBrowseModel) << "Returning result right away"; + return pendingReply.value(); + } else { //reply not yet ready or failed + const quint64 id = ++m_replyCounter; + if (pendingReply.isResultAvailable()) { // the call failed + qCDebug(qLcROQIviSearchAndBrowseModel) << "Returning failed reply"; + return QVariant::fromValue(QIviSearchAndBrowseModelPendingResult(id, true /* failed */)); + } + QIviSearchAndBrowseModelPendingResult result = QIviSearchAndBrowseModelPendingResult(id, false /* failed */); + qCDebug(qLcROQIviSearchAndBrowseModel) << "Returning a pending result: id:" << id; + connect(pendingReply.watcher(), &QIviPendingReplyWatcher::valueChanged, this, [this, pendingReply, id] (const QVariant &value) { + qCDebug(qLcROQIviSearchAndBrowseModel) << "Value for pending result available: id:" << id << "value:" << value; + emit pendingResultAvailable(id, pendingReply.isSuccessful(), value); + }); + return QVariant::fromValue(result); + } + + return QVariant(); +} + +QVariant QIviSearchAndBrowseModelQtRoAdapter::indexOf(const QUuid &identifier, const QVariant &item) +{ + QIviPendingReplyBase pendingReply = m_backend->indexOf(identifier, item); + qCDebug(qLcROQIviSearchAndBrowseModel) << Q_FUNC_INFO; + if (pendingReply.isSuccessful()) { + qCDebug(qLcROQIviSearchAndBrowseModel) << "Returning result right away"; + return pendingReply.value(); + } else { //reply not yet ready or failed + const quint64 id = ++m_replyCounter; + if (pendingReply.isResultAvailable()) { // the call failed + qCDebug(qLcROQIviSearchAndBrowseModel) << "Returning failed reply"; + return QVariant::fromValue(QIviSearchAndBrowseModelPendingResult(id, true /* failed */)); + } + QIviSearchAndBrowseModelPendingResult result = QIviSearchAndBrowseModelPendingResult(id, false /* failed */); + qCDebug(qLcROQIviSearchAndBrowseModel) << "Returning a pending result: id:" << id; + connect(pendingReply.watcher(), &QIviPendingReplyWatcher::valueChanged, this, [this, pendingReply, id] (const QVariant &value) { + qCDebug(qLcROQIviSearchAndBrowseModel) << "Value for pending result available: id:" << id << "value:" << value; + emit pendingResultAvailable(id, pendingReply.isSuccessful(), value); + }); + return QVariant::fromValue(result); + } + + return QVariant(); +} + + diff --git a/src/tools/media-simulation-server/qivisearchandbrowsemodelqtroadapter.h b/src/tools/media-simulation-server/qivisearchandbrowsemodelqtroadapter.h new file mode 100644 index 0000000..05247fc --- /dev/null +++ b/src/tools/media-simulation-server/qivisearchandbrowsemodelqtroadapter.h @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Luxoft Sweden AB +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtIVI module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL-QTAS$ +** Commercial License Usage +** Licensees holding valid commercial Qt Automotive Suite licenses may use +** this file in accordance with the commercial license agreement provided +** with the Software or, alternatively, in accordance with the terms +** contained in a written agreement between you and The Qt Company. For +** licensing terms and conditions see https://www.qt.io/terms-conditions. +** For further information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +** SPDX-License-Identifier: LGPL-3.0 +** +****************************************************************************/ + +#ifndef QIVISEARCHANDBROWSEMODELQTROADAPTER_H +#define QIVISEARCHANDBROWSEMODELQTROADAPTER_H + +#include "searchandbrowsebackend.h" +#include "rep_qivisearchandbrowsemodel_source.h" + +template <class ObjectType> +struct QIviSearchAndBrowseModelAddressWrapper: public QIviSearchAndBrowseModelSourceAPI<ObjectType> { + QIviSearchAndBrowseModelAddressWrapper(ObjectType *object, const QString &name = QStringLiteral("QIviSearchAndBrowseModel")) + : QIviSearchAndBrowseModelSourceAPI<ObjectType>(object, name) + {} +}; + +class QIviSearchAndBrowseModelQtRoAdapter : public QIviSearchAndBrowseModelSource +{ +public: + QIviSearchAndBrowseModelQtRoAdapter(QIviSearchAndBrowseModelInterface *parent); + + QStringList availableContentTypes() const override; + +public Q_SLOTS: + void setContentType(const QUuid &identifier, const QString &contentType) override; + void setupFilter(const QUuid &identifier, const QVariant &term, const QList<QIviOrderTerm> &orderTerms) override; + QVariant goBack(const QUuid &identifier) override; + QVariant goForward(const QUuid &identifier, int index) override; + QVariant insert(const QUuid &identifier, int index, const QVariant &item) override; + QVariant remove(const QUuid &identifier, int index) override; + QVariant move(const QUuid &identifier, int currentIndex, int newIndex) override; + QVariant indexOf(const QUuid &identifier, const QVariant &item) override; + + void registerInstance(const QUuid &identifier) override; + void unregisterInstance(const QUuid &identifier) override; + void fetchData(const QUuid &identifier, int start, int count) override; + +private: + QIviSearchAndBrowseModelInterface *m_backend; + quint64 m_replyCounter; + +}; + +#endif // QIVISEARCHANDBROWSEMODELQTROADAPTER_H |